diff --git a/metactl/cmd/metactl/v0/gen.go b/metactl/cmd/metactl/v0/gen.go index cec8327..543bd41 100644 --- a/metactl/cmd/metactl/v0/gen.go +++ b/metactl/cmd/metactl/v0/gen.go @@ -25,19 +25,14 @@ var genCmd = &cobra.Command{ return } - var sdkNames []string - for _, sdk0 := range c.V0.Gen.Sdks { - sdkNames = append(sdkNames, sdk0.Names...) - } - - errs = sdk.Reset(sdkNames) + errs = sdk.Reset(c.V0.Gen.Sdks) if len(errs) != 0 { return } - for _, sdk0 := range c.V0.Gen.Sdks { - for _, name := range sdk0.Names { - errs = sdk.Gen(d.MessageReport, d.FileSystem, d.Version, d.RootNode, name, sdk0.Data, sdk0.Endpoints, nil) + for _, c := range c.V0.Gen.Sdks { + for _, name := range c.Names { + errs = sdk.Gen(d.MessageReport, d.FileSystem, d.Version, d.RootNode, name, c, nil) if len(errs) != 0 { return } diff --git a/metactl/pkg/v0/business/sdk/sdk.go b/metactl/pkg/v0/business/sdk/sdk.go index 3d7403c..58d2319 100644 --- a/metactl/pkg/v0/business/sdk/sdk.go +++ b/metactl/pkg/v0/business/sdk/sdk.go @@ -5,6 +5,7 @@ import ( "github.com/metamatex/metamate/asg/pkg/v0/asg/graph" "github.com/metamatex/metamate/metactl/pkg/v0/business/gen" _go "github.com/metamatex/metamate/metactl/pkg/v0/business/sdk/go" + "github.com/metamatex/metamate/metactl/pkg/v0/business/sdk/typescript" "github.com/metamatex/metamate/metactl/pkg/v0/types" "github.com/metamatex/metamate/metactl/pkg/v0/utils/ptr" "github.com/pkg/errors" @@ -12,8 +13,9 @@ import ( "sort" ) -func GetSdks() (sdks []types.Sdk) { +func GetSdks() (sdks []types.SdkGenerator) { sdks = append(sdks, _go.GetSdks()...) + sdks = append(sdks, typescript.GetSdks()...) sort.Slice(sdks, func(i, j int) bool { return sdks[i].Name < sdks[j].Name @@ -22,7 +24,7 @@ func GetSdks() (sdks []types.Sdk) { return sdks } -func Format(sdks []types.Sdk) (s string) { +func Format(sdks []types.SdkGenerator) (s string) { for _, sdk := range sdks { s += sdk.Name + " : " + sdk.Description + "\n" } @@ -30,48 +32,50 @@ func Format(sdks []types.Sdk) (s string) { return } -func Reset(names []string) (errs []error) { - for _, name := range names { - sdk, err := getSdk(name) - if err != nil { - errs = append(errs, err) +func Reset(cs []types.SdkConfig) (errs []error) { + for _, c := range cs { + for _, n := range c.Names { + g, err := getSdkGenerator(n) + if err != nil { + errs = append(errs, err) - return - } + return + } - err = sdk.Reset() - if err != nil { - errs = append(errs, err) + err = g.Reset(c) + if err != nil { + errs = append(errs, err) - return + return + } } } return } -func Gen(report *types.MessageReport, fs afero.Fs, version types.Version, rn *graph.RootNode, name string, data map[string]interface{}, endpointFilter *graph.Filter, typeFilter *graph.Filter) (errs []error) { - sdk, err := getSdk(name) +func Gen(report *types.MessageReport, fs afero.Fs, version types.Version, rn *graph.RootNode, name string, c types.SdkConfig, typeFilter *graph.Filter) (errs []error) { + sdk, err := getSdkGenerator(name) if err != nil { errs = append(errs, err) return } - err = sdk.Init(&sdk, data) + err = sdk.Init(&sdk, c) if err != nil { errs = append(errs, err) return } - if endpointFilter != nil { + if c.Endpoints != nil { for i, _ := range sdk.Tasks { if sdk.Tasks[i].Dependencies == nil { sdk.Tasks[i].Dependencies = &types.RenderTaskDependencies{} } - sdk.Tasks[i].Dependencies.Endpoints = endpointFilter + sdk.Tasks[i].Dependencies.Endpoints = c.Endpoints } } @@ -106,7 +110,7 @@ func Gen(report *types.MessageReport, fs afero.Fs, version types.Version, rn *gr return } -func getSdk(name string) (sdk types.Sdk, err error) { +func getSdkGenerator(name string) (sdk types.SdkGenerator, err error) { for _, sdk = range GetSdks() { if sdk.Name == name { return diff --git a/metactl/pkg/v0/business/sdk/typescript/httpjson_client.go b/metactl/pkg/v0/business/sdk/typescript/httpjson_client.go new file mode 100644 index 0000000..24acbae --- /dev/null +++ b/metactl/pkg/v0/business/sdk/typescript/httpjson_client.go @@ -0,0 +1,97 @@ +package typescript + +import ( + "github.com/metamatex/metamate/metactl/pkg/v0/types" + "github.com/metamatex/metamate/metactl/pkg/v0/utils/ptr" +) + +const ( + TaskHttpJsonClient = "TaskHttpJsonClient" +) + +func init() { + tasks[TaskHttpJsonClient] = types.RenderTask{ + TemplateData: &typescriptHttpJsonClientTpl, + Out: ptr.String("mql_.ts"), + } +} + +var typescriptHttpJsonClientTpl = `import * as axios from 'axios'; + +export interface ClientOpts { + client: axios.AxiosInstance; + addr: string; +} + +export class Client { + opts: ClientOpts; + + constructor(opts: ClientOpts) { + this.opts = opts; + } + {{ range $i, $endpoint := .Endpoints }} + async {{ $endpoint.Name }}(req: {{ $endpoint.Edges.Type.Request.Name }}): Promise<{{ $endpoint.Edges.Type.Response.Name }}> { + let rsp = await this.opts.client.request<{{ $endpoint.Edges.Type.Response.Name }}>({ + url: this.opts.addr, + method: "post", + data: req, + headers: { + "X-MetaMate-Type": "{{ $endpoint.Edges.Type.Request.Name }}", + "Content-Type": "application/json; charset=utf-8", + }, + }); + + return rsp.data + } + {{ end }} +} +{{ range $i, $enum := .Enums }} +export const {{ $enum.Name }} = Object.freeze({ +{{- range $vi, $value := sortAlpha $enum.Data.Values }} + {{ camel $value }}: "{{ $value }}", +{{- end }} +}); +{{ end }} + +{{- range $i, $type := .Types }} +export interface {{ $type.Name }} { +{{- range $i, $fn := $type.Edges.Fields.Holds.Slice.Sort }} +{{- if $fn.IsBool }} + {{ $fn.Name }}?: boolean; +{{- end }} +{{- if $fn.IsFloat64 }} + {{ $fn.Name }}?: number; +{{- end }} +{{- if $fn.IsString }} + {{ $fn.Name }}?: string; +{{- end }} +{{- if $fn.IsInt32 }} + {{ $fn.Name }}?: number; +{{- end }} +{{- if $fn.IsType }} + {{ $fn.Name }}?: {{ camel $fn.Edges.Type.Holds.Name }}; +{{- end }} +{{- if $fn.IsEnum }} + {{ $fn.Name }}?: string; +{{- end }} +{{- if $fn.IsStringList }} + {{ $fn.Name }}?: string[]; +{{- end }} +{{- if $fn.IsInt32List }} + {{ $fn.Name }}?: number[]; +{{- end }} +{{- if $fn.IsFloat64List }} + {{ $fn.Name }}?: number[]; +{{- end }} +{{- if $fn.IsBoolList }} + {{ $fn.Name }}?: boolean[]; +{{- end }} +{{- if $fn.IsTypeList }} + {{ $fn.Name }}?: {{ camel $fn.Edges.Type.Holds.Name }}[]; +{{- end }} +{{- if $fn.IsEnumList }} + {{ $fn.Name }}?: string[]; +{{- end }} +{{- end }} +} +{{ end }}`