diff --git a/config/config.go b/config/config.go index d84cec9..908aa67 100644 --- a/config/config.go +++ b/config/config.go @@ -11,13 +11,20 @@ import ( ) type Target struct { - Package string `yaml:"package"` - Services map[string]string `yaml:"services"` - TypeScriptModule string `yaml:"module"` - Out string `yaml:"out"` - GoRPC []string `yaml:"gorpc"` - TSRPC []string `yaml:"tsrpc"` - SkipTSRPCClient bool `yaml:"skipTSRPCClient"` + // Go package name + Package string `json:"package" yaml:"package"` + // Map of default routes to service names + Services map[string]string `json:"services" yaml:"services"` + // TypeScript module name + TypeScriptModule string `json:"module" yaml:"module"` + // TypeScript output filename + Out string `json:"out" yaml:"out"` + // List of go rpc services to generate + GoRPC []string `json:"gorpc" yaml:"gorpc"` + // List of ts rpc services to generate + TSRPC []string `json:"tsrpc" yaml:"tsrpc"` + // Skip generating go rpc client + SkipTSRPCClient bool `json:"skipTSRPCClient" yaml:"skipTSRPCClient"` } func (t *Target) IsGoRPC(service string) bool { @@ -42,25 +49,36 @@ func (t *Target) IsTSRPC(service string) bool { } type Mapping struct { - GoPackage string `yaml:"-"` - Out string `yaml:"out"` - Structs []string `yaml:"structs"` - Scalars []string `yaml:"scalars"` - TypeScriptModule string `yaml:"module"` + // Internal go package name + GoPackage string `json:"-" yaml:"-"` + // TypeScript output filename + Out string `json:"out" yaml:"out"` + // List of go types to generate + Structs []string `json:"structs" yaml:"structs"` + // List of go types to generate + Scalars []string `json:"scalars" yaml:"scalars"` + // Optional TypeScript module name + TypeScriptModule string `json:"module" yaml:"module"` } type TypeScriptMappings map[string]*Mapping type Namespace struct { - Name string `yaml:"name"` - Path string `yaml:"path"` - ModFile *modfile.File `yaml:"-"` + // Go module name + Name string `json:"name" yaml:"name"` + // Go module path + Path string `json:"path" yaml:"path"` + // Internally loaded mod file + ModFile *modfile.File `json:"-" yaml:"-"` } type Config struct { - Module Namespace - Targets map[string]*Target - Mappings TypeScriptMappings + // Go module settings + Module Namespace `json:"module" yaml:"module"` + // Map of target names to target settings + Targets map[string]*Target `json:"targets" yaml:"targets"` + // Map of go module names to TypeScript mapping settings + Mappings TypeScriptMappings `json:"mappings" yaml:"mappings"` } func LoadConfigFile(file string) (conf *Config, err error) { diff --git a/gotsrpc.example.yaml b/gotsrpc.example.yaml new file mode 100644 index 0000000..8fc7e62 --- /dev/null +++ b/gotsrpc.example.yaml @@ -0,0 +1,19 @@ +# yaml-language-server: $schema=gotsrpc.schema.json +module: + name: github.com/foomo/gotsrpc/v2 + path: ./ + +targets: + basic: + services: + /service: Service + package: github.com/foomo/gotsrpc/v2/example/basic/service + out: ./client/src/service-client.ts + gorpc: + - Service + tsrpc: + - Service + +mappings: + github.com/foomo/gotsrpc/v2/example/basic/service: + out: ./client/src/service-vo.ts \ No newline at end of file diff --git a/gotsrpc.schema.json b/gotsrpc.schema.json new file mode 100644 index 0000000..0a850f2 --- /dev/null +++ b/gotsrpc.schema.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/foomo/gotsrpc/v2/config/config", + "$ref": "#/$defs/Config", + "$defs": { + "Config": { + "properties": { + "module": { + "$ref": "#/$defs/Namespace" + }, + "targets": { + "additionalProperties": { + "$ref": "#/$defs/Target" + }, + "type": "object" + }, + "mappings": { + "$ref": "#/$defs/TypeScriptMappings" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Mapping": { + "properties": { + "out": { + "type": "string" + }, + "structs": { + "items": { + "type": "string" + }, + "type": "array" + }, + "scalars": { + "items": { + "type": "string" + }, + "type": "array" + }, + "module": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Namespace": { + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object" + }, + "Target": { + "properties": { + "package": { + "type": "string" + }, + "services": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "module": { + "type": "string" + }, + "out": { + "type": "string" + }, + "gorpc": { + "items": { + "type": "string" + }, + "type": "array" + }, + "tsrpc": { + "items": { + "type": "string" + }, + "type": "array" + }, + "skipTSRPCClient": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object" + }, + "TypeScriptMappings": { + "additionalProperties": { + "$ref": "#/$defs/Mapping" + }, + "type": "object" + } + } +} \ No newline at end of file diff --git a/schema_test.go b/schema_test.go new file mode 100644 index 0000000..b9e7d9c --- /dev/null +++ b/schema_test.go @@ -0,0 +1,41 @@ +package gotsrpc_test + +import ( + "encoding/json" + "errors" + "os" + "path" + "testing" + + testingx "github.com/foomo/go/testing" + tagx "github.com/foomo/go/testing/tag" + "github.com/foomo/gotsrpc/v2/config" + "github.com/invopop/jsonschema" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSchema(t *testing.T) { + t.Parallel() + testingx.Tags(t, tagx.Short) + + cwd, err := os.Getwd() + require.NoError(t, err) + + reflector := new(jsonschema.Reflector) + reflector.RequiredFromJSONSchemaTags = true + require.NoError(t, reflector.AddGoComments("github.com/foomo/gotsrpc/v2/config", "./")) + schema := reflector.Reflect(&config.Config{}) + actual, err := json.MarshalIndent(schema, "", " ") + require.NoError(t, err) + + filename := path.Join(cwd, "gotsrpc.schema.json") + expected, err := os.ReadFile(filename) + if !errors.Is(err, os.ErrNotExist) { + require.NoError(t, err) + } + + if !assert.Equal(t, string(expected), string(actual)) { + require.NoError(t, os.WriteFile(filename, actual, 0600)) + } +}