@cnbcool/cnb-api-generate 2.4.7 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildQueryValueExpression = buildQueryValueExpression;
37
+ const ts = __importStar(require("typescript"));
38
+ const query_path_alias_1 = require("../../utils/query-path-alias");
39
+ /**
40
+ * 构造请求参数对象里 `params:` / `_originParams.query:` 字段的值表达式。
41
+ *
42
+ * 规则:
43
+ * - path 与 query 没有同名冲突时:直接返回 `Identifier(queryVarName)`,
44
+ * 生成代码形如 `params: __query`;
45
+ * - 存在同名冲突时(如 `/{repo}/-/knowledge/base/query/{query}` 同时带 `?query=xxx`):
46
+ * 返回对象字面量 `{ ...__query, ["<原始 key>"]: q_<原始 key>, ... }`,
47
+ * 通过计算属性把别名 `q_xxx` 映射回 swagger 里的原始 key,
48
+ * 保证发给后端的 query string key 与 swagger 契约一致。
49
+ */
50
+ function buildQueryValueExpression(queryVarName, pathParams, queryParams) {
51
+ const aliasMap = (0, query_path_alias_1.collectQueryPathAliasMap)(pathParams, queryParams);
52
+ if (aliasMap.size === 0) {
53
+ return ts.factory.createIdentifier(queryVarName);
54
+ }
55
+ const properties = [
56
+ ts.factory.createSpreadAssignment(ts.factory.createIdentifier(queryVarName)),
57
+ ];
58
+ aliasMap.forEach((aliasName, originalName) => {
59
+ properties.push(ts.factory.createPropertyAssignment(ts.factory.createComputedPropertyName(ts.factory.createStringLiteral(originalName)), ts.factory.createIdentifier(aliasName)));
60
+ });
61
+ return ts.factory.createObjectLiteralExpression(properties, false);
62
+ }
@@ -55,7 +55,7 @@ function generateApiFunctionASTNode(methodData, definitions, defintionsMap) {
55
55
  let dependencies = new Set();
56
56
  // 根据parameters的类型,处理请求中不同的数据的处理方式
57
57
  const { pathParams, bodyParams, queryParams } = (0, filter_api_param_1.filterApiParam)(path, parameters);
58
- const { requestParamsASTNodes: paramASTNodes, reduxActionMap, dependencies: paramsDependencies, requestInterfaceASTNodes: paramsInterfaceASTNodes, } = (0, generate_function_params_ast_node_1.generateFunctionParamsASTNode)(methodData, pathParams, queryParams, bodyParams, defintionsMap);
58
+ const { requestParamsASTNodes: paramASTNodes, reduxActionMap, dependencies: paramsDependencies, requestInterfaceASTNodes: paramsInterfaceASTNodes, paramAliases, } = (0, generate_function_params_ast_node_1.generateFunctionParamsASTNode)(methodData, pathParams, queryParams, bodyParams, defintionsMap);
59
59
  if (paramsDependencies && paramsDependencies.size > 0) {
60
60
  dependencies = new Set([...dependencies, ...paramsDependencies]);
61
61
  }
@@ -113,7 +113,7 @@ function generateApiFunctionASTNode(methodData, definitions, defintionsMap) {
113
113
  ? undefined
114
114
  : ts.factory.createIdentifier(methodData.exportName), undefined, paramASTNodes, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier('Promise'), [
115
115
  ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(constants_1.CNB_REQUEST_RESULT_INTERFACE), [successApiReturnType, errorApiReturnType]),
116
- ]), (0, generate_function_content_ast_node_1.generateFunctionContentASTNode)(methodData, successApiReturnType, errorApiReturnType, pathParams, queryParams, bodyParams)));
116
+ ]), (0, generate_function_content_ast_node_1.generateFunctionContentASTNode)(methodData, successApiReturnType, errorApiReturnType, pathParams, queryParams, bodyParams, paramAliases)));
117
117
  for (const dependency of dependencies) {
118
118
  const defintion = defintionsMap[dependency];
119
119
  requestFileDependenciesASTNodes.push((0, generate_import_ast_node_1.generateImportAstNode)(defintion.exportName, defintion.filename, false, category, defintion.type));
@@ -38,11 +38,17 @@ const ts = __importStar(require("typescript"));
38
38
  const constants_1 = require("../../constants");
39
39
  const generate_request_url_ast_node_1 = require("./generate-request-url-ast-node");
40
40
  const is_skills_1 = require("../../utils/is-skills");
41
- function generateFunctionContentASTNode(methodData, fetchSuccessResponse, fetchErrorResponse, pathParams, queryParams, bodyParams) {
41
+ const build_query_value_expression_1 = require("./build-query-value-expression");
42
+ function generateFunctionContentASTNode(methodData, fetchSuccessResponse, fetchErrorResponse, pathParams, queryParams, bodyParams, paramAliases) {
43
+ var _a, _b, _c, _d;
44
+ const queryVarName = (_a = paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.queryName) !== null && _a !== void 0 ? _a : constants_1.CNB_REQUEST_PARAM_QUERY_NAME;
45
+ const reqVarName = (_b = paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.reqName) !== null && _b !== void 0 ? _b : constants_1.CNB_REQUEST_PARAM_REQ_NAME;
46
+ const optionsVarName = (_c = paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.optionsName) !== null && _c !== void 0 ? _c : constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME;
47
+ const axiosConfigVarName = (_d = paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.axiosConfigName) !== null && _d !== void 0 ? _d : constants_1.CNB_REQUEST_AXIOS_CONFIG_NAME;
42
48
  const requestParams = [
43
- ts.factory.createSpreadAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_AXIOS_CONFIG_NAME)),
44
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_NEXT_REQ), ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_REQ_NAME)),
45
- ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME), ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME)),
49
+ ts.factory.createSpreadAssignment(ts.factory.createIdentifier(axiosConfigVarName)),
50
+ ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_NEXT_REQ), ts.factory.createIdentifier(reqVarName)),
51
+ ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME), ts.factory.createIdentifier(optionsVarName)),
46
52
  ];
47
53
  // 请求路径
48
54
  requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_URL), (0, generate_request_url_ast_node_1.generateRequestUrlASTNode)(methodData.path, pathParams)));
@@ -52,11 +58,12 @@ function generateFunctionContentASTNode(methodData, fetchSuccessResponse, fetchE
52
58
  requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_METHOD), ts.factory.createStringLiteral(methodData.method)));
53
59
  // 请求query
54
60
  if (queryParams && queryParams.length > 0) {
55
- requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_QUERY_KEY_NAME), ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_QUERY_NAME)));
61
+ requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_QUERY_KEY_NAME), (0, build_query_value_expression_1.buildQueryValueExpression)(queryVarName, pathParams, queryParams)));
56
62
  }
57
63
  // 请求body
58
64
  if (bodyParams) {
59
- requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_DATA), ts.factory.createIdentifier(bodyParams.name)));
65
+ const bodyVarName = (paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.bodyParamName) || bodyParams.name;
66
+ requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_CONFIG_DATA), ts.factory.createIdentifier(bodyVarName)));
60
67
  }
61
68
  // 生成skills时,请求参数需要包含_originalParams,用于后处理时使用
62
69
  if ((0, is_skills_1.isSkills)()) {
@@ -72,10 +79,11 @@ function generateFunctionContentASTNode(methodData, fetchSuccessResponse, fetchE
72
79
  objectLiteralExpression.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PATH_PARAM_ORIGIN_NAME), ts.factory.createObjectLiteralExpression(pathParams.map((p) => ts.factory.createShorthandPropertyAssignment(ts.factory.createIdentifier(p.name), undefined)), false)));
73
80
  }
74
81
  if (queryParams.length > 0) {
75
- objectLiteralExpression.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_QUERY_PARAM_ORIGIN_NAME), ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_QUERY_NAME)));
82
+ objectLiteralExpression.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_QUERY_PARAM_ORIGIN_NAME), (0, build_query_value_expression_1.buildQueryValueExpression)(queryVarName, pathParams, queryParams)));
76
83
  }
