next-openapi-gen 1.2.0 → 1.2.1

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
@@ -12106,7 +12106,9 @@ var ZodSchemaConverter = class {
12106
12106
  apiDir;
12107
12107
  zodSchemas = {};
12108
12108
  processingSchemas = /* @__PURE__ */ new Set();
12109
- processedModules = /* @__PURE__ */ new Set();
12109
+ /** Memoization guard for processFileForZodSchema. Keys: `${filePath}|${schemaName}`.
12110
+ * Prevents infinite recursion when re-export files reference schemas via z.infer<typeof X>. */
12111
+ processedFileSchemaPairs = /* @__PURE__ */ new Set();
12110
12112
  typeToSchemaMapping = {};
12111
12113
  drizzleZodImports = /* @__PURE__ */ new Set();
12112
12114
  factoryCache = /* @__PURE__ */ new Map();
@@ -12320,6 +12322,11 @@ var ZodSchemaConverter = class {
12320
12322
  * Process a file to find Zod schema definitions
12321
12323
  */
12322
12324
  processFileForZodSchema(filePath, schemaName) {
12325
+ const visitKey = `${filePath}|${schemaName}|${this.currentContentType}`;
12326
+ if (this.processedFileSchemaPairs.has(visitKey)) {
12327
+ return;
12328
+ }
12329
+ this.processedFileSchemaPairs.add(visitKey);
12323
12330
  try {
12324
12331
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
12325
12332
  if (!content.includes(schemaName)) {
@@ -12633,7 +12640,9 @@ var ZodSchemaConverter = class {
12633
12640
  const param = path25.node.typeAnnotation.typeParameters.params[0];
12634
12641
  if (t10.isTSTypeQuery(param) && t10.isIdentifier(param.exprName)) {
12635
12642
  const referencedSchemaName = param.exprName.name;
12636
- this.processFileForZodSchema(filePath, referencedSchemaName);
12643
+ if (!this.getStoredSchema(referencedSchemaName)) {
12644
+ this.processFileForZodSchema(filePath, referencedSchemaName);
12645
+ }
12637
12646
  }
12638
12647
  }
12639
12648
  }
@@ -14008,15 +14017,39 @@ function extractKeysFromLiteralType(node) {
14008
14017
  }
14009
14018
  return [];
14010
14019
  }
14020
+ function parsePropertyComment(commentValue) {
14021
+ const text = commentValue.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line.length > 0).join(" ").trim();
14022
+ const result = {};
14023
+ let remaining = text;
14024
+ const formatMatch = remaining.match(/@format\s+(\S+)/);
14025
+ if (formatMatch?.[1]) {
14026
+ result.format = formatMatch[1];
14027
+ remaining = remaining.replace(formatMatch[0], "").trim();
14028
+ }
14029
+ const exampleMatch = remaining.match(/@example\s+(.+?)(?=\s*@\w|$)/);
14030
+ if (exampleMatch?.[1]) {
14031
+ const raw = exampleMatch[1].trim();
14032
+ try {
14033
+ result.example = JSON.parse(raw);
14034
+ } catch {
14035
+ result.example = raw;
14036
+ }
14037
+ remaining = remaining.replace(exampleMatch[0], "").trim();
14038
+ }
14039
+ remaining = remaining.replace(/@\w+(?:\s+\S+)*/g, "").trim();
14040
+ if (remaining) {
14041
+ result.description = remaining;
14042
+ }
14043
+ return result;
14044
+ }
14011
14045
  function getPropertyOptions(node, contentType) {
14012
14046
  const isOptional = !!node.optional;
14013
- let description = null;
14014
- if (node.trailingComments && node.trailingComments.length) {
14015
- description = node.trailingComments[0].value.trim();
14016
- }
14017
14047
  const options = {};
14018
- if (description) {
14019
- options.description = description;
14048
+ const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
14049
+ const trailingComment = node.trailingComments?.[0];
14050
+ const sourceComment = leadingComment ?? trailingComment;
14051
+ if (sourceComment) {
14052
+ Object.assign(options, parsePropertyComment(sourceComment.value));
14020
14053
  }
14021
14054
  if (contentType === "body") {
14022
14055
  options.nullable = isOptional;
package/dist/index.js CHANGED
@@ -11655,7 +11655,9 @@ var ZodSchemaConverter = class {
11655
11655
  apiDir;
11656
11656
  zodSchemas = {};
11657
11657
  processingSchemas = /* @__PURE__ */ new Set();
11658
- processedModules = /* @__PURE__ */ new Set();
11658
+ /** Memoization guard for processFileForZodSchema. Keys: `${filePath}|${schemaName}`.
11659
+ * Prevents infinite recursion when re-export files reference schemas via z.infer<typeof X>. */
11660
+ processedFileSchemaPairs = /* @__PURE__ */ new Set();
11659
11661
  typeToSchemaMapping = {};
11660
11662
  drizzleZodImports = /* @__PURE__ */ new Set();
11661
11663
  factoryCache = /* @__PURE__ */ new Map();
@@ -11869,6 +11871,11 @@ var ZodSchemaConverter = class {
11869
11871
  * Process a file to find Zod schema definitions
11870
11872
  */
11871
11873
  processFileForZodSchema(filePath, schemaName) {
11874
+ const visitKey = `${filePath}|${schemaName}|${this.currentContentType}`;
11875
+ if (this.processedFileSchemaPairs.has(visitKey)) {
11876
+ return;
11877
+ }
11878
+ this.processedFileSchemaPairs.add(visitKey);
11872
11879
  try {
11873
11880
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
11874
11881
  if (!content.includes(schemaName)) {
@@ -12182,7 +12189,9 @@ var ZodSchemaConverter = class {
12182
12189
  const param = path25.node.typeAnnotation.typeParameters.params[0];
12183
12190
  if (t10.isTSTypeQuery(param) && t10.isIdentifier(param.exprName)) {
12184
12191
  const referencedSchemaName = param.exprName.name;
12185
- this.processFileForZodSchema(filePath, referencedSchemaName);
12192
+ if (!this.getStoredSchema(referencedSchemaName)) {
12193
+ this.processFileForZodSchema(filePath, referencedSchemaName);
12194
+ }
12186
12195
  }
12187
12196
  }
12188
12197
  }
@@ -13557,15 +13566,39 @@ function extractKeysFromLiteralType(node) {
13557
13566
  }
13558
13567
  return [];
13559
13568
  }
13569
+ function parsePropertyComment(commentValue) {
13570
+ const text = commentValue.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line.length > 0).join(" ").trim();
13571
+ const result = {};
13572
+ let remaining = text;
13573
+ const formatMatch = remaining.match(/@format\s+(\S+)/);
13574
+ if (formatMatch?.[1]) {
13575
+ result.format = formatMatch[1];
13576
+ remaining = remaining.replace(formatMatch[0], "").trim();
13577
+ }
13578
+ const exampleMatch = remaining.match(/@example\s+(.+?)(?=\s*@\w|$)/);
13579
+ if (exampleMatch?.[1]) {
13580
+ const raw = exampleMatch[1].trim();
13581
+ try {
13582
+ result.example = JSON.parse(raw);
13583
+ } catch {
13584
+ result.example = raw;
13585
+ }
13586
+ remaining = remaining.replace(exampleMatch[0], "").trim();
13587
+ }
13588
+ remaining = remaining.replace(/@\w+(?:\s+\S+)*/g, "").trim();
13589
+ if (remaining) {
13590
+ result.description = remaining;
13591
+ }
13592
+ return result;
13593
+ }
13560
13594
  function getPropertyOptions(node, contentType) {
13561
13595
  const isOptional = !!node.optional;
13562
- let description = null;
13563
- if (node.trailingComments && node.trailingComments.length) {
13564
- description = node.trailingComments[0].value.trim();
13565
- }
13566
13596
  const options = {};
13567
- if (description) {
13568
- options.description = description;
13597
+ const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
13598
+ const trailingComment = node.trailingComments?.[0];
13599
+ const sourceComment = leadingComment ?? trailingComment;
13600
+ if (sourceComment) {
13601
+ Object.assign(options, parsePropertyComment(sourceComment.value));
13569
13602
  }
13570
13603
  if (contentType === "body") {
13571
13604
  options.nullable = isOptional;
@@ -12689,7 +12689,9 @@ var ZodSchemaConverter = class {
12689
12689
  apiDir;
12690
12690
  zodSchemas = {};
12691
12691
  processingSchemas = /* @__PURE__ */ new Set();
12692
- processedModules = /* @__PURE__ */ new Set();
12692
+ /** Memoization guard for processFileForZodSchema. Keys: `${filePath}|${schemaName}`.
12693
+ * Prevents infinite recursion when re-export files reference schemas via z.infer<typeof X>. */
12694
+ processedFileSchemaPairs = /* @__PURE__ */ new Set();
12693
12695
  typeToSchemaMapping = {};
12694
12696
  drizzleZodImports = /* @__PURE__ */ new Set();
12695
12697
  factoryCache = /* @__PURE__ */ new Map();
@@ -12903,6 +12905,11 @@ var ZodSchemaConverter = class {
12903
12905
  * Process a file to find Zod schema definitions
12904
12906
  */
12905
12907
  processFileForZodSchema(filePath, schemaName) {
12908
+ const visitKey = `${filePath}|${schemaName}|${this.currentContentType}`;
12909
+ if (this.processedFileSchemaPairs.has(visitKey)) {
12910
+ return;
12911
+ }
12912
+ this.processedFileSchemaPairs.add(visitKey);
12906
12913
  try {
12907
12914
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
12908
12915
  if (!content.includes(schemaName)) {
@@ -13216,7 +13223,9 @@ var ZodSchemaConverter = class {
13216
13223
  const param = path19.node.typeAnnotation.typeParameters.params[0];
13217
13224
  if (t11.isTSTypeQuery(param) && t11.isIdentifier(param.exprName)) {
13218
13225
  const referencedSchemaName = param.exprName.name;
13219
- this.processFileForZodSchema(filePath, referencedSchemaName);
13226
+ if (!this.getStoredSchema(referencedSchemaName)) {
13227
+ this.processFileForZodSchema(filePath, referencedSchemaName);
13228
+ }
13220
13229
  }
13221
13230
  }
13222
13231
  }
@@ -14591,15 +14600,39 @@ function extractKeysFromLiteralType(node) {
14591
14600
  }
14592
14601
  return [];
14593
14602
  }
14603
+ function parsePropertyComment(commentValue) {
14604
+ const text = commentValue.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line.length > 0).join(" ").trim();
14605
+ const result = {};
14606
+ let remaining = text;
14607
+ const formatMatch = remaining.match(/@format\s+(\S+)/);
14608
+ if (formatMatch?.[1]) {
14609
+ result.format = formatMatch[1];
14610
+ remaining = remaining.replace(formatMatch[0], "").trim();
14611
+ }
14612
+ const exampleMatch = remaining.match(/@example\s+(.+?)(?=\s*@\w|$)/);
14613
+ if (exampleMatch?.[1]) {
14614
+ const raw = exampleMatch[1].trim();
14615
+ try {
14616
+ result.example = JSON.parse(raw);
14617
+ } catch {
14618
+ result.example = raw;
14619
+ }
14620
+ remaining = remaining.replace(exampleMatch[0], "").trim();
14621
+ }
14622
+ remaining = remaining.replace(/@\w+(?:\s+\S+)*/g, "").trim();
14623
+ if (remaining) {
14624
+ result.description = remaining;
14625
+ }
14626
+ return result;
14627
+ }
14594
14628
  function getPropertyOptions(node, contentType) {
14595
14629
  const isOptional = !!node.optional;
14596
- let description = null;
14597
- if (node.trailingComments && node.trailingComments.length) {
14598
- description = node.trailingComments[0].value.trim();
14599
- }
14600
14630
  const options = {};
14601
- if (description) {
14602
- options.description = description;
14631
+ const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
14632
+ const trailingComment = node.trailingComments?.[0];
14633
+ const sourceComment = leadingComment ?? trailingComment;
14634
+ if (sourceComment) {
14635
+ Object.assign(options, parsePropertyComment(sourceComment.value));
14603
14636
  }
14604
14637
  if (contentType === "body") {
14605
14638
  options.nullable = isOptional;
@@ -11693,7 +11693,9 @@ var ZodSchemaConverter = class {
11693
11693
  apiDir;
11694
11694
  zodSchemas = {};
11695
11695
  processingSchemas = /* @__PURE__ */ new Set();
11696
- processedModules = /* @__PURE__ */ new Set();
11696
+ /** Memoization guard for processFileForZodSchema. Keys: `${filePath}|${schemaName}`.
11697
+ * Prevents infinite recursion when re-export files reference schemas via z.infer<typeof X>. */
11698
+ processedFileSchemaPairs = /* @__PURE__ */ new Set();
11697
11699
  typeToSchemaMapping = {};
11698
11700
  drizzleZodImports = /* @__PURE__ */ new Set();
11699
11701
  factoryCache = /* @__PURE__ */ new Map();
@@ -11907,6 +11909,11 @@ var ZodSchemaConverter = class {
11907
11909
  * Process a file to find Zod schema definitions
11908
11910
  */
11909
11911
  processFileForZodSchema(filePath, schemaName) {
11912
+ const visitKey = `${filePath}|${schemaName}|${this.currentContentType}`;
11913
+ if (this.processedFileSchemaPairs.has(visitKey)) {
11914
+ return;
11915
+ }
11916
+ this.processedFileSchemaPairs.add(visitKey);
11910
11917
  try {
11911
11918
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
11912
11919
  if (!content.includes(schemaName)) {
@@ -12220,7 +12227,9 @@ var ZodSchemaConverter = class {
12220
12227
  const param = path17.node.typeAnnotation.typeParameters.params[0];
12221
12228
  if (t10.isTSTypeQuery(param) && t10.isIdentifier(param.exprName)) {
12222
12229
  const referencedSchemaName = param.exprName.name;
12223
- this.processFileForZodSchema(filePath, referencedSchemaName);
12230
+ if (!this.getStoredSchema(referencedSchemaName)) {
12231
+ this.processFileForZodSchema(filePath, referencedSchemaName);
12232
+ }
12224
12233
  }
12225
12234
  }
12226
12235
  }
@@ -13595,15 +13604,39 @@ function extractKeysFromLiteralType(node) {
13595
13604
  }
13596
13605
  return [];
13597
13606
  }
13607
+ function parsePropertyComment(commentValue) {
13608
+ const text = commentValue.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line.length > 0).join(" ").trim();
13609
+ const result = {};
13610
+ let remaining = text;
13611
+ const formatMatch = remaining.match(/@format\s+(\S+)/);
13612
+ if (formatMatch?.[1]) {
13613
+ result.format = formatMatch[1];
13614
+ remaining = remaining.replace(formatMatch[0], "").trim();
13615
+ }
13616
+ const exampleMatch = remaining.match(/@example\s+(.+?)(?=\s*@\w|$)/);
13617
+ if (exampleMatch?.[1]) {
13618
+ const raw = exampleMatch[1].trim();
13619
+ try {
13620
+ result.example = JSON.parse(raw);
13621
+ } catch {
13622
+ result.example = raw;
13623
+ }
13624
+ remaining = remaining.replace(exampleMatch[0], "").trim();
13625
+ }
13626
+ remaining = remaining.replace(/@\w+(?:\s+\S+)*/g, "").trim();
13627
+ if (remaining) {
13628
+ result.description = remaining;
13629
+ }
13630
+ return result;
13631
+ }
13598
13632
  function getPropertyOptions(node, contentType) {
13599
13633
  const isOptional = !!node.optional;
13600
- let description = null;
13601
- if (node.trailingComments && node.trailingComments.length) {
13602
- description = node.trailingComments[0].value.trim();
13603
- }
13604
13634
  const options = {};
13605
- if (description) {
13606
- options.description = description;
13635
+ const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
13636
+ const trailingComment = node.trailingComments?.[0];
13637
+ const sourceComment = leadingComment ?? trailingComment;
13638
+ if (sourceComment) {
13639
+ Object.assign(options, parsePropertyComment(sourceComment.value));
13607
13640
  }
13608
13641
  if (contentType === "body") {
13609
13642
  options.nullable = isOptional;
@@ -11693,7 +11693,9 @@ var ZodSchemaConverter = class {
11693
11693
  apiDir;
11694
11694
  zodSchemas = {};
11695
11695
  processingSchemas = /* @__PURE__ */ new Set();
11696
- processedModules = /* @__PURE__ */ new Set();
11696
+ /** Memoization guard for processFileForZodSchema. Keys: `${filePath}|${schemaName}`.
11697
+ * Prevents infinite recursion when re-export files reference schemas via z.infer<typeof X>. */
11698
+ processedFileSchemaPairs = /* @__PURE__ */ new Set();
11697
11699
  typeToSchemaMapping = {};
11698
11700
  drizzleZodImports = /* @__PURE__ */ new Set();
11699
11701
  factoryCache = /* @__PURE__ */ new Map();
@@ -11907,6 +11909,11 @@ var ZodSchemaConverter = class {
11907
11909
  * Process a file to find Zod schema definitions
11908
11910
  */
11909
11911
  processFileForZodSchema(filePath, schemaName) {
11912
+ const visitKey = `${filePath}|${schemaName}|${this.currentContentType}`;
11913
+ if (this.processedFileSchemaPairs.has(visitKey)) {
11914
+ return;
11915
+ }
11916
+ this.processedFileSchemaPairs.add(visitKey);
11910
11917
  try {
11911
11918
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
11912
11919
  if (!content.includes(schemaName)) {
@@ -12220,7 +12227,9 @@ var ZodSchemaConverter = class {
12220
12227
  const param = path17.node.typeAnnotation.typeParameters.params[0];
12221
12228
  if (t10.isTSTypeQuery(param) && t10.isIdentifier(param.exprName)) {
12222
12229
  const referencedSchemaName = param.exprName.name;
12223
- this.processFileForZodSchema(filePath, referencedSchemaName);
12230
+ if (!this.getStoredSchema(referencedSchemaName)) {
12231
+ this.processFileForZodSchema(filePath, referencedSchemaName);
12232
+ }
12224
12233
  }
12225
12234
  }
12226
12235
  }
@@ -13595,15 +13604,39 @@ function extractKeysFromLiteralType(node) {
13595
13604
  }
13596
13605
  return [];
13597
13606
  }
13607
+ function parsePropertyComment(commentValue) {
13608
+ const text = commentValue.split("\n").map((line) => line.replace(/^\s*\*\s?/, "").trim()).filter((line) => line.length > 0).join(" ").trim();
13609
+ const result = {};
13610
+ let remaining = text;
13611
+ const formatMatch = remaining.match(/@format\s+(\S+)/);
13612
+ if (formatMatch?.[1]) {
13613
+ result.format = formatMatch[1];
13614
+ remaining = remaining.replace(formatMatch[0], "").trim();
13615
+ }
13616
+ const exampleMatch = remaining.match(/@example\s+(.+?)(?=\s*@\w|$)/);
13617
+ if (exampleMatch?.[1]) {
13618
+ const raw = exampleMatch[1].trim();
13619
+ try {
13620
+ result.example = JSON.parse(raw);
13621
+ } catch {
13622
+ result.example = raw;
13623
+ }
13624
+ remaining = remaining.replace(exampleMatch[0], "").trim();
13625
+ }
13626
+ remaining = remaining.replace(/@\w+(?:\s+\S+)*/g, "").trim();
13627
+ if (remaining) {
13628
+ result.description = remaining;
13629
+ }
13630
+ return result;
13631
+ }
13598
13632
  function getPropertyOptions(node, contentType) {
13599
13633
  const isOptional = !!node.optional;
13600
- let description = null;
13601
- if (node.trailingComments && node.trailingComments.length) {
13602
- description = node.trailingComments[0].value.trim();
13603
- }
13604
13634
  const options = {};
13605
- if (description) {
13606
- options.description = description;
13635
+ const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
13636
+ const trailingComment = node.trailingComments?.[0];
13637
+ const sourceComment = leadingComment ?? trailingComment;
13638
+ if (sourceComment) {
13639
+ Object.assign(options, parsePropertyComment(sourceComment.value));
13607
13640
  }
13608
13641
  if (contentType === "body") {
13609
13642
  options.nullable = isOptional;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Automatically generate OpenAPI 3.0, 3.1, and 3.2 documentation from Next.js projects, with support for Zod schemas, TypeScript types, and reusable OpenAPI fragments.",
5
5
  "keywords": [
6
6
  "api",