Skip to content

Commit

Permalink
code-gen
Browse files Browse the repository at this point in the history
  • Loading branch information
YangSen-qn committed Oct 12, 2024
1 parent 32e91c1 commit 4487c05
Show file tree
Hide file tree
Showing 32 changed files with 2,214 additions and 0 deletions.
19 changes: 19 additions & 0 deletions code-gen/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module github.com/YangSen-qn/code-gen

require (
github.com/getkin/kin-openapi v0.124.0
github.com/iancoleman/strcase v0.3.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/swag v0.22.8 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/perimeterx/marshmallow v1.1.5 // indirect
)

go 1.21.8
1 change: 1 addition & 0 deletions code-gen/src/api_desc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package main
16 changes: 16 additions & 0 deletions code-gen/src/apidesc/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package apidesc

type ApiDetailedDescription struct {
Documentation string `yaml:"documentation,omitempty"` // API 文档
PackageName string `yaml:"package_name,omitempty"` // 包名,文件路径中提取
Name string `yaml:"name,omitempty"` // API 名称,文件名
CamelCaseName string `yaml:"camel_case_name,omitempty"` // 驼峰命名
SnakeCaseName string `yaml:"snake_case_name,omitempty"` // 蛇形命名:特指下划线命名
Method MethodName `yaml:"method,omitempty"` // HTTP 方法
ServiceNames []ServiceName `yaml:"service_names,omitempty"` // 七牛服务名称
Command string `yaml:"command,omitempty"` // URL 查询命令
BasePath string `yaml:"base_path,omitempty"` // URL 基础路径
PathSuffix string `yaml:"path_suffix,omitempty"` // URL 路径后缀
Request ApiRequestDescription `yaml:"request,omitempty"` // 请求参数
Response ApiResponseDescription `yaml:"response,omitempty"` // 响应参数
}
82 changes: 82 additions & 0 deletions code-gen/src/apidesc/body_json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package apidesc

import (
"fmt"

"gopkg.in/yaml.v3"
)

type (
JsonType struct {
String bool `yaml:"string,omitempty"` // 字符串
Integer bool `yaml:"integer,omitempty"` // 整型数字
Float bool `yaml:"float,omitempty"` // 浮点型数字
Boolean bool `yaml:"boolean,omitempty"` // 布尔值
Array *JsonArray `yaml:"array,omitempty"` // 数组
Struct *JsonStruct `yaml:"struct,omitempty"` // 结构体
Any bool `yaml:"any,omitempty"` // 任意数据结构
StringMap bool `yaml:"string_map,omitempty"` // 任意字符串映射结构
}

JsonArray struct {
Documentation string `yaml:"documentation,omitempty"` // JSON 数组参数文档
Name string `yaml:"name,omitempty"` // JSON 数组名称
CamelCaseName string `yaml:"camel_case_name,omitempty"` // JSON 数组驼峰命名
SnakeCaseName string `yaml:"snake_case_name,omitempty"` // JSON 数组下划线命名
Type *JsonType `yaml:"type,omitempty"` // JSON 数组类型
}

JsonStruct struct {
Documentation string `yaml:"documentation,omitempty"` // JSON 结构体参数文档
Name string `yaml:"name,omitempty"` // JSON 结构体名称
CamelCaseName string `yaml:"camel_case_name,omitempty"` // JSON 结构体驼峰命名
SnakeCaseName string `yaml:"snake_case_name,omitempty"` // JSON 结构体下划线命名
Fields []JsonField `yaml:"fields,omitempty"` // JSON 字段列表
}

JsonField struct {
Documentation string `yaml:"documentation,omitempty"` // JSON 字段参数文档
Key string `yaml:"key,omitempty"` // JSON 字段参数名称
FieldName string `yaml:"field_name,omitempty"` // JSON 字段名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // JSON 字段驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // JSON 字段下划线命名
Type JsonType `yaml:"type,omitempty"` // JSON 字段类型
Optional *OptionalType `yaml:"optional,omitempty"` // JSON 字段是否可选,如果为空,则表示必填
ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // JSON 字段是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式
ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // JSON 字段是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式
}
)

