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.
package/dist/cli.js CHANGED
@@ -904,7 +904,6 @@ function parseJSDocBlock(commentValue, filePath) {
904
904
  result.summary = explicitSummary;
905
905
  }
906
906
  result.description = extractLineValue(normalizedComment, "@description");
907
- result.tag = extractLineValue(normalizedComment, "@tag");
908
907
  result.tagSummary = extractLineValue(normalizedComment, "@tagSummary");
909
908
  result.tagKind = extractLineValue(normalizedComment, "@tagKind");
910
909
  result.tagParent = extractLineValue(normalizedComment, "@tagParent");
@@ -938,17 +937,28 @@ function parseJSDocBlock(commentValue, filePath) {
938
937
  if (Array.isArray(responsePrefixEncoding)) {
939
938
  result.responsePrefixEncoding = responsePrefixEncoding;
940
939
  }
941
- const parsedResponse = parseResponseTag(normalizedComment);
942
- if (parsedResponse) {
943
- result.successCode = parsedResponse.successCode;
944
- result.responseType = parsedResponse.responseType;
945
- if (!result.responseDescription && parsedResponse.responseDescription) {
946
- result.responseDescription = parsedResponse.responseDescription;
940
+ const responseMatches = [...normalizedComment.matchAll(/@response\s+([^\n\r@]+)/g)];
941
+ if (responseMatches.length > 0) {
942
+ const firstRaw = responseMatches[0]?.[1]?.trim();
943
+ if (firstRaw) {
944
+ const parsedResponse = parseResponseRawValue(firstRaw);
945
+ result.successCode = parsedResponse.successCode;
946
+ result.responseType = parsedResponse.responseType;
947
+ if (!result.responseDescription && parsedResponse.responseDescription) {
948
+ result.responseDescription = parsedResponse.responseDescription;
949
+ }
950
+ }
951
+ const extraResponses = responseMatches.slice(1).map((m) => m[1]?.trim()).filter((t17) => Boolean(t17));
952
+ if (extraResponses.length > 0) {
953
+ result.addResponses = extraResponses.join(",");
947
954
  }
948
955
  }
949
956
  const addMatches = [...normalizedComment.matchAll(/@add\s+([^\n\r@]*)/g)];
950
957
  if (addMatches.length > 0) {
951
- result.addResponses = addMatches.map((match) => match[1]?.trim() || "").filter(Boolean).join(",");
958
+ const addEntries = addMatches.map((match) => match[1]?.trim() || "").filter(Boolean).join(",");
959
+ if (addEntries) {
960
+ result.addResponses = result.addResponses ? `${result.addResponses},${addEntries}` : addEntries;
961
+ }
952
962
  }
953
963
  const examples = collectExampleDefinitions(normalizedComment, "@examples", filePath);
954
964
  result.requestExamples = buildExampleMap(examples.definitions, "request");
@@ -961,6 +971,17 @@ function parseJSDocBlock(commentValue, filePath) {
961
971
  if (additionalTags.length > 0) {
962
972
  result.tags = additionalTags;
963
973
  }
974
+ const tagMatches = [...normalizedComment.matchAll(/@tag\s+([^\n\r@]*)/g)];
975
+ if (tagMatches.length > 0) {
976
+ const primaryTag = tagMatches[0]?.[1]?.trim();
977
+ if (primaryTag) {
978
+ result.tag = primaryTag;
979
+ }
980
+ const extraTags = tagMatches.slice(1).map((m) => m[1]?.trim()).filter((t17) => Boolean(t17));
981
+ if (extraTags.length > 0) {
982
+ result.tags = [...result.tags ?? [], ...extraTags];
983
+ }
984
+ }
964
985
  const servers = parseServersTag(normalizedComment);
965
986
  if (servers.length > 0) {
966
987
  result.servers = servers;
@@ -1163,11 +1184,7 @@ function parseOpenApiOverrideTag(commentValue) {
1163
1184
  function extractTypeFromComment(commentValue, tag) {
1164
1185
  return commentValue.match(new RegExp(`^\\s*\\*?\\s*${tag}\\s+([\\w<>,\\s[\\]]+)`, "m"))?.[1]?.trim() || "";
1165
1186
  }
1166
- function parseResponseTag(commentValue) {
1167
- const rawValue = commentValue.match(/@response\s+([^\n\r@]+)/)?.[1]?.trim();
1168
- if (!rawValue) {
1169
- return null;
1170
- }
1187
+ function parseResponseRawValue(rawValue) {
1171
1188
  if (isStatusCodeToken(rawValue)) {
1172
1189
  return {
1173
1190
  responseDescription: "",
@@ -1616,6 +1633,18 @@ function getOperationId(routePath, method) {
1616
1633
  const operation = routePath.replaceAll(/\//g, "-").replace(/^-/, "");
1617
1634
  return `${method}-${operation}`;
1618
1635
  }
1636
+ function deepMerge(target, source) {
1637
+ for (const key of Object.keys(source)) {
1638
+ const sourceVal = source[key];
1639
+ const targetVal = target[key];
1640
+ if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
1641
+ deepMerge(targetVal, sourceVal);
1642
+ } else {
1643
+ target[key] = sourceVal;
1644
+ }
1645
+ }
1646
+ return target;
1647
+ }
1619
1648
  var DEFAULT_PARSER_OPTIONS = {
1620
1649
  sourceType: "module",
1621
1650
  plugins: ["typescript", "jsx", "decorators-legacy"]
@@ -2868,23 +2897,58 @@ var SymbolResolver = class {
2868
2897
  }
2869
2898
  /**
2870
2899
  * Returns a simple literal value (string/number/boolean/null) for a `const` declarator,
2871
- * or `null` if no such declarator exists.
2900
+ * following imports and re-exports when the name is not declared locally.
2872
2901
  */
2873
2902
  resolveLiteral(filePath, name) {
2903
+ const visited = /* @__PURE__ */ new Set();
2904
+ return this.resolveLiteralInternal(filePath, name, visited);
2905
+ }
2906
+ resolveLiteralInternal(filePath, name, visited) {
2907
+ if (visited.has(filePath))
2908
+ return void 0;
2909
+ visited.add(filePath);
2874
2910
  const index = this.getIndex(filePath);
2875
2911
  if (!index)
2876
2912
  return void 0;
2877
2913
  const literal2 = index.constLiterals.get(name);
2878
- if (!literal2)
2879
- return void 0;
2880
- if (t3.isStringLiteral(literal2))
2881
- return literal2.value;
2882
- if (t3.isNumericLiteral(literal2))
2883
- return literal2.value;
2884
- if (t3.isBooleanLiteral(literal2))
2885
- return literal2.value;
2886
- if (t3.isNullLiteral(literal2))
2887
- return null;
2914
+ if (literal2) {
2915
+ if (t3.isStringLiteral(literal2))
2916
+ return literal2.value;
2917
+ if (t3.isNumericLiteral(literal2))
2918
+ return literal2.value;
2919
+ if (t3.isBooleanLiteral(literal2))
2920
+ return literal2.value;
2921
+ if (t3.isNullLiteral(literal2))
2922
+ return null;
2923
+ }
2924
+ const imports = this.getImports(filePath);
2925
+ const importInfo = imports?.get(name);
2926
+ if (importInfo) {
2927
+ const resolved = this.resolveImportPath(filePath, importInfo.source);
2928
+ if (resolved) {
2929
+ const targetName = importInfo.importedName === "default" ? name : importInfo.importedName;
2930
+ const result = this.resolveLiteralInternal(resolved, targetName, visited);
2931
+ if (result !== void 0)
2932
+ return result;
2933
+ }
2934
+ }
2935
+ const reExport = index.namedReExports.get(name);
2936
+ if (reExport) {
2937
+ const resolved = this.resolveImportPath(filePath, reExport.source);
2938
+ if (resolved) {
2939
+ const result = this.resolveLiteralInternal(resolved, reExport.importedName, visited);
2940
+ if (result !== void 0)
2941
+ return result;
2942
+ }
2943
+ }
2944
+ for (const starSrc of index.exportsStar) {
2945
+ const resolved = this.resolveImportPath(filePath, starSrc);
2946
+ if (!resolved)
2947
+ continue;
2948
+ const result = this.resolveLiteralInternal(resolved, name, visited);
2949
+ if (result !== void 0)
2950
+ return result;
2951
+ }
2888
2952
  return void 0;
2889
2953
  }
2890
2954
  /**
@@ -13207,6 +13271,58 @@ var ZodSchemaConverter = class {
13207
13271
  this.symbolResolver.primeAST(this.currentFilePath, this.currentAST);
13208
13272
  return this.symbolResolver.resolveLiteral(this.currentFilePath, name);
13209
13273
  }
13274
+ /**
13275
+ * Unwrap a possible `TSAsExpression` / `TSSatisfiesExpression` to get the
13276
+ * underlying expression node. Returns the node itself when no wrapper is
13277
+ * present.
13278
+ */
13279
+ unwrapTypeAssertion(node) {
13280
+ if (!node)
13281
+ return void 0;
13282
+ if (t10.isTSAsExpression(node) || t10.isTSSatisfiesExpression(node)) {
13283
+ return node.expression;
13284
+ }
13285
+ return node;
13286
+ }
13287
+ /**
13288
+ * Resolve a numeric value from a call-expression argument.
13289
+ * Handles: numeric literals, identifier references to const numbers,
13290
+ * and `x as number` / `x satisfies number` wrappers around either.
13291
+ */
13292
+ resolveNumericArg(arg) {
13293
+ if (!arg)
13294
+ return void 0;
13295
+ const node = this.unwrapTypeAssertion(arg);
13296
+ if (t10.isNumericLiteral(node))
13297
+ return node.value;
13298
+ if (t10.isUnaryExpression(node) && node.operator === "-" && t10.isNumericLiteral(node.argument)) {
13299
+ return -node.argument.value;
13300
+ }
13301
+ if (t10.isIdentifier(node)) {
13302
+ const val = this.resolveLiteralValue(node.name);
13303
+ if (typeof val === "number")
13304
+ return val;
13305
+ }
13306
+ return void 0;
13307
+ }
13308
+ /**
13309
+ * Resolve a string value from a call-expression argument.
13310
+ * Handles: string literals, identifier references to const strings,
13311
+ * and `x as string` / `x satisfies string` wrappers around either.
13312
+ */
13313
+ resolveStringArg(arg) {
13314
+ if (!arg)
13315
+ return void 0;
13316
+ const node = this.unwrapTypeAssertion(arg);
13317
+ if (t10.isStringLiteral(node))
13318
+ return node.value;
13319
+ if (t10.isIdentifier(node)) {
13320
+ const val = this.resolveLiteralValue(node.name);
13321
+ if (typeof val === "string")
13322
+ return val;
13323
+ }
13324
+ return void 0;
13325
+ }
13210
13326
  /**
13211
13327
  * Resolve an identifier referring to a `z.object({...})` (or similar) call expression.
13212
13328
  * This lets callers inline the referenced object's shape.
@@ -13275,6 +13391,14 @@ var ZodSchemaConverter = class {
13275
13391
  if (t10.isNullLiteral(node)) {
13276
13392
  return null;
13277
13393
  }
13394
+ if (t10.isIdentifier(node)) {
13395
+ const val = this.resolveLiteralValue(node.name);
13396
+ if (val !== void 0)
13397
+ return val;
13398
+ }
13399
+ if (t10.isTSAsExpression(node) || t10.isTSSatisfiesExpression(node)) {
13400
+ return this.extractStaticJsonValue(node.expression);
13401
+ }
13278
13402
  if (t10.isArrayExpression(node)) {
13279
13403
  const values = [];
13280
13404
  for (const element of node.elements) {
@@ -13373,53 +13497,60 @@ var ZodSchemaConverter = class {
13373
13497
  schema.nullable = true;
13374
13498
  }
13375
13499
  break;
13376
- case "describe":
13377
- if (node.arguments.length > 0 && t10.isStringLiteral(node.arguments[0])) {
13378
- const description = node.arguments[0].value;
13379
- if (description.startsWith("@deprecated")) {
13500
+ case "describe": {
13501
+ const descVal = this.resolveStringArg(node.arguments[0]);
13502
+ if (descVal !== void 0) {
13503
+ if (descVal.startsWith("@deprecated")) {
13380
13504
  schema.deprecated = true;
13381
- schema.description = description.replace("@deprecated", "").trim();
13505
+ schema.description = descVal.replace("@deprecated", "").trim();
13382
13506
  } else {
13383
- schema.description = description;
13507
+ schema.description = descVal;
13384
13508
  }
13385
13509
  }
13386
13510
  break;
13511
+ }
13387
13512
  case "deprecated":
13388
13513
  schema.deprecated = true;
13389
13514
  break;
13390
- case "min":
13391
- if (node.arguments.length > 0 && t10.isNumericLiteral(node.arguments[0])) {
13515
+ case "min": {
13516
+ const minVal = this.resolveNumericArg(node.arguments[0]);
13517
+ if (minVal !== void 0) {
13392
13518
  if (schema.type === "string") {
13393
- schema.minLength = node.arguments[0].value;
13519
+ schema.minLength = minVal;
13394
13520
  } else if (schema.type === "number" || schema.type === "integer") {
13395
- schema.minimum = node.arguments[0].value;
13521
+ schema.minimum = minVal;
13396
13522
  } else if (schema.type === "array") {
13397
- schema.minItems = node.arguments[0].value;
13523
+ schema.minItems = minVal;
13398
13524
  }
13399
13525
  }
13400
13526
  break;
13401
- case "max":
13402
- if (node.arguments.length > 0 && t10.isNumericLiteral(node.arguments[0])) {
13527
+ }
13528
+ case "max": {
13529
+ const maxVal = this.resolveNumericArg(node.arguments[0]);
13530
+ if (maxVal !== void 0) {
13403
13531
  if (schema.type === "string") {
13404
- schema.maxLength = node.arguments[0].value;
13532
+ schema.maxLength = maxVal;
13405
13533
  } else if (schema.type === "number" || schema.type === "integer") {
13406
- schema.maximum = node.arguments[0].value;
13534
+ schema.maximum = maxVal;
13407
13535
  } else if (schema.type === "array") {
13408
- schema.maxItems = node.arguments[0].value;
13536
+ schema.maxItems = maxVal;
13409
13537
  }
13410
13538
  }
13411
13539
  break;
13412
- case "length":
13413
- if (node.arguments.length > 0 && t10.isNumericLiteral(node.arguments[0])) {
13540
+ }
13541
+ case "length": {
13542
+ const lenVal = this.resolveNumericArg(node.arguments[0]);
13543
+ if (lenVal !== void 0) {
13414
13544
  if (schema.type === "string") {
13415
- schema.minLength = node.arguments[0].value;
13416
- schema.maxLength = node.arguments[0].value;
13545
+ schema.minLength = lenVal;
13546
+ schema.maxLength = lenVal;
13417
13547
  } else if (schema.type === "array") {
13418
- schema.minItems = node.arguments[0].value;
13419
- schema.maxItems = node.arguments[0].value;
13548
+ schema.minItems = lenVal;
13549
+ schema.maxItems = lenVal;
13420
13550
  }
13421
13551
  }
13422
13552
  break;
13553
+ }
13423
13554
  case "nonempty":
13424
13555
  if (schema.type === "array") {
13425
13556
  schema.minItems = Math.max(schema.minItems ?? 0, 1);
@@ -13495,21 +13626,27 @@ var ZodSchemaConverter = class {
13495
13626
  schema.pattern = node.arguments[0].pattern;
13496
13627
  }
13497
13628
  break;
13498
- case "startsWith":
13499
- if (node.arguments.length > 0 && t10.isStringLiteral(node.arguments[0])) {
13500
- schema.pattern = `^${this.escapeRegExp(node.arguments[0].value)}`;
13629
+ case "startsWith": {
13630
+ const swVal = this.resolveStringArg(node.arguments[0]);
13631
+ if (swVal !== void 0) {
13632
+ schema.pattern = `^${this.escapeRegExp(swVal)}`;
13501
13633
  }
13502
13634
  break;
13503
- case "endsWith":
13504
- if (node.arguments.length > 0 && t10.isStringLiteral(node.arguments[0])) {
13505
- schema.pattern = `${this.escapeRegExp(node.arguments[0].value)}$`;
13635
+ }
13636
+ case "endsWith": {
13637
+ const ewVal = this.resolveStringArg(node.arguments[0]);
13638
+ if (ewVal !== void 0) {
13639
+ schema.pattern = `${this.escapeRegExp(ewVal)}$`;
13506
13640
  }
13507
13641
  break;
13508
- case "includes":
13509
- if (node.arguments.length > 0 && t10.isStringLiteral(node.arguments[0])) {
13510
- schema.pattern = this.escapeRegExp(node.arguments[0].value);
13642
+ }
13643
+ case "includes": {
13644
+ const incVal = this.resolveStringArg(node.arguments[0]);
13645
+ if (incVal !== void 0) {
13646
+ schema.pattern = this.escapeRegExp(incVal);
13511
13647
  }
13512
13648
  break;
13649
+ }
13513
13650
  case "int":
13514
13651
  schema.type = "integer";
13515
13652
  break;
@@ -13533,17 +13670,22 @@ var ZodSchemaConverter = class {
13533
13670
  break;
13534
13671
  case "default":
13535
13672
  if (node.arguments.length > 0) {
13536
- if (t10.isStringLiteral(node.arguments[0])) {
13537
- schema.default = node.arguments[0].value;
13538
- } else if (t10.isNumericLiteral(node.arguments[0])) {
13539
- schema.default = node.arguments[0].value;
13540
- } else if (t10.isBooleanLiteral(node.arguments[0])) {
13541
- schema.default = node.arguments[0].value;
13542
- } else if (t10.isNullLiteral(node.arguments[0])) {
13673
+ const defaultArg = this.unwrapTypeAssertion(node.arguments[0]);
13674
+ if (t10.isStringLiteral(defaultArg)) {
13675
+ schema.default = defaultArg.value;
13676
+ } else if (t10.isNumericLiteral(defaultArg)) {
13677
+ schema.default = defaultArg.value;
13678
+ } else if (t10.isBooleanLiteral(defaultArg)) {
13679
+ schema.default = defaultArg.value;
13680
+ } else if (t10.isNullLiteral(defaultArg)) {
13543
13681
  schema.default = null;
13544
- } else if (t10.isObjectExpression(node.arguments[0])) {
13682
+ } else if (t10.isIdentifier(defaultArg)) {
13683
+ const val = this.resolveLiteralValue(defaultArg.name);
13684
+ if (val !== void 0)
13685
+ schema.default = val;
13686
+ } else if (t10.isObjectExpression(defaultArg)) {
13545
13687
  const defaultObj = {};
13546
- node.arguments[0].properties.forEach((prop) => {
13688
+ defaultArg.properties.forEach((prop) => {
13547
13689
  if (t10.isObjectProperty(prop) && (t10.isIdentifier(prop.key) || t10.isStringLiteral(prop.key)) && (t10.isStringLiteral(prop.value) || t10.isNumericLiteral(prop.value) || t10.isBooleanLiteral(prop.value))) {
13548
13690
  const key = t10.isIdentifier(prop.key) ? prop.key.name : prop.key.value;
13549
13691
  const value = t10.isStringLiteral(prop.value) ? prop.value.value : t10.isNumericLiteral(prop.value) ? prop.value.value : t10.isBooleanLiteral(prop.value) ? prop.value.value : null;
@@ -16933,7 +17075,7 @@ var OperationProcessor = class {
16933
17075
  this.applyResponseHeaders(definition, responseHeaders);
16934
17076
  this.applyResponseLinks(definition, responseLinks);
16935
17077
  if (openapiOverride) {
16936
- Object.assign(definition, structuredClone(openapiOverride));
17078
+ deepMerge(definition, structuredClone(openapiOverride));
16937
17079
  }
16938
17080
  return {
16939
17081
  routePath,