Skip to content

Commit

Permalink
Merge pull request #23 from link-duan/main
Browse files Browse the repository at this point in the history
fix(plugins/gin): c.PostFormArray(); fix(plugins/gin): c.PostFormArray()
  • Loading branch information
link-duan authored Dec 2, 2022
2 parents 3d8dc06 + 3468141 commit 10a8152
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 52 deletions.
15 changes: 12 additions & 3 deletions formatter/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ func Group(docs ...Doc) *DocGroup {
return &DocGroup{Docs: docs}
}

func Content(code string) *DocContent {
res := DocContent(code)
return &res
func Content(contents ...interface{}) *DocGroup {
var res = Group()
for _, content := range contents {
switch content := content.(type) {
case string:
item := DocContent(content)
res.Docs = append(res.Docs, &item)
case Doc:
res.Docs = append(res.Docs, content)
}
}
return res
}
17 changes: 16 additions & 1 deletion generators/ts/ts.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ func (p *Printer) PrintType(definition *spec.SchemaRef) f.Doc {
return f.Content(typeName)
}

var t = definition.Value.Type
schema := definition.Value
if schema.ExtendedTypeInfo != nil {
return p.printExtendedType(schema.ExtendedTypeInfo)
}

var t = schema.Type
switch t {
case "object":
return p.printInterface(definition)
Expand Down Expand Up @@ -137,3 +142,13 @@ func (p *Printer) printBasicType(t string) f.Doc {
}
return f.Content("any")
}

func (p *Printer) printExtendedType(info *spec.ExtendedTypeInfo) f.Doc {
switch info.Type {
case spec.ExtendedTypeAny:
return f.Content("any")
case spec.ExtendedTypeMap:
return f.Content("Record<", p.PrintType(info.Key), ", ", p.PrintType(info.Value), ">")
}
return f.Content("unknown")
}
8 changes: 2 additions & 6 deletions generators/umi/umi.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,8 @@ func (p *Printer) requestFunctionBody(pathName string, method string, queryParam
if mediaType != nil {
if reqContentType == contentTypeFormData {
res.Docs = append(res.Docs, f.Group(
f.Content("let formData = new FormData();"), f.LineBreak(),
f.Content("for (const key in data) {"), f.LineBreak(),
f.Indent(f.Group(
f.Content("formData.append(key, data[key as keyof typeof data] as string | Blob);"), f.LineBreak(),
)),
f.Content("}"),
f.Content("const formData = new FormData();"), f.LineBreak(),
f.Content("Object.keys(data).forEach((key) => "), f.Content("formData.append(key, data[key])"), f.Content(");"),
f.LineBreak(),
))
}
Expand Down
16 changes: 7 additions & 9 deletions plugins/gin/handler_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ func (p *handlerAnalyzer) Parse() {
case "FormFile":
p.parseFormData(call, "file")
case "PostFormArray":
p.parsePrimitiveParamArray(call, "formData")
p.parseFormData(call, spec.TypeArray, func(s *spec.Schema) {
s.Items = spec.NewSchemaRef("", spec.NewStringSchema())
})
case "Redirect":
p.parseRedirectRes(call)
// TODO: supporting more methods (FileForm(), HTML(), Data(), etc...)
Expand Down Expand Up @@ -152,7 +154,7 @@ func (p *handlerAnalyzer) parsePrimitiveParam(call *ast.CallExpr, in string) {
p.spec.AddParameter(param)
}

func (p *handlerAnalyzer) parseFormData(call *ast.CallExpr, fieldType string) {
func (p *handlerAnalyzer) parseFormData(call *ast.CallExpr, fieldType string, options ...func(s *spec.Schema)) {
if len(call.Args) <= 0 {
return
}
Expand All @@ -166,6 +168,9 @@ func (p *handlerAnalyzer) parseFormData(call *ast.CallExpr, fieldType string) {
paramSchema := spec.NewSchema()
paramSchema.Title = name
paramSchema.Type = fieldType
for _, option := range options {
option(paramSchema)
}

mediaType := spec.NewMediaType()
requestBody := p.spec.RequestBody
Expand Down Expand Up @@ -228,13 +233,6 @@ func (p *handlerAnalyzer) primitiveParam(call *ast.CallExpr, in string) *spec.Pa
return res
}

func (p *handlerAnalyzer) parsePrimitiveParamArray(call *ast.CallExpr, in string) {
param := p.primitiveParam(call, in)
param.Schema.Value.Type = "array"
param.Schema.Value.Items = spec.NewSchemaRef("", spec.NewStringSchema())
p.spec.AddParameter(param)
}

func (p *handlerAnalyzer) matchCustomResponseRule(node ast.Node) (matched bool) {
if p.c == nil || len(p.c.Response) == 0 {
return false
Expand Down
60 changes: 36 additions & 24 deletions plugins/gin/testdata/server/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@
},
"raw": {
"description": "测试引用内置包类型",
"format": "byte",
"type": "string"
"type": "object"
},
"selfRef": {
"description": "测试循环引用",
Expand Down Expand Up @@ -103,9 +102,11 @@
"cover": {
"type": "string"
},
"mapInt": {},
"price": {
"type": "integer"
},
"properties": {},
"subTitle": {
"type": "string"
},
Expand All @@ -129,6 +130,15 @@
"title": "Image",
"type": "object"
},
"server_pkg_view.Property": {
"properties": {
"title": {
"type": "string"
}
},
"title": "Property",
"type": "object"
},
"server_pkg_view.SelfRefType": {
"properties": {
"data": {
Expand Down Expand Up @@ -221,20 +231,8 @@
"name": "guid",
"required": true,
"schema": {
"title": "guid"
}
},
{
"description": "日期范围",
"in": "path",
"name": "dateRange",
"required": true,
"schema": {
"items": {
"type": "string"
},
"title": "dateRange",
"type": "array"
"title": "guid",
"type": "string"
}
}
],
Expand All @@ -243,11 +241,19 @@
"multipart/form-data": {
"schema": {
"properties": {
"dateRange": {
"items": {
"type": "string"
},
"title": "dateRange",
"type": "array"
},
"operatorUid": {
"title": "operatorUid",
"type": "string"
}
},
"title": "ShopGoodsDownRequest",
"type": "object"
}
}
Expand Down Expand Up @@ -280,7 +286,8 @@
"name": "guid",
"required": true,
"schema": {
"title": "guid"
"title": "guid",
"type": "string"
}
}
],
Expand All @@ -303,22 +310,22 @@
},
"/wrapped-handler": {
"get": {
"operationId": "GET./wrapped-handler",
"operationId": "shop.WrappedHandler",
"parameters": [
{
"in": "path",
"in": "query",
"name": "hello",
"required": true,
"schema": {
"title": "hello"
"title": "hello",
"type": "string"
}
},
{
"in": "path",
"in": "query",
"name": "world",
"required": true,
"schema": {
"title": "world"
"title": "world",
"type": "string"
}
}
],
Expand All @@ -338,6 +345,11 @@
"type": "string"
}
},
"required": [
"data",
"code",
"msg"
],
"type": "object"
}
}
Expand Down
14 changes: 10 additions & 4 deletions plugins/gin/testdata/server/pkg/view/shop.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,16 @@ type GoodsCreateRes struct {
}

type GoodsInfoRes struct {
Title string `json:"title"`
SubTitle string `json:"subTitle"`
Cover string `json:"cover"`
Price int64 `json:"price"`
Title string `json:"title"`
SubTitle string `json:"subTitle"`
Cover string `json:"cover"`
Price int64 `json:"price"`
Properties map[string]*Property `json:"properties"`
MapInt map[int]*Property `json:"mapInt"`
}

type Property struct {
Title string `json:"title"`
}

type GoodsDownRes struct {
Expand Down
21 changes: 17 additions & 4 deletions schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ func (s *SchemaBuilder) ParseExpr(expr ast.Expr) (schema *spec.SchemaRef) {
return s.ParseExpr(expr.Sel)

case *ast.MapType:
return spec.MapProperty(s.ParseExpr(expr.Value))
return spec.NewSchemaRef(
"",
spec.NewSchema().
WithExtendedType(spec.NewMapExtendedType(
s.ParseExpr(expr.Key),
s.ParseExpr(expr.Value),
)),
)

case *ast.ArrayType:
return spec.ArrayProperty(s.ParseExpr(expr.Elt))
Expand Down Expand Up @@ -152,9 +159,15 @@ func (s *SchemaBuilder) parseIdent(expr *ast.Ident) *spec.SchemaRef {
}

var commonTypes = map[string]*spec.Schema{
"time.Time": spec.NewSchema().WithType("string").WithFormat("datetime"),
"encoding/json.RawMessage": spec.NewSchema().WithType("object").WithDescription("Any Json Type"),
"json.RawMessage": spec.NewSchema().WithType("object").WithDescription("Any Json Type"),
"time.Time": spec.NewSchema().WithType("string").WithFormat("datetime"),
"encoding/json.RawMessage": spec.NewSchema().
WithType("object").
WithDescription("Any Json Type").
WithExtendedType(spec.NewAnyExtendedType()),
"json.RawMessage": spec.NewSchema().
WithType("object").
WithDescription("Any Json Type").
WithExtendedType(spec.NewAnyExtendedType()),
}

func (s *SchemaBuilder) commonUsedType(t types.Type) *spec.SchemaRef {
Expand Down
47 changes: 47 additions & 0 deletions spec/extended_type_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package spec

type ExtendedType string

const (
ExtendedTypeMap ExtendedType = "map"
ExtendedTypeAny ExtendedType = "any"
ExtendedTypeEnum ExtendedType = "enum"
)

type ExtendedTypeInfo struct {
Type ExtendedType `json:"type"`

// When Type = 'map'. Key means type of key of map.
Key *SchemaRef
// When Type = 'map'. Value means type of value of map.
Value *SchemaRef `json:"valueType"`

// Enum Items
EnumItems []*ExtendedEnumItem `json:"enumItems"`
}

type ExtendedEnumItem struct {
Key string `json:"key"`
Value string `json:"value"`
Description string `json:"description"`
}

func NewExtendedEnumType(items ...*ExtendedEnumItem) *ExtendedTypeInfo {
return &ExtendedTypeInfo{
Type: ExtendedTypeEnum,
Value: nil,
EnumItems: items,
}
}

func NewAnyExtendedType() *ExtendedTypeInfo {
return &ExtendedTypeInfo{Type: ExtendedTypeAny}
}

func NewMapExtendedType(key, value *SchemaRef) *ExtendedTypeInfo {
return &ExtendedTypeInfo{
Type: ExtendedTypeMap,
Key: key,
Value: value,
}
}
10 changes: 9 additions & 1 deletion spec/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ type Schema struct {
AdditionalPropertiesAllowed *bool `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"` // In this order...
AdditionalProperties *SchemaRef `multijson:"additionalProperties,omitempty" json:"-" yaml:"-"` // ...for multijson
Discriminator *Discriminator `json:"discriminator,omitempty" yaml:"discriminator,omitempty"`

// 拓展类型信息. 用于代码生成
ExtendedTypeInfo *ExtendedTypeInfo `json:"-" yaml:"-"`
}

var _ jsonpointer.JSONPointable = (*Schema)(nil)
Expand All @@ -173,6 +176,11 @@ func NewSchema() *Schema {
return &Schema{}
}

func (schema *Schema) WithExtendedType(t *ExtendedTypeInfo) *Schema {
schema.ExtendedTypeInfo = t
return schema
}

// MarshalJSON returns the JSON encoding of Schema.
func (schema *Schema) MarshalJSON() ([]byte, error) {
return jsoninfo.MarshalStrictStruct(schema)
Expand All @@ -184,7 +192,7 @@ func (schema *Schema) UnmarshalJSON(data []byte) error {
}

// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable
func (schema Schema) JSONLookup(token string) (interface{}, error) {
func (schema *Schema) JSONLookup(token string) (interface{}, error) {
switch token {
case "additionalProperties":
if schema.AdditionalProperties != nil {
Expand Down

0 comments on commit 10a8152

Please sign in to comment.