diff --git a/model.go b/model.go index 5c9fff7..bb6f4f4 100644 --- a/model.go +++ b/model.go @@ -25,6 +25,7 @@ type StructType struct { } type Value struct { + JSONInfo *JSONInfo `json:",omitempty"` IsError bool `json:",omitempty"` IsInterface bool `json:",omitempty"` Scalar *Scalar `json:",omitempty"` diff --git a/servicereader.go b/servicereader.go index 46af581..1e3239d 100644 --- a/servicereader.go +++ b/servicereader.go @@ -262,7 +262,6 @@ func loadConstantTypes(pkg *ast.Package) map[string]interface{} { } } return constantTypes - } func Read( @@ -323,30 +322,26 @@ func Read( for _, structDef := range structs { if structDef != nil { structPackage := structDef.Package - _, ok := allConstantTypes[structPackage] - if !ok { - // fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", structPackage) - pkg, constPkgErr := parsePackage(goPaths, gomod, structPackage) - if constPkgErr != nil { + if _, ok := allConstantTypes[structPackage]; !ok { + if pkg, constPkgErr := parsePackage(goPaths, gomod, structPackage); constPkgErr != nil { err = constPkgErr return + } else { + allConstantTypes[structPackage] = loadConstantTypes(pkg) } - allConstantTypes[structPackage] = loadConstantTypes(pkg) } } } for _, scalarDef := range scalars { if scalarDef != nil { scalarPackage := scalarDef.Package - _, ok := allConstantTypes[scalarPackage] - if !ok { - // fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", structPackage) - pkg, constPkgErr := parsePackage(goPaths, gomod, scalarPackage) - if constPkgErr != nil { + if _, ok := allConstantTypes[scalarPackage]; !ok { + if pkg, constPkgErr := parsePackage(goPaths, gomod, scalarPackage); constPkgErr != nil { err = constPkgErr return + } else { + allConstantTypes[scalarPackage] = loadConstantTypes(pkg) } - allConstantTypes[scalarPackage] = loadConstantTypes(pkg) } } } @@ -448,7 +443,7 @@ func collectTypes(goPaths []string, gomod config.Namespace, missingTypes map[str scannedPackageStructs := map[string]map[string]*Struct{} scannedPackageScalars := map[string]map[string]*Scalar{} missingTypeNames := func() []string { - missing := []string{} + var missing []string for name, isMissing := range missingTypes { if isMissing { missing = append(missing, name) @@ -576,8 +571,7 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string] return false } for _, field := range s.Fields { - var fieldStructType *StructType - fieldStructType = nil + var fieldStructType *StructType = nil if field.Value.StructType != nil { fieldStructType = field.Value.StructType } else if field.Value.Array != nil && field.Value.Array.Value.StructType != nil { @@ -597,21 +591,25 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string] } } } - if s.Array != nil { - if s.Array.Value != nil { - if s.Array.Value.StructType != nil { - if needsWork(s.Array.Value.StructType.FullName()) { - return false - } + if s.Array != nil && s.Array.Value != nil { + if s.Array.Value.StructType != nil { + if needsWork(s.Array.Value.StructType.FullName()) { + return false + } + } else if s.Array.Value.Scalar != nil { + if needsWork(s.Array.Value.Scalar.FullName()) { + return false } } } - if s.Map != nil { - if s.Map.Value != nil { - if s.Map.Value.StructType != nil { - if needsWork(s.Map.Value.StructType.FullName()) { - return false - } + if s.Map != nil && s.Map.Value != nil { + if s.Map.Value.StructType != nil { + if needsWork(s.Map.Value.StructType.FullName()) { + return false + } + } else if s.Map.Value.Scalar != nil { + if needsWork(s.Map.Value.Scalar.FullName()) { + return false } } } diff --git a/typescript.go b/typescript.go index 8ca9145..753eca4 100644 --- a/typescript.go +++ b/typescript.go @@ -22,24 +22,24 @@ func (f *Field) tsName() string { return n } -func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code) { - switch true { +func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code, jsonInfo *JSONInfo) { + switch { case v.Map != nil: ts.app("Record<") if v.Map.Key != nil { - v.Map.Key.tsType(mappings, scalars, structs, ts) + v.Map.Key.tsType(mappings, scalars, structs, ts, nil) } else { ts.app(v.Map.KeyType) } ts.app(",") - v.Map.Value.tsType(mappings, scalars, structs, ts) + v.Map.Value.tsType(mappings, scalars, structs, ts, nil) ts.app(">") ts.app("|null") case v.Array != nil: if v.Array.Value.ScalarType != ScalarTypeByte { ts.app("Array<") } - v.Array.Value.tsType(mappings, scalars, structs, ts) + v.Array.Value.tsType(mappings, scalars, structs, ts, nil) if v.Array.Value.ScalarType != ScalarTypeByte { ts.app(">") } @@ -52,6 +52,9 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S tsModule = mapping.TypeScriptModule } ts.app(tsModule + "." + tsTypeFromScalarType(v.ScalarType)) + if v.IsPtr && (jsonInfo == nil || !jsonInfo.OmitEmpty) { + ts.app("|null") + } return } ts.app(tsTypeFromScalarType(v.Scalar.Type)) @@ -62,39 +65,11 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S if ok { tsModule = mapping.TypeScriptModule } - scalarName := v.StructType.FullName() - // is it a hidden scalar ?! - hiddenScalar, ok := scalars[scalarName] - if ok { - ts.app(tsTypeFromScalarType(hiddenScalar.Type)) - return - } - - hiddenStruct, okHiddenStruct := structs[scalarName] - if okHiddenStruct && hiddenStruct.Array != nil { - if hiddenStruct.Array.Value.StructType != nil { - hiddenMapping, hiddenMappingOK := mappings[hiddenStruct.Array.Value.StructType.Package] - var tsModule string - if hiddenMappingOK { - tsModule = hiddenMapping.TypeScriptModule - } - ts.app(tsModule + "." + hiddenStruct.Array.Value.StructType.Name + "[]") - return - } else if hiddenStruct.Array.Value.Scalar != nil { - var tsModule string - if value, ok := mappings[hiddenStruct.Array.Value.Scalar.Package]; ok { - tsModule = value.TypeScriptModule - } - ts.app(tsModule + "." + tsTypeFromScalarType(hiddenStruct.Array.Value.Scalar.Type)) - return - } else if hiddenStruct.Array.Value.GoScalarType == "byte" { // this fixes types like primitive.ID [12]byte - ts.app(tsTypeFromScalarType(hiddenStruct.Array.Value.ScalarType)) - return - } - } - ts.app(tsModule + "." + v.StructType.Name) - if v.IsPtr { + hiddenStruct, isHiddenStruct := structs[v.StructType.FullName()] + if isHiddenStruct && (hiddenStruct.Array != nil || hiddenStruct.Map != nil) && (jsonInfo == nil || !jsonInfo.OmitEmpty) { + ts.app("|null") + } else if v.IsPtr && (jsonInfo == nil || !jsonInfo.OmitEmpty) { ts.app("|null") } return @@ -105,19 +80,16 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalars map[string]*S ts.l("{").ind(1) renderStructFields(v.Struct.Fields, mappings, scalars, structs, ts) ts.ind(-1).app("}") - if v.IsPtr { + if v.IsPtr && (jsonInfo == nil || !jsonInfo.OmitEmpty) { ts.app("|null") } case len(v.ScalarType) > 0: ts.app(tsTypeFromScalarType(v.ScalarType)) - if v.IsPtr { + if v.IsPtr && (jsonInfo == nil || !jsonInfo.OmitEmpty) { ts.app("|null") } default: ts.app("any") - if v.IsPtr { - ts.app("|null") - } } return } @@ -142,28 +114,29 @@ func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, sca ts.app("?") } ts.app(":") - f.Value.tsType(mappings, scalars, structs, ts) + f.Value.tsType(mappings, scalars, structs, ts, f.JSONInfo) ts.app(";") ts.nl() } } func renderTypescriptStruct(str *Struct, mappings config.TypeScriptMappings, scalars map[string]*Scalar, structs map[string]*Struct, ts *code) error { - if str.Array != nil { - // skipping array type - return nil - } ts.l("// " + str.FullName()) switch { + case str.Array != nil: + ts.app("export type " + str.Name + " = Array<") + str.Array.Value.tsType(mappings, scalars, structs, ts, nil) + ts.app(">") + ts.nl() case str.Map != nil: ts.app("export type " + str.Name + " = Record<") if str.Map.Key != nil { - str.Map.Key.tsType(mappings, scalars, structs, ts) + str.Map.Key.tsType(mappings, scalars, structs, ts, nil) } else { ts.app(str.Map.KeyType) } ts.app(",") - str.Map.Value.tsType(mappings, scalars, structs, ts) + str.Map.Value.tsType(mappings, scalars, structs, ts, nil) ts.app(">") ts.nl() default: diff --git a/typescriptclient.go b/typescriptclient.go index 6d64df3..a2a6d0b 100644 --- a/typescriptclient.go +++ b/typescriptclient.go @@ -28,9 +28,8 @@ func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, serv for _, method := range service.Methods { ts.app(lcfirst(method.Name) + "(") - // actual args - //args := []string{} - callArgs := []string{} + + var callArgs []string argOffset := 0 for index, arg := range method.Args { @@ -54,7 +53,7 @@ func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, serv ts.app(", ") } ts.app(arg.tsName() + ":") - arg.Value.tsType(mappings, scalars, structs, ts) + arg.Value.tsType(mappings, scalars, structs, ts, arg.JSONInfo) callArgs = append(callArgs, arg.Name) argCount++ } @@ -76,7 +75,7 @@ func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, serv ts.app(", ") } ts.app(retArgName + ":") - retField.Value.tsType(mappings, scalars, structs, ts) + retField.Value.tsType(mappings, scalars, structs, ts, retField.JSONInfo) } ts.app(") => void") diff --git a/typscriptclientasync.go b/typscriptclientasync.go index ab69de5..13874d6 100644 --- a/typscriptclientasync.go +++ b/typscriptclientasync.go @@ -49,13 +49,7 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap } ts.app(arg.tsName()) ts.app(":") - arg.Value.tsType(mappings, scalars, structs, ts) - if arg.Value.IsPtr || - arg.Value.Map != nil || - arg.Value.Array != nil || - (arg.JSONInfo != nil && arg.JSONInfo.OmitEmpty) { - ts.app("|null") - } + arg.Value.tsType(mappings, scalars, structs, ts, arg.JSONInfo) callArgs = append(callArgs, arg.Name) argCount++ } @@ -80,11 +74,6 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap countInnerReturns++ retArgName := retField.tsName() - isNilable := retField.Value.IsPtr || - retField.Value.Array != nil || - retField.Value.Map != nil || - (retField.JSONInfo != nil && retField.JSONInfo.OmitEmpty) - if len(retArgName) == 0 { retArgName = "ret" if index > 0 { @@ -98,33 +87,22 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap innerReturnTypeTS.app(strconv.Itoa(index)) innerReturnTypeTS.app(":") - retField.Value.tsType(mappings, scalars, structs, innerReturnTypeTS) - if isNilable { - innerReturnTypeTS.app("|null") - } + retField.Value.tsType(mappings, scalars, structs, innerReturnTypeTS, retField.JSONInfo) if index == len(method.Return)-1 && retField.Value.IsError { throwLastError = true - //lastErrorName = retArgName errIndex = index } else { if index == 0 { firstReturnTypeTS := newCode(" ") - retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS) + retField.Value.tsType(mappings, scalars, structs, firstReturnTypeTS, retField.JSONInfo) firstReturnType = firstReturnTypeTS.string() - if isNilable { - firstReturnType += "|null" - } - //firstReturnFieldName = retArgName } countReturns++ returnTypeTS.app(retArgName) returnTypeTS.app(":") responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]" - retField.Value.tsType(mappings, scalars, structs, returnTypeTS) - if isNilable { - returnTypeTS.app("|null") - } + retField.Value.tsType(mappings, scalars, structs, returnTypeTS, retField.JSONInfo) } responseObjectPrefix = ", " }