Skip to content

Commit

Permalink
Cleanup unused object and scalar types (#24)
Browse files Browse the repository at this point in the history
* clean unused object and scalar types
  • Loading branch information
hgiasac committed Jun 5, 2024
1 parent cfd0f85 commit b7fb2b4
Show file tree
Hide file tree
Showing 14 changed files with 687 additions and 240 deletions.
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

0 comments on commit b7fb2b4

Please sign in to comment.