77
84
  if (bodyParams) {
78
- objectLiteralExpression.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_BODY_PARAM_ORIGIN_NAME), ts.factory.createIdentifier(bodyParams.name)));
85
+ const bodyVarName = (paramAliases === null || paramAliases === void 0 ? void 0 : paramAliases.bodyParamName) || bodyParams.name;
86
+ objectLiteralExpression.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_BODY_PARAM_ORIGIN_NAME), ts.factory.createIdentifier(bodyVarName)));
79
87
  }
80
88
  requestParams.push(ts.factory.createPropertyAssignment(ts.factory.createIdentifier(constants_1.CNB_REQUEST_ORIGIN_PARAM_NAME), ts.factory.createObjectLiteralExpression(objectLiteralExpression, true)));
81
89
  }
@@ -42,8 +42,13 @@ const get_keyword_type_node_1 = require("../../utils/get-keyword-type-node");
42
42
  const is_english_only_1 = require("../../utils/is-english-only");
43
43
  const constants_1 = require("../../constants");
44
44
  const md_array_type_content_ast_node_1 = require("../types/md-array-type-content-ast-node");
45
+ const compute_param_aliases_1 = require("../../utils/compute-param-aliases");
46
+ const query_path_alias_1 = require("../../utils/query-path-alias");
45
47
  function generateFunctionParamsASTNode(methodData, pathParams, queryParams, bodyParams, defintionsMap) {
46
48
  var _a;
49
+ // 计算保留变量名(query/req/options/axiosConfig)的安全别名,
50
+ // 避免与 path/body 参数重名导致 "Argument name clash" 等语法错误。
51
+ const paramAliases = (0, compute_param_aliases_1.computeParamAliases)(pathParams, bodyParams);
47
52
  // request函数参数
48
53
  const requestParamsASTNodes = [];
49
54
  const requestInterfaceASTNodes = [];
@@ -60,8 +65,29 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
60
65
  const paramsInterfaceName = `${(0, format_interface_name_1.formatInterfaceName)(methodData.exportName)}Params`;
61
66
  const paramMap = {};
62
67
  const firstParams = [];
63
- // 排重
64
- [...pathParams, ...queryParams].map((item) => {
68
+ // path 参数与 query 参数同名时(如 /{repo}/-/knowledge/base/query/{query} 同时带 ?query=xxx):
69
+ // 两者语义不同,需要同时在类型里表达:
70
+ // - path 字段沿用 swagger 的原名(URL 模板里的字面占位,必须保持原名);
71
+ // - query 字段通过 `q_<name>` 别名字段在 interface 中暴露,
72
+ // 运行时再通过计算属性把别名映射回 swagger 的原始 key(见 generate-function-content-ast-node.ts)。
73
+ const pathParamNameSet = new Set(pathParams.map((p) => p.name));
74
+ [
75
+ ...pathParams,
76
+ ...queryParams.map((q) => {
77
+ if (!pathParamNameSet.has(q.name))
78
+ return q;
79
+ // 同名冲突:拷贝 query 参数并改名为 `q_<name>`,以便在 interface 中作为独立字段出现
80
+ const aliasName = (0, query_path_alias_1.getQueryPathAliasName)(q.name);
81
+ const aliasDesc = q.description
82
+ ? `${q.description}(query string 参数;该路由 path 也存在同名字段,为避免冲突此处使用别名 ${aliasName})`
83
+ : `query string 参数;该路由 path 也存在同名字段,为避免冲突此处使用别名 ${aliasName}`;
84
+ return {
85
+ ...q,
86
+ name: aliasName,
87
+ description: aliasDesc,
88
+ };
89
+ }),
90
+ ].map((item) => {
65
91
  paramMap[item.name] = item;
66
92
  });
67
93
  Object.keys(paramMap).forEach((key) => {
@@ -146,10 +172,21 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
146
172
  const pathParamsBindingElements = pathParams.map((item) => {
147
173
  return ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(item.name), undefined);
148
174
  });
175
+ // 同名 path/query 别名字段(如 q_query),需要单独从对象中解构出来,
176
+ // 避免被 `...__query` 吞掉后再做重映射(保留了可读性,并与 generate-function-content-ast-node 联动)。
177
+ const aliasQueryBindingElements = (queryParams || [])
178
+ .filter((q) => pathParamNameSet.has(q.name))
179
+ .map((q) => {
180
+ const aliasName = (0, query_path_alias_1.getQueryPathAliasName)(q.name);
181
+ return ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(aliasName), undefined);
182
+ });
149
183
  // 创建解构参数
150
- const deconstructionParams = [...pathParamsBindingElements];
184
+ const deconstructionParams = [
185
+ ...pathParamsBindingElements,
186
+ ...aliasQueryBindingElements,
187
+ ];
151
188
  if (queryParams && queryParams.length > 0) {
152
- deconstructionParams.push(ts.factory.createBindingElement(ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), undefined, ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_QUERY_NAME), undefined));
189
+ deconstructionParams.push(ts.factory.createBindingElement(ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), undefined, ts.factory.createIdentifier(paramAliases.queryName), undefined));
153
190
  }
154
191
  requestParamsASTNodes.push(ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern(deconstructionParams), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(paramsInterfaceName), undefined), undefined));
155
192
  // redux action参数定义
@@ -176,6 +213,11 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
176
213
  // eslint-disable-next-line @typescript-eslint/prefer-for-of
177
214
  for (let i = 0; i < allRequestParams.length; i++) {
178
215
  const param = allRequestParams[i];
216
+ // 仅 body 参数需要用别名替换标识符;单个 path 参数保留原名(必须等于 URL 占位符)
217
+ const isBodyParam = bodyParams !== null && param === bodyParams;
218
+ const effectiveParamName = isBodyParam && paramAliases.bodyParamName
219
+ ? paramAliases.bodyParamName
220
+ : param.name;
179
221
  if (param === null || param === void 0 ? void 0 : param.schema) {
180
222
  // 多维数组处理
181
223
  if (param.schema.type &&
@@ -192,13 +234,13 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
192
234
  requestInterfaceASTNodes.push(ts.factory.createExpressionStatement(ts.factory.createStringLiteral(`<$${paramsBodyName}$>`)));
193
235
  // 创建interface主体
194
236
  requestInterfaceASTNodes.push(ts.factory.createTypeAliasDeclaration([ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], ts.factory.createIdentifier(paramsBodyName), undefined, returnType));
195
- requestParamsASTNodes.push(ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier(param.name), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(paramsBodyName), undefined), undefined));
237
+ requestParamsASTNodes.push(ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier(effectiveParamName), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(paramsBodyName), undefined), undefined));
196
238
  if (typeDependencies && typeDependencies.size > 0) {
197
239
  dependencies = new Set([...dependencies, ...typeDependencies]);
198
240
  }
199
241
  // redux action参数定义
200
242
  reduxActionMap.paramsSequence.push({
201
- param: param.name,
243
+ param: effectiveParamName,
202
244
  typeLiteral: paramsBodyName,
203
245
  typeLiteralLabel: constants_1.TypeLiteralLabel.Quoted,
204
246
  required: param.required,
@@ -207,7 +249,14 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
207
249
  }
208
250
  else {
209
251
  const [imports, astNode, paramsSequenceItem] = (0, generate_function_refs_type_params_ast_node_1.generateFunctionReferenceTypeDataParamsASTNode)(param, defintionsMap);
210
- astNode && requestParamsASTNodes.push(astNode);
252
+ if (astNode && isBodyParam && effectiveParamName !== param.name) {
253
+ // 替换 body 参数的标识符为别名
254
+ requestParamsASTNodes.push(ts.factory.updateParameterDeclaration(astNode, astNode.modifiers, astNode.dotDotDotToken, ts.factory.createIdentifier(effectiveParamName), astNode.questionToken, astNode.type, astNode.initializer));
255
+ paramsSequenceItem.param = effectiveParamName;
256
+ }
257
+ else {
258
+ astNode && requestParamsASTNodes.push(astNode);
259
+ }
211
260
  if (imports && imports.size > 0) {
212
261
  dependencies = new Set([...dependencies, ...imports]);
213
262
  }
@@ -216,11 +265,14 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
216
265
  }
217
266
  }
