添加注释
This commit is contained in:
parent
c6482c7f08
commit
4dc4427f2a
|
|
@ -384,6 +384,7 @@ const buildPlannedModuleExports = (selectedModules) => {
|
||||||
|
|
||||||
const buildModuleMap = (swagger) => {
|
const buildModuleMap = (swagger) => {
|
||||||
const moduleMap = new Map()
|
const moduleMap = new Map()
|
||||||
|
const tagDescriptionMap = buildTagDescriptionMap(swagger.tags)
|
||||||
|
|
||||||
for (const [apiPath, pathItem] of Object.entries(swagger.paths || {})) {
|
for (const [apiPath, pathItem] of Object.entries(swagger.paths || {})) {
|
||||||
for (const method of HTTP_METHOD_ORDER) {
|
for (const method of HTTP_METHOD_ORDER) {
|
||||||
|
|
@ -396,11 +397,17 @@ const buildModuleMap = (swagger) => {
|
||||||
const moduleName = extractModuleName(apiPath, operation)
|
const moduleName = extractModuleName(apiPath, operation)
|
||||||
const moduleKey = normalizeLookupKey(moduleName)
|
const moduleKey = normalizeLookupKey(moduleName)
|
||||||
const aliases = new Set([moduleName, toKebabCase(moduleName), ...(operation.tags || [])])
|
const aliases = new Set([moduleName, toKebabCase(moduleName), ...(operation.tags || [])])
|
||||||
|
const moduleDescription = resolveModuleDescription({
|
||||||
|
moduleName,
|
||||||
|
operation,
|
||||||
|
tagDescriptionMap,
|
||||||
|
})
|
||||||
|
|
||||||
if (!moduleMap.has(moduleKey)) {
|
if (!moduleMap.has(moduleKey)) {
|
||||||
moduleMap.set(moduleKey, {
|
moduleMap.set(moduleKey, {
|
||||||
aliases,
|
aliases,
|
||||||
fileName: toKebabCase(moduleName),
|
fileName: toKebabCase(moduleName),
|
||||||
|
moduleDescription,
|
||||||
moduleName,
|
moduleName,
|
||||||
operations: [],
|
operations: [],
|
||||||
})
|
})
|
||||||
|
|
@ -412,6 +419,10 @@ const buildModuleMap = (swagger) => {
|
||||||
moduleInfo.aliases.add(alias)
|
moduleInfo.aliases.add(alias)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!moduleInfo.moduleDescription && moduleDescription) {
|
||||||
|
moduleInfo.moduleDescription = moduleDescription
|
||||||
|
}
|
||||||
|
|
||||||
moduleInfo.operations.push({
|
moduleInfo.operations.push({
|
||||||
method,
|
method,
|
||||||
operation,
|
operation,
|
||||||
|
|
@ -851,10 +862,17 @@ const generateModuleFile = ({ moduleInfo, paramStyle, schemas, requestImport, sw
|
||||||
AUTO_GENERATED_BANNER,
|
AUTO_GENERATED_BANNER,
|
||||||
`// Swagger: ${swaggerUrl}`,
|
`// Swagger: ${swaggerUrl}`,
|
||||||
`// Module: ${moduleInfo.moduleName}`,
|
`// Module: ${moduleInfo.moduleName}`,
|
||||||
|
]
|
||||||
|
|
||||||
|
if (moduleInfo.moduleDescription) {
|
||||||
|
lines.push(`// Module description: ${escapeComment(moduleInfo.moduleDescription)}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push(
|
||||||
`// Param style: ${paramStyle}`,
|
`// Param style: ${paramStyle}`,
|
||||||
'',
|
'',
|
||||||
`import request from '${requestImport}'`,
|
`import request from '${requestImport}'`,
|
||||||
]
|
)
|
||||||
|
|
||||||
if (needsBuildUrl) {
|
if (needsBuildUrl) {
|
||||||
lines.push(`import { buildUrl } from '${DEFAULT_SHARED_IMPORT}'`)
|
lines.push(`import { buildUrl } from '${DEFAULT_SHARED_IMPORT}'`)
|
||||||
|
|
@ -1528,6 +1546,37 @@ const extractModuleName = (apiPath, operation) => {
|
||||||
return operation.tags?.[0] || segments[0] || 'default'
|
return operation.tags?.[0] || segments[0] || 'default'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildTagDescriptionMap = (tags = []) => {
|
||||||
|
const descriptionMap = new Map()
|
||||||
|
|
||||||
|
for (const tag of tags) {
|
||||||
|
const tagName = String(tag?.name || '').trim()
|
||||||
|
const tagDescription = String(tag?.description || '').trim()
|
||||||
|
|
||||||
|
if (!tagName || !tagDescription) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionMap.set(normalizeLookupKey(tagName), tagDescription)
|
||||||
|
}
|
||||||
|
|
||||||
|
return descriptionMap
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolveModuleDescription = ({ moduleName, operation, tagDescriptionMap }) => {
|
||||||
|
const candidates = [...(operation.tags || []), moduleName]
|
||||||
|
|
||||||
|
for (const candidate of candidates) {
|
||||||
|
const description = tagDescriptionMap.get(normalizeLookupKey(candidate))
|
||||||
|
|
||||||
|
if (description) {
|
||||||
|
return description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
const getEndpointName = (apiPath) => {
|
const getEndpointName = (apiPath) => {
|
||||||
const segments = apiPath.split('/').filter(Boolean)
|
const segments = apiPath.split('/').filter(Boolean)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,98 @@ test('generated index includes namespace exports and flattened re-exports', asyn
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('generated module file includes module description from swagger tags', async () => {
|
||||||
|
const tempDir = await createTempDir()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const swaggerPath = path.join(tempDir, 'swagger.json')
|
||||||
|
const outputDir = path.join(tempDir, 'generated')
|
||||||
|
|
||||||
|
await writeJson(swaggerPath, {
|
||||||
|
openapi: '3.0.0',
|
||||||
|
tags: [
|
||||||
|
{
|
||||||
|
name: 'Ranking',
|
||||||
|
description: '排行榜',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paths: {
|
||||||
|
'/api/v1/Ranking/GetList': {
|
||||||
|
get: {
|
||||||
|
responses: {
|
||||||
|
200: { description: 'OK' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await generateApiFiles({
|
||||||
|
projectRoot: tempDir,
|
||||||
|
swaggerUrl: swaggerPath,
|
||||||
|
swaggerTimeoutMs: 1000,
|
||||||
|
outputDir,
|
||||||
|
requestImport: '../request',
|
||||||
|
paramStyle: 'object',
|
||||||
|
modules: [],
|
||||||
|
cleanOutput: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const rankingContent = await readFile(path.join(outputDir, 'ranking.js'))
|
||||||
|
|
||||||
|
assert.match(rankingContent, /\/\/ Module: Ranking/)
|
||||||
|
assert.match(rankingContent, /\/\/ Module description: 排行榜/)
|
||||||
|
} finally {
|
||||||
|
await fs.rm(tempDir, { recursive: true, force: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('generated module file omits module description when swagger tags have no description', async () => {
|
||||||
|
const tempDir = await createTempDir()
|
||||||
|
|
||||||
|
try {
|
||||||
|
const swaggerPath = path.join(tempDir, 'swagger.json')
|
||||||
|
const outputDir = path.join(tempDir, 'generated')
|
||||||
|
|
||||||
|
await writeJson(swaggerPath, {
|
||||||
|
openapi: '3.0.0',
|
||||||
|
tags: [
|
||||||
|
{
|
||||||
|
name: 'Ranking',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paths: {
|
||||||
|
'/api/v1/Ranking/GetList': {
|
||||||
|
get: {
|
||||||
|
tags: ['Ranking'],
|
||||||
|
responses: {
|
||||||
|
200: { description: 'OK' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
await generateApiFiles({
|
||||||
|
projectRoot: tempDir,
|
||||||
|
swaggerUrl: swaggerPath,
|
||||||
|
swaggerTimeoutMs: 1000,
|
||||||
|
outputDir,
|
||||||
|
requestImport: '../request',
|
||||||
|
paramStyle: 'object',
|
||||||
|
modules: [],
|
||||||
|
cleanOutput: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const rankingContent = await readFile(path.join(outputDir, 'ranking.js'))
|
||||||
|
|
||||||
|
assert.match(rankingContent, /\/\/ Module: Ranking/)
|
||||||
|
assert.doesNotMatch(rankingContent, /\/\/ Module description:/)
|
||||||
|
} finally {
|
||||||
|
await fs.rm(tempDir, { recursive: true, force: true })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
test('generation can skip generated index.js when generateIndexFile is false', async () => {
|
test('generation can skip generated index.js when generateIndexFile is false', async () => {
|
||||||
const tempDir = await createTempDir()
|
const tempDir = await createTempDir()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue