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/README.md +22 -21
- package/dist/cli.js +187 -10
- package/dist/index.js +187 -10
- package/dist/next/index.js +187 -10
- package/dist/react-router/index.js +187 -10
- package/dist/vite/index.js +187 -10
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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
|
}
|
package/dist/next/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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
|
}
|