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

docs-util: fixes for circular references, PAK in examples, namespaces #9091

Merged
merged 4 commits into from
Sep 16, 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
Original file line number Diff line number Diff line change
Expand Up @@ -216,11 +216,15 @@ class OasExamplesGenerator {
]

if (isAdminAuthenticated) {
exampleArr.push(`-H 'x-medusa-access-token: {api_token}'`)
exampleArr.push(`-H 'Authorization: Bearer {access_token}'`)
} else if (isStoreAuthenticated) {
exampleArr.push(`-H 'Authorization: Bearer {access_token}'`)
}

if (path.startsWith("/store")) {
exampleArr.push(`-H 'x-publishable-api-key: {your_publishable_api_key}'`)
}

if (requestSchema) {
const requestData = this.getSchemaRequiredData(requestSchema)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ class OasSchemaHelper {
})
}

this.schemas.set(schema["x-schemaName"], schema)
if (this.canAddSchema(schema)) {
this.schemas.set(schema["x-schemaName"], schema)
}

return {
$ref: this.constructSchemaReference(schema["x-schemaName"]),
Expand Down Expand Up @@ -181,6 +183,36 @@ class OasSchemaHelper {
return clonedSchema
}

isSchemaEmpty(schema: OpenApiSchema): boolean {
switch (schema.type) {
case "object":
return (
schema.properties === undefined ||
Object.keys(schema.properties).length === 0
)
case "array":
return (
!this.isRefObject(schema.items) && this.isSchemaEmpty(schema.items)
)
default:
return false
}
}

canAddSchema(schema: OpenApiSchema): boolean {
if (!schema["x-schemaName"]) {
return false
}

const existingSchema = this.schemas.get(schema["x-schemaName"])

if (!existingSchema) {
return true
}

return this.isSchemaEmpty(existingSchema) && !this.isSchemaEmpty(schema)
}

/**
* Retrieve the expected file name of the schema.
*
Expand Down Expand Up @@ -212,7 +244,7 @@ class OasSchemaHelper {
// check if it already exists in the schemas map
if (this.schemas.has(schemaName)) {
return {
schema: this.schemas.get(schemaName)!,
schema: JSON.parse(JSON.stringify(this.schemas.get(schemaName)!)),
schemaPrefix: `@schema ${schemaName}`,
}
}
Expand Down Expand Up @@ -272,7 +304,7 @@ class OasSchemaHelper {
return name
.replace("DTO", "")
.replace(this.schemaRefPrefix, "")
.replace(/(?<!AdminProduct)Type$/, "")
.replace(/(?<!(AdminProduct|CreateProduct))Type$/, "")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class SchemaFactory {
schema = Object.assign(schema, {
...additionalData,
// keep the description
description: schema.description || additionalData.description
description: schema.description || additionalData.description,
})
}

Expand Down
115 changes: 95 additions & 20 deletions www/utils/packages/docs-generator/src/classes/kinds/oas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ class OasKindGenerator extends FunctionKindGenerator {
node,
tagName,
methodName,
forUpdate: true,
})

// update query parameters
Expand Down Expand Up @@ -511,6 +512,7 @@ class OasKindGenerator extends FunctionKindGenerator {
const newResponseSchema = this.getResponseSchema({
node,
tagName,
forUpdate: true,
})
let updatedResponseSchema: OpenApiSchema | undefined

Expand Down Expand Up @@ -968,6 +970,7 @@ class OasKindGenerator extends FunctionKindGenerator {
node,
tagName,
methodName,
forUpdate = false,
}: {
/**
* The node to retrieve its request parameters.
Expand All @@ -981,6 +984,10 @@ class OasKindGenerator extends FunctionKindGenerator {
* The tag's name.
*/
tagName?: string
/**
* Whether the request parameters are retrieved for update purposes only.
*/
forUpdate?: boolean
}): {
/**
* The query parameters.
Expand Down Expand Up @@ -1041,6 +1048,7 @@ class OasKindGenerator extends FunctionKindGenerator {
title: propertyName,
descriptionOptions,
context: "request",
saveSchema: !forUpdate,
}),
})
)
Expand All @@ -1063,6 +1071,7 @@ class OasKindGenerator extends FunctionKindGenerator {
},
zodObjectTypeName: zodObjectTypeName,
context: "request",
saveSchema: !forUpdate,
})

// If function is a GET function, add the type parameter to the
Expand Down Expand Up @@ -1135,6 +1144,7 @@ class OasKindGenerator extends FunctionKindGenerator {
getResponseSchema({
node,
tagName,
forUpdate = false,
}: {
/**
* The node to retrieve its response schema.
Expand All @@ -1144,6 +1154,10 @@ class OasKindGenerator extends FunctionKindGenerator {
* The tag's name.
*/
tagName?: string
/**
* Whether the response schema is retrieved for update only.
*/
forUpdate?: boolean
}): OpenApiSchema | undefined {
let responseSchema: OpenApiSchema | undefined

Expand All @@ -1170,6 +1184,7 @@ class OasKindGenerator extends FunctionKindGenerator {
itemType: responseTypeArguments[0],
}),
context: "response",
saveSchema: !forUpdate,
})
}
}
Expand All @@ -1191,6 +1206,7 @@ class OasKindGenerator extends FunctionKindGenerator {
allowedChildren,
disallowedChildren,
zodObjectTypeName,
saveSchema = true,
...rest
}: {
/**
Expand Down Expand Up @@ -1229,6 +1245,10 @@ class OasKindGenerator extends FunctionKindGenerator {
* Whether the type is in a request / response
*/
context?: "request" | "response"
/**
* Whether to save object schemas. Useful when only getting schemas to update.
*/
saveSchema?: boolean
}): OpenApiSchema {
if (level > this.MAX_LEVEL) {
return {}
Expand Down Expand Up @@ -1354,6 +1374,7 @@ class OasKindGenerator extends FunctionKindGenerator {
parentName: title || descriptionOptions?.parentName,
}
: undefined,
saveSchema,
...rest,
}),
}
Expand Down Expand Up @@ -1384,6 +1405,7 @@ class OasKindGenerator extends FunctionKindGenerator {
level,
title,
descriptionOptions,
saveSchema,
...rest,
})
)
Expand All @@ -1407,6 +1429,7 @@ class OasKindGenerator extends FunctionKindGenerator {
level,
title,
descriptionOptions,
saveSchema,
...rest,
})
})
Expand Down Expand Up @@ -1437,6 +1460,7 @@ class OasKindGenerator extends FunctionKindGenerator {
level,
descriptionOptions,
allowedChildren: pickedProperties,
saveSchema,
...rest,
})
case typeAsString.startsWith("Omit"):
Expand All @@ -1458,6 +1482,7 @@ class OasKindGenerator extends FunctionKindGenerator {
level,
descriptionOptions,
disallowedChildren: omitProperties,
saveSchema,
...rest,
})
case typeAsString.startsWith("Partial"):
Expand All @@ -1475,6 +1500,7 @@ class OasKindGenerator extends FunctionKindGenerator {
descriptionOptions,
disallowedChildren,
allowedChildren,
saveSchema,
...rest,
})