218
267
  else {
219
- const normalParamsASTNode = (0, generate_function_normal_params_ast_node_1.generateFunctionNormalParamsASTNode)(param);
268
+ let normalParamsASTNode = (0, generate_function_normal_params_ast_node_1.generateFunctionNormalParamsASTNode)(param);
269
+ if (isBodyParam && effectiveParamName !== param.name) {
270
+ normalParamsASTNode = ts.factory.updateParameterDeclaration(normalParamsASTNode, normalParamsASTNode.modifiers, normalParamsASTNode.dotDotDotToken, ts.factory.createIdentifier(effectiveParamName), normalParamsASTNode.questionToken, normalParamsASTNode.type, normalParamsASTNode.initializer);
271
+ }
220
272
  requestParamsASTNodes.push(normalParamsASTNode);
221
273
  // redux action参数定义
222
274
  reduxActionMap.paramsSequence.push({
223
- param: param.name,
275
+ param: effectiveParamName,
224
276
  typeLiteral: param.type || null,
225
277
  typeLiteralLabel: constants_1.TypeLiteralLabel.Native,
226
278
  required: param.required,
@@ -229,9 +281,13 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
229
281
  }
230
282
  // 添加requestConfig
231
283
  requestParamsASTNodes.push(ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createObjectBindingPattern([
232
- ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_REQ_NAME), undefined),
233
- ts.factory.createBindingElement(undefined, undefined, ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME), undefined),
234
- ts.factory.createBindingElement(ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), undefined, ts.factory.createIdentifier(constants_1.CNB_REQUEST_AXIOS_CONFIG_NAME), undefined),
284
+ ts.factory.createBindingElement(undefined, paramAliases.reqName === constants_1.CNB_REQUEST_PARAM_REQ_NAME
285
+ ? undefined
286
+ : ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_REQ_NAME), ts.factory.createIdentifier(paramAliases.reqName), undefined),
287
+ ts.factory.createBindingElement(undefined, paramAliases.optionsName === constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME
288
+ ? undefined
289
+ : ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME), ts.factory.createIdentifier(paramAliases.optionsName), undefined),
290
+ ts.factory.createBindingElement(ts.factory.createToken(ts.SyntaxKind.DotDotDotToken), undefined, ts.factory.createIdentifier(paramAliases.axiosConfigName), undefined),
235
291
  ]), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(constants_1.CNB_REQUEST_PARAM_TYPE_NAME), undefined), ts.factory.createObjectLiteralExpression([], false)));
236
292
  // redux action参数定义
237
293
  reduxActionMap.paramsSequence.push({
@@ -245,5 +301,6 @@ function generateFunctionParamsASTNode(methodData, pathParams, queryParams, body
245
301
  reduxActionMap,
246
302
  dependencies,
247
303
  requestInterfaceASTNodes,
304
+ paramAliases,
248
305
  };
249
306
  }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeParamAliases = computeParamAliases;
4
+ const constants_1 = require("../constants");
5
+ const RESERVED_DEFAULTS = {
6
+ queryName: constants_1.CNB_REQUEST_PARAM_QUERY_NAME,
7
+ reqName: constants_1.CNB_REQUEST_PARAM_REQ_NAME,
8
+ optionsName: constants_1.CNB_REQUEST_PARAM_OPTIONS_NAME,
9
+ axiosConfigName: constants_1.CNB_REQUEST_AXIOS_CONFIG_NAME,
10
+ };
11
+ /**
12
+ * 给定一个目标变量名 base 和已被占用的名字集合 used,
13
+ * 返回不与 used 冲突的安全名(依次尝试 _base、__base 等)。
14
+ */
15
+ function pickUniqueName(base, used) {
16
+ if (!used.has(base))
17
+ return base;
18
+ let candidate = `_${base}`;
19
+ while (used.has(candidate)) {
20
+ candidate = `_${candidate}`;
21
+ }
22
+ return candidate;
23
+ }
24
+ /**
25
+ * 根据 path/body 参数名计算需要使用的保留变量名别名,避免命名冲突。
26
+ *
27
+ * 注意 path 参数名是"硬约束"(必须等于 URL 模板中的占位符名),
28
+ * 因此优先占用 path 参数名,再依次给 body / 保留变量分配安全名。
29
+ */
30
+ function computeParamAliases(pathParams = [], bodyParams = null) {
31
+ var _a;
32
+ const used = new Set();
33
+ pathParams.forEach((p) => {
34
+ if (p === null || p === void 0 ? void 0 : p.name)
35
+ used.add(p.name);
36
+ });
37
+ // body 参数名:与 path 参数 / 保留名冲突时改名
38
+ const originalBodyName = (_a = bodyParams === null || bodyParams === void 0 ? void 0 : bodyParams.name) !== null && _a !== void 0 ? _a : '';
39
+ const bodyParamName = originalBodyName
40
+ ? pickUniqueName(originalBodyName, used)
41
+ : '';
42
+ if (bodyParamName)
43
+ used.add(bodyParamName);
44
+ const aliases = {
45
+ ...RESERVED_DEFAULTS,
46
+ bodyParamName,
47
+ };
48
+ // 保留变量按顺序分配,先分配出去的别名也要避免后续被占用
49
+ ['queryName', 'reqName', 'optionsName', 'axiosConfigName'].forEach((key) => {
50
+ const safe = pickUniqueName(RESERVED_DEFAULTS[key], used);
51
+ aliases[key] = safe;
52
+ used.add(safe);
53
+ });
54
+ return aliases;
55
+ }
@@ -36,20 +36,25 @@ function flattenToolOptions(toolInfo) {
36
36
  });
37
37
  }
38
38
  }