func (jsonType *JsonType) UnmarshalYAML(value *yaml.Node) error {
switch value.ShortTag() {
case "!!str":
switch value.Value {
case "string":
jsonType.String = true
case "integer":
jsonType.Integer = true
case "float":
jsonType.Float = true
case "boolean":
jsonType.Boolean = true
case "any":
jsonType.Any = true
case "string_map":
jsonType.StringMap = true
default:
return fmt.Errorf("unknown json type: %s", value.Value)
}
return nil
case "!!map":
switch value.Content[0].Value {
case "array":
return value.Content[1].Decode(&jsonType.Array)
case "struct":
return value.Content[1].Decode(&jsonType.Struct)
default:
return fmt.Errorf("unknown json type: %s", value.Content[0].Value)
}
default:
return fmt.Errorf("unknown json type: %s", value.ShortTag())
}
}
95 changes: 95 additions & 0 deletions code-gen/src/apidesc/consts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package apidesc

import (
"net/http"
)

type MethodName string

const (
MethodNameGET MethodName = http.MethodGet
MethodNamePOST MethodName = http.MethodPost
MethodNamePUT MethodName = http.MethodPut
MethodNameDELETE MethodName = http.MethodDelete
)

type ServiceName string

const (
ServiceNameUp ServiceName = "up"
ServiceNameIo ServiceName = "io"
ServiceNameRs ServiceName = "rs"
ServiceNameRsf ServiceName = "rsf"
ServiceNameApi ServiceName = "api"
ServiceNameBucket ServiceName = "uc"
)

// StringLikeType 类字符串参数类型
type StringLikeType = string

const (
StringLikeTypeString StringLikeType = "string" // 字符串
StringLikeTypeInteger StringLikeType = "integer" // 整型数字
StringLikeTypeFloat StringLikeType = "float" // 浮点型数字
StringLikeTypeBoolean StringLikeType = "boolean" // 布尔值
)

type MultipartFormDataType = string

const (
MultipartFormDataTypeString MultipartFormDataType = "string" // 字符串
MultipartFormDataTypeInteger MultipartFormDataType = "integer"
MultipartFormDataTypeUploadToken MultipartFormDataType = "upload_token"
MultipartFormDataTypeBinaryData MultipartFormDataType = "binary_data"
)

type OptionalType string

const (
OptionalTypeRequired OptionalType = "" // 用户必须传值
OptionalTypeOmitEmpty OptionalType = "omitempty" // 如果用户不传值,则该字段省略
OptionalTypeKeepEmpty OptionalType = "keepempty" // 即使用户不传值,也会发送空值
OptionalTypeNullable OptionalType = "nullable" // 如果用户不传值,则该字段省略,但如果用户传值,即使是空值也会发送
)

type Authorization string

const (
AuthorizationNone Authorization = ""
AuthorizationQbox Authorization = "Qbox"
AuthorizationQiniu Authorization = "qiniu"
AuthorizationUpToken Authorization = "UploadToken"
)

type Idempotent string

const (
IdempotentDefault Idempotent = "default" // 默认幂等性(根据 HTTP 方法判定)
IdempotentAlways Idempotent = "always" // 总是幂等
IdempotentNever Idempotent = "never" // 总是不幂等
)

type EncodeType string

const (
EncodeTypeNone EncodeType = "none"
EncodeTypeUrlSafeBase64 EncodeType = "url_safe_base64" // 需要进行编码
EncodeTypeUrlSafeBase64OrNone EncodeType = "url_safe_base64_or_none" // 不仅需要编码,即使路径参数的值是 None 也要编码。该选项暗示了 nullable
)

type ServiceBucketType string

const (
ServiceBucketTypeNone ServiceBucketType = "" //
ServiceBucketTypePlainText ServiceBucketType = "plain_text" // 该值为存储空间名称
ServiceBucketTypeEntry ServiceBucketType = "entry" // 该值格式为 UrlSafeBase64("$bucket:$key")
ServiceBucketTypeUploadToken ServiceBucketType = "upload_token" // 该值为上传凭证,内部包含存储空间信息
)

