diff --git a/docs-util/packages/docblock-generator/src/classes/helpers/oas-schema.ts b/docs-util/packages/docblock-generator/src/classes/helpers/oas-schema.ts index 1ce9e55d93..f2f5633f54 100644 --- a/docs-util/packages/docblock-generator/src/classes/helpers/oas-schema.ts +++ b/docs-util/packages/docblock-generator/src/classes/helpers/oas-schema.ts @@ -63,17 +63,41 @@ class OasSchemaHelper { // and convert those if (schema.properties) { Object.keys(schema.properties).forEach((property) => { - if ( - "$ref" in schema.properties![property] || - !(schema.properties![property] as OpenApiSchema)["x-schemaName"] - ) { + const propertySchema = schema.properties![property] + if ("$ref" in propertySchema) { return } + // if the property is an array, possibly convert its items schema + // to a reference. + if ( + propertySchema.type === "array" && + propertySchema.items && + !("$ref" in propertySchema.items) + ) { + propertySchema.items = + this.schemaToReference(propertySchema.items) || propertySchema.items + } else if ( + propertySchema.oneOf || + propertySchema.allOf || + propertySchema.anyOf + ) { + // if the property is a combination of types, go through each of + // the types and try to convert them to references. + const schemaTarget = + propertySchema.oneOf || propertySchema.allOf || propertySchema.anyOf + schemaTarget!.forEach((item, index) => { + if ("$ref" in item) { + return + } + + schemaTarget![index] = this.schemaToReference(item) || item + }) + } + schema.properties![property] = - this.schemaToReference( - schema.properties![property] as OpenApiSchema - ) || schema.properties![property] + this.schemaToReference(propertySchema as OpenApiSchema) || + propertySchema }) } diff --git a/docs-util/packages/docblock-generator/src/classes/helpers/schema-factory.ts b/docs-util/packages/docblock-generator/src/classes/helpers/schema-factory.ts new file mode 100644 index 0000000000..18aec4954b --- /dev/null +++ b/docs-util/packages/docblock-generator/src/classes/helpers/schema-factory.ts @@ -0,0 +1,45 @@ +import { OpenApiSchema } from "../../types/index.js" + +/** + * This class has predefined OAS schemas for some types. It's used to bypass + * the logic of creating a schema for certain types. + */ +class SchemaFactory { + /** + * The pre-defined schemas. + */ + private schemas: Record = { + BigNumberInput: { + type: "string", + }, + BigNumber: { + type: "string", + }, + } + + /** + * Try to retrieve the pre-defined schema of a type name. + * + * @param name - the name of the type. + * @param additionalData - Additional data to pass along/override in the predefined schema. For example, a description. + * @returns The schema, if found. + */ + public tryGetSchema( + name: string, + additionalData?: Partial + ): OpenApiSchema | undefined { + if (!Object.hasOwn(this.schemas, name)) { + return + } + + let schema = Object.assign({}, this.schemas[name]) + + if (additionalData) { + schema = Object.assign(schema, additionalData) + } + + return schema + } +} + +export default SchemaFactory diff --git a/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts b/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts index 35d0a37205..1548b52fae 100644 --- a/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts +++ b/docs-util/packages/docblock-generator/src/classes/kinds/oas.ts @@ -27,6 +27,7 @@ import parseOas, { ExistingOas } from "../../utils/parse-oas.js" import OasSchemaHelper from "../helpers/oas-schema.js" import formatOas from "../../utils/format-oas.js" import { DEFAULT_OAS_RESPONSES } from "../../constants.js" +import SchemaFactory from "../helpers/schema-factory.js" export const API_ROUTE_PARAM_REGEX = /\[(.+?)\]/g const RES_STATUS_REGEX = /^res[\s\S]*\.status\((\d+)\)/ @@ -68,6 +69,7 @@ class OasKindGenerator extends FunctionKindGenerator { protected baseOutputPath: string protected oasExamplesGenerator: OasExamplesGenerator protected oasSchemaHelper: OasSchemaHelper + protected schemaFactory: SchemaFactory constructor(options: GeneratorOptions) { super(options) @@ -77,6 +79,7 @@ class OasKindGenerator extends FunctionKindGenerator { this.tags = new Map() this.oasSchemaHelper = new OasSchemaHelper() + this.schemaFactory = new SchemaFactory() this.init() this.generatorEventManager.listen( @@ -1230,6 +1233,21 @@ class OasKindGenerator extends FunctionKindGenerator { : this.defaultSummary const typeAsString = this.checker.typeToString(itemType) + const schemaFromFactory = this.schemaFactory.tryGetSchema( + itemType.symbol?.getName() || + itemType.aliasSymbol?.getName() || + title || + typeAsString, + { + title: title || typeAsString, + description, + } + ) + + if (schemaFromFactory) { + return schemaFromFactory + } + switch (true) { case itemType.flags === ts.TypeFlags.Enum: const enumMembers: string[] = [] @@ -1442,6 +1460,7 @@ class OasKindGenerator extends FunctionKindGenerator { }) }) } + const objSchema: OpenApiSchema = { type: "object", description, @@ -1743,6 +1762,7 @@ class OasKindGenerator extends FunctionKindGenerator { } oldSchemaObj!.required = newSchemaObj?.required + oldSchemaObj!["x-schemaName"] = newSchemaObj?.["x-schemaName"] if (oldSchemaObj!.type === "object") { if (!oldSchemaObj?.properties && newSchemaObj?.properties) { diff --git a/packages/oas/medusa-oas-cli/redocly/redocly-config.yaml b/packages/oas/medusa-oas-cli/redocly/redocly-config.yaml index 632a112796..312f53e94f 100644 --- a/packages/oas/medusa-oas-cli/redocly/redocly-config.yaml +++ b/packages/oas/medusa-oas-cli/redocly/redocly-config.yaml @@ -138,6 +138,10 @@ decorators: - Order - Cart - PublishableApiKey + CustomerGroupResponse: + - CustomerResponse + ProductCategoryResponse: + - ProductCategoryResponse # Similar config to /www/docs/docusaurus.config.js > redocusaurus # Allows to emulate rendering of API public documentation when using `yarn redocly preview-docs openapi.yaml`