Expand All @@ -1485,13 +1511,29 @@ class OasKindGenerator extends FunctionKindGenerator {
case itemType.isClassOrInterface() ||
itemType.isTypeParameter() ||
(itemType as ts.Type).flags === ts.TypeFlags.Object:
const properties: Record<string, OpenApiSchema> = {}
const properties: Record<
string,
OpenApiSchema | OpenAPIV3.ReferenceObject
> = {}
const requiredProperties: string[] = []

const baseType = itemType.getBaseTypes()?.[0]
const isDeleteResponse =
baseType?.aliasSymbol?.getEscapedName() === "DeleteResponse"

const objSchema: OpenApiSchema = {
type: "object",
description,
"x-schemaName":
itemType.isClassOrInterface() ||
itemType.isTypeParameter() ||
(isZodObject(itemType) && zodObjectTypeName)
? this.oasSchemaHelper.normalizeSchemaName(typeAsString)
: undefined,
// this is changed later
required: undefined,
}

if (level + 1 <= this.MAX_LEVEL) {
itemType.getProperties().forEach((property) => {
if (
Expand All @@ -1504,6 +1546,41 @@ class OasKindGenerator extends FunctionKindGenerator {
requiredProperties.push(property.name)
}
const propertyType = this.checker.getTypeOfSymbol(property)

// if property's type is same as parent's property,
// create a reference to the parent
const arrHasParentType =
this.checker.isArrayType(propertyType) &&
this.areTypesEqual(
itemType,
this.checker.getTypeArguments(
propertyType as ts.TypeReference
)[0]
)
const isParentType = this.areTypesEqual(itemType, propertyType)

if (isParentType && objSchema["x-schemaName"]) {
properties[property.name] = {
$ref: this.oasSchemaHelper.constructSchemaReference(
objSchema["x-schemaName"]
),
}

return
} else if (arrHasParentType && objSchema["x-schemaName"]) {
properties[property.name] = {
type: "array",
description,
items: {
$ref: this.oasSchemaHelper.constructSchemaReference(
objSchema["x-schemaName"]
),
},
} as OpenAPIV3.ArraySchemaObject

return
}

properties[property.name] = this.typeToSchema({
itemType: propertyType,
level: level + 1,
Expand All @@ -1513,38 +1590,34 @@ class OasKindGenerator extends FunctionKindGenerator {
typeStr: property.name,
parentName: title || descriptionOptions?.parentName,
},
saveSchema,
...rest,
})

if (isDeleteResponse && property.name === "object") {
if (
isDeleteResponse &&
property.name === "object" &&
!this.oasSchemaHelper.isRefObject(properties[property.name])
) {
const schemaProperty = properties[property.name] as OpenApiSchema
// try to retrieve default from `DeleteResponse`'s type argument
const deleteTypeArg = baseType.aliasTypeArguments?.[0]
properties[property.name].default =
schemaProperty.default =
deleteTypeArg && "value" in deleteTypeArg
? (deleteTypeArg.value as string)
: properties[property.name].default
: schemaProperty.default
}
})
}

const objSchema: OpenApiSchema = {
type: "object",
description,
"x-schemaName":
itemType.isClassOrInterface() ||
itemType.isTypeParameter() ||
(isZodObject(itemType) && zodObjectTypeName)
? this.oasSchemaHelper.normalizeSchemaName(typeAsString)
: undefined,
required:
requiredProperties.length > 0 ? requiredProperties : undefined,
}

if (Object.values(properties).length) {
objSchema.properties = properties
}

if (objSchema["x-schemaName"]) {
objSchema.required =
requiredProperties.length > 0 ? requiredProperties : undefined

if (saveSchema && objSchema["x-schemaName"]) {
// add object to schemas to be created
// if necessary
this.oasSchemaHelper.namedSchemaToReference(objSchema)
Expand Down Expand Up @@ -1947,8 +2020,6 @@ class OasKindGenerator extends FunctionKindGenerator {
}) || oldSchemaObj.items
}

// update schema

if (
oldSchemaObj!.description !== newSchemaObj?.description &&
oldSchemaObj!.description === SUMMARY_PLACEHOLDER
Expand Down Expand Up @@ -2184,6 +2255,10 @@ class OasKindGenerator extends FunctionKindGenerator {
return true
})
}

private areTypesEqual(type1: ts.Type, type2: ts.Type): boolean {
return "id" in type1 && "id" in type2 && type1.id === type2.id
}
}

export default OasKindGenerator
Loading
Loading