From abdd4c9e99476561379294d4d69180ada40880e9 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Fri, 6 Dec 2024 12:21:19 +0200 Subject: [PATCH] docs-util: support new query type argument (#10468) * add support for second query argument * more fixes --- .../src/classes/helpers/schema-factory.ts | 6 + .../docs-generator/src/classes/kinds/oas.ts | 227 ++++++++++-------- 2 files changed, 139 insertions(+), 94 deletions(-) diff --git a/www/utils/packages/docs-generator/src/classes/helpers/schema-factory.ts b/www/utils/packages/docs-generator/src/classes/helpers/schema-factory.ts index 6be03bca6165a..c5c2f05471a28 100644 --- a/www/utils/packages/docs-generator/src/classes/helpers/schema-factory.ts +++ b/www/utils/packages/docs-generator/src/classes/helpers/schema-factory.ts @@ -37,6 +37,12 @@ class SchemaFactory { BigNumberValue: { type: "number", }, + difference_due: { + type: "number", + }, + refund_amount: { + type: "number", + }, File: { type: "object", description: "A File to upload.", diff --git a/www/utils/packages/docs-generator/src/classes/kinds/oas.ts b/www/utils/packages/docs-generator/src/classes/kinds/oas.ts index ec63cde75575b..8657ae76d4c4d 100644 --- a/www/utils/packages/docs-generator/src/classes/kinds/oas.ts +++ b/www/utils/packages/docs-generator/src/classes/kinds/oas.ts @@ -65,6 +65,7 @@ class OasKindGenerator extends FunctionKindGenerator { "MedusaRequest", "RequestWithContext", "AuthenticatedMedusaRequest", + "MedusaStoreRequest", ] // as it's not always possible to detect authenticated request // use this to override the default detection logic. @@ -1015,120 +1016,158 @@ class OasKindGenerator extends FunctionKindGenerator { */ requestSchema?: OpenApiSchema } { - const parameters: OpenAPIV3.ParameterObject[] = [] + const queryParameters: OpenAPIV3.ParameterObject[] = [] let requestSchema: OpenApiSchema | undefined if ( - node.parameters[0].type && - ts.isTypeReferenceNode(node.parameters[0].type) + !node.parameters[0].type || + !ts.isTypeReferenceNode(node.parameters[0].type) ) { - const requestType = this.checker.getTypeFromTypeNode( - node.parameters[0].type - ) as ts.TypeReference - // TODO for now I'll use the type for validatedQuery until - // we have an actual approach to infer query types - const querySymbol = requestType.getProperty("validatedQuery") - if (querySymbol) { - const { shouldAddFields, shouldAddPagination } = - this.shouldAddQueryParams(node) - const queryType = this.checker.getTypeOfSymbol(querySymbol) - const queryTypeName = this.checker.typeToString(queryType) - queryType.getProperties().forEach((property) => { - const propertyName = property.getName() - // if this is a field / pagination query parameter and - // they're not used in the route, don't add them. - if ( - (this.FIELD_QUERY_PARAMS.includes(propertyName) && - !shouldAddFields) || - (this.PAGINATION_QUERY_PARAMS.includes(propertyName) && - !shouldAddPagination) - ) { - return - } - const propertyType = this.checker.getTypeOfSymbol(property) - const descriptionOptions: SchemaDescriptionOptions = { - typeStr: propertyName, - parentName: tagName, - rawParentName: queryTypeName, - node: property.valueDeclaration, - symbol: property, - nodeType: propertyType, - } - parameters.push( - this.getParameterObject({ - name: propertyName, - type: "query", - description: this.getSchemaDescription(descriptionOptions), - required: this.isRequired(property), - schema: this.typeToSchema({ - itemType: propertyType, - title: propertyName, - descriptionOptions, - context: "query", - saveSchema: !forUpdate, - }), - }) - ) - }) + return { + queryParameters, + requestSchema, } + } - const requestTypeArguments = - requestType.typeArguments || requestType.aliasTypeArguments + const requestType = this.checker.getTypeFromTypeNode( + node.parameters[0].type + ) as ts.TypeReference + // TODO for now I'll use the type for validatedQuery until + // we have an actual approach to infer query types + const querySymbol = requestType.getProperty("validatedQuery") + if (querySymbol) { + const { shouldAddFields, shouldAddPagination } = + this.shouldAddQueryParams(node) + const queryType = this.checker.getTypeOfSymbol(querySymbol) + const queryTypeName = this.checker.typeToString(queryType) + queryType.getProperties().forEach((property) => { + const propertyName = property.getName() + // if this is a field / pagination query parameter and + // they're not used in the route, don't add them. + if ( + (this.FIELD_QUERY_PARAMS.includes(propertyName) && + !shouldAddFields) || + (this.PAGINATION_QUERY_PARAMS.includes(propertyName) && + !shouldAddPagination) + ) { + return + } + const propertyType = this.checker.getTypeOfSymbol(property) + const descriptionOptions: SchemaDescriptionOptions = { + typeStr: propertyName, + parentName: tagName, + rawParentName: queryTypeName, + node: property.valueDeclaration, + symbol: property, + nodeType: propertyType, + } + queryParameters.push( + this.getParameterObject({ + name: propertyName, + type: "query", + description: this.getSchemaDescription(descriptionOptions), + required: this.isRequired(property), + schema: this.typeToSchema({ + itemType: propertyType, + title: propertyName, + descriptionOptions, + context: "query", + saveSchema: !forUpdate, + }), + }) + ) + }) + } - if (requestTypeArguments?.length === 1) { - const zodObjectTypeName = getCorrectZodTypeName({ - typeReferenceNode: node.parameters[0].type, - itemType: requestTypeArguments[0], - }) - const isQuery = methodName === "get" - const parameterSchema = this.typeToSchema({ - itemType: requestTypeArguments[0], + const requestTypeArguments = + requestType.typeArguments || requestType.aliasTypeArguments + + if (!requestTypeArguments || requestTypeArguments.length < 2) { + return { + queryParameters, + requestSchema, + } + } + + // Not all routes support a second type argument yet, + // so the query param may be passed in the first type argument + const hasQueryParams = requestTypeArguments[1].getProperties().length > 0 + // Not all routes support a second type argument yet, + // so we have to support routes that pass the query parameters type + // in the first type argument + const isQuery = methodName === "get" + + const zodObjectRequestBodyTypeName = getCorrectZodTypeName({ + typeReferenceNode: node.parameters[0].type, + itemType: requestTypeArguments[0], + }) + const zodObjectQueryTypeName = getCorrectZodTypeName({ + typeReferenceNode: node.parameters[0].type, + itemType: requestTypeArguments[1], + }) + + const requestBodyParameterSchema = this.typeToSchema({ + itemType: requestTypeArguments[0], + descriptionOptions: { + parentName: tagName, + rawParentName: this.checker.typeToString(requestTypeArguments[0]), + }, + zodObjectTypeName: zodObjectRequestBodyTypeName, + context: isQuery ? "query" : "request", + saveSchema: !forUpdate, + }) + const queryParameterSchema = hasQueryParams + ? this.typeToSchema({ + itemType: requestTypeArguments[1], descriptionOptions: { parentName: tagName, - rawParentName: this.checker.typeToString(requestTypeArguments[0]), + rawParentName: this.checker.typeToString(requestTypeArguments[1]), }, - zodObjectTypeName: zodObjectTypeName, - context: isQuery ? "query" : "request", + zodObjectTypeName: zodObjectQueryTypeName, + context: "query", saveSchema: !forUpdate, }) + : requestBodyParameterSchema - // If function is a GET function, add the type parameter to the - // query parameters instead of request parameters. - if (isQuery) { - if (parameterSchema.type === "object" && parameterSchema.properties) { - Object.entries(parameterSchema.properties).forEach( - ([key, propertySchema]) => { - if ("$ref" in propertySchema) { - return - } + // If function is a GET function, add the type parameter to the + // query parameters instead of request parameters. + if ( + (isQuery || hasQueryParams) && + queryParameterSchema.type === "object" && + queryParameterSchema.properties + ) { + Object.entries(queryParameterSchema.properties).forEach( + ([key, propertySchema]) => { + if ("$ref" in propertySchema) { + return + } - // check if parameter is already added - const isAdded = parameters.some((param) => param.name === key) + // check if parameter is already added + const isAdded = queryParameters.some((param) => param.name === key) - if (isAdded) { - return - } - - parameters.push( - this.getParameterObject({ - name: key, - type: "query", - description: propertySchema.description, - required: parameterSchema.required?.includes(key) || false, - schema: propertySchema, - }) - ) - } - ) + if (isAdded) { + return } - } else if (methodName !== "delete") { - requestSchema = parameterSchema + + queryParameters.push( + this.getParameterObject({ + name: key, + type: "query", + description: propertySchema.description, + required: queryParameterSchema.required?.includes(key) || false, + schema: propertySchema, + }) + ) } - } + ) + } + + if (methodName !== "delete" && methodName !== "get") { + requestSchema = requestBodyParameterSchema } return { - queryParameters: parameters, + queryParameters, requestSchema, } }