From 44735e949cedfdc802cf7c54eaec8de0d38a011d Mon Sep 17 00:00:00 2001 From: kesonan Date: Thu, 24 Apr 2025 07:59:01 +0800 Subject: [PATCH] fix array schmea generation incorrect (#4801) --- .../goctl/api/swagger/example/example_cn.api | 4 + tools/goctl/api/swagger/parameter.go | 17 +++-- tools/goctl/api/swagger/properties.go | 16 ++-- tools/goctl/api/swagger/swagger.go | 73 ++++++------------- 4 files changed, 47 insertions(+), 63 deletions(-) diff --git a/tools/goctl/api/swagger/example/example_cn.api b/tools/goctl/api/swagger/example/example_cn.api index 670a728e4..546ebf871 100644 --- a/tools/goctl/api/swagger/example/example_cn.api +++ b/tools/goctl/api/swagger/example/example_cn.api @@ -144,6 +144,8 @@ type ( MapMapNumber map[string]map[string]float64 `json:"mapMapNumber"` MapMapBoolean map[string]map[string]bool `json:"mapMapBoolean"` MapMapString map[string]map[string]string `json:"mapMapString"` + MapMapObject map[string]map[string]ComplexJsonLevel1 `json:"mapMapObject"` + MapMapPointerObject map[string]map[string]*ComplexJsonLevel1 `json:"mapMapPointerObject"` // Object Object ComplexJsonLevel1 `json:"object"` PointerObject *ComplexJsonLevel1 `json:"pointerObject"` @@ -194,6 +196,8 @@ type ( MapMapNumber map[string]map[string]float64 `json:"mapMapNumber"` MapMapBoolean map[string]map[string]bool `json:"mapMapBoolean"` MapMapString map[string]map[string]string `json:"mapMapString"` + MapMapObject map[string]map[string]ComplexJsonLevel1 `json:"mapMapObject"` + MapMapPointerObject map[string]map[string]*ComplexJsonLevel1 `json:"mapMapPointerObject"` // Object Object ComplexJsonLevel1 `json:"object"` PointerObject *ComplexJsonLevel1 `json:"pointerObject"` diff --git a/tools/goctl/api/swagger/parameter.go b/tools/goctl/api/swagger/parameter.go index 0cf8e0a37..35941ba78 100644 --- a/tools/goctl/api/swagger/parameter.go +++ b/tools/goctl/api/swagger/parameter.go @@ -137,8 +137,7 @@ func parametersFromType(method string, tp apiSpec.Type) []spec.Parameter { if required { requiredFields = append(requiredFields, jsonTag.Name) } - p, r := propertiesFromType(member.Type) - properties[jsonTag.Name] = spec.Schema{ + var schema = spec.Schema{ SwaggerSchemaProps: spec.SwaggerSchemaProps{ Example: exampleValueFromOptions(jsonTag.Options, member.Type), }, @@ -150,13 +149,19 @@ func parametersFromType(method string, tp apiSpec.Type) []spec.Parameter { ExclusiveMaximum: exclusiveMaximum, Minimum: minimum, ExclusiveMinimum: exclusiveMinimum, - Enum: enumsValueFromOptions(jsonTag.Options), - Items: itemsFromGoType(member.Type), - Properties: p, - Required: r, + Enum: enumsValueFromOptions(jsonTag.Options), AdditionalProperties: mapFromGoType(member.Type), }, } + switch sampleTypeFromGoType(member.Type) { + case swaggerTypeArray: + schema.Items=itemsFromGoType(member.Type) + case swaggerTypeObject: + p, r := propertiesFromType(member.Type) + schema.Properties = p + schema.Required = r + } + properties[jsonTag.Name] = schema } }) if len(properties) > 0 { diff --git a/tools/goctl/api/swagger/properties.go b/tools/goctl/api/swagger/properties.go index 5c6db4e3a..e9814f363 100644 --- a/tools/goctl/api/swagger/properties.go +++ b/tools/goctl/api/swagger/properties.go @@ -36,8 +36,7 @@ func propertiesFromType(tp apiSpec.Type) (spec.SchemaProperties, []string) { if required { requiredFields = append(requiredFields, jsonTagString) } - p, r := propertiesFromType(member.Type) - properties[jsonTagString] = spec.Schema{ + var schema = spec.Schema{ SwaggerSchemaProps: spec.SwaggerSchemaProps{ Example: example, }, @@ -50,12 +49,19 @@ func propertiesFromType(tp apiSpec.Type) (spec.SchemaProperties, []string) { Minimum: minimum, ExclusiveMinimum: exclusiveMinimum, Enum: enum, - Items: itemsFromGoType(member.Type), - Properties: p, - Required: r, AdditionalProperties: mapFromGoType(member.Type), }, } + switch sampleTypeFromGoType(member.Type) { + case swaggerTypeArray: + schema.Items=itemsFromGoType(member.Type) + case swaggerTypeObject: + p, r := propertiesFromType(member.Type) + schema.Properties = p + schema.Required = r + } + + properties[jsonTagString] = schema }) } diff --git a/tools/goctl/api/swagger/swagger.go b/tools/goctl/api/swagger/swagger.go index fc65bf2d3..c5f5a2f38 100644 --- a/tools/goctl/api/swagger/swagger.go +++ b/tools/goctl/api/swagger/swagger.go @@ -67,7 +67,7 @@ func itemsFromGoType(tp apiSpec.Type) *spec.SchemaOrArray { if !ok { return nil } - return itemFromGoType(array) + return itemFromGoType(array.Value) } func mapFromGoType(tp apiSpec.Type) *spec.SchemaOrBool { @@ -75,18 +75,23 @@ func mapFromGoType(tp apiSpec.Type) *spec.SchemaOrBool { if !ok { return nil } - p, r := propertiesFromType(mapType.Value) + var schema = &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: typeFromGoType(mapType.Value), + AdditionalProperties: mapFromGoType(mapType.Value), + }, + } + switch sampleTypeFromGoType(mapType.Value) { + case swaggerTypeArray: + schema.Items = itemsFromGoType(mapType.Value) + case swaggerTypeObject: + p, r := propertiesFromType(mapType.Value) + schema.Properties = p + schema.Required = r + } return &spec.SchemaOrBool{ Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: typeFromGoType(mapType.Value), - Items: itemsFromGoType(mapType.Value), - Properties: p, - Required: r, - AdditionalProperties: mapFromGoType(mapType.Value), - }, - }, + Schema: schema, } } @@ -101,41 +106,8 @@ func itemFromGoType(tp apiSpec.Type) *spec.SchemaOrArray { }, }, } - case apiSpec.DefineStruct: - var ( - properties = map[string]spec.Schema{} - requiredFields []string - ) - rangeMemberAndDo(itemType, func(tag *apiSpec.Tags, required bool, member apiSpec.Member) { - jsonTag, _ := tag.Get(tagJson) - if jsonTag == nil { - return - } - minimum, maximum, exclusiveMinimum, exclusiveMaximum := rangeValueFromOptions(jsonTag.Options) - if required { - requiredFields = append(requiredFields, jsonTag.Name) - } - p, r := propertiesFromType(member.Type) - properties[jsonTag.Name] = spec.Schema{ - SwaggerSchemaProps: spec.SwaggerSchemaProps{ - Example: exampleValueFromOptions(jsonTag.Options, member.Type), - }, - SchemaProps: spec.SchemaProps{ - Description: formatComment(member.Comment), - Type: typeFromGoType(member.Type), - Default: defValueFromOptions(jsonTag.Options, member.Type), - Maximum: maximum, - ExclusiveMaximum: exclusiveMaximum, - Minimum: minimum, - ExclusiveMinimum: exclusiveMinimum, - Enum: enumsValueFromOptions(jsonTag.Options), - Items: itemsFromGoType(member.Type), - Properties: p, - Required: r, - AdditionalProperties: mapFromGoType(member.Type), - }, - } - }) + case apiSpec.DefineStruct, apiSpec.NestedStruct: + properties, requiredFields := propertiesFromType(itemType) return &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -148,16 +120,13 @@ func itemFromGoType(tp apiSpec.Type) *spec.SchemaOrArray { }, } case apiSpec.PointerType: - return itemsFromGoType(itemType.Type) + return itemFromGoType(itemType.Type) case apiSpec.ArrayType: - p, r := propertiesFromType(itemType.Value) return &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Type: typeFromGoType(itemType.Value), - Items: itemsFromGoType(itemType.Value), - Properties: p, - Required: r, + Type: typeFromGoType(itemType), + Items: itemsFromGoType(itemType), }, }, }