Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cli/cmd/encore/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (

"encr.dev/cli/cmd/encore/cmdutil"
"encr.dev/cli/internal/manifest"
"encr.dev/internal/clientgen"
"encr.dev/pkg/appfile"
"encr.dev/pkg/clientgen"
daemonpb "encr.dev/proto/encore/daemon"
)

Expand All @@ -32,6 +32,7 @@ func init() {
endpointTags []string
excludedEndpointTags []string
openAPIExcludePrivateEndpoints bool
tsSharedTypes bool
)

genClientCmd := &cobra.Command{
Expand Down Expand Up @@ -118,6 +119,7 @@ To further narrow down the services to generate, use the '--services' flag.
EndpointTags: endpointTags,
ExcludedEndpointTags: excludedEndpointTags,
OpenapiExcludePrivateEndpoints: &openAPIExcludePrivateEndpoints,
TsSharedTypes: &tsSharedTypes,
})
if err != nil {
fatal(err)
Expand Down Expand Up @@ -185,4 +187,6 @@ which may require the user-facing wrapper code to be manually generated.`,
StringSliceVar(&excludedEndpointTags, "excluded-tags", nil, "The names of endpoint tags to exclude in the output")
genClientCmd.Flags().
BoolVar(&openAPIExcludePrivateEndpoints, "openapi-exclude-private-endpoints", false, "Exclude private endpoints from the OpenAPI spec")
genClientCmd.Flags().
BoolVar(&tsSharedTypes, "ts:shared-types", false, "Import types from ~backend instead of re-generating them")
}
7 changes: 5 additions & 2 deletions cli/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import (
"encr.dev/cli/daemon/sqldb"
"encr.dev/cli/internal/platform"
"encr.dev/cli/internal/update"
"encr.dev/internal/clientgen"
"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/internal/version"
"encr.dev/pkg/builder"
"encr.dev/pkg/builder/builderimpl"
"encr.dev/pkg/clientgen"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/errlist"
"encr.dev/pkg/fns"
daemonpb "encr.dev/proto/encore/daemon"
Expand Down Expand Up @@ -147,6 +147,9 @@ func (s *Server) GenClient(ctx context.Context, params *daemonpb.GenClientReques
if params.OpenapiExcludePrivateEndpoints != nil {
opts.OpenAPIExcludePrivateEndpoints = *params.OpenapiExcludePrivateEndpoints
}
if params.TsSharedTypes != nil {
opts.TSSharedTypes = *params.TsSharedTypes
}
code, err := clientgen.Client(lang, params.AppId, md, servicesToGenerate, tagSet, opts)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
Expand Down
2 changes: 1 addition & 1 deletion cli/daemon/dash/ai/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"slices"
"strings"

"encr.dev/internal/clientgen"
"encr.dev/pkg/clientgen"
meta "encr.dev/proto/encore/parser/meta/v1"
schema "encr.dev/proto/encore/parser/schema/v1"
"encr.dev/v2/internals/resourcepaths"
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/echo_app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (
"encr.dev/cli/daemon/namespace"
. "encr.dev/cli/daemon/run"
"encr.dev/cli/daemon/run/infra"
"encr.dev/internal/clientgen"
"encr.dev/internal/clientgen/clientgentypes"
. "encr.dev/internal/optracker"
"encr.dev/pkg/clientgen"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/golden"
"encr.dev/pkg/svcproxy"
"encr.dev/v2/v2builder"
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/testdata/echo_client/ts/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ class BaseClient {

// Add User-Agent header if the script is running in the server
// because browsers do not allow setting User-Agent headers to requests
if (typeof window === "undefined") {
if ( typeof globalThis === "object" && !("window" in globalThis) ) {
this.headers["User-Agent"] = "slug-Generated-TS-Client (Encore/v0.0.0-develop)";
}

Expand Down
10 changes: 7 additions & 3 deletions internal/clientgen/client.go → pkg/clientgen/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"path/filepath"
"strings"

"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/internal/clientgen/openapi"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/clientgen/openapi"
"encr.dev/pkg/errinsrc/srcerrors"
meta "encr.dev/proto/encore/parser/meta/v1"
)
Expand Down Expand Up @@ -69,7 +69,11 @@ func Client(
var gen generator
switch lang {
case LangTypeScript:
gen = &typescript{generatorVersion: typescriptGenLatestVersion}
if opts.TSSharedTypes && md.Language == meta.Lang_TYPESCRIPT {
gen = &typescript{generatorVersion: typescriptGenLatestVersion, sharedTypes: true, clientTarget: opts.TSClientTarget}
} else {
gen = &typescript{generatorVersion: typescriptGenLatestVersion, sharedTypes: false}
}
case LangJavascript:
gen = &javascript{generatorVersion: javascriptGenLatestVersion}
case LangGo:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/rogpeppe/go-internal/txtar"

"encr.dev/cli/daemon/apps"
"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/pkg/builder"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/golden"
"encr.dev/v2/tsbuilder"
"encr.dev/v2/v2builder"
Expand Down Expand Up @@ -72,6 +72,7 @@ func TestClientCodeGenerationFromGoApp(t *testing.T) {
c.Assert(ok, qt.IsTrue, qt.Commentf("Unable to detect language type for %s", file.Name()))

services := clientgentypes.AllServices(res.Meta)

generatedClient, err := Client(
language,
"app",
Expand Down Expand Up @@ -137,6 +138,10 @@ func TestClientCodeGenerationFromTSApp(t *testing.T) {
if strings.Contains(file.Name(), "openapi") {
language, ok = LangOpenAPI, true
}
options := clientgentypes.Options{}
if strings.Contains(file.Name(), "shared") {
options.TSSharedTypes = true
}
c.Assert(ok, qt.IsTrue, qt.Commentf("Unable to detect language type for %s", file.Name()))

services := clientgentypes.AllServices(res.Meta)
Expand All @@ -146,7 +151,7 @@ func TestClientCodeGenerationFromTSApp(t *testing.T) {
res.Meta,
services,
clientgentypes.TagSet{},
clientgentypes.Options{},
options,
)
c.Assert(err, qt.IsNil)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
// Options for the client generator.
type Options struct {
OpenAPIExcludePrivateEndpoints bool
TSSharedTypes bool
TSClientTarget string
}

type GenerateParams struct {
Expand Down
File renamed without changes.
29 changes: 26 additions & 3 deletions internal/clientgen/golang.go → pkg/clientgen/golang.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package clientgen
import (
"bytes"
"fmt"
"regexp"
"sort"
"strings"
"unicode"

"github.com/cockroachdb/errors"
. "github.com/dave/jennifer/jen"
"github.com/fatih/structtag"

"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/internal/gocodegen"
"encr.dev/internal/version"
"encr.dev/parser/encoding"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/idents"
meta "encr.dev/proto/encore/parser/meta/v1"
schema "encr.dev/proto/encore/parser/schema/v1"
Expand Down Expand Up @@ -769,11 +771,32 @@ func (g *golang) rpcCallSite(rpc *meta.RPC) (code []Code, err error) {
return code, err
}

// goIdentifier converts a string into a valid Go identifier.
func goIdentifier(input string) string {
if input == "" {
return "_"
}

// Convert string to rune slice for proper handling of Unicode characters
runes := []rune(input)

// Ensure the first character is a valid Go identifier start (letter or `_`)
if !unicode.IsLetter(runes[0]) && runes[0] != '_' {
runes[0] = '_'
}

// Regex to replace invalid characters (anything that isn't a letter, number, or `_`)
invalidChars := regexp.MustCompile(`[^\p{L}\p{N}_]`)
output := invalidChars.ReplaceAllString(string(runes), "_")

return output
}

func (g *golang) declToID(decl *schema.Decl) *Statement {
if g.skipPkgTypePrefix {
return Id(strings.Title(decl.Name))
return Id(goIdentifier(strings.Title(decl.Name)))
} else {
return Id(fmt.Sprintf("%s%s", strings.Title(decl.Loc.PkgName), strings.Title(decl.Name)))
return Id(goIdentifier(fmt.Sprintf("%s%s", strings.Title(decl.Loc.PkgName), strings.Title(decl.Name))))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"golang.org/x/text/cases"
"golang.org/x/text/language"

"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/pkg/clientgen/clientgentypes"
"encr.dev/pkg/idents"

"encr.dev/internal/version"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
"github.com/cockroachdb/errors"
"github.com/getkin/kin-openapi/openapi3"

"encr.dev/internal/clientgen/clientgentypes"
"encr.dev/parser/encoding"
"encr.dev/pkg/clientgen/clientgentypes"
meta "encr.dev/proto/encore/parser/meta/v1"
)

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class BaseClient {

// Add User-Agent header if the script is running in the server
// because browsers do not allow setting User-Agent headers to requests
if (typeof window === "undefined") {
if ( typeof globalThis === "object" && !("window" in globalThis) ) {
this.headers["User-Agent"] = "app-Generated-TS-Client (Encore/v0.0.0-develop)";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ class BaseClient {

// Add User-Agent header if the script is running in the server
// because browsers do not allow setting User-Agent headers to requests
if (typeof window === "undefined") {
if ( typeof globalThis === "object" && !("window" in globalThis) ) {
this.headers["User-Agent"] = "app-Generated-TS-Client (Encore/v0.0.0-develop)";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ class BaseClient {

// Add User-Agent header if the script is running in the server
// because browsers do not allow setting User-Agent headers to requests
if (typeof window === "undefined") {
if ( typeof globalThis === "object" && !("window" in globalThis) ) {
this.headers["User-Agent"] = "app-Generated-TS-Client (Encore/v0.0.0-develop)";
}

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ class SvcServiceClient {
await this.baseClient.callTypedAPI("POST", `/dummy`, JSON.stringify(body), {headers, query})
}

async imported(params) {
// Now make the actual call to the API
const resp = await this.baseClient.callTypedAPI("POST", `/imported`, JSON.stringify(params))
return await resp.json()
}

async onlyPathParams(pathParam, pathParam2) {
// Now make the actual call to the API
const resp = await this.baseClient.callTypedAPI("POST", `/path/${encodeURIComponent(pathParam)}/${encodeURIComponent(pathParam2)}`)
return await resp.json()
}

async root(params) {
// Convert our params into the objects we need for the request
const headers = makeRecord({
Expand Down
Loading