39
- // query 参数
39
+ // query 参数:与 path 同名时,optKey 前缀 q- 以避免 Commander 选项名冲突
40
40
  if (queryDef) {
41
+ const pathKeys = new Set(pathDef ? Object.keys(pathDef) : []);
41
42
  for (const [key, param] of Object.entries(queryDef)) {
42
43
  const valuePlaceholder = (0, option_value_flag_1.optionValueFlag)(param.type);
43
44
  const rawDesc = (0, trim_summary_1.trimSummary)(param.description || '');
44
45
  const desc = param.required ? `[必填] ${rawDesc}` : rawDesc;
46
+ const conflict = pathKeys.has(key);
47
+ const optKey = conflict ? `q-${key}` : key;
45
48
  const opt = {
46
- optKey: key,
49
+ optKey,
47
50
  valuePlaceholder,
48
51
  description: desc,
49
52
  required: !!param.required,
50
53
  isArray: false,
51
54
  source: 'query',
52
55
  };
56
+ if (conflict)
57
+ opt.originalName = key;
53
58
  if (param.enum)
54
59
  opt.choices = param.enum;
55
60
  if (param.default !== undefined)
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QUERY_PATH_ALIAS_PREFIX = void 0;
4
+ exports.getQueryPathAliasName = getQueryPathAliasName;
5
+ exports.collectQueryPathAliasMap = collectQueryPathAliasMap;
6
+ /**
7
+ * path 参数与 query 参数同名时,query 字段在生成的 interface / 函数解构里
8
+ * 统一使用的别名前缀。
9
+ *
10
+ * 例如 swagger 中 `/{repo}/-/knowledge/base/query/{query}` 同时存在
11
+ * { name: 'query', in: 'path' }
12
+ * { name: 'query', in: 'query' }
13
+ * 两个语义不同的参数。我们保留 path 字段的原名(URL 占位),
14
+ * 而 query 字段改名为 `q_query`,运行时再用计算属性映射回原始 key。
15
+ */
16
+ exports.QUERY_PATH_ALIAS_PREFIX = 'q_';
17
+ /**
18
+ * 给定 swagger 原始 query 参数名,返回它在生成代码里的别名。
19
+ */
20
+ function getQueryPathAliasName(originalName) {
21
+ return `${exports.QUERY_PATH_ALIAS_PREFIX}${originalName}`;
22
+ }
23
+ /**
24
+ * 收集 query 参数中名字与 path 参数同名的项,返回 `原始名 -> 别名` 的映射。
25
+ * 没有冲突时返回空 Map。
26
+ */
27
+ function collectQueryPathAliasMap(pathParams = [], queryParams = []) {
28
+ const map = new Map();
29
+ if (!pathParams.length || !queryParams.length)
30
+ return map;
31
+ const pathNameSet = new Set(pathParams.map((p) => p.name));
32
+ for (const q of queryParams) {
33
+ if (pathNameSet.has(q.name)) {
34
+ map.set(q.name, getQueryPathAliasName(q.name));
35
+ }
36
+ }
37
+ return map;
38
+ }
@@ -48,8 +48,7 @@ export function formatParams(
48
48
  const bodyProps = paramDefs.body?.schema?.properties || {};
49
49
 
50
50
  const reservedKeys = new Set([
51
- 'module', 'tool', 'help', 'short', 'verbose',
52
- 'path', 'query', 'data', 'h', 'v',
51
+ 'module', 'tool', 'help', 'short', 'verbose', 'h', 'v',
53
52
  ]);
54
53
 
55
54
  // 收集 array<object> 展开字段的临时存储:{ arrayName: { propName: string[] } }
@@ -97,6 +96,18 @@ export function formatParams(
97
96
  // 归入 path
98
97
  if (!formatted.path) formatted.path = {};
99
98
  formatted.path[key] = value;
99
+ // path 与 query 同名时,query 参数通过 q- 前缀传入(见下方 q- 分支);
100
+ // 但若调用方直接用 --<name> 传了值(旧习惯/兼容),且 queryDef 里也有同名项,
101
+ // 则同时回填到 query,保证 URL 查询参数也被带上。
102
+ if (queryDef[key]) {
103
+ if (!formatted.query) formatted.query = {};
104
+ const paramType = queryDef[key].type;
105
+ if (paramType === 'number' && typeof value === 'string' && !isNaN(Number(value))) {
106
+ formatted.query[key] = Number(value);
107
+ } else {
108
+ formatted.query[key] = value;
109
+ }
110
+ }
100
111
  } else if (queryDef[key]) {
101
112
  // 归入 query
102
113
  if (!formatted.query) formatted.query = {};
@@ -106,6 +117,17 @@ export function formatParams(
106
117
  } else {
107
118
  formatted.query[key] = value;
108
119
  }
120
+ } else if ((key.startsWith('q-') || key.startsWith('q_'))
121
+ && queryDef[key.replace(/^q[-_]/, '')]) {
122
+ // query 参数与 path 同名时,CLI 层以 q- 前缀区分,这里还原为真实 query key
123
+ const originalKey = key.replace(/^q[-_]/, '');
124
+ if (!formatted.query) formatted.query = {};
125
+ const paramType = queryDef[originalKey].type;
126
+ if (paramType === 'number' && typeof value === 'string' && !isNaN(Number(value))) {
127
+ formatted.query[originalKey] = Number(value);
128
+ } else {
129
+ formatted.query[originalKey] = value;
130
+ }
109
131
  } else if (bodyProps[key]) {
110
132
  // body 字段(无冲突,直接用原 key)
111
133
  if (!formatted.data) formatted.data = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cnbcool/cnb-api-generate",
3
- "version": "2.4.7",
3
+ "version": "2.5.0",
4
4
  "main": "./built/index.js",
5
5
  "module": "./src/index.ts",
6
6
  "types": "./src/index.ts",