next-openapi-gen 1.2.3 → 1.3.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.
package/README.md CHANGED
@@ -288,33 +288,34 @@ Version guidance:
288
288
  | `ignoreRoutes` | Exclude routes with wildcard support |
289
289
  | `defaultResponseSet` / `responseSets` | Reusable error-response groups |
290
290
  | `errorConfig` | Shared error schema templates |
291
+ | `authPresets` | Override or extend the `@auth` keyword → scheme-name mapping |
291
292
 
292
293
  For a fuller setup guide, Pages Router notes, response sets, and route exclusion
293
294
  patterns, see [docs/getting-started.md](./docs/getting-started.md).
294
295
 
295
296
  ## JSDoc tags you will use most
296
297
 
297
- | Tag | Purpose |
298
- | -------------------------- | ---------------------------------------------------------------- |
299
- | `@pathParams` | Path parameter schema or type |
300
- | `@params` / `@queryParams` | Query parameter schema or type |
301
- | `@header` / `@cookie` | Header / cookie parameter schema or type |
302
- | `@body` | Request body schema or type |
303
- | `@response` | Response schema, code, and optional description |
304
- | `@responseDescription` | Response description without redefining the schema |
305
- | `@responseHeader` | Add a response header to a given status code |
306
- | `@link` | Add an OpenAPI link to a response |
307
- | `@auth` / `@security` | Security requirement(s); `@security` accepts explicit scopes |
308
- | `@servers` | Operation-level servers |
309
- | `@externalDocs` | Operation-level external documentation |
310
- | `@callback` | OpenAPI operation callback |
311
- | `@webhook` | Mark the handler as a webhook (`3.1`+ `webhooks` section) |
312
- | `@contentType` | Request content type such as `multipart/form-data` |
313
- | `@examples` | Request, response, and querystring examples |
314
- | `@openapi` | Explicit inclusion marker when `includeOpenApiRoutes` is enabled |
315
- | `@openapi-override` | Deep-merge extra OpenAPI fields onto the operation |
316
- | `@ignore` | Exclude a route from generation |
317
- | `@method` | Required HTTP method tag for Pages Router handlers |
298
+ | Tag | Purpose |
299
+ | -------------------------- | ------------------------------------------------------------------------------------------------------- |
300
+ | `@pathParams` | Path parameter schema or type |
301
+ | `@params` / `@queryParams` | Query parameter schema or type |
302
+ | `@header` / `@cookie` | Header / cookie parameter schema or type |
303
+ | `@body` | Request body schema or type |
304
+ | `@response` | Response schema, code, and optional description |
305
+ | `@responseDescription` | Response description without redefining the schema |
306
+ | `@responseHeader` | Add a response header to a given status code |
307
+ | `@link` | Add an OpenAPI link to a response |
308
+ | `@auth` / `@security` | Security requirement(s); built-in presets: `bearer`, `basic`, `apikey` — configurable via `authPresets` |
309
+ | `@servers` | Operation-level servers |
310
+ | `@externalDocs` | Operation-level external documentation |
311
+ | `@callback` | OpenAPI operation callback |
312
+ | `@webhook` | Mark the handler as a webhook (`3.1`+ `webhooks` section) |
313
+ | `@contentType` | Request content type such as `multipart/form-data` |
314
+ | `@examples` | Request, response, and querystring examples |
315
+ | `@openapi` | Explicit inclusion marker when `includeOpenApiRoutes` is enabled |
316
+ | `@openapi-override` | Deep-merge extra OpenAPI fields onto the operation |
317
+ | `@ignore` | Exclude a route from generation |
318
+ | `@method` | Required HTTP method tag for Pages Router handlers |
318
319
 
319
320
  For the complete tag guide and usage recipes, see
320
321
  [docs/jsdoc-reference.md](./docs/jsdoc-reference.md).
