Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for default values #140

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
91 changes: 91 additions & 0 deletions pkg/generators/models/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ func (g generator) Generate(ctx context.Context) (err error) {
}
log.Debug().Msg("Paths have been processed.")

log.Debug().Msg("Preprocessing schemas...")
err = g.preprocessSchemas(ctx, g.spec.Components.Schemas)
if err != nil {
return err
}
log.Debug().Msg("Schemas have been preprocessed.")

log.Debug().Msg("Processing schemas...")
for _, name := range sortedKeys(g.spec.Components.Schemas) {
ref := g.spec.Components.Schemas[name]
Expand Down Expand Up @@ -299,3 +306,87 @@ func (g generator) writeModelToFile(ctx context.Context, model *Model, dst strin

return nil
}

func (g generator) preprocessSchemas(ctx context.Context, schemas openapi3.Schemas) error {
for _, name := range sortedKeys(schemas) {
ref := schemas[name]
err := g.createNamedSchemaForInlineSchemas(ctx, name, ref, false, schemas)
if err != nil {
return err
}
}

return nil
}

func (g generator) createNamedSchemaForInlineSchemas(ctx context.Context, name string, ref *openapi3.SchemaRef, shouldCreate bool, schemas openapi3.Schemas) (err error) {
if ctx.Err() != nil {
return ctx.Err()
}

if ref == nil {
return nil
}

ref = resolveAllOf(ref, shouldCreate, nil)
if ref.Ref != "" {
return nil
}

switch ref.Value.Type {
case "string", "integer", "number", "boolean":
// Only create a named schema for enums
if shouldCreate && len(ref.Value.Enum) > 0 {
err = g.createNamedSchemaForInlineSchema(ctx, name, ref, schemas)
}
case "array":
// Follow array items schema
err = g.createNamedSchemaForInlineSchemas(ctx, name, ref.Value.Items, true, schemas)
case "", "object":
// Create a ref if the object has properties or additionalProperties
if shouldCreate && (len(ref.Value.Properties) > 0 || ref.Value.AdditionalProperties != nil) {
err = g.createNamedSchemaForInlineSchema(ctx, name, ref, schemas)
}

// Check all properties for inline schemas
for propName, propRef := range ref.Value.Properties {
err = g.createNamedSchemaForInlineSchemas(ctx, fmt.Sprintf("%s_%s", name, propName), propRef, true, schemas)
if err != nil {
return err
}
}

// Check additionalProperties for inline schemas
if ref.Value.AdditionalProperties != nil {
err = g.createNamedSchemaForInlineSchemas(ctx, fmt.Sprintf("%s_additional_properties", name), ref.Value.AdditionalProperties, true, schemas)
}

// Check oneOf for inline schemas
for i, oneOfRef := range ref.Value.OneOf {
err = g.createNamedSchemaForInlineSchemas(ctx, fmt.Sprintf("%s_one_of_idx%d", name, i), oneOfRef, true, schemas)
if err != nil {
return err
}
}
}
return err
}

func (g generator) createNamedSchemaForInlineSchema(ctx context.Context, name string, schemaRef *openapi3.SchemaRef, schemas openapi3.Schemas) (err error) {
// Iterate until inlineName is not found in schemas
inlineName := name
for i := 0; true; i++ {
if _, exists := schemas[inlineName]; !exists {
break
}
if ctx.Err() != nil {
return ctx.Err()
}
inlineName = fmt.Sprintf("%s_%d", name, i)
}
g.opts.Logger.Debug().Str("inline_name", inlineName).Msg("Creating inline schema")
schemas[inlineName] = openapi3.NewSchemaRef("", schemaRef.Value)
schemaRef.Ref = "#/components/schemas/" + inlineName

return nil
}