docs-util: support new query type argument (#10468)
* add support for second query argument * more fixes
This commit is contained in:
1 parent
e3459b1f2f
commit
abdd4c9e99
2 files changed
+151
-106
No files matched your search
@@ -37,6 +37,12 @@ class SchemaFactory {
|
|||||||
BigNumberValue: {
|
BigNumberValue: {
|
||||||
type: "number",
|
type: "number",
|
||||||
},
|
},
|
||||||
|
difference_due: {
|
||||||
|
type: "number",
|
||||||
|
},
|
||||||
|
refund_amount: {
|
||||||
|
type: "number",
|
||||||
|
},
|
||||||
File: {
|
File: {
|
||||||
type: "object",
|
type: "object",
|
||||||
description: "A File to upload.",
|
description: "A File to upload.",
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
|||||||
"MedusaRequest",
|
"MedusaRequest",
|
||||||
"RequestWithContext",
|
"RequestWithContext",
|
||||||
"AuthenticatedMedusaRequest",
|
"AuthenticatedMedusaRequest",
|
||||||
|
"MedusaStoreRequest",
|
||||||
]
|
]
|
||||||
// as it's not always possible to detect authenticated request
|
// as it's not always possible to detect authenticated request
|
||||||
// use this to override the default detection logic.
|
// use this to override the default detection logic.
|
||||||
@@ -1015,120 +1016,158 @@ class OasKindGenerator extends FunctionKindGenerator {
|
|||||||
*/
|
*/
|
||||||
requestSchema?: OpenApiSchema
|
requestSchema?: OpenApiSchema
|
||||||
} {
|
} {
|
||||||
const parameters: OpenAPIV3.ParameterObject[] = []
|
const queryParameters: OpenAPIV3.ParameterObject[] = []
|
||||||
let requestSchema: OpenApiSchema | undefined
|
let requestSchema: OpenApiSchema | undefined
|
||||||
|
|
||||||
if (
|
if (
|
||||||
node.parameters[0].type &&
|
!node.parameters[0].type ||
|
||||||
ts.isTypeReferenceNode(node.parameters[0].type)
|
!ts.isTypeReferenceNode(node.parameters[0].type)
|
||||||
) {
|
) {
|
||||||
const requestType = this.checker.getTypeFromTypeNode(
|
return {
|
||||||
node.parameters[0].type
|
queryParameters,
|
||||||
) as ts.TypeReference
|
requestSchema,
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
return {
|
||||||
queryParameters: parameters,
|
queryParameters,
|
||||||
requestSchema,
|
requestSchema,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user