package/dist/cli.js CHANGED
@@ -667,6 +667,7 @@ function normalizeOpenApiConfig(template) {
667
667
  outputDir: template.outputDir ?? DEFAULT_OUTPUT_DIR,
668
668
  includeOpenApiRoutes: template.includeOpenApiRoutes ?? DEFAULT_INCLUDE_OPENAPI_ROUTES,
669
669
  ignoreRoutes: template.ignoreRoutes ?? [],
670
+ excludeSchemas: template.excludeSchemas ?? [],
670
671
  schemaType: template.schemaType ?? DEFAULT_RUNTIME_SCHEMA_TYPE,
671
672
  schemaBackends,
672
673
  schemaFiles: template.schemaFiles ?? [],
@@ -1406,6 +1407,17 @@ function mergeJSDocData(target, source) {
1406
1407
  function cleanComment(commentValue) {
1407
1408
  return commentValue.replace(/\*\s*/g, "").trim();
1408
1409
  }
1410
+ function extractInternalFlagFromComments(comments) {
1411
+ if (!comments)
1412
+ return false;
1413
+ for (const comment of comments) {
1414
+ const cleaned = cleanComment(comment.value);
1415
+ if (/@internal\b/.test(cleaned) || /@schema\s+false\b/.test(cleaned)) {
1416
+ return true;
1417
+ }
1418
+ }
1419
+ return false;
1420
+ }
1409
1421
  function extractSchemaIdFromComments(comments) {
1410
1422
  if (!comments)
1411
1423
  return null;
@@ -1702,7 +1714,8 @@ var INTERNAL_OPENAPI_CONFIG_KEYS = [
1702
1714
  "framework",
1703
1715
  "next",
1704
1716
  "diagnostics",
1705
- "debug"
1717
+ "debug",
1718
+ "excludeSchemas"
1706
1719
  ];
1707
1720
  var AUTH_PRESET_REPLACEMENTS = {
1708
1721
  bearer: "BearerAuth",
@@ -12145,6 +12158,8 @@ var ZodSchemaConverter = class {
12145
12158
  /** Schema variable names whose component name was overridden via .meta({ id }). These must
12146
12159
  * NOT be copied back under the original variable name in the OpenAPI components object. */
12147
12160
  metaIdSchemaNames = /* @__PURE__ */ new Set();
12161
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
12162
+ internalSchemaNames = /* @__PURE__ */ new Set();
12148
12163
  // Current processing context (set during file processing)
12149
12164
  currentFilePath;
12150
12165
  currentAST;
@@ -13766,7 +13781,13 @@ var ZodSchemaConverter = class {
13766
13781
  * Get all processed Zod schemas
13767
13782
  */
13768
13783
  getProcessedSchemas() {
13769
- return this.zodSchemas;
13784
+ const result = {};
13785
+ for (const [name, schema] of Object.entries(this.zodSchemas)) {
13786
+ if (!this.internalSchemaNames.has(name)) {
13787
+ result[name] = schema;
13788
+ }
13789
+ }
13790
+ return result;
13770
13791
  }
13771
13792
  /**
13772
13793
  * Pre-scan all files to build type mappings
@@ -13818,6 +13839,15 @@ var ZodSchemaConverter = class {
13818
13839
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13819
13840
  const schemaName = declaration.id.name;
13820
13841
  if (this.isZodSchema(declaration.init)) {
13842
+ const decl = path25.node.declaration;
13843
+ const allComments = [
13844
+ ...path25.node.leadingComments ?? [],
13845
+ ...decl?.leadingComments ?? [],
13846
+ ...declaration.leadingComments ?? []
13847
+ ];
13848
+ if (extractInternalFlagFromComments(allComments)) {
13849
+ this.internalSchemaNames.add(schemaName);
13850
+ }
13821
13851
  if (!this.getStoredSchema(schemaName)) {
13822
13852
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13823
13853
  this.processingSchemas.add(schemaName);
@@ -13843,6 +13873,13 @@ var ZodSchemaConverter = class {
13843
13873
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13844
13874
  const schemaName = declaration.id.name;
13845
13875
  if (this.isZodSchema(declaration.init)) {
13876
+ const allComments = [
13877
+ ...path25.node.leadingComments ?? [],
13878
+ ...declaration.leadingComments ?? []
13879
+ ];
13880
+ if (extractInternalFlagFromComments(allComments)) {
13881
+ this.internalSchemaNames.add(schemaName);
13882
+ }
13846
13883
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13847
13884
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13848
13885
  this.processingSchemas.add(schemaName);
@@ -14577,7 +14614,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
14577
14614
  const firstMember = body.body?.[0];
14578
14615
  return firstMember?.leadingComments ?? [];
14579
14616
  }
14580
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14617
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
14581
14618
  function registerDefinition(name, entry, allComments) {
14582
14619
  if (!typeDefinitions[name]) {
14583
14620
  typeDefinitions[name] = entry;
@@ -14589,6 +14626,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
14589
14626
  typeDefinitions[overrideId] = entry;
14590
14627
  }
14591
14628
  }
14629
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
14630
+ internalSchemaNames.add(name);
14631
+ }
14592
14632
  }
14593
14633
  resolvedTraverse(ast, {
14594
14634
  TSTypeAliasDeclaration: (path25) => {
@@ -15068,6 +15108,7 @@ var SchemaProcessor = class {
15068
15108
  schemaTypes;
15069
15109
  isResolvingPickOmitBase = false;
15070
15110
  schemaIdAliases = {};
15111
+ internalSchemaNames = /* @__PURE__ */ new Set();
15071
15112
  fileAccess;
15072
15113
  symbolResolver;
15073
15114
  // Track imports per file for resolving ReturnType<typeof func>
@@ -15108,7 +15149,7 @@ var SchemaProcessor = class {
15108
15149
  getDefinedSchemas() {
15109
15150
  const filteredSchemas = {};
15110
15151
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
15111
- if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
15152
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key) && !this.internalSchemaNames.has(key)) {
15112
15153
  filteredSchemas[key] = value;
15113
15154
  }
15114
15155
  });
@@ -15118,6 +15159,22 @@ var SchemaProcessor = class {
15118
15159
  this.customSchemaProcessor.getDefinedSchemas()
15119
15160
  ]);
15120
15161
  }
15162
+ getInternalSchemas() {
15163
+ const result = {};
15164
+ for (const name of this.internalSchemaNames) {
15165
+ const def = this.openapiDefinitions[name];
15166
+ if (def)
15167
+ result[name] = def;
15168
+ }
15169
+ if (this.zodSchemaConverter) {
15170
+ for (const name of this.zodSchemaConverter.internalSchemaNames) {
15171
+ const schema = this.zodSchemaConverter.zodSchemas[name];
15172
+ if (schema)
15173
+ result[name] = schema;
15174
+ }
15175
+ }
15176
+ return result;
15177
+ }
15121
15178
  findSchemaDefinition(schemaName, contentType) {
15122
15179
  this.contentType = contentType;
15123
15180
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -15268,7 +15325,7 @@ var SchemaProcessor = class {
15268
15325
  * Used when processing imported files to ensure all referenced types are available
15269
15326
  */
15270
15327
  collectAllExportedDefinitions(ast, filePath) {
15271
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
15328
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
15272
15329
  }
15273
15330
  collectTypeDefinitions(ast, schemaName, filePath) {
15274
15331
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -17254,6 +17311,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
17254
17311
  });
17255
17312
  }
17256
17313
 
17314
+ // ../openapi-core/dist/core/exclude-schemas.js
17315
+ function patternToRegExp(pattern) {
17316
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
17317
+ return new RegExp(`^${escaped.replace(/\*/g, ".*")}$`);
17318
+ }
17319
+ function matchExcludePatterns(names, patterns) {
17320
+ if (patterns.length === 0)
17321
+ return [];
17322
+ const regexes = patterns.map(patternToRegExp);
17323
+ return names.filter((name) => regexes.some((re) => re.test(name)));
17324
+ }
17325
+ function applyExcludeSchemas(document, mergedSchemas, excludedSchemas) {
17326
+ const excludedNames = new Set(Object.keys(excludedSchemas));
17327
+ if (excludedNames.size === 0)
17328
+ return;
17329
+ walkAndInline(document, excludedSchemas, excludedNames, /* @__PURE__ */ new Set());
17330
+ for (const name of excludedNames) {
17331
+ delete mergedSchemas[name];
17332
+ }
17333
+ }
17334
+ function walkAndInline(obj, excluded, excludedNames, visiting) {
17335
+ if (!obj || typeof obj !== "object")
17336
+ return;
17337
+ if (Array.isArray(obj)) {
17338
+ for (const item of obj) {
17339
+ walkAndInline(item, excluded, excludedNames, visiting);
17340
+ }
17341
+ return;
17342
+ }
17343
+ const rec = obj;
17344
+ const ref = rec["$ref"];
17345
+ if (typeof ref === "string") {
17346
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
17347
+ const name = match?.[1];
17348
+ if (name && excludedNames.has(name)) {
17349
+ if (visiting.has(name)) {
17350
+ logger.warn(`Circular reference to internal schema "${name}", keeping $ref`);
17351
+ return;
17352
+ }
17353
+ const schemaDef = excluded[name];
17354
+ if (schemaDef) {
17355
+ const cloned = JSON.parse(JSON.stringify(schemaDef));
17356
+ delete rec["$ref"];
17357
+ Object.assign(rec, cloned);
17358
+ const newVisiting = new Set(visiting);
17359
+ newVisiting.add(name);
17360
+ for (const key of Object.keys(rec)) {
17361
+ walkAndInline(rec[key], excluded, excludedNames, newVisiting);
17362
+ }
17363
+ return;
17364
+ }
17365
+ }
17366
+ }
17367
+ for (const key of Object.keys(rec)) {
17368
+ walkAndInline(rec[key], excluded, excludedNames, visiting);
17369
+ }
17370
+ }
17371
+
17257
17372
  // ../openapi-core/dist/core/orchestrator.js
17258
17373
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
17259
17374
  const diagnostics = new DiagnosticsCollector();
@@ -17324,11 +17439,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
17324
17439
  }
17325
17440
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
17326
17441
  phaseStartedAt = performance.now();
17327
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
17442
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
17443
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
17328
17444
  const mergedSchemas = {
17329
17445
  ...document.components.schemas,
17330
17446
  ...definedSchemas
17331
17447
  };
17448
+ const internalSchemas = schemaProcessor.getInternalSchemas();
17449
+ const patternExcludedNames = matchExcludePatterns(Object.keys(mergedSchemas), config2.excludeSchemas ?? []);
17450
+ const allExcludedSchemas = {
17451
+ ...internalSchemas,
17452
+ ...Object.fromEntries(patternExcludedNames.map((name) => [name, mergedSchemas[name]]))
17453
+ };
17454
+ if (Object.keys(allExcludedSchemas).length > 0) {
17455
+ applyExcludeSchemas(document, mergedSchemas, allExcludedSchemas);
17456
+ }
17332
17457
  if (Object.keys(mergedSchemas).length > 0) {
17333
17458
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
17334
17459
  }
package/dist/index.js CHANGED
@@ -211,6 +211,7 @@ function normalizeOpenApiConfig(template) {
211
211
  outputDir: template.outputDir ?? DEFAULT_OUTPUT_DIR,
212
212
  includeOpenApiRoutes: template.includeOpenApiRoutes ?? DEFAULT_INCLUDE_OPENAPI_ROUTES,
213
213
  ignoreRoutes: template.ignoreRoutes ?? [],
214
+ excludeSchemas: template.excludeSchemas ?? [],
214
215
  schemaType: template.schemaType ?? DEFAULT_RUNTIME_SCHEMA_TYPE,
215
216
  schemaBackends,
216
217
  schemaFiles: template.schemaFiles ?? [],
@@ -950,6 +951,17 @@ function mergeJSDocData(target, source) {
950
951
  function cleanComment(commentValue) {
951
952
  return commentValue.replace(/\*\s*/g, "").trim();
952
953
  }
954
+ function extractInternalFlagFromComments(comments) {
955
+ if (!comments)
956
+ return false;
957
+ for (const comment of comments) {
958
+ const cleaned = cleanComment(comment.value);
959
+ if (/@internal\b/.test(cleaned) || /@schema\s+false\b/.test(cleaned)) {
960
+ return true;
961
+ }
962
+ }
963
+ return false;
964
+ }
953
965
  function extractSchemaIdFromComments(comments) {
954
966
  if (!comments)
955
967
  return null;
@@ -1246,7 +1258,8 @@ var INTERNAL_OPENAPI_CONFIG_KEYS = [
1246
1258
  "framework",
1247
1259
  "next",
1248
1260
  "diagnostics",
1249
- "debug"
1261
+ "debug",
1262
+ "excludeSchemas"
1250
1263
  ];
1251
1264
  var AUTH_PRESET_REPLACEMENTS = {
1252
1265
  bearer: "BearerAuth",
@@ -11694,6 +11707,8 @@ var ZodSchemaConverter = class {
11694
11707
  /** Schema variable names whose component name was overridden via .meta({ id }). These must
11695
11708
  * NOT be copied back under the original variable name in the OpenAPI components object. */
11696
11709
  metaIdSchemaNames = /* @__PURE__ */ new Set();
11710
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
11711
+ internalSchemaNames = /* @__PURE__ */ new Set();
11697
11712
  // Current processing context (set during file processing)
11698
11713
  currentFilePath;
11699
11714
  currentAST;
@@ -13315,7 +13330,13 @@ var ZodSchemaConverter = class {
13315
13330
  * Get all processed Zod schemas
13316
13331
  */
13317
13332
  getProcessedSchemas() {
13318
- return this.zodSchemas;
13333
+ const result = {};
13334
+ for (const [name, schema] of Object.entries(this.zodSchemas)) {
13335
+ if (!this.internalSchemaNames.has(name)) {
13336
+ result[name] = schema;
13337
+ }
13338
+ }
13339
+ return result;
13319
13340
  }
13320
13341
  /**
13321
13342
  * Pre-scan all files to build type mappings
@@ -13367,6 +13388,15 @@ var ZodSchemaConverter = class {
13367
13388
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13368
13389
  const schemaName = declaration.id.name;
13369
13390
  if (this.isZodSchema(declaration.init)) {
13391
+ const decl = path25.node.declaration;
13392
+ const allComments = [
13393
+ ...path25.node.leadingComments ?? [],
13394
+ ...decl?.leadingComments ?? [],
13395
+ ...declaration.leadingComments ?? []
13396
+ ];
13397
+ if (extractInternalFlagFromComments(allComments)) {
13398
+ this.internalSchemaNames.add(schemaName);
13399
+ }
13370
13400
  if (!this.getStoredSchema(schemaName)) {
13371
13401
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13372
13402
  this.processingSchemas.add(schemaName);
@@ -13392,6 +13422,13 @@ var ZodSchemaConverter = class {
13392
13422
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13393
13423
  const schemaName = declaration.id.name;
13394
13424
  if (this.isZodSchema(declaration.init)) {
13425
+ const allComments = [
13426
+ ...path25.node.leadingComments ?? [],
13427
+ ...declaration.leadingComments ?? []
13428
+ ];
13429
+ if (extractInternalFlagFromComments(allComments)) {
13430
+ this.internalSchemaNames.add(schemaName);
13431
+ }
13395
13432
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13396
13433
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13397
13434
  this.processingSchemas.add(schemaName);
@@ -14126,7 +14163,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
14126
14163
  const firstMember = body.body?.[0];
14127
14164
  return firstMember?.leadingComments ?? [];
14128
14165
  }
14129
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14166
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
14130
14167
  function registerDefinition(name, entry, allComments) {
14131
14168
  if (!typeDefinitions[name]) {
14132
14169
  typeDefinitions[name] = entry;
@@ -14138,6 +14175,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
14138
14175
  typeDefinitions[overrideId] = entry;
14139
14176
  }
14140
14177
  }
14178
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
14179
+ internalSchemaNames.add(name);
14180
+ }
14141
14181
  }
14142
14182
  resolvedTraverse(ast, {
14143
14183
  TSTypeAliasDeclaration: (path25) => {
@@ -14617,6 +14657,7 @@ var SchemaProcessor = class {
14617
14657
  schemaTypes;
14618
14658
  isResolvingPickOmitBase = false;
14619
14659
  schemaIdAliases = {};
14660
+ internalSchemaNames = /* @__PURE__ */ new Set();
14620
14661
  fileAccess;
14621
14662
  symbolResolver;
14622
14663
  // Track imports per file for resolving ReturnType<typeof func>
@@ -14657,7 +14698,7 @@ var SchemaProcessor = class {
14657
14698
  getDefinedSchemas() {
14658
14699
  const filteredSchemas = {};
14659
14700
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
14660
- if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
14701
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key) && !this.internalSchemaNames.has(key)) {
14661
14702
  filteredSchemas[key] = value;
14662
14703
  }
14663
14704
  });
@@ -14667,6 +14708,22 @@ var SchemaProcessor = class {
14667
14708
  this.customSchemaProcessor.getDefinedSchemas()
14668
14709
  ]);
14669
14710
  }
14711
+ getInternalSchemas() {
14712
+ const result = {};
14713
+ for (const name of this.internalSchemaNames) {
14714
+ const def = this.openapiDefinitions[name];
14715
+ if (def)
14716
+ result[name] = def;
14717
+ }
14718
+ if (this.zodSchemaConverter) {
14719
+ for (const name of this.zodSchemaConverter.internalSchemaNames) {
14720
+ const schema = this.zodSchemaConverter.zodSchemas[name];
14721
+ if (schema)
14722
+ result[name] = schema;
14723
+ }
14724
+ }
14725
+ return result;
14726
+ }
14670
14727
  findSchemaDefinition(schemaName, contentType) {
14671
14728
  this.contentType = contentType;
14672
14729
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -14817,7 +14874,7 @@ var SchemaProcessor = class {
14817
14874
  * Used when processing imported files to ensure all referenced types are available
14818
14875
  */
14819
14876
  collectAllExportedDefinitions(ast, filePath) {
14820
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
14877
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
14821
14878
  }
14822
14879
  collectTypeDefinitions(ast, schemaName, filePath) {
14823
14880
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -16803,6 +16860,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
16803
16860
  });
16804
16861
  }
16805
16862
 
16863
+ // ../openapi-core/dist/core/exclude-schemas.js
16864
+ function patternToRegExp(pattern) {
16865
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
16866
+ return new RegExp(`^${escaped.replace(/\*/g, ".*")}$`);
16867
+ }
16868
+ function matchExcludePatterns(names, patterns) {
16869
+ if (patterns.length === 0)
16870
+ return [];
16871
+ const regexes = patterns.map(patternToRegExp);
16872
+ return names.filter((name) => regexes.some((re) => re.test(name)));
16873
+ }
16874
+ function applyExcludeSchemas(document, mergedSchemas, excludedSchemas) {
16875
+ const excludedNames = new Set(Object.keys(excludedSchemas));
16876
+ if (excludedNames.size === 0)
16877
+ return;
16878
+ walkAndInline(document, excludedSchemas, excludedNames, /* @__PURE__ */ new Set());
16879
+ for (const name of excludedNames) {
16880
+ delete mergedSchemas[name];
16881
+ }
16882
+ }
16883
+ function walkAndInline(obj, excluded, excludedNames, visiting) {
16884
+ if (!obj || typeof obj !== "object")
16885
+ return;
16886
+ if (Array.isArray(obj)) {
16887
+ for (const item of obj) {
16888
+ walkAndInline(item, excluded, excludedNames, visiting);
16889
+ }
16890
+ return;
16891
+ }
16892
+ const rec = obj;
16893
+ const ref = rec["$ref"];
16894
+ if (typeof ref === "string") {
16895
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
16896
+ const name = match?.[1];
16897
+ if (name && excludedNames.has(name)) {
16898
+ if (visiting.has(name)) {
16899
+ logger.warn(`Circular reference to internal schema "${name}", keeping $ref`);
16900
+ return;
16901
+ }
16902
+ const schemaDef = excluded[name];
16903
+ if (schemaDef) {
16904
+ const cloned = JSON.parse(JSON.stringify(schemaDef));
16905
+ delete rec["$ref"];
16906
+ Object.assign(rec, cloned);
16907
+ const newVisiting = new Set(visiting);
16908
+ newVisiting.add(name);
16909
+ for (const key of Object.keys(rec)) {
16910
+ walkAndInline(rec[key], excluded, excludedNames, newVisiting);
16911
+ }
16912
+ return;
16913
+ }
16914
+ }
16915
+ }
16916
+ for (const key of Object.keys(rec)) {
16917
+ walkAndInline(rec[key], excluded, excludedNames, visiting);
16918
+ }
16919
+ }
16920
+
16806
16921
  // ../openapi-core/dist/core/orchestrator.js
16807
16922
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
16808
16923
  const diagnostics = new DiagnosticsCollector();
@@ -16873,11 +16988,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
16873
16988
  }
16874
16989
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
16875
16990
  phaseStartedAt = performance.now();
16876
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
16991
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
16992
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
16877
16993
  const mergedSchemas = {
16878
16994
  ...document.components.schemas,
16879
16995
  ...definedSchemas
16880
16996
  };
16997
+ const internalSchemas = schemaProcessor.getInternalSchemas();
16998
+ const patternExcludedNames = matchExcludePatterns(Object.keys(mergedSchemas), config2.excludeSchemas ?? []);
16999
+ const allExcludedSchemas = {
17000
+ ...internalSchemas,
17001
+ ...Object.fromEntries(patternExcludedNames.map((name) => [name, mergedSchemas[name]]))
17002
+ };
17003
+ if (Object.keys(allExcludedSchemas).length > 0) {
17004
+ applyExcludeSchemas(document, mergedSchemas, allExcludedSchemas);
17005
+ }
16881
17006
  if (Object.keys(mergedSchemas).length > 0) {
16882
17007
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
16883
17008
  }
@@ -1306,6 +1306,17 @@ function mergeJSDocData(target, source) {
1306
1306
  function cleanComment(commentValue) {
1307
1307
  return commentValue.replace(/\*\s*/g, "").trim();
1308
1308
  }
1309
+ function extractInternalFlagFromComments(comments) {
1310
+ if (!comments)
1311
+ return false;
1312
+ for (const comment of comments) {
1313
+ const cleaned = cleanComment(comment.value);
1314
+ if (/@internal\b/.test(cleaned) || /@schema\s+false\b/.test(cleaned)) {
1315
+ return true;
1316
+ }
1317
+ }
1318
+ return false;
1319
+ }
1309
1320
  function extractSchemaIdFromComments(comments) {
1310
1321
  if (!comments)
1311
1322
  return null;
@@ -1602,7 +1613,8 @@ var INTERNAL_OPENAPI_CONFIG_KEYS = [
1602
1613
  "framework",
1603
1614
  "next",
1604
1615
  "diagnostics",
1605
- "debug"
1616
+ "debug",
1617
+ "excludeSchemas"
1606
1618
  ];
1607
1619
  var AUTH_PRESET_REPLACEMENTS = {
1608
1620
  bearer: "BearerAuth",
@@ -2316,6 +2328,7 @@ function normalizeOpenApiConfig(template) {
2316
2328
  outputDir: template.outputDir ?? DEFAULT_OUTPUT_DIR,
2317
2329
  includeOpenApiRoutes: template.includeOpenApiRoutes ?? DEFAULT_INCLUDE_OPENAPI_ROUTES,
2318
2330
  ignoreRoutes: template.ignoreRoutes ?? [],
2331
+ excludeSchemas: template.excludeSchemas ?? [],
2319
2332
  schemaType: template.schemaType ?? DEFAULT_RUNTIME_SCHEMA_TYPE,
2320
2333
  schemaBackends,
2321
2334
  schemaFiles: template.schemaFiles ?? [],
@@ -12728,6 +12741,8 @@ var ZodSchemaConverter = class {
12728
12741
  /** Schema variable names whose component name was overridden via .meta({ id }). These must
12729
12742
  * NOT be copied back under the original variable name in the OpenAPI components object. */
12730
12743
  metaIdSchemaNames = /* @__PURE__ */ new Set();
12744
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
12745
+ internalSchemaNames = /* @__PURE__ */ new Set();
12731
12746
  // Current processing context (set during file processing)
12732
12747
  currentFilePath;
12733
12748
  currentAST;
@@ -14349,7 +14364,13 @@ var ZodSchemaConverter = class {
14349
14364
  * Get all processed Zod schemas
14350
14365
  */
14351
14366
  getProcessedSchemas() {
14352
- return this.zodSchemas;
14367
+ const result = {};
14368
+ for (const [name, schema] of Object.entries(this.zodSchemas)) {
14369
+ if (!this.internalSchemaNames.has(name)) {
14370
+ result[name] = schema;
14371
+ }
14372
+ }
14373
+ return result;
14353
14374
  }
14354
14375
  /**
14355
14376
  * Pre-scan all files to build type mappings
@@ -14401,6 +14422,15 @@ var ZodSchemaConverter = class {
14401
14422
  if (t11.isIdentifier(declaration.id) && declaration.init) {
14402
14423
  const schemaName = declaration.id.name;
14403
14424
  if (this.isZodSchema(declaration.init)) {
14425
+ const decl = path19.node.declaration;
14426
+ const allComments = [
14427
+ ...path19.node.leadingComments ?? [],
14428
+ ...decl?.leadingComments ?? [],
14429
+ ...declaration.leadingComments ?? []
14430
+ ];
14431
+ if (extractInternalFlagFromComments(allComments)) {
14432
+ this.internalSchemaNames.add(schemaName);
14433
+ }
14404
14434
  if (!this.getStoredSchema(schemaName)) {
14405
14435
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
14406
14436
  this.processingSchemas.add(schemaName);
@@ -14426,6 +14456,13 @@ var ZodSchemaConverter = class {
14426
14456
  if (t11.isIdentifier(declaration.id) && declaration.init) {
14427
14457
  const schemaName = declaration.id.name;
14428
14458
  if (this.isZodSchema(declaration.init)) {
14459
+ const allComments = [
14460
+ ...path19.node.leadingComments ?? [],
14461
+ ...declaration.leadingComments ?? []
14462
+ ];
14463
+ if (extractInternalFlagFromComments(allComments)) {
14464
+ this.internalSchemaNames.add(schemaName);
14465
+ }
14429
14466
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
14430
14467
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
14431
14468
  this.processingSchemas.add(schemaName);
@@ -15160,7 +15197,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
15160
15197
  const firstMember = body.body?.[0];
15161
15198
  return firstMember?.leadingComments ?? [];
15162
15199
  }
15163
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
15200
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
15164
15201
  function registerDefinition(name, entry, allComments) {
15165
15202
  if (!typeDefinitions[name]) {
15166
15203
  typeDefinitions[name] = entry;
@@ -15172,6 +15209,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
15172
15209
  typeDefinitions[overrideId] = entry;
15173
15210
  }
15174
15211
  }
15212
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
15213
+ internalSchemaNames.add(name);
15214
+ }
15175
15215
  }
15176
15216
  resolvedTraverse(ast, {
15177
15217
  TSTypeAliasDeclaration: (path19) => {
@@ -15651,6 +15691,7 @@ var SchemaProcessor = class {
15651
15691
  schemaTypes;
15652
15692
  isResolvingPickOmitBase = false;
15653
15693
  schemaIdAliases = {};
15694
+ internalSchemaNames = /* @__PURE__ */ new Set();
15654
15695
  fileAccess;
15655
15696
  symbolResolver;
15656
15697
  // Track imports per file for resolving ReturnType<typeof func>
@@ -15691,7 +15732,7 @@ var SchemaProcessor = class {
15691
15732
  getDefinedSchemas() {
15692
15733
  const filteredSchemas = {};
15693
15734
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
15694
- if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
15735
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key) && !this.internalSchemaNames.has(key)) {
15695
15736
  filteredSchemas[key] = value;
15696
15737
  }
15697
15738
  });
@@ -15701,6 +15742,22 @@ var SchemaProcessor = class {
15701
15742
  this.customSchemaProcessor.getDefinedSchemas()
15702
15743
  ]);
15703
15744
  }
15745
+ getInternalSchemas() {
15746
+ const result = {};
15747
+ for (const name of this.internalSchemaNames) {
15748
+ const def = this.openapiDefinitions[name];
15749
+ if (def)
15750
+ result[name] = def;
15751
+ }
15752
+ if (this.zodSchemaConverter) {
15753
+ for (const name of this.zodSchemaConverter.internalSchemaNames) {
15754
+ const schema = this.zodSchemaConverter.zodSchemas[name];
15755
+ if (schema)
15756
+ result[name] = schema;
15757
+ }
15758
+ }
15759
+ return result;
15760
+ }
15704
15761
  findSchemaDefinition(schemaName, contentType) {
15705
15762
  this.contentType = contentType;
15706
15763
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -15851,7 +15908,7 @@ var SchemaProcessor = class {
15851
15908
  * Used when processing imported files to ensure all referenced types are available
15852
15909
  */
15853
15910
  collectAllExportedDefinitions(ast, filePath) {
15854
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
15911
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
15855
15912
  }
15856
15913
  collectTypeDefinitions(ast, schemaName, filePath) {
15857
15914
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -17837,6 +17894,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
17837
17894
  });
17838
17895
  }
17839
17896
 
17897
+ // ../openapi-core/dist/core/exclude-schemas.js
17898
+ function patternToRegExp(pattern) {
17899
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
17900
+ return new RegExp(`^${escaped.replace(/\*/g, ".*")}$`);
17901
+ }
17902
+ function matchExcludePatterns(names, patterns) {
17903
+ if (patterns.length === 0)
17904
+ return [];
17905
+ const regexes = patterns.map(patternToRegExp);
17906
+ return names.filter((name) => regexes.some((re) => re.test(name)));
17907
+ }
17908
+ function applyExcludeSchemas(document, mergedSchemas, excludedSchemas) {
17909
+ const excludedNames = new Set(Object.keys(excludedSchemas));
17910
+ if (excludedNames.size === 0)
17911
+ return;
17912
+ walkAndInline(document, excludedSchemas, excludedNames, /* @__PURE__ */ new Set());
17913
+ for (const name of excludedNames) {
17914
+ delete mergedSchemas[name];
17915
+ }
17916
+ }
17917
+ function walkAndInline(obj, excluded, excludedNames, visiting) {
17918
+ if (!obj || typeof obj !== "object")
17919
+ return;
17920
+ if (Array.isArray(obj)) {
17921
+ for (const item of obj) {
17922
+ walkAndInline(item, excluded, excludedNames, visiting);
17923
+ }
17924
+ return;
17925
+ }
17926
+ const rec = obj;
17927
+ const ref = rec["$ref"];
17928
+ if (typeof ref === "string") {
17929
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
17930
+ const name = match?.[1];
17931
+ if (name && excludedNames.has(name)) {
17932
+ if (visiting.has(name)) {
17933
+ logger.warn(`Circular reference to internal schema "${name}", keeping $ref`);
17934
+ return;
17935
+ }
17936
+ const schemaDef = excluded[name];
17937
+ if (schemaDef) {
17938
+ const cloned = JSON.parse(JSON.stringify(schemaDef));
17939
+ delete rec["$ref"];
17940
+ Object.assign(rec, cloned);
17941
+ const newVisiting = new Set(visiting);
17942
+ newVisiting.add(name);
17943
+ for (const key of Object.keys(rec)) {
17944
+ walkAndInline(rec[key], excluded, excludedNames, newVisiting);
17945
+ }
17946
+ return;
17947
+ }
17948
+ }
17949
+ }
17950
+ for (const key of Object.keys(rec)) {
17951
+ walkAndInline(rec[key], excluded, excludedNames, visiting);
17952
+ }
17953
+ }
17954
+
17840
17955
  // ../openapi-core/dist/core/orchestrator.js
17841
17956
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
17842
17957
  const diagnostics = new DiagnosticsCollector();
@@ -17907,11 +18022,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
17907
18022
  }
17908
18023
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
17909
18024
  phaseStartedAt = performance.now();
17910
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
18025
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
18026
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
17911
18027
  const mergedSchemas = {
17912
18028
  ...document.components.schemas,
17913
18029
  ...definedSchemas
17914
18030
  };
18031
+ const internalSchemas = schemaProcessor.getInternalSchemas();
18032
+ const patternExcludedNames = matchExcludePatterns(Object.keys(mergedSchemas), config2.excludeSchemas ?? []);
18033
+ const allExcludedSchemas = {
18034
+ ...internalSchemas,
18035
+ ...Object.fromEntries(patternExcludedNames.map((name) => [name, mergedSchemas[name]]))
18036
+ };
18037
+ if (Object.keys(allExcludedSchemas).length > 0) {
18038
+ applyExcludeSchemas(document, mergedSchemas, allExcludedSchemas);
18039
+ }
17915
18040
  if (Object.keys(mergedSchemas).length > 0) {
17916
18041
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
17917
18042
  }
@@ -756,6 +756,17 @@ function mergeJSDocData(target, source) {
756
756
  function cleanComment(commentValue) {
757
757
  return commentValue.replace(/\*\s*/g, "").trim();
758
758
  }
759
+ function extractInternalFlagFromComments(comments) {
760
+ if (!comments)
761
+ return false;
762
+ for (const comment of comments) {
763
+ const cleaned = cleanComment(comment.value);
764
+ if (/@internal\b/.test(cleaned) || /@schema\s+false\b/.test(cleaned)) {
765
+ return true;
766
+ }
767
+ }
768
+ return false;
769
+ }
759
770
  function extractSchemaIdFromComments(comments) {
760
771
  if (!comments)
761
772
  return null;
@@ -1052,7 +1063,8 @@ var INTERNAL_OPENAPI_CONFIG_KEYS = [
1052
1063
  "framework",
1053
1064
  "next",
1054
1065
  "diagnostics",
1055
- "debug"
1066
+ "debug",
1067
+ "excludeSchemas"
1056
1068
  ];
1057
1069
  var AUTH_PRESET_REPLACEMENTS = {
1058
1070
  bearer: "BearerAuth",
@@ -1320,6 +1332,7 @@ function normalizeOpenApiConfig(template) {
1320
1332
  outputDir: template.outputDir ?? DEFAULT_OUTPUT_DIR,
1321
1333
  includeOpenApiRoutes: template.includeOpenApiRoutes ?? DEFAULT_INCLUDE_OPENAPI_ROUTES,
1322
1334
  ignoreRoutes: template.ignoreRoutes ?? [],
1335
+ excludeSchemas: template.excludeSchemas ?? [],
1323
1336
  schemaType: template.schemaType ?? DEFAULT_RUNTIME_SCHEMA_TYPE,
1324
1337
  schemaBackends,
1325
1338
  schemaFiles: template.schemaFiles ?? [],
@@ -11732,6 +11745,8 @@ var ZodSchemaConverter = class {
11732
11745
  /** Schema variable names whose component name was overridden via .meta({ id }). These must
11733
11746
  * NOT be copied back under the original variable name in the OpenAPI components object. */
11734
11747
  metaIdSchemaNames = /* @__PURE__ */ new Set();
11748
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
11749
+ internalSchemaNames = /* @__PURE__ */ new Set();
11735
11750
  // Current processing context (set during file processing)
11736
11751
  currentFilePath;
11737
11752
  currentAST;
@@ -13353,7 +13368,13 @@ var ZodSchemaConverter = class {
13353
13368
  * Get all processed Zod schemas
13354
13369
  */
13355
13370
  getProcessedSchemas() {
13356
- return this.zodSchemas;
13371
+ const result = {};
13372
+ for (const [name, schema] of Object.entries(this.zodSchemas)) {
13373
+ if (!this.internalSchemaNames.has(name)) {
13374
+ result[name] = schema;
13375
+ }
13376
+ }
13377
+ return result;
13357
13378
  }
13358
13379
  /**
13359
13380
  * Pre-scan all files to build type mappings
@@ -13405,6 +13426,15 @@ var ZodSchemaConverter = class {
13405
13426
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13406
13427
  const schemaName = declaration.id.name;
13407
13428
  if (this.isZodSchema(declaration.init)) {
13429
+ const decl = path17.node.declaration;
13430
+ const allComments = [
13431
+ ...path17.node.leadingComments ?? [],
13432
+ ...decl?.leadingComments ?? [],
13433
+ ...declaration.leadingComments ?? []
13434
+ ];
13435
+ if (extractInternalFlagFromComments(allComments)) {
13436
+ this.internalSchemaNames.add(schemaName);
13437
+ }
13408
13438
  if (!this.getStoredSchema(schemaName)) {
13409
13439
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13410
13440
  this.processingSchemas.add(schemaName);
@@ -13430,6 +13460,13 @@ var ZodSchemaConverter = class {
13430
13460
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13431
13461
  const schemaName = declaration.id.name;
13432
13462
  if (this.isZodSchema(declaration.init)) {
13463
+ const allComments = [
13464
+ ...path17.node.leadingComments ?? [],
13465
+ ...declaration.leadingComments ?? []
13466
+ ];
13467
+ if (extractInternalFlagFromComments(allComments)) {
13468
+ this.internalSchemaNames.add(schemaName);
13469
+ }
13433
13470
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13434
13471
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13435
13472
  this.processingSchemas.add(schemaName);
@@ -14164,7 +14201,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
14164
14201
  const firstMember = body.body?.[0];
14165
14202
  return firstMember?.leadingComments ?? [];
14166
14203
  }
14167
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14204
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
14168
14205
  function registerDefinition(name, entry, allComments) {
14169
14206
  if (!typeDefinitions[name]) {
14170
14207
  typeDefinitions[name] = entry;
@@ -14176,6 +14213,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
14176
14213
  typeDefinitions[overrideId] = entry;
14177
14214
  }
14178
14215
  }
14216
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
14217
+ internalSchemaNames.add(name);
14218
+ }
14179
14219
  }
14180
14220
  resolvedTraverse(ast, {
14181
14221
  TSTypeAliasDeclaration: (path17) => {
@@ -14655,6 +14695,7 @@ var SchemaProcessor = class {
14655
14695
  schemaTypes;
14656
14696
  isResolvingPickOmitBase = false;
14657
14697
  schemaIdAliases = {};
14698
+ internalSchemaNames = /* @__PURE__ */ new Set();
14658
14699
  fileAccess;
14659
14700
  symbolResolver;
14660
14701
  // Track imports per file for resolving ReturnType<typeof func>
@@ -14695,7 +14736,7 @@ var SchemaProcessor = class {
14695
14736
  getDefinedSchemas() {
14696
14737
  const filteredSchemas = {};
14697
14738
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
14698
- if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
14739
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key) && !this.internalSchemaNames.has(key)) {
14699
14740
  filteredSchemas[key] = value;
14700
14741
  }
14701
14742
  });
@@ -14705,6 +14746,22 @@ var SchemaProcessor = class {
14705
14746
  this.customSchemaProcessor.getDefinedSchemas()
14706
14747
  ]);
14707
14748
  }
14749
+ getInternalSchemas() {
14750
+ const result = {};
14751
+ for (const name of this.internalSchemaNames) {
14752
+ const def = this.openapiDefinitions[name];
14753
+ if (def)
14754
+ result[name] = def;
14755
+ }
14756
+ if (this.zodSchemaConverter) {
14757
+ for (const name of this.zodSchemaConverter.internalSchemaNames) {
14758
+ const schema = this.zodSchemaConverter.zodSchemas[name];
14759
+ if (schema)
14760
+ result[name] = schema;
14761
+ }
14762
+ }
14763
+ return result;
14764
+ }
14708
14765
  findSchemaDefinition(schemaName, contentType) {
14709
14766
  this.contentType = contentType;
14710
14767
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -14855,7 +14912,7 @@ var SchemaProcessor = class {
14855
14912
  * Used when processing imported files to ensure all referenced types are available
14856
14913
  */
14857
14914
  collectAllExportedDefinitions(ast, filePath) {
14858
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
14915
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
14859
14916
  }
14860
14917
  collectTypeDefinitions(ast, schemaName, filePath) {
14861
14918
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -16841,6 +16898,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
16841
16898
  });
16842
16899
  }
16843
16900
 
16901
+ // ../openapi-core/dist/core/exclude-schemas.js
16902
+ function patternToRegExp(pattern) {
16903
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
16904
+ return new RegExp(`^${escaped.replace(/\*/g, ".*")}$`);
16905
+ }
16906
+ function matchExcludePatterns(names, patterns) {
16907
+ if (patterns.length === 0)
16908
+ return [];
16909
+ const regexes = patterns.map(patternToRegExp);
16910
+ return names.filter((name) => regexes.some((re) => re.test(name)));
16911
+ }
16912
+ function applyExcludeSchemas(document, mergedSchemas, excludedSchemas) {
16913
+ const excludedNames = new Set(Object.keys(excludedSchemas));
16914
+ if (excludedNames.size === 0)
16915
+ return;
16916
+ walkAndInline(document, excludedSchemas, excludedNames, /* @__PURE__ */ new Set());
16917
+ for (const name of excludedNames) {
16918
+ delete mergedSchemas[name];
16919
+ }
16920
+ }
16921
+ function walkAndInline(obj, excluded, excludedNames, visiting) {
16922
+ if (!obj || typeof obj !== "object")
16923
+ return;
16924
+ if (Array.isArray(obj)) {
16925
+ for (const item of obj) {
16926
+ walkAndInline(item, excluded, excludedNames, visiting);
16927
+ }
16928
+ return;
16929
+ }
16930
+ const rec = obj;
16931
+ const ref = rec["$ref"];
16932
+ if (typeof ref === "string") {
16933
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
16934
+ const name = match?.[1];
16935
+ if (name && excludedNames.has(name)) {
16936
+ if (visiting.has(name)) {
16937
+ logger.warn(`Circular reference to internal schema "${name}", keeping $ref`);
16938
+ return;
16939
+ }
16940
+ const schemaDef = excluded[name];
16941
+ if (schemaDef) {
16942
+ const cloned = JSON.parse(JSON.stringify(schemaDef));
16943
+ delete rec["$ref"];
16944
+ Object.assign(rec, cloned);
16945
+ const newVisiting = new Set(visiting);
16946
+ newVisiting.add(name);
16947
+ for (const key of Object.keys(rec)) {
16948
+ walkAndInline(rec[key], excluded, excludedNames, newVisiting);
16949
+ }
16950
+ return;
16951
+ }
16952
+ }
16953
+ }
16954
+ for (const key of Object.keys(rec)) {
16955
+ walkAndInline(rec[key], excluded, excludedNames, visiting);
16956
+ }
16957
+ }
16958
+
16844
16959
  // ../openapi-core/dist/core/orchestrator.js
16845
16960
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
16846
16961
  const diagnostics = new DiagnosticsCollector();
@@ -16911,11 +17026,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
16911
17026
  }
16912
17027
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
16913
17028
  phaseStartedAt = performance.now();
16914
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
17029
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
17030
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
16915
17031
  const mergedSchemas = {
16916
17032
  ...document.components.schemas,
16917
17033
  ...definedSchemas
16918
17034
  };
17035
+ const internalSchemas = schemaProcessor.getInternalSchemas();
17036
+ const patternExcludedNames = matchExcludePatterns(Object.keys(mergedSchemas), config2.excludeSchemas ?? []);
17037
+ const allExcludedSchemas = {
17038
+ ...internalSchemas,
17039
+ ...Object.fromEntries(patternExcludedNames.map((name) => [name, mergedSchemas[name]]))
17040
+ };
17041
+ if (Object.keys(allExcludedSchemas).length > 0) {
17042
+ applyExcludeSchemas(document, mergedSchemas, allExcludedSchemas);
17043
+ }
16919
17044
  if (Object.keys(mergedSchemas).length > 0) {
16920
17045
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
16921
17046
  }
@@ -756,6 +756,17 @@ function mergeJSDocData(target, source) {
756
756
  function cleanComment(commentValue) {
757
757
  return commentValue.replace(/\*\s*/g, "").trim();
758
758
  }
759
+ function extractInternalFlagFromComments(comments) {
760
+ if (!comments)
761
+ return false;
762
+ for (const comment of comments) {
763
+ const cleaned = cleanComment(comment.value);
764
+ if (/@internal\b/.test(cleaned) || /@schema\s+false\b/.test(cleaned)) {
765
+ return true;
766
+ }
767
+ }
768
+ return false;
769
+ }
759
770
  function extractSchemaIdFromComments(comments) {
760
771
  if (!comments)
761
772
  return null;
@@ -1052,7 +1063,8 @@ var INTERNAL_OPENAPI_CONFIG_KEYS = [
1052
1063
  "framework",
1053
1064
  "next",
1054
1065
  "diagnostics",
1055
- "debug"
1066
+ "debug",
1067
+ "excludeSchemas"
1056
1068
  ];
1057
1069
  var AUTH_PRESET_REPLACEMENTS = {
1058
1070
  bearer: "BearerAuth",
@@ -1320,6 +1332,7 @@ function normalizeOpenApiConfig(template) {
1320
1332
  outputDir: template.outputDir ?? DEFAULT_OUTPUT_DIR,
1321
1333
  includeOpenApiRoutes: template.includeOpenApiRoutes ?? DEFAULT_INCLUDE_OPENAPI_ROUTES,
1322
1334
  ignoreRoutes: template.ignoreRoutes ?? [],
1335
+ excludeSchemas: template.excludeSchemas ?? [],
1323
1336
  schemaType: template.schemaType ?? DEFAULT_RUNTIME_SCHEMA_TYPE,
1324
1337
  schemaBackends,
1325
1338
  schemaFiles: template.schemaFiles ?? [],
@@ -11732,6 +11745,8 @@ var ZodSchemaConverter = class {
11732
11745
  /** Schema variable names whose component name was overridden via .meta({ id }). These must
11733
11746
  * NOT be copied back under the original variable name in the OpenAPI components object. */
11734
11747
  metaIdSchemaNames = /* @__PURE__ */ new Set();
11748
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
11749
+ internalSchemaNames = /* @__PURE__ */ new Set();
11735
11750
  // Current processing context (set during file processing)
11736
11751
  currentFilePath;
11737
11752
  currentAST;
@@ -13353,7 +13368,13 @@ var ZodSchemaConverter = class {
13353
13368
  * Get all processed Zod schemas
13354
13369
  */
13355
13370
  getProcessedSchemas() {
13356
- return this.zodSchemas;
13371
+ const result = {};
13372
+ for (const [name, schema] of Object.entries(this.zodSchemas)) {
13373
+ if (!this.internalSchemaNames.has(name)) {
13374
+ result[name] = schema;
13375
+ }
13376
+ }
13377
+ return result;
13357
13378
  }
13358
13379
  /**
13359
13380
  * Pre-scan all files to build type mappings
@@ -13405,6 +13426,15 @@ var ZodSchemaConverter = class {
13405
13426
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13406
13427
  const schemaName = declaration.id.name;
13407
13428
  if (this.isZodSchema(declaration.init)) {
13429
+ const decl = path17.node.declaration;
13430
+ const allComments = [
13431
+ ...path17.node.leadingComments ?? [],
13432
+ ...decl?.leadingComments ?? [],
13433
+ ...declaration.leadingComments ?? []
13434
+ ];
13435
+ if (extractInternalFlagFromComments(allComments)) {
13436
+ this.internalSchemaNames.add(schemaName);
13437
+ }
13408
13438
  if (!this.getStoredSchema(schemaName)) {
13409
13439
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13410
13440
  this.processingSchemas.add(schemaName);
@@ -13430,6 +13460,13 @@ var ZodSchemaConverter = class {
13430
13460
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13431
13461
  const schemaName = declaration.id.name;
13432
13462
  if (this.isZodSchema(declaration.init)) {
13463
+ const allComments = [
13464
+ ...path17.node.leadingComments ?? [],
13465
+ ...declaration.leadingComments ?? []
13466
+ ];
13467
+ if (extractInternalFlagFromComments(allComments)) {
13468
+ this.internalSchemaNames.add(schemaName);
13469
+ }
13433
13470
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13434
13471
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13435
13472
  this.processingSchemas.add(schemaName);
@@ -14164,7 +14201,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
14164
14201
  const firstMember = body.body?.[0];
14165
14202
  return firstMember?.leadingComments ?? [];
14166
14203
  }
14167
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14204
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
14168
14205
  function registerDefinition(name, entry, allComments) {
14169
14206
  if (!typeDefinitions[name]) {
14170
14207
  typeDefinitions[name] = entry;
@@ -14176,6 +14213,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
14176
14213
  typeDefinitions[overrideId] = entry;
14177
14214
  }
14178
14215
  }
14216
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
14217
+ internalSchemaNames.add(name);
14218
+ }
14179
14219
  }
14180
14220
  resolvedTraverse(ast, {
14181
14221
  TSTypeAliasDeclaration: (path17) => {
@@ -14655,6 +14695,7 @@ var SchemaProcessor = class {
14655
14695
  schemaTypes;
14656
14696
  isResolvingPickOmitBase = false;
14657
14697
  schemaIdAliases = {};
14698
+ internalSchemaNames = /* @__PURE__ */ new Set();
14658
14699
  fileAccess;
14659
14700
  symbolResolver;
14660
14701
  // Track imports per file for resolving ReturnType<typeof func>
@@ -14695,7 +14736,7 @@ var SchemaProcessor = class {
14695
14736
  getDefinedSchemas() {
14696
14737
  const filteredSchemas = {};
14697
14738
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
14698
- if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
14739
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key) && !this.internalSchemaNames.has(key)) {
14699
14740
  filteredSchemas[key] = value;
14700
14741
  }
14701
14742
  });
@@ -14705,6 +14746,22 @@ var SchemaProcessor = class {
14705
14746
  this.customSchemaProcessor.getDefinedSchemas()
14706
14747
  ]);
14707
14748
  }
14749
+ getInternalSchemas() {
14750
+ const result = {};
14751
+ for (const name of this.internalSchemaNames) {
14752
+ const def = this.openapiDefinitions[name];
14753
+ if (def)
14754
+ result[name] = def;
14755
+ }
14756
+ if (this.zodSchemaConverter) {
14757
+ for (const name of this.zodSchemaConverter.internalSchemaNames) {
14758
+ const schema = this.zodSchemaConverter.zodSchemas[name];
14759
+ if (schema)
14760
+ result[name] = schema;
14761
+ }
14762
+ }
14763
+ return result;
14764
+ }
14708
14765
  findSchemaDefinition(schemaName, contentType) {
14709
14766
  this.contentType = contentType;
14710
14767
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -14855,7 +14912,7 @@ var SchemaProcessor = class {
14855
14912
  * Used when processing imported files to ensure all referenced types are available
14856
14913
  */
14857
14914
  collectAllExportedDefinitions(ast, filePath) {
14858
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
14915
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
14859
14916
  }
14860
14917
  collectTypeDefinitions(ast, schemaName, filePath) {
14861
14918
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -16841,6 +16898,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
16841
16898
  });
16842
16899
  }
16843
16900
 
16901
+ // ../openapi-core/dist/core/exclude-schemas.js
16902
+ function patternToRegExp(pattern) {
16903
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
16904
+ return new RegExp(`^${escaped.replace(/\*/g, ".*")}$`);
16905
+ }
16906
+ function matchExcludePatterns(names, patterns) {
16907
+ if (patterns.length === 0)
16908
+ return [];
16909
+ const regexes = patterns.map(patternToRegExp);
16910
+ return names.filter((name) => regexes.some((re) => re.test(name)));
16911
+ }
16912
+ function applyExcludeSchemas(document, mergedSchemas, excludedSchemas) {
16913
+ const excludedNames = new Set(Object.keys(excludedSchemas));
16914
+ if (excludedNames.size === 0)
16915
+ return;
16916
+ walkAndInline(document, excludedSchemas, excludedNames, /* @__PURE__ */ new Set());
16917
+ for (const name of excludedNames) {
16918
+ delete mergedSchemas[name];
16919
+ }
16920
+ }
16921
+ function walkAndInline(obj, excluded, excludedNames, visiting) {
16922
+ if (!obj || typeof obj !== "object")
16923
+ return;
16924
+ if (Array.isArray(obj)) {
16925
+ for (const item of obj) {
16926
+ walkAndInline(item, excluded, excludedNames, visiting);
16927
+ }
16928
+ return;
16929
+ }
16930
+ const rec = obj;
16931
+ const ref = rec["$ref"];
16932
+ if (typeof ref === "string") {
16933
+ const match = ref.match(/^#\/components\/schemas\/(.+)$/);
16934
+ const name = match?.[1];
16935
+ if (name && excludedNames.has(name)) {
16936
+ if (visiting.has(name)) {
16937
+ logger.warn(`Circular reference to internal schema "${name}", keeping $ref`);
16938
+ return;
16939
+ }
16940
+ const schemaDef = excluded[name];
16941
+ if (schemaDef) {
16942
+ const cloned = JSON.parse(JSON.stringify(schemaDef));
16943
+ delete rec["$ref"];
16944
+ Object.assign(rec, cloned);
16945
+ const newVisiting = new Set(visiting);
16946
+ newVisiting.add(name);
16947
+ for (const key of Object.keys(rec)) {
16948
+ walkAndInline(rec[key], excluded, excludedNames, newVisiting);
16949
+ }
16950
+ return;
16951
+ }
16952
+ }
16953
+ }
16954
+ for (const key of Object.keys(rec)) {
16955
+ walkAndInline(rec[key], excluded, excludedNames, visiting);
16956
+ }
16957
+ }
16958
+
16844
16959
  // ../openapi-core/dist/core/orchestrator.js
16845
16960
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
16846
16961
  const diagnostics = new DiagnosticsCollector();
@@ -16911,11 +17026,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
16911
17026
  }
16912
17027
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
16913
17028
  phaseStartedAt = performance.now();
16914
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
17029
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
17030
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
16915
17031
  const mergedSchemas = {
16916
17032
  ...document.components.schemas,
16917
17033
  ...definedSchemas
16918
17034
  };
17035
+ const internalSchemas = schemaProcessor.getInternalSchemas();
17036
+ const patternExcludedNames = matchExcludePatterns(Object.keys(mergedSchemas), config2.excludeSchemas ?? []);
17037
+ const allExcludedSchemas = {
17038
+ ...internalSchemas,
17039
+ ...Object.fromEntries(patternExcludedNames.map((name) => [name, mergedSchemas[name]]))
17040
+ };
17041
+ if (Object.keys(allExcludedSchemas).length > 0) {
17042
+ applyExcludeSchemas(document, mergedSchemas, allExcludedSchemas);
17043
+ }
16919
17044
  if (Object.keys(mergedSchemas).length > 0) {
16920
17045
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
16921
17046
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
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",