go.mod: Update oapi-codegen and kin-openapi
This commit is contained in:
parent
add17bba45
commit
a83cf95d5b
156 changed files with 29663 additions and 2248 deletions
353
vendor/github.com/deepmap/oapi-codegen/pkg/codegen/schema.go
generated
vendored
353
vendor/github.com/deepmap/oapi-codegen/pkg/codegen/schema.go
generated
vendored
|
|
@ -13,6 +13,8 @@ type Schema struct {
|
|||
GoType string // The Go type needed to represent the schema
|
||||
RefType string // If the type has a type name, this is set
|
||||
|
||||
ArrayType *Schema // The schema of array element
|
||||
|
||||
EnumValues map[string]string // Enum values
|
||||
|
||||
Properties []Property // For an object, the fields with names
|
||||
|
|
@ -21,6 +23,11 @@ type Schema struct {
|
|||
AdditionalTypes []TypeDefinition // We may need to generate auxiliary helper types, stored here
|
||||
|
||||
SkipOptionalPointer bool // Some types don't need a * in front when they're optional
|
||||
|
||||
Description string // The description of the element
|
||||
|
||||
// The original OpenAPIv3 Schema.
|
||||
OAPISchema *openapi3.Schema
|
||||
}
|
||||
|
||||
func (s Schema) IsRef() bool {
|
||||
|
|
@ -55,11 +62,12 @@ func (s Schema) GetAdditionalTypeDefs() []TypeDefinition {
|
|||
}
|
||||
|
||||
type Property struct {
|
||||
Description string
|
||||
JsonFieldName string
|
||||
Schema Schema
|
||||
Required bool
|
||||
Nullable bool
|
||||
Description string
|
||||
JsonFieldName string
|
||||
Schema Schema
|
||||
Required bool
|
||||
Nullable bool
|
||||
ExtensionProps *openapi3.ExtensionProps
|
||||
}
|
||||
|
||||
func (p Property) GoFieldName() string {
|
||||
|
|
@ -74,11 +82,56 @@ func (p Property) GoTypeDef() string {
|
|||
return typeDef
|
||||
}
|
||||
|
||||
type TypeDefinition struct {
|
||||
TypeName string
|
||||
JsonName string
|
||||
ResponseName string
|
||||
// EnumDefinition holds type information for enum
|
||||
type EnumDefinition struct {
|
||||
Schema Schema
|
||||
TypeName string
|
||||
ValueWrapper string
|
||||
}
|
||||
|
||||
type Constants struct {
|
||||
// SecuritySchemeProviderNames holds all provider names for security schemes.
|
||||
SecuritySchemeProviderNames []string
|
||||
// EnumDefinitions holds type and value information for all enums
|
||||
EnumDefinitions []EnumDefinition
|
||||
}
|
||||
|
||||
// TypeDefinition describes a Go type definition in generated code.
|
||||
//
|
||||
// Let's use this example schema:
|
||||
// components:
|
||||
// schemas:
|
||||
// Person:
|
||||
// type: object
|
||||
// properties:
|
||||
// name:
|
||||
// type: string
|
||||
type TypeDefinition struct {
|
||||
// The name of the type, eg, type <...> Person
|
||||
TypeName string
|
||||
|
||||
// The name of the corresponding JSON description, as it will sometimes
|
||||
// differ due to invalid characters.
|
||||
JsonName string
|
||||
|
||||
// This is the Schema wrapper is used to populate the type description
|
||||
Schema Schema
|
||||
}
|
||||
|
||||
// ResponseTypeDefinition is an extension of TypeDefinition, specifically for
|
||||
// response unmarshaling in ClientWithResponses.
|
||||
type ResponseTypeDefinition struct {
|
||||
TypeDefinition
|
||||
// The content type name where this is used, eg, application/json
|
||||
ContentTypeName string
|
||||
|
||||
// The type name of a response model.
|
||||
ResponseName string
|
||||
}
|
||||
|
||||
func (t *TypeDefinition) CanAlias() bool {
|
||||
return t.Schema.IsRef() || /* actual reference */
|
||||
(t.Schema.ArrayType != nil && t.Schema.ArrayType.IsRef()) /* array to ref */
|
||||
}
|
||||
|
||||
func PropertiesEqual(a, b Property) bool {
|
||||
|
|
@ -86,39 +139,44 @@ func PropertiesEqual(a, b Property) bool {
|
|||
}
|
||||
|
||||
func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
|
||||
// If Ref is set on the SchemaRef, it means that this type is actually a reference to
|
||||
// another type. We're not de-referencing, so simply use the referenced type.
|
||||
var refType string
|
||||
|
||||
// Add a fallback value in case the sref is nil.
|
||||
// i.e. the parent schema defines a type:array, but the array has
|
||||
// no items defined. Therefore we have at least valid Go-Code.
|
||||
if sref == nil {
|
||||
return Schema{GoType: "interface{}", RefType: refType}, nil
|
||||
return Schema{GoType: "interface{}"}, nil
|
||||
}
|
||||
|
||||
schema := sref.Value
|
||||
|
||||
if sref.Ref != "" {
|
||||
var err error
|
||||
// If Ref is set on the SchemaRef, it means that this type is actually a reference to
|
||||
// another type. We're not de-referencing, so simply use the referenced type.
|
||||
if IsGoTypeReference(sref.Ref) {
|
||||
// Convert the reference path to Go type
|
||||
refType, err = RefPathToGoType(sref.Ref)
|
||||
refType, err := RefPathToGoType(sref.Ref)
|
||||
if err != nil {
|
||||
return Schema{}, fmt.Errorf("error turning reference (%s) into a Go type: %s",
|
||||
sref.Ref, err)
|
||||
}
|
||||
return Schema{
|
||||
GoType: refType,
|
||||
GoType: refType,
|
||||
Description: StringToGoComment(schema.Description),
|
||||
}, nil
|
||||
}
|
||||
|
||||
outSchema := Schema{
|
||||
Description: StringToGoComment(schema.Description),
|
||||
OAPISchema: schema,
|
||||
}
|
||||
|
||||
// We can't support this in any meaningful way
|
||||
if schema.AnyOf != nil {
|
||||
return Schema{GoType: "interface{}", RefType: refType}, nil
|
||||
outSchema.GoType = "interface{}"
|
||||
return outSchema, nil
|
||||
}
|
||||
// We can't support this in any meaningful way
|
||||
if schema.OneOf != nil {
|
||||
return Schema{GoType: "interface{}", RefType: refType}, nil
|
||||
outSchema.GoType = "interface{}"
|
||||
return outSchema, nil
|
||||
}
|
||||
|
||||
// AllOf is interesting, and useful. It's the union of a number of other
|
||||
|
|
@ -130,14 +188,10 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
|
|||
if err != nil {
|
||||
return Schema{}, errors.Wrap(err, "error merging schemas")
|
||||
}
|
||||
mergedSchema.RefType = refType
|
||||
mergedSchema.OAPISchema = schema
|
||||
return mergedSchema, nil
|
||||
}
|
||||
|
||||
outSchema := Schema{
|
||||
RefType: refType,
|
||||
}
|
||||
|
||||
// Check for custom Go type extension
|
||||
if extension, ok := schema.Extensions[extPropGoType]; ok {
|
||||
typeName, err := extTypeName(extension)
|
||||
|
|
@ -200,11 +254,12 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
|
|||
description = p.Value.Description
|
||||
}
|
||||
prop := Property{
|
||||
JsonFieldName: pName,
|
||||
Schema: pSchema,
|
||||
Required: required,
|
||||
Description: description,
|
||||
Nullable: p.Value.Nullable,
|
||||
JsonFieldName: pName,
|
||||
Schema: pSchema,
|
||||
Required: required,
|
||||
Description: description,
|
||||
Nullable: p.Value.Nullable,
|
||||
ExtensionProps: &p.Value.ExtensionProps,
|
||||
}
|
||||
outSchema.Properties = append(outSchema.Properties, prop)
|
||||
}
|
||||
|
|
@ -224,76 +279,133 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
|
|||
outSchema.GoType = GenStructFromSchema(outSchema)
|
||||
}
|
||||
return outSchema, nil
|
||||
} else if len(schema.Enum) > 0 {
|
||||
err := resolveType(schema, path, &outSchema)
|
||||
if err != nil {
|
||||
return Schema{}, errors.Wrap(err, "error resolving primitive type")
|
||||
}
|
||||
enumValues := make([]string, len(schema.Enum))
|
||||
for i, enumValue := range schema.Enum {
|
||||
enumValues[i] = fmt.Sprintf("%v", enumValue)
|
||||
}
|
||||
|
||||
sanitizedValues := SanitizeEnumNames(enumValues)
|
||||
outSchema.EnumValues = make(map[string]string, len(sanitizedValues))
|
||||
var constNamePath []string
|
||||
for k, v := range sanitizedValues {
|
||||
if v == "" {
|
||||
constNamePath = append(path, "Empty")
|
||||
} else {
|
||||
constNamePath = append(path, k)
|
||||
}
|
||||
outSchema.EnumValues[SchemaNameToTypeName(PathToTypeName(constNamePath))] = v
|
||||
}
|
||||
if len(path) > 1 { // handle additional type only on non-toplevel types
|
||||
typeName := SchemaNameToTypeName(PathToTypeName(path))
|
||||
typeDef := TypeDefinition{
|
||||
TypeName: typeName,
|
||||
JsonName: strings.Join(path, "."),
|
||||
Schema: outSchema,
|
||||
}
|
||||
outSchema.AdditionalTypes = append(outSchema.AdditionalTypes, typeDef)
|
||||
outSchema.RefType = typeName
|
||||
}
|
||||
//outSchema.RefType = typeName
|
||||
} else {
|
||||
f := schema.Format
|
||||
|
||||
switch t {
|
||||
case "array":
|
||||
// For arrays, we'll get the type of the Items and throw a
|
||||
// [] in front of it.
|
||||
arrayType, err := GenerateGoSchema(schema.Items, path)
|
||||
if err != nil {
|
||||
return Schema{}, errors.Wrap(err, "error generating type for array")
|
||||
}
|
||||
outSchema.GoType = "[]" + arrayType.TypeDecl()
|
||||
outSchema.Properties = arrayType.Properties
|
||||
case "integer":
|
||||
// We default to int if format doesn't ask for something else.
|
||||
if f == "int64" {
|
||||
outSchema.GoType = "int64"
|
||||
} else if f == "int32" {
|
||||
outSchema.GoType = "int32"
|
||||
} else if f == "" {
|
||||
outSchema.GoType = "int"
|
||||
} else {
|
||||
return Schema{}, fmt.Errorf("invalid integer format: %s", f)
|
||||
}
|
||||
case "number":
|
||||
// We default to float for "number"
|
||||
if f == "double" {
|
||||
outSchema.GoType = "float64"
|
||||
} else if f == "float" || f == "" {
|
||||
outSchema.GoType = "float32"
|
||||
} else {
|
||||
return Schema{}, fmt.Errorf("invalid number format: %s", f)
|
||||
}
|
||||
case "boolean":
|
||||
if f != "" {
|
||||
return Schema{}, fmt.Errorf("invalid format (%s) for boolean", f)
|
||||
}
|
||||
outSchema.GoType = "bool"
|
||||
case "string":
|
||||
enumValues := make([]string, len(schema.Enum))
|
||||
for i, enumValue := range schema.Enum {
|
||||
enumValues[i] = enumValue.(string)
|
||||
}
|
||||
|
||||
outSchema.EnumValues = SanitizeEnumNames(enumValues)
|
||||
|
||||
// Special case string formats here.
|
||||
switch f {
|
||||
case "byte":
|
||||
outSchema.GoType = "[]byte"
|
||||
case "email":
|
||||
outSchema.GoType = "openapi_types.Email"
|
||||
case "date":
|
||||
outSchema.GoType = "openapi_types.Date"
|
||||
case "date-time":
|
||||
outSchema.GoType = "time.Time"
|
||||
case "json":
|
||||
outSchema.GoType = "json.RawMessage"
|
||||
outSchema.SkipOptionalPointer = true
|
||||
default:
|
||||
// All unrecognized formats are simply a regular string.
|
||||
outSchema.GoType = "string"
|
||||
}
|
||||
default:
|
||||
return Schema{}, fmt.Errorf("unhandled Schema type: %s", t)
|
||||
err := resolveType(schema, path, &outSchema)
|
||||
if err != nil {
|
||||
return Schema{}, errors.Wrap(err, "error resolving primitive type")
|
||||
}
|
||||
}
|
||||
return outSchema, nil
|
||||
}
|
||||
|
||||
// resolveType resolves primitive type or array for schema
|
||||
func resolveType(schema *openapi3.Schema, path []string, outSchema *Schema) error {
|
||||
f := schema.Format
|
||||
t := schema.Type
|
||||
|
||||
switch t {
|
||||
case "array":
|
||||
// For arrays, we'll get the type of the Items and throw a
|
||||
// [] in front of it.
|
||||
arrayType, err := GenerateGoSchema(schema.Items, path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error generating type for array")
|
||||
}
|
||||
outSchema.ArrayType = &arrayType
|
||||
outSchema.GoType = "[]" + arrayType.TypeDecl()
|
||||
additionalTypes := arrayType.GetAdditionalTypeDefs()
|
||||
// Check also types defined in array item
|
||||
if len(additionalTypes) > 0 {
|
||||
outSchema.AdditionalTypes = append(outSchema.AdditionalTypes, additionalTypes...)
|
||||
}
|
||||
outSchema.Properties = arrayType.Properties
|
||||
case "integer":
|
||||
// We default to int if format doesn't ask for something else.
|
||||
if f == "int64" {
|
||||
outSchema.GoType = "int64"
|
||||
} else if f == "int32" {
|
||||
outSchema.GoType = "int32"
|
||||
} else if f == "int16" {
|
||||
outSchema.GoType = "int16"
|
||||
} else if f == "int8" {
|
||||
outSchema.GoType = "int8"
|
||||
} else if f == "int" {
|
||||
outSchema.GoType = "int"
|
||||
} else if f == "uint64" {
|
||||
outSchema.GoType = "uint64"
|
||||
} else if f == "uint32" {
|
||||
outSchema.GoType = "uint32"
|
||||
} else if f == "uint16" {
|
||||
outSchema.GoType = "uint16"
|
||||
} else if f == "uint8" {
|
||||
outSchema.GoType = "uint8"
|
||||
} else if f == "uint" {
|
||||
outSchema.GoType = "uint"
|
||||
} else if f == "" {
|
||||
outSchema.GoType = "int"
|
||||
} else {
|
||||
return fmt.Errorf("invalid integer format: %s", f)
|
||||
}
|
||||
case "number":
|
||||
// We default to float for "number"
|
||||
if f == "double" {
|
||||
outSchema.GoType = "float64"
|
||||
} else if f == "float" || f == "" {
|
||||
outSchema.GoType = "float32"
|
||||
} else {
|
||||
return fmt.Errorf("invalid number format: %s", f)
|
||||
}
|
||||
case "boolean":
|
||||
if f != "" {
|
||||
return fmt.Errorf("invalid format (%s) for boolean", f)
|
||||
}
|
||||
outSchema.GoType = "bool"
|
||||
case "string":
|
||||
// Special case string formats here.
|
||||
switch f {
|
||||
case "byte":
|
||||
outSchema.GoType = "[]byte"
|
||||
case "email":
|
||||
outSchema.GoType = "openapi_types.Email"
|
||||
case "date":
|
||||
outSchema.GoType = "openapi_types.Date"
|
||||
case "date-time":
|
||||
outSchema.GoType = "time.Time"
|
||||
case "json":
|
||||
outSchema.GoType = "json.RawMessage"
|
||||
outSchema.SkipOptionalPointer = true
|
||||
default:
|
||||
// All unrecognized formats are simply a regular string.
|
||||
outSchema.GoType = "string"
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unhandled Schema type: %s", t)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// This describes a Schema, a type definition.
|
||||
type SchemaDescriptor struct {
|
||||
Fields []FieldDescriptor
|
||||
|
|
@ -313,20 +425,49 @@ type FieldDescriptor struct {
|
|||
// JSON annotations
|
||||
func GenFieldsFromProperties(props []Property) []string {
|
||||
var fields []string
|
||||
for _, p := range props {
|
||||
for i, p := range props {
|
||||
field := ""
|
||||
// Add a comment to a field in case we have one, otherwise skip.
|
||||
if p.Description != "" {
|
||||
// Separate the comment from a previous-defined, unrelated field.
|
||||
// Make sure the actual field is separated by a newline.
|
||||
field += fmt.Sprintf("\n%s\n", StringToGoComment(p.Description))
|
||||
if i != 0 {
|
||||
field += "\n"
|
||||
}
|
||||
field += fmt.Sprintf("%s\n", StringToGoComment(p.Description))
|
||||
}
|
||||
field += fmt.Sprintf(" %s %s", p.GoFieldName(), p.GoTypeDef())
|
||||
if p.Required || p.Nullable {
|
||||
field += fmt.Sprintf(" `json:\"%s\"`", p.JsonFieldName)
|
||||
} else {
|
||||
field += fmt.Sprintf(" `json:\"%s,omitempty\"`", p.JsonFieldName)
|
||||
|
||||
// Support x-omitempty
|
||||
omitEmpty := true
|
||||
if _, ok := p.ExtensionProps.Extensions[extPropOmitEmpty]; ok {
|
||||
if extOmitEmpty, err := extParseOmitEmpty(p.ExtensionProps.Extensions[extPropOmitEmpty]); err == nil {
|
||||
omitEmpty = extOmitEmpty
|
||||
}
|
||||
}
|
||||
|
||||
fieldTags := make(map[string]string)
|
||||
|
||||
if p.Required || p.Nullable || !omitEmpty {
|
||||
fieldTags["json"] = p.JsonFieldName
|
||||
} else {
|
||||
fieldTags["json"] = p.JsonFieldName + ",omitempty"
|
||||
}
|
||||
if extension, ok := p.ExtensionProps.Extensions[extPropExtraTags]; ok {
|
||||
if tags, err := extExtraTags(extension); err == nil {
|
||||
keys := SortedStringKeys(tags)
|
||||
for _, k := range keys {
|
||||
fieldTags[k] = tags[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
// Convert the fieldTags map into Go field annotations.
|
||||
keys := SortedStringKeys(fieldTags)
|
||||
tags := make([]string, len(keys))
|
||||
for i, k := range keys {
|
||||
tags[i] = fmt.Sprintf(`%s:"%s"`, k, fieldTags[k])
|
||||
}
|
||||
field += "`" + strings.Join(tags, " ") + "`"
|
||||
fields = append(fields, field)
|
||||
}
|
||||
return fields
|
||||
|
|
@ -359,7 +500,7 @@ func MergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) {
|
|||
|
||||
var refType string
|
||||
var err error
|
||||
if ref != "" {
|
||||
if IsGoTypeReference(ref) {
|
||||
refType, err = RefPathToGoType(ref)
|
||||
if err != nil {
|
||||
return Schema{}, errors.Wrap(err, "error converting reference path to a go type")
|
||||
|
|
@ -412,7 +553,7 @@ func GenStructFromAllOf(allOf []*openapi3.SchemaRef, path []string) (string, err
|
|||
objectParts := []string{"struct {"}
|
||||
for _, schemaOrRef := range allOf {
|
||||
ref := schemaOrRef.Ref
|
||||
if ref != "" {
|
||||
if IsGoTypeReference(ref) {
|
||||
// We have a referenced type, we will generate an inlined struct
|
||||
// member.
|
||||
// struct {
|
||||
|
|
@ -426,7 +567,7 @@ func GenStructFromAllOf(allOf []*openapi3.SchemaRef, path []string) (string, err
|
|||
objectParts = append(objectParts,
|
||||
fmt.Sprintf(" // Embedded struct due to allOf(%s)", ref))
|
||||
objectParts = append(objectParts,
|
||||
fmt.Sprintf(" %s", goType))
|
||||
fmt.Sprintf(" %s `yaml:\",inline\"`", goType))
|
||||
} else {
|
||||
// Inline all the fields from the schema into the output struct,
|
||||
// just like in the simple case of generating an object.
|
||||
|
|
@ -471,7 +612,8 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) {
|
|||
// so we'll return the parameter as a string, not bothering to decode it.
|
||||
if len(param.Content) > 1 {
|
||||
return Schema{
|
||||
GoType: "string",
|
||||
GoType: "string",
|
||||
Description: StringToGoComment(param.Description),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -480,7 +622,8 @@ func paramToGoType(param *openapi3.Parameter, path []string) (Schema, error) {
|
|||
if !found {
|
||||
// If we don't have json, it's a string
|
||||
return Schema{
|
||||
GoType: "string",
|
||||
GoType: "string",
|
||||
Description: StringToGoComment(param.Description),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue