next-openapi-gen 1.4.1 → 1.4.3

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.
@@ -923,7 +923,6 @@ function parseJSDocBlock(commentValue, filePath) {
923
923
  result.summary = explicitSummary;
924
924
  }
925
925
  result.description = extractLineValue(normalizedComment, "@description");
926
- result.tag = extractLineValue(normalizedComment, "@tag");
927
926
  result.tagSummary = extractLineValue(normalizedComment, "@tagSummary");
928
927
  result.tagKind = extractLineValue(normalizedComment, "@tagKind");
929
928
  result.tagParent = extractLineValue(normalizedComment, "@tagParent");
@@ -957,17 +956,28 @@ function parseJSDocBlock(commentValue, filePath) {
957
956
  if (Array.isArray(responsePrefixEncoding)) {
958
957
  result.responsePrefixEncoding = responsePrefixEncoding;
959
958
  }
960
- const parsedResponse = parseResponseTag(normalizedComment);
961
- if (parsedResponse) {
962
- result.successCode = parsedResponse.successCode;
963
- result.responseType = parsedResponse.responseType;
964
- if (!result.responseDescription && parsedResponse.responseDescription) {
965
- result.responseDescription = parsedResponse.responseDescription;
959
+ const responseMatches = [...normalizedComment.matchAll(/@response\s+([^\n\r@]+)/g)];
960
+ if (responseMatches.length > 0) {
961
+ const firstRaw = responseMatches[0]?.[1]?.trim();
962
+ if (firstRaw) {
963
+ const parsedResponse = parseResponseRawValue(firstRaw);
964
+ result.successCode = parsedResponse.successCode;
965
+ result.responseType = parsedResponse.responseType;
966
+ if (!result.responseDescription && parsedResponse.responseDescription) {
967
+ result.responseDescription = parsedResponse.responseDescription;
968
+ }
969
+ }
970
+ const extraResponses = responseMatches.slice(1).map((m) => m[1]?.trim()).filter((t17) => Boolean(t17));
971
+ if (extraResponses.length > 0) {
972
+ result.addResponses = extraResponses.join(",");
966
973
  }
967
974
  }
968
975
  const addMatches = [...normalizedComment.matchAll(/@add\s+([^\n\r@]*)/g)];
969
976
  if (addMatches.length > 0) {
970
- result.addResponses = addMatches.map((match) => match[1]?.trim() || "").filter(Boolean).join(",");
977
+ const addEntries = addMatches.map((match) => match[1]?.trim() || "").filter(Boolean).join(",");
978
+ if (addEntries) {
979
+ result.addResponses = result.addResponses ? `${result.addResponses},${addEntries}` : addEntries;
980
+ }
971
981
  }
972
982
  const examples = collectExampleDefinitions(normalizedComment, "@examples", filePath);
973
983
  result.requestExamples = buildExampleMap(examples.definitions, "request");
@@ -980,6 +990,17 @@ function parseJSDocBlock(commentValue, filePath) {
980
990
  if (additionalTags.length > 0) {
981
991
  result.tags = additionalTags;
982
992
  }
993
+ const tagMatches = [...normalizedComment.matchAll(/@tag\s+([^\n\r@]*)/g)];
994
+ if (tagMatches.length > 0) {
995
+ const primaryTag = tagMatches[0]?.[1]?.trim();
996
+ if (primaryTag) {
997
+ result.tag = primaryTag;
998
+ }
999
+ const extraTags = tagMatches.slice(1).map((m) => m[1]?.trim()).filter((t17) => Boolean(t17));
1000
+ if (extraTags.length > 0) {
1001
+ result.tags = [...result.tags ?? [], ...extraTags];
1002
+ }
1003
+ }
983
1004
  const servers = parseServersTag(normalizedComment);
984
1005
  if (servers.length > 0) {
985
1006
  result.servers = servers;
@@ -1182,11 +1203,7 @@ function parseOpenApiOverrideTag(commentValue) {
1182
1203
  function extractTypeFromComment(commentValue, tag) {
1183
1204
  return commentValue.match(new RegExp(`^\\s*\\*?\\s*${tag}\\s+([\\w<>,\\s[\\]]+)`, "m"))?.[1]?.trim() || "";
1184
1205
  }
1185
- function parseResponseTag(commentValue) {
1186
- const rawValue = commentValue.match(/@response\s+([^\n\r@]+)/)?.[1]?.trim();
1187
- if (!rawValue) {
1188
- return null;
1189
- }
1206
+ function parseResponseRawValue(rawValue) {
1190
1207
  if (isStatusCodeToken(rawValue)) {
1191
1208
  return {
1192
1209
  responseDescription: "",
@@ -1635,6 +1652,18 @@ function getOperationId(routePath, method) {
1635
1652
  const operation = routePath.replaceAll(/\//g, "-").replace(/^-/, "");
1636
1653
  return `${method}-${operation}`;
1637
1654
  }
1655
+ function deepMerge(target, source) {
1656
+ for (const key of Object.keys(source)) {
1657
+ const sourceVal = source[key];
1658
+ const targetVal = target[key];
1659
+ if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
1660
+ deepMerge(targetVal, sourceVal);
1661
+ } else {
1662
+ target[key] = sourceVal;
1663
+ }
1664
+ }
1665
+ return target;
1666
+ }
1638
1667
  var DEFAULT_PARSER_OPTIONS = {
1639
1668
  sourceType: "module",
1640
1669
  plugins: ["typescript", "jsx", "decorators-legacy"]
@@ -3455,23 +3484,58 @@ var SymbolResolver = class {
3455
3484
  }
3456
3485
  /**
3457
3486
  * Returns a simple literal value (string/number/boolean/null) for a `const` declarator,
3458
- * or `null` if no such declarator exists.
3487
+ * following imports and re-exports when the name is not declared locally.
3459
3488
  */
3460
3489
  resolveLiteral(filePath, name) {
3490
+ const visited = /* @__PURE__ */ new Set();
3491
+ return this.resolveLiteralInternal(filePath, name, visited);
3492
+ }
3493
+ resolveLiteralInternal(filePath, name, visited) {
3494
+ if (visited.has(filePath))
3495
+ return void 0;
3496
+ visited.add(filePath);
3461
3497
  const index = this.getIndex(filePath);
3462
3498
  if (!index)
3463
3499
  return void 0;
3464
3500
  const literal2 = index.constLiterals.get(name);
3465
- if (!literal2)
3466
- return void 0;
3467
- if (t4.isStringLiteral(literal2))
3468
- return literal2.value;
3469
- if (t4.isNumericLiteral(literal2))
3470
- return literal2.value;
3471
- if (t4.isBooleanLiteral(literal2))
3472
- return literal2.value;
3473
- if (t4.isNullLiteral(literal2))
3474
- return null;
3501
+ if (literal2) {
3502
+ if (t4.isStringLiteral(literal2))
3503
+ return literal2.value;
3504
+ if (t4.isNumericLiteral(literal2))
3505
+ return literal2.value;
3506
+ if (t4.isBooleanLiteral(literal2))
3507
+ return literal2.value;
3508
+ if (t4.isNullLiteral(literal2))
3509
+ return null;
3510
+ }
3511
+ const imports = this.getImports(filePath);
3512
+ const importInfo = imports?.get(name);
3513
+ if (importInfo) {
3514
+ const resolved = this.resolveImportPath(filePath, importInfo.source);
3515
+ if (resolved) {
3516
+ const targetName = importInfo.importedName === "default" ? name : importInfo.importedName;
3517
+ const result = this.resolveLiteralInternal(resolved, targetName, visited);
3518
+ if (result !== void 0)
3519
+ return result;
3520
+ }
3521
+ }
3522
+ const reExport = index.namedReExports.get(name);
3523
+ if (reExport) {
3524
+ const resolved = this.resolveImportPath(filePath, reExport.source);
3525
+ if (resolved) {
3526
+ const result = this.resolveLiteralInternal(resolved, reExport.importedName, visited);
3527
+ if (result !== void 0)
3528
+ return result;
3529
+ }
3530
+ }
3531
+ for (const starSrc of index.exportsStar) {
3532
+ const resolved = this.resolveImportPath(filePath, starSrc);
3533
+ if (!resolved)
3534
+ continue;
3535
+ const result = this.resolveLiteralInternal(resolved, name, visited);
3536
+ if (result !== void 0)
3537
+ return result;
3538
+ }
3475
3539
  return void 0;
3476
3540
  }
3477
3541
  /**
@@ -13794,6 +13858,58 @@ var ZodSchemaConverter = class {
13794
13858
  this.symbolResolver.primeAST(this.currentFilePath, this.currentAST);
13795
13859
  return this.symbolResolver.resolveLiteral(this.currentFilePath, name);
13796
13860
  }
13861
+ /**
13862
+ * Unwrap a possible `TSAsExpression` / `TSSatisfiesExpression` to get the
13863
+ * underlying expression node. Returns the node itself when no wrapper is
13864
+ * present.
13865
+ */
13866
+ unwrapTypeAssertion(node) {
13867
+ if (!node)
13868
+ return void 0;
13869
+ if (t11.isTSAsExpression(node) || t11.isTSSatisfiesExpression(node)) {
13870
+ return node.expression;
13871
+ }
13872
+ return node;
13873
+ }
13874
+ /**
13875
+ * Resolve a numeric value from a call-expression argument.
13876
+ * Handles: numeric literals, identifier references to const numbers,
13877
+ * and `x as number` / `x satisfies number` wrappers around either.
13878
+ */
13879
+ resolveNumericArg(arg) {
13880
+ if (!arg)
13881
+ return void 0;
13882
+ const node = this.unwrapTypeAssertion(arg);
13883
+ if (t11.isNumericLiteral(node))
13884
+ return node.value;
13885
+ if (t11.isUnaryExpression(node) && node.operator === "-" && t11.isNumericLiteral(node.argument)) {
13886
+ return -node.argument.value;
13887
+ }
13888
+ if (t11.isIdentifier(node)) {
13889
+ const val = this.resolveLiteralValue(node.name);
13890
+ if (typeof val === "number")
13891
+ return val;
13892
+ }
13893
+ return void 0;
13894
+ }
13895
+ /**
13896
+ * Resolve a string value from a call-expression argument.
13897
+ * Handles: string literals, identifier references to const strings,
13898
+ * and `x as string` / `x satisfies string` wrappers around either.
13899
+ */
13900
+ resolveStringArg(arg) {
13901
+ if (!arg)
13902
+ return void 0;
13903
+ const node = this.unwrapTypeAssertion(arg);
13904
+ if (t11.isStringLiteral(node))
13905
+ return node.value;
13906
+ if (t11.isIdentifier(node)) {
13907
+ const val = this.resolveLiteralValue(node.name);
13908
+ if (typeof val === "string")
13909
+ return val;
13910
+ }
13911
+ return void 0;
13912
+ }
13797
13913
  /**
13798
13914
  * Resolve an identifier referring to a `z.object({...})` (or similar) call expression.
13799
13915
  * This lets callers inline the referenced object's shape.
@@ -13862,6 +13978,14 @@ var ZodSchemaConverter = class {
13862
13978
  if (t11.isNullLiteral(node)) {
13863
13979
  return null;
13864
13980
  }
13981
+ if (t11.isIdentifier(node)) {
13982
+ const val = this.resolveLiteralValue(node.name);
13983
+ if (val !== void 0)
13984
+ return val;
13985
+ }
13986
+ if (t11.isTSAsExpression(node) || t11.isTSSatisfiesExpression(node)) {
13987
+ return this.extractStaticJsonValue(node.expression);
13988
+ }
13865
13989
  if (t11.isArrayExpression(node)) {
13866
13990
  const values = [];
13867
13991
  for (const element of node.elements) {
@@ -13960,53 +14084,60 @@ var ZodSchemaConverter = class {
13960
14084
  schema.nullable = true;
13961
14085
  }
13962
14086
  break;
13963
- case "describe":
13964
- if (node.arguments.length > 0 && t11.isStringLiteral(node.arguments[0])) {
13965
- const description = node.arguments[0].value;
13966
- if (description.startsWith("@deprecated")) {
14087
+ case "describe": {
14088
+ const descVal = this.resolveStringArg(node.arguments[0]);
14089
+ if (descVal !== void 0) {
14090
+ if (descVal.startsWith("@deprecated")) {
13967
14091
  schema.deprecated = true;
13968
- schema.description = description.replace("@deprecated", "").trim();
14092
+ schema.description = descVal.replace("@deprecated", "").trim();
13969
14093
  } else {
13970
- schema.description = description;
14094
+ schema.description = descVal;
13971
14095
  }
13972
14096
  }
13973
14097
  break;
14098
+ }
13974
14099
  case "deprecated":
13975
14100
  schema.deprecated = true;
13976
14101
  break;
13977
- case "min":
13978
- if (node.arguments.length > 0 && t11.isNumericLiteral(node.arguments[0])) {
14102
+ case "min": {
14103
+ const minVal = this.resolveNumericArg(node.arguments[0]);
14104
+ if (minVal !== void 0) {
13979
14105
  if (schema.type === "string") {
13980
- schema.minLength = node.arguments[0].value;
14106
+ schema.minLength = minVal;
13981
14107
  } else if (schema.type === "number" || schema.type === "integer") {
13982
- schema.minimum = node.arguments[0].value;
14108
+ schema.minimum = minVal;
13983
14109
  } else if (schema.type === "array") {
13984
- schema.minItems = node.arguments[0].value;
14110
+ schema.minItems = minVal;
13985
14111
  }
13986
14112
  }
13987
14113
  break;
13988
- case "max":
13989
- if (node.arguments.length > 0 && t11.isNumericLiteral(node.arguments[0])) {
14114
+ }
14115
+ case "max": {
14116
+ const maxVal = this.resolveNumericArg(node.arguments[0]);
14117
+ if (maxVal !== void 0) {
13990
14118
  if (schema.type === "string") {
13991
- schema.maxLength = node.arguments[0].value;
14119
+ schema.maxLength = maxVal;
13992
14120
  } else if (schema.type === "number" || schema.type === "integer") {
13993
- schema.maximum = node.arguments[0].value;
14121
+ schema.maximum = maxVal;
13994
14122
  } else if (schema.type === "array") {
13995
- schema.maxItems = node.arguments[0].value;
14123
+ schema.maxItems = maxVal;
13996
14124
  }
13997
14125
  }
13998
14126
  break;
13999
- case "length":
14000
- if (node.arguments.length > 0 && t11.isNumericLiteral(node.arguments[0])) {
14127
+ }
14128
+ case "length": {
14129
+ const lenVal = this.resolveNumericArg(node.arguments[0]);
14130
+ if (lenVal !== void 0) {
14001
14131
  if (schema.type === "string") {
14002
- schema.minLength = node.arguments[0].value;
14003
- schema.maxLength = node.arguments[0].value;
14132
+ schema.minLength = lenVal;
14133
+ schema.maxLength = lenVal;
14004
14134
  } else if (schema.type === "array") {
14005
- schema.minItems = node.arguments[0].value;
14006
- schema.maxItems = node.arguments[0].value;
14135
+ schema.minItems = lenVal;
14136
+ schema.maxItems = lenVal;
14007
14137
  }
14008
14138
  }
14009
14139
  break;
14140
+ }
14010
14141
  case "nonempty":
14011
14142
  if (schema.type === "array") {
14012
14143
  schema.minItems = Math.max(schema.minItems ?? 0, 1);
@@ -14082,21 +14213,27 @@ var ZodSchemaConverter = class {
14082
14213
  schema.pattern = node.arguments[0].pattern;
14083
14214
  }
14084
14215
  break;
14085
- case "startsWith":
14086
- if (node.arguments.length > 0 && t11.isStringLiteral(node.arguments[0])) {
14087
- schema.pattern = `^${this.escapeRegExp(node.arguments[0].value)}`;
14216
+ case "startsWith": {
14217
+ const swVal = this.resolveStringArg(node.arguments[0]);
14218
+ if (swVal !== void 0) {
14219
+ schema.pattern = `^${this.escapeRegExp(swVal)}`;
14088
14220
  }
14089
14221
  break;
14090
- case "endsWith":
14091
- if (node.arguments.length > 0 && t11.isStringLiteral(node.arguments[0])) {
14092
- schema.pattern = `${this.escapeRegExp(node.arguments[0].value)}$`;
14222
+ }
14223
+ case "endsWith": {
14224
+ const ewVal = this.resolveStringArg(node.arguments[0]);
14225
+ if (ewVal !== void 0) {
14226
+ schema.pattern = `${this.escapeRegExp(ewVal)}$`;
14093
14227
  }
14094
14228
  break;
14095
- case "includes":
14096
- if (node.arguments.length > 0 && t11.isStringLiteral(node.arguments[0])) {
14097
- schema.pattern = this.escapeRegExp(node.arguments[0].value);
14229
+ }
14230
+ case "includes": {
14231
+ const incVal = this.resolveStringArg(node.arguments[0]);
14232
+ if (incVal !== void 0) {
14233
+ schema.pattern = this.escapeRegExp(incVal);
14098
14234
  }
14099
14235
  break;
14236
+ }
14100
14237
  case "int":
14101
14238
  schema.type = "integer";
14102
14239
  break;
@@ -14120,17 +14257,22 @@ var ZodSchemaConverter = class {
14120
14257
  break;
14121
14258
  case "default":
14122
14259
  if (node.arguments.length > 0) {
14123
- if (t11.isStringLiteral(node.arguments[0])) {
14124
- schema.default = node.arguments[0].value;
14125
- } else if (t11.isNumericLiteral(node.arguments[0])) {
14126
- schema.default = node.arguments[0].value;
14127
- } else if (t11.isBooleanLiteral(node.arguments[0])) {
14128
- schema.default = node.arguments[0].value;
14129
- } else if (t11.isNullLiteral(node.arguments[0])) {
14260
+ const defaultArg = this.unwrapTypeAssertion(node.arguments[0]);
14261
+ if (t11.isStringLiteral(defaultArg)) {
14262
+ schema.default = defaultArg.value;
14263
+ } else if (t11.isNumericLiteral(defaultArg)) {
14264
+ schema.default = defaultArg.value;
14265
+ } else if (t11.isBooleanLiteral(defaultArg)) {
14266
+ schema.default = defaultArg.value;
14267
+ } else if (t11.isNullLiteral(defaultArg)) {
14130
14268
  schema.default = null;
14131
- } else if (t11.isObjectExpression(node.arguments[0])) {
14269
+ } else if (t11.isIdentifier(defaultArg)) {
14270
+ const val = this.resolveLiteralValue(defaultArg.name);
14271
+ if (val !== void 0)
14272
+ schema.default = val;
14273
+ } else if (t11.isObjectExpression(defaultArg)) {
14132
14274
  const defaultObj = {};
14133
- node.arguments[0].properties.forEach((prop) => {
14275
+ defaultArg.properties.forEach((prop) => {
14134
14276
  if (t11.isObjectProperty(prop) && (t11.isIdentifier(prop.key) || t11.isStringLiteral(prop.key)) && (t11.isStringLiteral(prop.value) || t11.isNumericLiteral(prop.value) || t11.isBooleanLiteral(prop.value))) {
14135
14277
  const key = t11.isIdentifier(prop.key) ? prop.key.name : prop.key.value;
14136
14278
  const value = t11.isStringLiteral(prop.value) ? prop.value.value : t11.isNumericLiteral(prop.value) ? prop.value.value : t11.isBooleanLiteral(prop.value) ? prop.value.value : null;
@@ -17520,7 +17662,7 @@ var OperationProcessor = class {
17520
17662
  this.applyResponseHeaders(definition, responseHeaders);
17521
17663
  this.applyResponseLinks(definition, responseLinks);
17522
17664
  if (openapiOverride) {
17523
- Object.assign(definition, structuredClone(openapiOverride));
17665
+ deepMerge(definition, structuredClone(openapiOverride));
17524
17666
  }
17525
17667
  return {
17526
17668
  routePath,