docs-util: improvements and fixes to OAS generation (#8855)
- Add to knowledge base summaries for delete-related properties - Fix long curl examples overflowing the line - Fix singular / plural usage in some knowledge base descriptions / summaries - Fix some workflows not picked up - Remove query params for routes that don't use them.
This commit is contained in:
@@ -35,6 +35,7 @@ type SchemaDescriptionOptions = {
|
||||
nodeType?: ts.Type
|
||||
typeStr: string
|
||||
parentName?: string
|
||||
rawParentName?: string
|
||||
}
|
||||
|
||||
export type OasArea = "admin" | "store"
|
||||
@@ -954,13 +955,15 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
// 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) {
|
||||
if (querySymbol && this.shouldAddQueryParams(node)) {
|
||||
const queryType = this.checker.getTypeOfSymbol(querySymbol)
|
||||
const queryTypeName = this.checker.typeToString(queryType)
|
||||
queryType.getProperties().forEach((property) => {
|
||||
const propertyType = this.checker.getTypeOfSymbol(property)
|
||||
const descriptionOptions: SchemaDescriptionOptions = {
|
||||
typeStr: property.getName(),
|
||||
parentName: tagName,
|
||||
rawParentName: queryTypeName,
|
||||
node: property.valueDeclaration,
|
||||
symbol: property,
|
||||
nodeType: propertyType,
|
||||
@@ -993,6 +996,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
itemType: requestTypeArguments[0],
|
||||
descriptionOptions: {
|
||||
parentName: tagName,
|
||||
rawParentName: this.checker.typeToString(requestTypeArguments[0]),
|
||||
},
|
||||
zodObjectTypeName: zodObjectTypeName,
|
||||
})
|
||||
@@ -1095,6 +1099,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
itemType: responseTypeArguments[0],
|
||||
descriptionOptions: {
|
||||
parentName: tagName,
|
||||
rawParentName: this.checker.typeToString(responseTypeArguments[0]),
|
||||
},
|
||||
zodObjectTypeName: getCorrectZodTypeName({
|
||||
typeReferenceNode: node.parameters[1].type,
|
||||
@@ -1390,8 +1395,9 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
if (this.isRequired(property)) {
|
||||
requiredProperties.push(property.name)
|
||||
}
|
||||
const propertyType = this.checker.getTypeOfSymbol(property)
|
||||
properties[property.name] = this.typeToSchema({
|
||||
itemType: this.checker.getTypeOfSymbol(property),
|
||||
itemType: propertyType,
|
||||
level: level + 1,
|
||||
title: property.name,
|
||||
descriptionOptions: {
|
||||
@@ -1453,7 +1459,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
node,
|
||||
nodeType,
|
||||
typeStr,
|
||||
parentName,
|
||||
...templateOptions
|
||||
}: SchemaDescriptionOptions): string {
|
||||
if (!symbol && !node && !nodeType) {
|
||||
// if none of the associated symbol, node, or type are provided,
|
||||
@@ -1462,9 +1468,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
return (
|
||||
this.knowledgeBaseFactory.tryToGetOasSchemaDescription({
|
||||
str: typeStr,
|
||||
templateOptions: {
|
||||
parentName,
|
||||
},
|
||||
templateOptions,
|
||||
}) || SUMMARY_PLACEHOLDER
|
||||
)
|
||||
}
|
||||
@@ -1882,66 +1886,54 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
getAssociatedWorkflow(node: FunctionNode): string | undefined {
|
||||
let workflow: string | undefined
|
||||
|
||||
if (
|
||||
(!ts.isFunctionDeclaration(node) && !ts.isArrowFunction(node)) ||
|
||||
!node.body ||
|
||||
!ts.isBlock(node.body)
|
||||
) {
|
||||
if (!ts.isFunctionDeclaration(node) && !ts.isArrowFunction(node)) {
|
||||
return
|
||||
}
|
||||
|
||||
const sourceFile = node.getSourceFile()
|
||||
const fileLocalSymbols: Map<string, ts.Symbol> =
|
||||
"locals" in sourceFile
|
||||
? (sourceFile.locals as Map<string, ts.Symbol>)
|
||||
: new Map()
|
||||
|
||||
if (!fileLocalSymbols.size) {
|
||||
// if a source file doesn't have imports, then it's assumed that it's not using workflows.
|
||||
if (!("imports" in sourceFile) || !Array.isArray(sourceFile.imports)) {
|
||||
return
|
||||
}
|
||||
|
||||
node.body.statements.some((statement) => {
|
||||
let awaitExpression: ts.AwaitExpression | undefined
|
||||
// retrieve workflows imported from `@medusajs/core-flows`
|
||||
// since there could be multiple import statements from the
|
||||
// same package, put them in an array
|
||||
const coreFlowsImports: ts.ImportClause[] = []
|
||||
;(sourceFile.imports as ts.Node[]).forEach((importNode) => {
|
||||
if (
|
||||
ts.isVariableStatement(statement) &&
|
||||
statement.declarationList.declarations[0].initializer &&
|
||||
ts.isAwaitExpression(
|
||||
statement.declarationList.declarations[0].initializer
|
||||
)
|
||||
!importNode.parent ||
|
||||
!ts.isImportDeclaration(importNode.parent) ||
|
||||
!importNode.parent.importClause?.namedBindings ||
|
||||
importNode.getText() !== `"@medusajs/core-flows"`
|
||||
) {
|
||||
awaitExpression = statement.declarationList.declarations[0].initializer
|
||||
} else if (ts.isAwaitExpression(statement)) {
|
||||
awaitExpression = statement
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
!awaitExpression ||
|
||||
!ts.isCallExpression(awaitExpression.expression) ||
|
||||
!ts.isPropertyAccessExpression(awaitExpression.expression.expression) ||
|
||||
!awaitExpression.expression.expression.name.getText().startsWith("run")
|
||||
) {
|
||||
return false
|
||||
}
|
||||
coreFlowsImports.push(importNode.parent.importClause)
|
||||
})
|
||||
|
||||
const fullExpressionText = awaitExpression.expression.getText()
|
||||
const parenIndex = fullExpressionText.indexOf("(")
|
||||
const dotIndex = fullExpressionText.indexOf(".")
|
||||
const cutOffIndex =
|
||||
parenIndex !== -1 && dotIndex === -1
|
||||
? parenIndex
|
||||
: parenIndex === -1 && dotIndex !== -1
|
||||
? dotIndex
|
||||
: parenIndex === -1 && dotIndex === -1
|
||||
? fullExpressionText.length
|
||||
: Math.min(parenIndex, dotIndex)
|
||||
const expressionName = fullExpressionText.substring(0, cutOffIndex)
|
||||
// if no imports found from `@medusajs/core-flows`, return
|
||||
if (!coreFlowsImports.length) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!fileLocalSymbols.has(expressionName)) {
|
||||
return false
|
||||
}
|
||||
// check if any of the imported vars are used in the function node
|
||||
// const fileWorkflowImports: Map<string, ts.Identifier> = new Map()
|
||||
const fnText = node.getText()
|
||||
coreFlowsImports.forEach((coreFlowsImport) => {
|
||||
coreFlowsImport.namedBindings?.forEachChild((childImport) => {
|
||||
if (!ts.isImportSpecifier(childImport) || workflow) {
|
||||
return
|
||||
}
|
||||
|
||||
workflow = expressionName
|
||||
return true
|
||||
const workflowName = childImport.name.getText()
|
||||
|
||||
if (fnText.includes(workflowName)) {
|
||||
workflow = workflowName
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return workflow
|
||||
@@ -2031,6 +2023,17 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
writeFileSync(areaYamlPath, stringify(areaYaml))
|
||||
}
|
||||
}
|
||||
|
||||
shouldAddQueryParams(node: FunctionNode): boolean {
|
||||
const queryParamsUsageIndicators = [
|
||||
`req.filterableFields`,
|
||||
`req.remoteQueryConfig`,
|
||||
]
|
||||
const fnText = node.getText()
|
||||
return queryParamsUsageIndicators.some((indicator) =>
|
||||
fnText.includes(indicator)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default OasKindGenerator
|
||||
|
||||
Reference in New Issue
Block a user