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

Cleanup unused object and scalar types #24

Merged
merged 5 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions openapi/internal/oas2.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,20 @@ import (
"github.com/pb33f/libopenapi/orderedmap"
)

// OAS2Builder the NDC schema builder from OpenAPI 2.0 specification
type OAS2Builder struct {
schema *rest.NDCRestSchema
*ConvertOptions

schema *rest.NDCRestSchema
typeUsageCounter TypeUsageCounter
}

// NewOAS2Builder creates an OAS3Builder instance
func NewOAS2Builder(schema *rest.NDCRestSchema, options ConvertOptions) *OAS2Builder {
builder := &OAS2Builder{
schema: schema,
ConvertOptions: applyConvertOptions(options),
schema: schema,
typeUsageCounter: TypeUsageCounter{},
ConvertOptions: applyConvertOptions(options),
}

setDefaultSettings(builder.schema.Settings, builder.ConvertOptions)
Expand Down Expand Up @@ -82,6 +87,7 @@ func (oc *OAS2Builder) BuildDocumentModel(docModel *libopenapi.DocumentModel[v2.
}

oc.schema.Settings.Security = convertSecurities(docModel.Model.Security)
cleanUnusedSchemaTypes(oc.schema, &oc.typeUsageCounter)

return nil
}
Expand Down Expand Up @@ -251,6 +257,7 @@ func (oc *OAS2Builder) getSchemaTypeFromParameter(param *v2.Parameter, apiPath s
if isPrimitiveScalar(param.Type) {
scalarName := getScalarFromType(oc.schema, []string{param.Type}, param.Format, param.Enum, oc.trimPathPrefix(apiPath), fieldPaths)
result = schema.NewNamedType(scalarName)
oc.typeUsageCounter.Increase(scalarName)
} else {
switch param.Type {
case "object":
Expand All @@ -262,6 +269,7 @@ func (oc *OAS2Builder) getSchemaTypeFromParameter(param *v2.Parameter, apiPath s

itemName := getScalarFromType(oc.schema, []string{param.Items.Type}, param.Format, param.Enum, oc.trimPathPrefix(apiPath), fieldPaths)
result = schema.NewArrayType(schema.NewNamedType(itemName))
oc.typeUsageCounter.Increase(itemName)

default:
return nil, fmt.Errorf("unsupported schema type %s", param.Type)
Expand All @@ -287,6 +295,7 @@ func (oc *OAS2Builder) getSchemaType(typeSchema *base.Schema, apiPath string, fi
if _, ok := oc.schema.ScalarTypes[scalarName]; !ok {
oc.schema.ScalarTypes[scalarName] = *defaultScalarTypes[rest.ScalarJSON]
}
oc.typeUsageCounter.Increase(scalarName)
typeResult = createSchemaFromOpenAPISchema(typeSchema, scalarName)
return schema.NewNamedType(scalarName), typeResult, nil
}
Expand All @@ -300,6 +309,7 @@ func (oc *OAS2Builder) getSchemaType(typeSchema *base.Schema, apiPath string, fi
if isPrimitiveScalar(typeName) {
scalarName := getScalarFromType(oc.schema, typeSchema.Type, typeSchema.Format, typeSchema.Enum, oc.trimPathPrefix(apiPath), fieldPaths)
result = schema.NewNamedType(scalarName)
oc.typeUsageCounter.Increase(scalarName)
typeResult = createSchemaFromOpenAPISchema(typeSchema, scalarName)
} else {

Expand Down Expand Up @@ -337,6 +347,8 @@ func (oc *OAS2Builder) getSchemaType(typeSchema *base.Schema, apiPath string, fi
propApiSchema.Nullable = nullable
typeResult.Properties[propName] = *propApiSchema
object.Fields[propName] = objField

oc.typeUsageCounter.Increase(getNamedType(propType, true, ""))
}

oc.schema.ObjectTypes[refName] = object
Expand All @@ -350,6 +362,7 @@ func (oc *OAS2Builder) getSchemaType(typeSchema *base.Schema, apiPath string, fi
itemName := getSchemaRefTypeNameV2(typeSchema.Items.A.GetReference())
if itemName != "" {
itemName := utils.ToPascalCase(itemName)
oc.typeUsageCounter.Increase(itemName)
result = schema.NewArrayType(schema.NewNamedType(itemName))
} else {
itemSchemaA := typeSchema.Items.A.Schema()
Expand All @@ -361,6 +374,7 @@ func (oc *OAS2Builder) getSchemaType(typeSchema *base.Schema, apiPath string, fi

typeResult.Items = propType
result = schema.NewArrayType(itemSchema)
oc.typeUsageCounter.Increase(getNamedType(itemSchema, true, ""))
}
}

Expand Down
6 changes: 5 additions & 1 deletion openapi/internal/oas2_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ func (oc *oas2OperationBuilder) convertParameters(params []*v2.Parameter, apiPat
return nil, err
}

oc.builder.typeUsageCounter.Increase(getNamedType(typeEncoder, true, ""))
argument := schema.ArgumentInfo{
Type: typeEncoder.Encode(),
}
Expand Down Expand Up @@ -262,12 +263,15 @@ func (oc *oas2OperationBuilder) convertResponse(responses *v2.Responses, apiPath

// return nullable boolean type if the response content is null
if resp == nil || resp.Schema == nil {
return schema.NewNullableNamedType("Boolean"), nil
scalarName := string(rest.ScalarBoolean)
oc.builder.typeUsageCounter.Increase(scalarName)
return schema.NewNullableNamedType(scalarName), nil
}

schemaType, _, err := oc.builder.getSchemaTypeFromProxy(resp.Schema, false, apiPath, fieldPaths)
if err != nil {
return nil, err
}
oc.builder.typeUsageCounter.Increase(getNamedType(schemaType, true, ""))
return schemaType, nil
}
22 changes: 17 additions & 5 deletions openapi/internal/oas3.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,22 @@ import (
"github.com/pb33f/libopenapi/orderedmap"
)

// OAS3Builder the NDC schema builder from OpenAPI 3.0 specification
type OAS3Builder struct {
schema *rest.NDCRestSchema
evaluatingTypes map[string]string
*ConvertOptions

schema *rest.NDCRestSchema
evaluatingTypes map[string]string
typeUsageCounter TypeUsageCounter
}

// NewOAS3Builder creates an OAS3Builder instance
func NewOAS3Builder(schema *rest.NDCRestSchema, options ConvertOptions) *OAS3Builder {
builder := &OAS3Builder{
schema: schema,
evaluatingTypes: make(map[string]string),
ConvertOptions: applyConvertOptions(options),
schema: schema,
evaluatingTypes: make(map[string]string),
typeUsageCounter: TypeUsageCounter{},
ConvertOptions: applyConvertOptions(options),
}

setDefaultSettings(builder.schema.Settings, builder.ConvertOptions)
Expand Down Expand Up @@ -71,6 +76,7 @@ func (oc *OAS3Builder) BuildDocumentModel(docModel *libopenapi.DocumentModel[v3.
// reevaluate write argument types
oc.evaluatingTypes = make(map[string]string)
oc.transformWriteSchema()
cleanUnusedSchemaTypes(oc.schema, &oc.typeUsageCounter)

return nil
}
Expand Down Expand Up @@ -242,6 +248,7 @@ func (oc *OAS3Builder) convertComponentSchemas(schemaItem orderedmap.Pair[string
scalar := schema.NewScalarType()
scalar.Representation = schema.NewTypeRepresentationJSON().Encode()
oc.schema.ScalarTypes[refName] = *scalar
oc.evaluatingTypes[fmt.Sprintf("#/components/schemas/%s", typeKey)] = refName
}

return err
Expand All @@ -260,6 +267,7 @@ func (oc *OAS3Builder) buildScalarJSON() *schema.NamedType {
if _, ok := oc.schema.ScalarTypes[scalarName]; !ok {
oc.schema.ScalarTypes[scalarName] = *defaultScalarTypes[rest.ScalarJSON]
}
oc.typeUsageCounter.Increase(scalarName)
return schema.NewNamedType(scalarName)
}

Expand Down Expand Up @@ -311,6 +319,8 @@ func (oc *OAS3Builder) populateWriteSchemaType(schemaType schema.Type) (schema.T

writeName := formatWriteObjectName(ty.Name)
if _, ok := oc.schema.ObjectTypes[writeName]; ok {
oc.typeUsageCounter.Increase(writeName)
oc.typeUsageCounter.Decrease(ty.Name)
return schema.NewNamedType(writeName).Encode(), writeName, true
}
if evaluated {
Expand Down Expand Up @@ -339,6 +349,8 @@ func (oc *OAS3Builder) populateWriteSchemaType(schemaType schema.Type) (schema.T
}
}
if hasWriteField {
oc.typeUsageCounter.Increase(writeName)
oc.typeUsageCounter.Decrease(ty.Name)
oc.schema.ObjectTypes[writeName] = writeObject
return schema.NewNamedType(writeName).Encode(), writeName, true
}
Expand Down
7 changes: 6 additions & 1 deletion openapi/internal/oas3_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
return nil, nil, nil
}

oc.builder.typeUsageCounter.Increase(getNamedType(schemaType, true, ""))
bodyResult := &rest.RequestBody{
ContentType: contentType,
Schema: typeSchema,
Expand Down Expand Up @@ -366,6 +367,7 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
EncodingObject: headerEncoding,
}

oc.builder.typeUsageCounter.Increase(getNamedType(ndcType, true, ""))
argument := schema.ArgumentInfo{
Type: ndcType.Encode(),
}
Expand Down Expand Up @@ -400,7 +402,9 @@ func (oc *oas3OperationBuilder) convertResponse(responses *v3.Responses, apiPath

// return nullable boolean type if the response content is null
if resp == nil || resp.Content == nil {
return schema.NewNullableNamedType("Boolean"), nil
scalarName := string(rest.ScalarBoolean)
oc.builder.typeUsageCounter.Increase(scalarName)
return schema.NewNullableNamedType(scalarName), nil
}
jsonContent, ok := resp.Content.Get("application/json")
if !ok {
Expand All @@ -412,6 +416,7 @@ func (oc *oas3OperationBuilder) convertResponse(responses *v3.Responses, apiPath
if err != nil {
return nil, err
}
oc.builder.typeUsageCounter.Increase(getNamedType(schemaType, true, ""))
return schemaType, nil
}

Expand Down
14 changes: 13 additions & 1 deletion openapi/internal/oas3_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ func (oc *oas3SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
var err error

rawRefName := schemaProxy.GetReference()

if rawRefName == "" {
ndcType, typeSchema, isRef, err = oc.getSchemaType(innerSchema, fieldPaths)
if err != nil {
Expand All @@ -58,6 +57,7 @@ func (oc *oas3SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
Type: objectName,
Description: innerSchema.Description,
}
oc.builder.typeUsageCounter.Increase(objectName)
} else {
// return early object from ref
refName := getSchemaRefTypeNameV3(rawRefName)
Expand All @@ -72,12 +72,14 @@ func (oc *oas3SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
return nil, nil, false, err
}
typeSchema.Description = innerSchema.Description
oc.builder.typeUsageCounter.Increase(getNamedType(ndcType, true, ""))
} else {
ndcType = schema.NewNamedType(objectName)
typeSchema = &rest.TypeSchema{
Type: objectName,
Description: innerSchema.Description,
}
oc.builder.typeUsageCounter.Increase(objectName)
}
}

Expand Down Expand Up @@ -152,6 +154,7 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
scalarName := getScalarFromType(oc.builder.schema, typeSchema.Type, typeSchema.Format, typeSchema.Enum, oc.builder.trimPathPrefix(oc.apiPath), fieldPaths)
result = schema.NewNamedType(scalarName)
typeResult = createSchemaFromOpenAPISchema(typeSchema, scalarName)
oc.builder.typeUsageCounter.Increase(scalarName)
} else {
typeName := typeSchema.Type[0]
typeResult = createSchemaFromOpenAPISchema(typeSchema, typeName)
Expand Down Expand Up @@ -219,6 +222,7 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
if len(readObject.Fields) == 0 && len(writeObject.Fields) == 0 {
oc.builder.schema.ObjectTypes[refName] = object
result = schema.NewNamedType(refName)
oc.builder.typeUsageCounter.Increase(refName)
} else {
for key, field := range object.Fields {
readObject.Fields[key] = field
Expand All @@ -229,8 +233,10 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
oc.builder.schema.ObjectTypes[writeRefName] = writeObject
if oc.writeMode {
result = schema.NewNamedType(writeRefName)
oc.builder.typeUsageCounter.Increase(writeRefName)
} else {
result = schema.NewNamedType(refName)
oc.builder.typeUsageCounter.Increase(refName)
}
}
case "array":
Expand All @@ -239,7 +245,9 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
}

itemName := getSchemaRefTypeNameV3(typeSchema.Items.A.GetReference())
var refName string
if itemName != "" {
refName = itemName
result = schema.NewArrayType(schema.NewNamedType(utils.ToPascalCase(itemName)))
} else {
itemSchemaA := typeSchema.Items.A.Schema()
Expand All @@ -249,6 +257,7 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
return nil, nil, isRef, err
}
if itemSchema != nil {
refName = getNamedType(itemSchema, true, "")
result = schema.NewArrayType(itemSchema)
} else {
result = schema.NewArrayType(oc.builder.buildScalarJSON())
Expand All @@ -262,6 +271,7 @@ func (oc *oas3SchemaBuilder) getSchemaType(typeSchema *base.Schema, fieldPaths [
if result == nil {
return nil, nil, false, fmt.Errorf("cannot parse type reference name: %s", typeSchema.Items.A.GetReference())
}
oc.builder.typeUsageCounter.Increase(refName)
default:
return nil, nil, false, fmt.Errorf("unsupported schema type %s", typeName)
}
Expand Down Expand Up @@ -362,6 +372,8 @@ func (oc *oas3SchemaBuilder) buildAllOfAnyOfSchemaType(schemaProxies []*base.Sch
if oc.writeMode && len(writeObject.Fields) > 0 {
refName = writeRefName
}

oc.builder.typeUsageCounter.Increase(refName)
if len(typeSchema.Properties) == 0 {
typeSchema = &rest.TypeSchema{
Type: refName,
Expand Down
Loading