docs-util: support new query type argument (#10468)
* add support for second query argument * more fixes
This commit is contained in:
@@ -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.",
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const requestTypeArguments =
|
||||
requestType.typeArguments || requestType.aliasTypeArguments
|
||||
|
||||
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],
|
||||
descriptionOptions: {
|
||||
parentName: tagName,
|
||||
rawParentName: this.checker.typeToString(requestTypeArguments[0]),
|
||||
},
|
||||
zodObjectTypeName: zodObjectTypeName,
|
||||
context: isQuery ? "query" : "request",
|
||||
saveSchema: !forUpdate,
|
||||
})
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// check if parameter is already added
|
||||
const isAdded = parameters.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,
|
||||
})
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
} else if (methodName !== "delete") {
|
||||
requestSchema = parameterSchema
|
||||
}
|
||||
return {
|
||||
queryParameters,
|
||||
requestSchema,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}),
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
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[1]),
|
||||
},
|
||||
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 || 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 = queryParameters.some((param) => param.name === key)
|
||||
|
||||
if (isAdded) {
|
||||
return
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user