type ServiceObjectType string

const (
ServiceObjectTypeNone ServiceObjectType = "" //
ServiceObjectTypePlainText ServiceObjectType = "plain_text" // 该值为对象名称
ServiceObjectTypeEntry ServiceObjectType = "entry" // 该值格式为 UrlSafeBase64("$bucket:$key")
)
12 changes: 12 additions & 0 deletions code-gen/src/apidesc/header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package apidesc

type HeaderName struct {
HeaderName string `yaml:"header_name,omitempty"` // HTTP 头名称
Documentation string `yaml:"documentation,omitempty"` // HTTP 头参数文档
FieldName string `yaml:"field_name,omitempty"` // HTTP 头参数名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // HTTP 头参数驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // HTTP 头参数下划线命名
Optional *OptionalType `yaml:"optional,omitempty"` // HTTP 头参数是否可选,如果为空,则表示必填
}

type HeaderNames []HeaderName
77 changes: 77 additions & 0 deletions code-gen/src/apidesc/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package apidesc

import (
"fmt"

"gopkg.in/yaml.v3"
)

type NamedPathParam struct {
Documentation string `yaml:"documentation,omitempty"` // URL 路径参数文档
PathSegment string `yaml:"path_segment,omitempty"` // URL 路径段落,如果为空,则表示参数直接追加在 URL 路径末尾
FieldName string `yaml:"field_name,omitempty"` // URL 路径参数名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名
Type *StringLikeType `yaml:"type,omitempty"` // URL 路径参数类型
Encode *EncodeType `yaml:"encode,omitempty"` // URL 路径参数编码方式,如果为空,表示直接转码成字符串
ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 路径参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式
ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 路径参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式
Optional *OptionalType `yaml:"optional,omitempty"` // URL 路径参数是否可选,如果为空,则表示必填
}

type FreePathParams struct {
FieldName string `yaml:"field_name,omitempty"` // URL 路径参数名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名
Documentation string `yaml:"documentation,omitempty"` // URL 路径参数文档
EncodeParamKey *EncodeType `yaml:"encode_param_key"` // URL 路径参数键编码方式,如果为空,表示直接转码成字符串
EncodeParamValue *EncodeType `yaml:"encode_param_value"` // URL 路径参数值编码方式,如果为空,表示直接转码成字符串
}

type PathParams struct {
Named []NamedPathParam `yaml:"named,omitempty"` // URL 路径有名参数列表
Free *FreePathParams `yaml:"free,omitempty"` // URL 路径自由参数列表
}

type RequestBody struct {
Json *JsonType `yaml:"json,omitempty"` // JSON 类型
FormUrlencoded *FormUrlencodedRequestStruct `yaml:"form_urlencoded,omitempty"` // URL 编码表单调用(无法上传二进制数据)
MultipartFormData *MultipartFormFields `yaml:"multipart_form_data,omitempty"` // 复合表单调用(可以上传二进制数据)
BinaryData bool `yaml:"binary_data,omitempty"` // 二进制数据
}

func (body *RequestBody) UnmarshalYAML(value *yaml.Node) error {
switch value.ShortTag() {
case "!!str":
switch value.Value {
case "binary_data":
body.BinaryData = true
default:
return fmt.Errorf("unknown request body type: %s", value.Value)
}
return nil
case "!!map":
switch value.Content[0].Value {
case "json":
return value.Content[1].Decode(&body.Json)
case "form_urlencoded":
return value.Content[1].Decode(&body.FormUrlencoded)
case "multipart_form_data":
return value.Content[1].Decode(&body.MultipartFormData)
default:
return fmt.Errorf("unknown request body type: %s", value.Content[0].Value)
}
default:
return fmt.Errorf("unknown request body type: %s", value.ShortTag())
}
}

type ApiRequestDescription struct {
PathParams *PathParams `yaml:"path_params,omitempty"` // URL 路径参数列表
HeaderNames HeaderNames `yaml:"header_names,omitempty"` // HTTP 头参数列表
QueryNames QueryNames `yaml:"query_names,omitempty"` // URL 查询参数列表
Body *RequestBody `yaml:"body,omitempty"` // 请求体
Authorization *Authorization `yaml:"authorization,omitempty"` // 鉴权参数
Idempotent *Idempotent `yaml:"idempotent,omitempty"` // 幂等性
responseTypeRequired bool `yaml:"response_type_required"` //
}
18 changes: 18 additions & 0 deletions code-gen/src/apidesc/request_body_form.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package apidesc

type FormUrlencodedRequestStruct struct {
Fields []FormUrlencodedRequestField `yaml:"fields,omitempty"` // URL 编码表单字段列表
}

type FormUrlencodedRequestField struct {
FieldName string `yaml:"field_name,omitempty"` // URL 编码表单字段名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 编码表单字段驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 编码表单字段下划线命名
Key string `yaml:"key,omitempty"` // URL 编码表单参数名称
Documentation string `yaml:"documentation,omitempty"` // URL 编码表单参数文档
Type *StringLikeType `yaml:"type,omitempty"` // URL 编码表单参数类型
Multiple bool `yaml:"multiple,omitempty"` // URL 编码表单参数是否可以有多个值
Optional *OptionalType `yaml:"optional,omitempty"` // URL 编码表单参数是否可选,如果为空,则表示必填
ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 编码表单参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式
ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 编码表单参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式
}
25 changes: 25 additions & 0 deletions code-gen/src/apidesc/request_body_multipart.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package apidesc

type MultipartFormFields struct {
Named []NamedMultipartFormField `yaml:"named_fields,omitempty"`
Free *FreeMultipartFormFields `yaml:"free_fields,omitempty"`
}

type NamedMultipartFormField struct {
FieldName string `yaml:"field_name,omitempty"`
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"`
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"`
Key string `yaml:"key,omitempty"`
Type *MultipartFormDataType `yaml:"type,omitempty"`
Documentation string `yaml:"documentation,omitempty"`
ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"`
ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"`
Optional *OptionalType `yaml:"optional,omitempty"`
}

type FreeMultipartFormFields struct {
FieldName string `yaml:"field_name,omitempty"`
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"`
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"`
Documentation string `yaml:"documentation,omitempty"`
}
16 changes: 16 additions & 0 deletions code-gen/src/apidesc/request_query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package apidesc

type QueryName struct {
FieldName string `yaml:"field_name,omitempty"` // 参数名称
FieldCamelCaseName string `yaml:"field_camel_case_name,omitempty"` // URL 路径参数驼峰命名
FieldSnakeCaseName string `yaml:"field_snake_case_name,omitempty"` // URL 路径参数下划线命名
QueryName string `yaml:"query_name,omitempty"` // URL 查询参数名称
Documentation string `yaml:"documentation,omitempty"` // URL 查询参数文档
Multiple bool `yaml:"multiple,omitempty"` // URL 查询参数是否可以有多个值
QueryType *StringLikeType `yaml:"query_type,omitempty"` // URL 查询参数类型
ServiceBucket *ServiceBucketType `yaml:"service_bucket,omitempty"` // URL 查询参数是否是空间名称,如果为空,则表示不是,如果不为空,则填写格式
ServiceObject *ServiceObjectType `yaml:"service_object,omitempty"` // URL 查询参数是否是对象名称,如果为空,则表示不是,如果不为空,则填写格式
Optional *OptionalType `yaml:"optional,omitempty"` // URL 查询参数是否可选,如果为空,则表示必填
}

type QueryNames []QueryName
6 changes: 6 additions & 0 deletions code-gen/src/apidesc/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package apidesc

type ApiResponseDescription struct {
HeaderNames HeaderNames `yaml:"header_names,omitempty"` // HTTP 头参数列表
Body *ResponseBody `yaml:"body,omitempty"` // 响应体
}
Loading

0 comments on commit 4487c05

Please sign in to comment.