next-openapi-gen 1.2.2 → 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/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",
@@ -11691,6 +11704,11 @@ var ZodSchemaConverter = class {
11691
11704
  schemaNameToFiles = /* @__PURE__ */ new Map();
11692
11705
  /** Per-file import alias for the `zod` module (`import { z as zod }` sets this to `"zod"`). */
11693
11706
  zodImportAlias = /* @__PURE__ */ new Map();
11707
+ /** Schema variable names whose component name was overridden via .meta({ id }). These must
11708
+ * NOT be copied back under the original variable name in the OpenAPI components object. */
11709
+ metaIdSchemaNames = /* @__PURE__ */ new Set();
11710
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
11711
+ internalSchemaNames = /* @__PURE__ */ new Set();
11694
11712
  // Current processing context (set during file processing)
11695
11713
  currentFilePath;
11696
11714
  currentAST;
@@ -11717,7 +11735,14 @@ var ZodSchemaConverter = class {
11717
11735
  }
11718
11736
  logger.debug(`Looking for Zod schema: ${schemaName}`);
11719
11737
  const requestedSchemaName = schemaName;
11720
- const mappedSchemaName = this.typeToSchemaMapping[schemaName];
11738
+ let mappedSchemaName = this.typeToSchemaMapping[schemaName];
11739
+ if (!mappedSchemaName) {
11740
+ const candidate = this.deriveSchemaNameByConvention(schemaName);
11741
+ if (candidate && this.locateSchemaByConvention(candidate)) {
11742
+ this.typeToSchemaMapping[schemaName] = candidate;
11743
+ mappedSchemaName = candidate;
11744
+ }
11745
+ }
11721
11746
  if (mappedSchemaName) {
11722
11747
  logger.debug(`Type '${schemaName}' is mapped to schema '${mappedSchemaName}'`);
11723
11748
  schemaName = mappedSchemaName;
@@ -11767,7 +11792,7 @@ var ZodSchemaConverter = class {
11767
11792
  this.processingSchemas.delete(schemaName);
11768
11793
  if (mappedSchemaName && requestedSchemaName !== schemaName) {
11769
11794
  const resolvedReference = this.getSchemaReferenceName(schemaName, this.currentContentType);
11770
- if (this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
11795
+ if (!this.metaIdSchemaNames.has(requestedSchemaName) && this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
11771
11796
  this.zodSchemas[requestedSchemaName] = this.zodSchemas[resolvedReference];
11772
11797
  }
11773
11798
  this.schemaVariantRefs.set(this.getVariantKey(requestedSchemaName, this.currentContentType), this.zodSchemas[requestedSchemaName] ? requestedSchemaName : resolvedReference);
@@ -13305,7 +13330,13 @@ var ZodSchemaConverter = class {
13305
13330
  * Get all processed Zod schemas
13306
13331
  */
13307
13332
  getProcessedSchemas() {
13308
- 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;
13309
13340
  }
13310
13341
  /**
13311
13342
  * Pre-scan all files to build type mappings
@@ -13357,6 +13388,15 @@ var ZodSchemaConverter = class {
13357
13388
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13358
13389
  const schemaName = declaration.id.name;
13359
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
+ }
13360
13400
  if (!this.getStoredSchema(schemaName)) {
13361
13401
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13362
13402
  this.processingSchemas.add(schemaName);
@@ -13382,6 +13422,13 @@ var ZodSchemaConverter = class {
13382
13422
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13383
13423
  const schemaName = declaration.id.name;
13384
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
+ }
13385
13432
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13386
13433
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13387
13434
  this.processingSchemas.add(schemaName);
@@ -13424,15 +13471,57 @@ var ZodSchemaConverter = class {
13424
13471
  if (finalName !== schemaName) {
13425
13472
  this.indexSchemaName(finalName, filePath);
13426
13473
  }
13427
- if (!this.getStoredSchema(finalName)) {
13474
+ if (!this.zodSchemas[finalName]) {
13428
13475
  if (overrideId && overrideId !== schemaName) {
13429
13476
  this.typeToSchemaMapping[schemaName] = overrideId;
13477
+ this.metaIdSchemaNames.add(schemaName);
13478
+ if (this.typeToSchemaMapping[overrideId] === schemaName) {
13479
+ delete this.typeToSchemaMapping[overrideId];
13480
+ }
13430
13481
  }
13431
- this.storeResolvedSchema(finalName, schema);
13482
+ const variantKey = this.getVariantKey(finalName, this.currentContentType);
13483
+ this.zodSchemas[finalName] = schema;
13484
+ this.schemaVariantRefs.set(variantKey, finalName);
13432
13485
  } else {
13433
13486
  logger.warn(`Schema component name '${overrideId ?? finalName}' conflicts with an existing schema, ignoring .meta({ id }) on '${schemaName}'`);
13434
13487
  }
13435
13488
  }
13489
+ /**
13490
+ * Derives the conventional Zod schema name from a TypeScript type name.
13491
+ * e.g. "Slider" → "sliderSchema", "SliderItem" → "sliderItemSchema".
13492
+ * Returns null when the input is already a schema name or is not PascalCase.
13493
+ */
13494
+ deriveSchemaNameByConvention(typeName) {
13495
+ if (!typeName || !/^[A-Z]/.test(typeName) || typeName.endsWith("Schema")) {
13496
+ return null;
13497
+ }
13498
+ return typeName[0].toLowerCase() + typeName.slice(1) + "Schema";
13499
+ }
13500
+ /**
13501
+ * Checks whether a Zod schema with the given name is present in schemaDirs
13502
+ * WITHOUT populating the processed-schema cache. A file-content substring check
13503
+ * (the same heuristic used by processFileForZodSchema) is sufficient here: we
13504
+ * only want to know whether the candidate *might* live in schemaDirs so that the
13505
+ * convention mapping can be registered; the actual processing happens later in
13506
+ * the normal convertZodSchemaToOpenApi lookup flow.
13507
+ */
13508
+ locateSchemaByConvention(candidate) {
13509
+ if (this.schemaNameToFiles.has(candidate)) {
13510
+ return true;
13511
+ }
13512
+ for (const dir of this.schemaDirs) {
13513
+ for (const filePath of this.getSchemaFiles(dir)) {
13514
+ try {
13515
+ const content = this.fileAccess.readFileSync(filePath, "utf-8");
13516
+ if (content.includes(candidate)) {
13517
+ return true;
13518
+ }
13519
+ } catch {
13520
+ }
13521
+ }
13522
+ }
13523
+ return false;
13524
+ }
13436
13525
  /**
13437
13526
  * Check if node is Zod schema
13438
13527
  */
@@ -14074,7 +14163,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
14074
14163
  const firstMember = body.body?.[0];
14075
14164
  return firstMember?.leadingComments ?? [];
14076
14165
  }
14077
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14166
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
14078
14167
  function registerDefinition(name, entry, allComments) {
14079
14168
  if (!typeDefinitions[name]) {
14080
14169
  typeDefinitions[name] = entry;
@@ -14086,6 +14175,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
14086
14175
  typeDefinitions[overrideId] = entry;
14087
14176
  }
14088
14177
  }
14178
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
14179
+ internalSchemaNames.add(name);
14180
+ }
14089
14181
  }
14090
14182
  resolvedTraverse(ast, {
14091
14183
  TSTypeAliasDeclaration: (path25) => {
@@ -14565,6 +14657,7 @@ var SchemaProcessor = class {
14565
14657
  schemaTypes;
14566
14658
  isResolvingPickOmitBase = false;
14567
14659
  schemaIdAliases = {};
14660
+ internalSchemaNames = /* @__PURE__ */ new Set();
14568
14661
  fileAccess;
14569
14662
  symbolResolver;
14570
14663
  // Track imports per file for resolving ReturnType<typeof func>
@@ -14605,7 +14698,7 @@ var SchemaProcessor = class {
14605
14698
  getDefinedSchemas() {
14606
14699
  const filteredSchemas = {};
14607
14700
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
14608
- 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)) {
14609
14702
  filteredSchemas[key] = value;
14610
14703
  }
14611
14704
  });
@@ -14615,6 +14708,22 @@ var SchemaProcessor = class {
14615
14708
  this.customSchemaProcessor.getDefinedSchemas()
14616
14709
  ]);
14617
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
+ }
14618
14727
  findSchemaDefinition(schemaName, contentType) {
14619
14728
  this.contentType = contentType;
14620
14729
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -14765,7 +14874,7 @@ var SchemaProcessor = class {
14765
14874
  * Used when processing imported files to ensure all referenced types are available
14766
14875
  */
14767
14876
  collectAllExportedDefinitions(ast, filePath) {
14768
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
14877
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
14769
14878
  }
14770
14879
  collectTypeDefinitions(ast, schemaName, filePath) {
14771
14880
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -16751,6 +16860,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
16751
16860
  });
16752
16861
  }
16753
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
+
16754
16921
  // ../openapi-core/dist/core/orchestrator.js
16755
16922
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
16756
16923
  const diagnostics = new DiagnosticsCollector();
@@ -16821,11 +16988,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
16821
16988
  }
16822
16989
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
16823
16990
  phaseStartedAt = performance.now();
16824
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
16991
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
16992
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
16825
16993
  const mergedSchemas = {
16826
16994
  ...document.components.schemas,
16827
16995
  ...definedSchemas
16828
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
+ }
16829
17006
  if (Object.keys(mergedSchemas).length > 0) {
16830
17007
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
16831
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 ?? [],
@@ -12725,6 +12738,11 @@ var ZodSchemaConverter = class {
12725
12738
  schemaNameToFiles = /* @__PURE__ */ new Map();
12726
12739
  /** Per-file import alias for the `zod` module (`import { z as zod }` sets this to `"zod"`). */
12727
12740
  zodImportAlias = /* @__PURE__ */ new Map();
12741
+ /** Schema variable names whose component name was overridden via .meta({ id }). These must
12742
+ * NOT be copied back under the original variable name in the OpenAPI components object. */
12743
+ metaIdSchemaNames = /* @__PURE__ */ new Set();
12744
+ /** Schema variable names marked @internal — excluded from components/schemas output. */
12745
+ internalSchemaNames = /* @__PURE__ */ new Set();
12728
12746
  // Current processing context (set during file processing)
12729
12747
  currentFilePath;
12730
12748
  currentAST;
@@ -12751,7 +12769,14 @@ var ZodSchemaConverter = class {
12751
12769
  }
12752
12770
  logger.debug(`Looking for Zod schema: ${schemaName}`);
12753
12771
  const requestedSchemaName = schemaName;
12754
- const mappedSchemaName = this.typeToSchemaMapping[schemaName];
12772
+ let mappedSchemaName = this.typeToSchemaMapping[schemaName];
12773
+ if (!mappedSchemaName) {
12774
+ const candidate = this.deriveSchemaNameByConvention(schemaName);
12775
+ if (candidate && this.locateSchemaByConvention(candidate)) {
12776
+ this.typeToSchemaMapping[schemaName] = candidate;
12777
+ mappedSchemaName = candidate;
12778
+ }
12779
+ }
12755
12780
  if (mappedSchemaName) {
12756
12781
  logger.debug(`Type '${schemaName}' is mapped to schema '${mappedSchemaName}'`);
12757
12782
  schemaName = mappedSchemaName;
@@ -12801,7 +12826,7 @@ var ZodSchemaConverter = class {
12801
12826
  this.processingSchemas.delete(schemaName);
12802
12827
  if (mappedSchemaName && requestedSchemaName !== schemaName) {
12803
12828
  const resolvedReference = this.getSchemaReferenceName(schemaName, this.currentContentType);
12804
- if (this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
12829
+ if (!this.metaIdSchemaNames.has(requestedSchemaName) && this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
12805
12830
  this.zodSchemas[requestedSchemaName] = this.zodSchemas[resolvedReference];
12806
12831
  }
12807
12832
  this.schemaVariantRefs.set(this.getVariantKey(requestedSchemaName, this.currentContentType), this.zodSchemas[requestedSchemaName] ? requestedSchemaName : resolvedReference);
@@ -14339,7 +14364,13 @@ var ZodSchemaConverter = class {
14339
14364
  * Get all processed Zod schemas
14340
14365
  */
14341
14366
  getProcessedSchemas() {
14342
- 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;
14343
14374
  }
14344
14375
  /**
14345
14376
  * Pre-scan all files to build type mappings
@@ -14391,6 +14422,15 @@ var ZodSchemaConverter = class {
14391
14422
  if (t11.isIdentifier(declaration.id) && declaration.init) {
14392
14423
  const schemaName = declaration.id.name;
14393
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
+ }
14394
14434
  if (!this.getStoredSchema(schemaName)) {
14395
14435
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
14396
14436
  this.processingSchemas.add(schemaName);
@@ -14416,6 +14456,13 @@ var ZodSchemaConverter = class {
14416
14456
  if (t11.isIdentifier(declaration.id) && declaration.init) {
14417
14457
  const schemaName = declaration.id.name;
14418
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
+ }
14419
14466
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
14420
14467
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
14421
14468
  this.processingSchemas.add(schemaName);
@@ -14458,15 +14505,57 @@ var ZodSchemaConverter = class {
14458
14505
  if (finalName !== schemaName) {
14459
14506
  this.indexSchemaName(finalName, filePath);
14460
14507
  }
14461
- if (!this.getStoredSchema(finalName)) {
14508
+ if (!this.zodSchemas[finalName]) {
14462
14509
  if (overrideId && overrideId !== schemaName) {
14463
14510
  this.typeToSchemaMapping[schemaName] = overrideId;
14511
+ this.metaIdSchemaNames.add(schemaName);
14512
+ if (this.typeToSchemaMapping[overrideId] === schemaName) {
14513
+ delete this.typeToSchemaMapping[overrideId];
14514
+ }
14464
14515
  }
14465
- this.storeResolvedSchema(finalName, schema);
14516
+ const variantKey = this.getVariantKey(finalName, this.currentContentType);
14517
+ this.zodSchemas[finalName] = schema;
14518
+ this.schemaVariantRefs.set(variantKey, finalName);
14466
14519
  } else {
14467
14520
  logger.warn(`Schema component name '${overrideId ?? finalName}' conflicts with an existing schema, ignoring .meta({ id }) on '${schemaName}'`);
14468
14521
  }
14469
14522
  }
14523
+ /**
14524
+ * Derives the conventional Zod schema name from a TypeScript type name.
14525
+ * e.g. "Slider" → "sliderSchema", "SliderItem" → "sliderItemSchema".
14526
+ * Returns null when the input is already a schema name or is not PascalCase.
14527
+ */
14528
+ deriveSchemaNameByConvention(typeName) {
14529
+ if (!typeName || !/^[A-Z]/.test(typeName) || typeName.endsWith("Schema")) {
14530
+ return null;
14531
+ }
14532
+ return typeName[0].toLowerCase() + typeName.slice(1) + "Schema";
14533
+ }
14534
+ /**
14535
+ * Checks whether a Zod schema with the given name is present in schemaDirs
14536
+ * WITHOUT populating the processed-schema cache. A file-content substring check
14537
+ * (the same heuristic used by processFileForZodSchema) is sufficient here: we
14538
+ * only want to know whether the candidate *might* live in schemaDirs so that the
14539
+ * convention mapping can be registered; the actual processing happens later in
14540
+ * the normal convertZodSchemaToOpenApi lookup flow.
14541
+ */
14542
+ locateSchemaByConvention(candidate) {
14543
+ if (this.schemaNameToFiles.has(candidate)) {
14544
+ return true;
14545
+ }
14546
+ for (const dir of this.schemaDirs) {
14547
+ for (const filePath of this.getSchemaFiles(dir)) {
14548
+ try {
14549
+ const content = this.fileAccess.readFileSync(filePath, "utf-8");
14550
+ if (content.includes(candidate)) {
14551
+ return true;
14552
+ }
14553
+ } catch {
14554
+ }
14555
+ }
14556
+ }
14557
+ return false;
14558
+ }
14470
14559
  /**
14471
14560
  * Check if node is Zod schema
14472
14561
  */
@@ -15108,7 +15197,7 @@ function collectFirstMemberLeadingComments(interfaceDecl) {
15108
15197
  const firstMember = body.body?.[0];
15109
15198
  return firstMember?.leadingComments ?? [];
15110
15199
  }
15111
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
15200
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases, internalSchemaNames) {
15112
15201
  function registerDefinition(name, entry, allComments) {
15113
15202
  if (!typeDefinitions[name]) {
15114
15203
  typeDefinitions[name] = entry;
@@ -15120,6 +15209,9 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schema
15120
15209
  typeDefinitions[overrideId] = entry;
15121
15210
  }
15122
15211
  }
15212
+ if (internalSchemaNames && extractInternalFlagFromComments(allComments)) {
15213
+ internalSchemaNames.add(name);
15214
+ }
15123
15215
  }
15124
15216
  resolvedTraverse(ast, {
15125
15217
  TSTypeAliasDeclaration: (path19) => {
@@ -15599,6 +15691,7 @@ var SchemaProcessor = class {
15599
15691
  schemaTypes;
15600
15692
  isResolvingPickOmitBase = false;
15601
15693
  schemaIdAliases = {};
15694
+ internalSchemaNames = /* @__PURE__ */ new Set();
15602
15695
  fileAccess;
15603
15696
  symbolResolver;
15604
15697
  // Track imports per file for resolving ReturnType<typeof func>
@@ -15639,7 +15732,7 @@ var SchemaProcessor = class {
15639
15732
  getDefinedSchemas() {
15640
15733
  const filteredSchemas = {};
15641
15734
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
15642
- 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)) {
15643
15736
  filteredSchemas[key] = value;
15644
15737
  }
15645
15738
  });
@@ -15649,6 +15742,22 @@ var SchemaProcessor = class {
15649
15742
  this.customSchemaProcessor.getDefinedSchemas()
15650
15743
  ]);
15651
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
+ }
15652
15761
  findSchemaDefinition(schemaName, contentType) {
15653
15762
  this.contentType = contentType;
15654
15763
  if (schemaName.includes("<") && schemaName.includes(">")) {
@@ -15799,7 +15908,7 @@ var SchemaProcessor = class {
15799
15908
  * Used when processing imported files to ensure all referenced types are available
15800
15909
  */
15801
15910
  collectAllExportedDefinitions(ast, filePath) {
15802
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
15911
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases, this.internalSchemaNames);
15803
15912
  }
15804
15913
  collectTypeDefinitions(ast, schemaName, filePath) {
15805
15914
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -17785,6 +17894,64 @@ function generateErrorResponsesFromConfig(document, errorConfig) {
17785
17894
  });
17786
17895
  }
17787
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
+
17788
17955
  // ../openapi-core/dist/core/orchestrator.js
17789
17956
  function runGenerationOrchestrator({ config: config2, template, hooks, runtime, createFrameworkSource }) {
17790
17957
  const diagnostics = new DiagnosticsCollector();
@@ -17855,11 +18022,21 @@ function runGenerationOrchestrator({ config: config2, template, hooks, runtime,
17855
18022
  }
17856
18023
  profile.defaultComponentsAndErrorsMs = performance.now() - phaseStartedAt;
17857
18024
  phaseStartedAt = performance.now();
17858
- const definedSchemas = routeProcessor.getSchemaProcessor().getDefinedSchemas();
18025
+ const schemaProcessor = routeProcessor.getSchemaProcessor();
18026
+ const definedSchemas = schemaProcessor.getDefinedSchemas();
17859
18027
  const mergedSchemas = {
17860
18028
  ...document.components.schemas,
17861
18029
  ...definedSchemas
17862
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
+ }
17863
18040
  if (Object.keys(mergedSchemas).length > 0) {
17864
18041
  document.components.schemas = Object.fromEntries(Object.entries(mergedSchemas).sort(([a], [b]) => a.localeCompare(b, "en", { sensitivity: "base" })));
17865
18042
  }