通过swagger-typescript-api获取的接口方法,默认的命名方式是后端的方法名,后端经常会在不同的controller下写很多相同的方法名(如list这种命名) 通过自定义调用generateApi,可以将命名规则改为 请求方法+路径
import path from 'node:path'
import { generateApi } from 'swagger-typescript-api'
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
function singular(word) {
// 简易处理,可换成更完善的库(如 pluralize)
if (word.endsWith('s')) return word.slice(0, -1)
return word
}
function joinSegments(segments) {
return segments.join('')
}
/* NOTE: all fields are optional expect one of `input`, `url`, `spec` */
generateApi({
name: 'ApiBusiness.ts',
fileName: 'ApiBusiness.ts',
// set to `false` to prevent the tool from writing to disk
url: 'http://10.10.10.115:7000/business/v3/api-docs',
output: path.resolve(process.cwd(), './src/api'),
httpClientType: 'axios',
generateRouteTypes: false,
hooks: {
onFormatRouteName: (routeInfo) => {
/**
* routeInfo 示例:
* {
* method: 'get',
* route: '/users/{id}/roles',
* originalPath: '/users/{id}/roles',
* ... 其他字段
* }
*/
const httpMethod = (routeInfo.method || '').toLowerCase()
const rawPath = routeInfo.route || ''
// 1. 拆分路径段
const segments = rawPath
.split('/')
.filter(Boolean)
.map((s) => s.replace(/\{|\}/g, '')) // 去掉 {param}
// 3. 标识业务主资源(第一个非参数段)
const resourceSegments = segments.filter((s) => !rawPath.includes(`{${s}}`))
// 简单判断动作(可按需扩展更复杂逻辑)
const verbMap = {
get: 'get',
post: 'create',
put: 'update',
patch: 'patch',
delete: 'delete',
}
// 特殊:嵌套 + POST 往往表示“添加子资源”
// 例如 /users/{id}/roles POST -> addUserRole
if (httpMethod === 'post' && segments.length > 2) {
// 最后一个非参数段作为子资源
const last = segments[segments.length - 1]
if (!rawPath.includes(`{${last}}`)) {
return (
'add' +
capitalize(joinSegments(resourceSegments.slice(0, 1))) +
singular(capitalize(last))
)
}
}
// 构造核心资源名(主资源+可能的子资源)
let core = resourceSegments.map(capitalize).join('')
if (!core) {
core = 'Request'
}
// 拼接参数修饰(ByXxx...)
let byPart = ''
const paramNames = segments.filter((s) => rawPath.includes(`{${s}}`))
if (paramNames.length) {
byPart = 'By' + paramNames.map(capitalize).join('And')
}
// 选择动词
let verb = verbMap[httpMethod] || httpMethod
// 如果是 GET 并且无参数且资源名复数 -> getUsers 这种就保留
// 如果是 GET + 有参数 -> getUserById
// 如果是 DELETE + 有子资源参数 -> deleteUserRoleByRoleId
// 已在通用逻辑覆盖
return verb + core + byPart
},
},
prettier: {
// By default prettier config is load from your project
printWidth: 120,
tabWidth: 2,
trailingComma: 'all',
parser: 'typescript',
},
})