From 6bbbc742a13427692d16cb1f91b018559dcb0c45 Mon Sep 17 00:00:00 2001 From: Alexander Korelskiy Date: Fri, 27 Oct 2023 23:56:55 +0300 Subject: [PATCH] Add Dart rpc client generation, update dependencies, fix tests --- README.md | 44 ++++ dart/dart_client.go | 323 ++++++++++++++++++++++++++++ dart/dart_client_test.go | 35 +++ dart/dart_template.go | 82 +++++++ dart/testdata/client.dart | 118 ++++++++++ gen/gen.go | 74 ++++++- generator.go | 5 + go.mod | 6 +- go.sum | 6 + golang/rpcgen_test.go | 2 +- golang/testdata/catalogue_client.go | 3 +- openrpc/testdata/openrpc.json | 6 +- php/php_client.go | 2 +- php/php_client_test.go | 2 +- swift/swift_client_test.go | 2 +- 15 files changed, 700 insertions(+), 10 deletions(-) create mode 100644 dart/dart_client.go create mode 100644 dart/dart_client_test.go create mode 100644 dart/dart_template.go create mode 100755 dart/testdata/client.dart diff --git a/README.md b/README.md index ccb9d53..d1235ad 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/vmkteam/rpcgen)](https://goreportcard.com/report/github.com/vmkteam/rpcgen) [![Go Reference](https://pkg.go.dev/badge/github.com/vmkteam/rpcgen.svg)](https://pkg.go.dev/github.com/vmkteam/rpcgen) `rpcgen` is a JSON-RPC 2.0 client library generator for [zenrpc](https://github.com/vmkteam/zenrpc). It supports client generation for following languages: +- Dart - Golang - PHP - TypeScript @@ -45,6 +46,7 @@ import ( "net/http" "github.com/vmkteam/rpcgen/v2" + "github.com/vmkteam/rpcgen/v2/dart" "github.com/vmkteam/rpcgen/v2/golang" "github.com/vmkteam/rpcgen/v2/swift" "github.com/vmkteam/zenrpc/v2" @@ -59,6 +61,7 @@ func main() { http.HandleFunc("/client.ts", rpcgen.Handler(gen.TSClient(nil))) http.HandleFunc("/RpcClient.php", rpcgen.Handler(gen.PHPClient(""))) http.HandleFunc("/client.swift", rpcgen.Handler(gen.SwiftClient(swift.Settings{}))) + http.HandleFunc("/client.dart", rpcgen.Handler(gen.DartClient(dart.Settings{ Part: "client"}))) } ``` @@ -131,3 +134,44 @@ func main() { http.HandleFunc("/client.swift", rpcgen.Handler(gen.SwiftClient(swift.Settings{"", typeMapper}))) } ``` + +### Add custom Dart type mapper + +```go +package main + +import ( + "net/http" + + "github.com/vmkteam/rpcgen/v2" + "github.com/vmkteam/rpcgen/v2/dart" + "github.com/vmkteam/zenrpc/v2" + "github.com/vmkteam/zenrpc/v2/smd" +) + +func main() { + rpc := zenrpc.NewServer(zenrpc.Options{}) + + gen := rpcgen.FromSMD(rpc.SMD()) + + typeMapper := func(in smd.JSONSchema, param dart.Parameter) dart.Parameter { + if in.Type == smd.Object { + switch in.TypeName { + case "Time", "Date": + param.Type = "String" + } + } + if in.Type == smd.Array { + switch in.TypeName { + case "[]Date", "[]Time": + param.Type = "List" + param.ReturnType = "List" + } + } + + return param + } + + http.HandleFunc("/client.dart", rpcgen.Handler(gen.DartClient(dart.Settings{Part: "client", TypeMapper: typeMapper}))) +} +``` diff --git a/dart/dart_client.go b/dart/dart_client.go new file mode 100644 index 0000000..f9cf2bc --- /dev/null +++ b/dart/dart_client.go @@ -0,0 +1,323 @@ +package dart + +import ( + "bytes" + "fmt" + "regexp" + "sort" + "strings" + "text/template" + + "github.com/vmkteam/rpcgen/v2/gen" + "github.com/vmkteam/zenrpc/v2/smd" +) + +const ( + defaultPart = "generated_rpc_client" + + Bool = "bool" + Int = "int" + Double = "double" + String = "String" +) + +var ( + linebreakRegex = regexp.MustCompile("[\r\n]+") +) + +type Namespaces []Namespace + +type Namespace struct { + Name string + Methods []Method +} + +type Method struct { + Name string + SafeName string + Description []string + Parameters []Parameter + Returns Parameter + // all params and return models, used in method + Models []Parameter +} + +func (m Method) ParamsClass() string { + return m.SafeName + "Params" +} + +type Parameter struct { + Name string + Description string + Type string + BaseType string + ReturnType string + Optional bool + DefaultValue string + IsArray bool + IsObject bool + Properties []Parameter +} + +func (ns Namespaces) Models() []Parameter { + var out []Parameter + m := make(map[string]Parameter) + for _, namespace := range ns { + for _, method := range namespace.Methods { + for _, p := range method.Models { + m[p.Type] = p + } + } + } + for _, p := range m { + out = append(out, p) + } + sort.Slice(out, func(i, j int) bool { + return out[i].Type < out[j].Type + }) + return out +} + +type TypeMapper func(in smd.JSONSchema, dartType Parameter) Parameter + +type templateData struct { + gen.GeneratorData + Part string + Namespaces Namespaces + Models []Parameter +} + +type Generator struct { + schema smd.Schema + + settings Settings +} + +type Settings struct { + Part string + TypeMapper TypeMapper +} + +func NewClient(schema smd.Schema, settings Settings) *Generator { + return &Generator{schema: schema, settings: settings} +} + +// Generate returns generated Dart client +func (g *Generator) Generate() ([]byte, error) { + data := templateData{Part: defaultPart, GeneratorData: gen.DefaultGeneratorData()} + + if g.settings.Part != "" { + data.Part = g.settings.Part + } + + for _, namespaceName := range gen.GetNamespaceNames(g.schema) { + data.Namespaces = append(data.Namespaces, Namespace{ + Name: namespaceName, + Methods: g.getNamespaceMethods(g.schema, namespaceName), + }) + } + data.Models = data.Namespaces.Models() + + tmpl, err := template.New("dart_client").Funcs(gen.TemplateFuncs).Parse(client) + if err != nil { + return nil, err + } + + // compile template + var buf bytes.Buffer + if err := tmpl.Execute(&buf, data); err != nil { + return nil, err + } + + return buf.Bytes(), nil + +} + +// getNamespaceMethods return all namespace methods +func (g *Generator) getNamespaceMethods(schema smd.Schema, namespace string) (res []Method) { + for name, service := range schema.Services { + if gen.GetNamespace(name) == namespace { + res = append(res, g.newMethod(name, service)) + } + } + + sort.Slice(res, func(i, j int) bool { + return res[i].Name < res[j].Name + }) + + return res +} + +func (g *Generator) newMethod(methodName string, service smd.Service) Method { + desc := linebreakRegex.ReplaceAllString(service.Description, "\n") + + method := Method{ + Name: gen.GetMethodName(methodName), + SafeName: strings.ReplaceAll(gen.GetMethodName(methodName), ".", ""), + Description: strings.Split(desc, "\n"), + Returns: g.prepareParameter(service.Returns), + } + method.Parameters = g.prepareParameters(service.Parameters) + method.Models = g.prepareModels(service) + + return method +} + +func (g *Generator) prepareModels(service smd.Service) []Parameter { + var out []Parameter + + params := g.definitionsToParams(service) + params = append(params, g.prepareParameter(service.Returns)) + params = append(params, g.prepareParameters(service.Parameters)...) + // remove non-objects and empty objects + for i, p := range params { + if !params[i].IsObject || len(params[i].Properties) == 0 { + continue + } + out = append(out, p) + } + + return out +} + +func (g *Generator) definitionsToParams(service smd.Service) []Parameter { + var out []Parameter + for typeName, definition := range service.Returns.Definitions { + out = append(out, g.definitionToParam(typeName, definition)) + } + for _, p := range service.Parameters { + for typeName, definition := range p.Definitions { + out = append(out, g.definitionToParam(typeName, definition)) + } + } + return out +} + +func (g *Generator) definitionToParam(typeName string, definition smd.Definition) Parameter { + return Parameter{ + Name: typeName, + Type: typeName, + IsObject: definition.Type == smd.Object, + Properties: g.propertiesToParams(definition.Properties), + } +} + +// propertiesToParams convert smd.PropertyList to []Parameter +func (g *Generator) propertiesToParams(list smd.PropertyList) []Parameter { + var parameters []Parameter + for _, prop := range list { + p := Parameter{ + Name: prop.Name, + Optional: prop.Optional, + Description: prop.Description, + } + + pType := dartType(prop.Type) + if prop.Type == smd.Object && prop.Ref != "" { + pType = strings.TrimPrefix(prop.Ref, gen.DefinitionsPrefix) + p.IsObject = true + } + + if prop.Type == smd.Array { + pType = arrayType(prop.Items) + p.IsArray = true + } + + p.Type = pType + + if g.settings.TypeMapper != nil { + p = g.settings.TypeMapper(smd.JSONSchema{ + Name: prop.Name, + Type: prop.Type, + TypeName: pType, + Description: prop.Description, + Optional: prop.Optional, + }, p) + } + parameters = append(parameters, p) + } + + sort.Slice(parameters, func(i, j int) bool { + return parameters[i].Name < parameters[j].Name + }) + + return parameters +} + +func (g *Generator) prepareParameters(in []smd.JSONSchema) []Parameter { + var out []Parameter + for _, param := range in { + out = append(out, g.prepareParameter(param)) + } + + return out +} + +// prepareParameter create Parameter from smd.JSONSchema +func (g *Generator) prepareParameter(in smd.JSONSchema) Parameter { + out := Parameter{ + Name: in.Name, + Description: in.Description, + BaseType: dartType(in.Type), + Optional: in.Optional, + Properties: g.propertiesToParams(in.Properties), + } + + pType := dartType(in.Type) + if in.Type == smd.Object { + typeName := in.TypeName + if typeName == "" && in.Description != "" && smd.IsSMDTypeName(in.Description, in.Type) { + typeName = in.Description + } + + if typeName != "" { + pType = typeName + } + out.IsObject = true + } + + if in.Type == smd.Array { + pType = arrayType(in.Items) + out.IsArray = true + } + out.Type = pType + out.ReturnType = pType + + defaultValue := "" + if in.Default != nil { + defaultValue = string(*in.Default) + } + out.DefaultValue = defaultValue + + if g.settings.TypeMapper != nil { + out = g.settings.TypeMapper(in, out) + } + + return out +} + +// dartType convert smd types to dart types +func dartType(smdType string) string { + switch smdType { + case smd.String: + return String + case smd.Boolean: + return Bool + case smd.Float: + return Double + case smd.Integer: + return Int + } + return "void" +} + +func arrayType(items map[string]string) string { + var subType string + if scalar, ok := items["type"]; ok { + subType = dartType(scalar) + } + if ref, ok := items["$ref"]; ok { + subType = strings.TrimPrefix(ref, gen.DefinitionsPrefix) + } + return fmt.Sprintf("List<%s>", subType) +} diff --git a/dart/dart_client_test.go b/dart/dart_client_test.go new file mode 100644 index 0000000..c02ddf9 --- /dev/null +++ b/dart/dart_client_test.go @@ -0,0 +1,35 @@ +package dart + +import ( + "bytes" + "os" + "testing" + + "github.com/vmkteam/zenrpc/v2" + "github.com/vmkteam/zenrpc/v2/testdata" +) + +func TestGenerateDartClient(t *testing.T) { + rpc := zenrpc.NewServer(zenrpc.Options{}) + rpc.Register("catalogue", testdata.CatalogueService{}) + + cl := NewClient(rpc.SMD(), Settings{Part: "client"}) + + generated, err := cl.Generate() + if err != nil { + t.Fatalf("generate dart client: %v", err) + } + + testData, err := os.ReadFile("./testdata/client.dart") + if err != nil { + t.Fatalf("open test data file: %v", err) + } + + // cut first line with version from comparison + _, generatedBody, _ := bytes.Cut(generated, []byte{'\n'}) + _, testDataBody, _ := bytes.Cut(testData, []byte{'\n'}) + + if !bytes.Equal(generatedBody, testDataBody) { + t.Fatalf("bad generator output") + } +} diff --git a/dart/dart_template.go b/dart/dart_template.go new file mode 100644 index 0000000..0bc4a48 --- /dev/null +++ b/dart/dart_template.go @@ -0,0 +1,82 @@ +package dart + +const client = `/// Code generated from jsonrpc schema by rpcgen v{{ .Version }}; DO NOT EDIT. + +import 'package:json_annotation/json_annotation.dart'; +import 'package:smd_annotations/annotations.dart'; + +part '{{ .Part }}.g.dart'; +{{ range .Models }} +{{- if .Description }} +/// {{ .Description }} +{{- end }} +@JsonSerializable() +class {{ .Type }} { + {{- range .Properties }} + {{- if .Description }} + /// {{ .Description }} + {{- end }} + @JsonKey(name: '{{ .Name }}') + final {{ .Type }}{{ if .Optional }}?{{ end }} {{ .Name }}; + {{- end }} + + {{ .Type }}({ + {{- range .Properties }} + {{ if ne .Optional true }}required {{ end }}this.{{ .Name }}, + {{- end }} + }); + + Map toJson() => _${{ .Type }}ToJson(this); + + factory {{ .Type }}.fromJson(Map json) => + _${{ .Type }}FromJson(json); +} +{{ end }} + +{{- range .Namespaces }} +{{- $namespaceName := .Name }} +{{- range .Methods }} +{{- $paramsLen := len .Parameters }} +{{- if ne $paramsLen 0 }} +@JsonSerializable() +class {{ title $namespaceName }}{{ .ParamsClass }} { + {{- range .Parameters }} + {{- if .Description }} + /// {{ .Description }} + {{- end }} + @JsonKey(name: '{{ .Name }}') + final {{ .Type }}{{ if .Optional }}?{{ end }} {{ .Name }}; + {{- end }} + + {{ title $namespaceName }}{{ .ParamsClass }}({ + {{- range .Parameters }} + {{ if ne .Optional true }}required {{ end }}this.{{ .Name }}, + {{- end }} + }); + + Map toJson() => _${{ title $namespaceName }}{{ .ParamsClass }}ToJson(this); + + factory {{ title $namespaceName }}{{ .ParamsClass }}.fromJson(Map json) => + _${{ title $namespaceName }}{{ .ParamsClass }}FromJson(json); +} +{{ end }} +{{- end }} +{{- end }} + +{{ range .Namespaces }} +{{- $namespaceName := .Name }} +{{ title .Name }}RPC {{ .Name }}RPCInstance({required RPC rpc}) => _{{ title .Name }}RPC(rpc: rpc); +@RPCNamespace('{{ .Name }}') +abstract class {{ title .Name }}RPC { +{{- range .Methods }}{{- $paramsLen := len .Parameters }} + {{- range .Description }} + {{- if ne . "" }} + /// {{ . }} + {{- end }} + {{- end }} + @RPCMethod('{{ title .SafeName }}') + Future<{{ .Returns.Type }}{{ if .Returns.Optional }}?{{ end }}> {{ camelCase .SafeName }}({{ if ne $paramsLen 0 }}{{ title $namespaceName }}{{ .ParamsClass }} params{{ end }}); + +{{- end }} +} +{{ end }}` diff --git a/dart/testdata/client.dart b/dart/testdata/client.dart new file mode 100755 index 0000000..a120243 --- /dev/null +++ b/dart/testdata/client.dart @@ -0,0 +1,118 @@ +/// Code generated from jsonrpc schema by rpcgen v2.4.sdsd2; DO NOT EDIT. + +import 'package:json_annotation/json_annotation.dart'; +import 'package:smd_annotations/annotations.dart'; + +part 'client.g.dart'; + +@JsonSerializable() +class Campaign { + @JsonKey(name: 'groups') + final List groups; + @JsonKey(name: 'id') + final int id; + + Campaign({ + required this.groups, + required this.id, + }); + + Map toJson() => _$CampaignToJson(this); + + factory Campaign.fromJson(Map json) => + _$CampaignFromJson(json); +} + +@JsonSerializable() +class Group { + @JsonKey(name: 'child') + final Group? child; + @JsonKey(name: 'groups') + final List groups; + @JsonKey(name: 'id') + final int id; + @JsonKey(name: 'nodes') + final List nodes; + @JsonKey(name: 'sub') + final SubGroup sub; + @JsonKey(name: 'title') + final String title; + + Group({ + this.child, + required this.groups, + required this.id, + required this.nodes, + required this.sub, + required this.title, + }); + + Map toJson() => _$GroupToJson(this); + + factory Group.fromJson(Map json) => + _$GroupFromJson(json); +} + +@JsonSerializable() +class SubGroup { + @JsonKey(name: 'id') + final int id; + @JsonKey(name: 'nodes') + final List nodes; + @JsonKey(name: 'title') + final String title; + + SubGroup({ + required this.id, + required this.nodes, + required this.title, + }); + + Map toJson() => _$SubGroupToJson(this); + + factory SubGroup.fromJson(Map json) => + _$SubGroupFromJson(json); +} + +@JsonSerializable() +class CatalogueFirstParams { + @JsonKey(name: 'groups') + final List groups; + + CatalogueFirstParams({ + required this.groups, + }); + + Map toJson() => _$CatalogueFirstParamsToJson(this); + + factory CatalogueFirstParams.fromJson(Map json) => + _$CatalogueFirstParamsFromJson(json); +} + +@JsonSerializable() +class CatalogueSecondParams { + @JsonKey(name: 'campaigns') + final List campaigns; + + CatalogueSecondParams({ + required this.campaigns, + }); + + Map toJson() => _$CatalogueSecondParamsToJson(this); + + factory CatalogueSecondParams.fromJson(Map json) => + _$CatalogueSecondParamsFromJson(json); +} + + + +CatalogueRPC catalogueRPCInstance({required RPC rpc}) => _CatalogueRPC(rpc: rpc); +@RPCNamespace('catalogue') +abstract class CatalogueRPC { + @RPCMethod('First') + Future first(CatalogueFirstParams params); + @RPCMethod('Second') + Future second(CatalogueSecondParams params); + @RPCMethod('Third') + Future third(); +} diff --git a/gen/gen.go b/gen/gen.go index b343d6f..371c8f8 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -1,6 +1,16 @@ package gen -const version = "2.4.1" +import ( + "sort" + "strings" + "text/template" + + "github.com/vmkteam/zenrpc/v2/smd" + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +const version = "2.4.2" const DefinitionsPrefix = "#/definitions/" @@ -13,3 +23,65 @@ func DefaultGeneratorData() GeneratorData { Version: version, } } + +// GetNamespaceNames return all namespace names from schema. +func GetNamespaceNames(schema smd.Schema) (res []string) { + m := map[string]struct{}{} + for name := range schema.Services { + m[GetNamespace(name)] = struct{}{} + } + + for name := range m { + res = append(res, name) + } + + sort.Strings(res) + + return res +} + +// GetNamespace extract namespace from string like "namespace.method" +func GetNamespace(methodName string) string { + return strings.Split(methodName, ".")[0] +} + +// GetMethodName extract method from string like "namespace.method" +func GetMethodName(methodName string) string { + const methodNameLen = 2 + + arr := strings.Split(methodName, ".") + if len(arr) != methodNameLen { + return methodName + } + + return arr[1] +} + +var TemplateFuncs = template.FuncMap{ + "notLast": func(index int, len int) bool { + return index+1 != len + }, + "title": title, + "camelCase": func(s string) string { + s = title(s) + lowerFirst := strings.ToLower(s[:1]) + + return lowerFirst + s[1:] + }, +} + +func title(s string) string { + if strings.EqualFold(s, "id") { + return "ID" + } + + c := cases.Title(language.Und, cases.NoLower) + if strings.HasSuffix(s, "Id") { + s = strings.TrimSuffix(s, "Id") + s += "ID" + + return c.String(s) + } + + return c.String(s) +} diff --git a/generator.go b/generator.go index 041f2df..3b594e3 100644 --- a/generator.go +++ b/generator.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" + "github.com/vmkteam/rpcgen/v2/dart" "github.com/vmkteam/rpcgen/v2/golang" "github.com/vmkteam/rpcgen/v2/openrpc" "github.com/vmkteam/rpcgen/v2/php" @@ -42,6 +43,10 @@ func (g RPCGen) SwiftClient(settings swift.Settings) Generator { return swift.NewClient(g.schema, settings) } +func (g RPCGen) DartClient(settings dart.Settings) Generator { + return dart.NewClient(g.schema, settings) +} + func (g RPCGen) OpenRPC(title, host string) Generator { return openrpc.NewClient(g.schema, title, host) } diff --git a/go.mod b/go.mod index cc3e30d..7d3ad6a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/vmkteam/meta-schema/v2 v2.0.1 github.com/vmkteam/zenrpc v1.1.1 - github.com/vmkteam/zenrpc/v2 v2.2.9 + github.com/vmkteam/zenrpc/v2 v2.2.11 ) require ( @@ -19,7 +19,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect - golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect google.golang.org/protobuf v1.28.1 // indirect ) diff --git a/go.sum b/go.sum index 3fbe7cf..cf78e88 100644 --- a/go.sum +++ b/go.sum @@ -199,6 +199,8 @@ github.com/vmkteam/zenrpc v1.1.1 h1:WmModRVCwgs7XEkeJcVvmDOwEtAQk0TuYV91wdpAaCw= github.com/vmkteam/zenrpc v1.1.1/go.mod h1:x3fCkb9HHOpqwqC7TKXf8pyXWdPxEt2Zrndl50YxexM= github.com/vmkteam/zenrpc/v2 v2.2.9 h1:J7WnYZEIImOyBhh1DRutJJSCkXcH0tJ7lIn4DSt8fE0= github.com/vmkteam/zenrpc/v2 v2.2.9/go.mod h1:ZQW8eYsnkWpfq6/lkW4P2NyQafQzamfyb81SXpq3GYs= +github.com/vmkteam/zenrpc/v2 v2.2.11 h1:JfB7QYWhFPXhw9FZuVk5FBwtoVesYscmS3RrSqDK1Zc= +github.com/vmkteam/zenrpc/v2 v2.2.11/go.mod h1:T/ZQlJbKThBNJtyN0313xEPcxjEyB19uNldTBr0o2KE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -330,6 +332,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -340,6 +344,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/golang/rpcgen_test.go b/golang/rpcgen_test.go index d454139..e435bc8 100644 --- a/golang/rpcgen_test.go +++ b/golang/rpcgen_test.go @@ -27,7 +27,7 @@ func TestGenerateGoClient(t *testing.T) { t.Fatalf("open test data file: %v", err) } - // cut first line with version from comparsion + // cut first line with version from comparison _, generatedBody, _ := bytes.Cut(generated, []byte{'\n'}) _, testDataBody, _ := bytes.Cut(testData, []byte{'\n'}) diff --git a/golang/testdata/catalogue_client.go b/golang/testdata/catalogue_client.go index 3f650bb..ac0939a 100755 --- a/golang/testdata/catalogue_client.go +++ b/golang/testdata/catalogue_client.go @@ -1,4 +1,4 @@ -// Code generated from jsonrpc schema by rpcgen v2.4.0; DO NOT EDIT. +// Code generated from jsonrpc schema by rpcgen v2.4.2; DO NOT EDIT. package client @@ -78,6 +78,7 @@ type ObjectsAbstractObject struct { type Person struct { // Addresses Could be nil or len() == 0. Addresses []Address `json:"Addresses"` + BirthDate string `json:"BirthDate"` // Deleted is flag for Deleted bool `json:"Deleted"` FirstName string `json:"FirstName"` diff --git a/openrpc/testdata/openrpc.json b/openrpc/testdata/openrpc.json index e201cd3..9d86f41 100755 --- a/openrpc/testdata/openrpc.json +++ b/openrpc/testdata/openrpc.json @@ -2,7 +2,7 @@ "openrpc": "1.2.6", "info": { "title": "test", - "version": "v0.0.0-9ac57ca8e88fda67daec2cbaa50d71bd" + "version": "v0.0.0-6920a46120f3837481a03bee56a8ac6a" }, "servers": [ { @@ -667,6 +667,7 @@ "ID", "FirstName", "LastName", + "BirthDate", "Phone", "Mobile", "Deleted", @@ -683,6 +684,9 @@ "LastName": { "type": "string" }, + "BirthDate": { + "type": "string" + }, "Phone": { "description": "Phone is main phone", "type": "string" diff --git a/php/php_client.go b/php/php_client.go index 0cd640c..64da40b 100644 --- a/php/php_client.go +++ b/php/php_client.go @@ -38,7 +38,7 @@ func NewClient(schema smd.Schema, phpNamespace string) *Generator { return &Generator{schema: schema, phpNamespace: ns} } -// Generate returns generate TypeScript client +// Generate returns generate PHP client func (g *Generator) Generate() ([]byte, error) { m := g.PHPModels() m.GeneratorData = gen.DefaultGeneratorData() diff --git a/php/php_client_test.go b/php/php_client_test.go index a775660..ab63d31 100644 --- a/php/php_client_test.go +++ b/php/php_client_test.go @@ -25,7 +25,7 @@ func TestGeneratePHPClient(t *testing.T) { t.Fatalf("open test data file: %v", err) } - // cut first two lines with version from comparsion + // cut first two lines with version from comparison generated = bytes.TrimPrefix(generated, []byte("