orval 8.18.0 → 8.19.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/bin/orval.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { c as description, i as startWatcher, l as name, n as loadConfigFile, r as generateSpec, s as normalizeOptions, t as findConfigFile, u as version } from "../config-
|
|
2
|
+
import { c as description, i as startWatcher, l as name, n as loadConfigFile, r as generateSpec, s as normalizeOptions, t as findConfigFile, u as version } from "../config-D-TQRn-G.mjs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { Option, program } from "@commander-js/extra-typings";
|
|
5
5
|
import { ErrorWithTag, OutputClient, OutputMode, SupportedFormatter, getWarningCount, isString, log, logError, resetWarnings, setVerbose, startMessage } from "@orval/core";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SupportedFormatter, asyncReduce, buildDynamicScope, collectReferencedComponents, conventionName, createSuccessMessage, dynamicImport, fixCrossDirectoryImports, fixRegularSchemaImports, generateComponentDefinition, generateDependencyImports, generateMutator, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getBaseUrlRuntimeImports, getFileInfo, getFullRoute, getImportExtension, getMockFileExtensionByTypeName, getRefInfo, getRoute, isBoolean, isComponentRef, isFunction, isNullish, isObject, isReference, isString, isUrl, jsDoc, log, logError, logVerbose, logWarning, pascal, removeFilesAndEmptyFolders, resolveInstalledVersions, resolveRef, resolveValue, splitSchemasByType, upath, writeGeneratedFile, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode } from "@orval/core";
|
|
2
|
+
import { DefaultTag, FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SupportedFormatter, asyncReduce, buildDynamicScope, buildSchemaTagMap, collectReferencedComponents, conventionName, createSuccessMessage, dynamicImport, fixCrossDirectoryImports, fixRegularSchemaImports, generateComponentDefinition, generateDependencyImports, generateMutator, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getBaseUrlRuntimeImports, getFileInfo, getFullRoute, getImportExtension, getMockFileExtensionByTypeName, getRefInfo, getRoute, isBoolean, isComponentRef, isFunction, isNullish, isObject, isReference, isString, isUrl, jsDoc, kebab, log, logError, logVerbose, logWarning, pascal, removeFilesAndEmptyFolders, resolveInstalledVersions, resolveRef, resolveValue, splitSchemasByType, upath, writeGeneratedFile, writeSchemas, writeSchemasTagsSplit, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode } from "@orval/core";
|
|
3
3
|
import { bundle } from "@scalar/json-magic/bundle";
|
|
4
4
|
import { fetchUrls, parseJson, parseYaml, readFiles } from "@scalar/json-magic/bundle/plugins/node";
|
|
5
5
|
import { upgrade, validate } from "@scalar/openapi-parser";
|
|
@@ -15,7 +15,7 @@ import mcp from "@orval/mcp";
|
|
|
15
15
|
import query from "@orval/query";
|
|
16
16
|
import solidStart from "@orval/solid-start";
|
|
17
17
|
import swr from "@orval/swr";
|
|
18
|
-
import zod, { dereference, generateFormDataZodSchema, generateZodValidationSchemaDefinition,
|
|
18
|
+
import zod, { dereference, generateFormDataZodSchema, generateZodValidationSchemaDefinition, parseZodValidationSchemaDefinition, resolveIsZodV4 } from "@orval/zod";
|
|
19
19
|
import { ExecaError, execa } from "execa";
|
|
20
20
|
import fs from "fs-extra";
|
|
21
21
|
import fs$1, { access } from "node:fs/promises";
|
|
@@ -28,7 +28,7 @@ import fs$2 from "node:fs";
|
|
|
28
28
|
import { createJiti } from "jiti";
|
|
29
29
|
//#region package.json
|
|
30
30
|
var name = "orval";
|
|
31
|
-
var version = "8.
|
|
31
|
+
var version = "8.19.0";
|
|
32
32
|
var description = "A swagger client generator for typescript";
|
|
33
33
|
//#endregion
|
|
34
34
|
//#region src/client.ts
|
|
@@ -77,21 +77,24 @@ const generateClientImports = ({ client, implementation, imports, projectName, h
|
|
|
77
77
|
};
|
|
78
78
|
const generateClientHeader = ({ outputClient = DEFAULT_CLIENT, isRequestOptions, isGlobalMutator, isMutator, provideIn, hasAwaitedType, titles, output, verbOptions, tag, isDefaultTagBucket, clientImplementation }) => {
|
|
79
79
|
const { header } = getGeneratorClient(outputClient, output);
|
|
80
|
+
const rawHeader = header ? header({
|
|
81
|
+
title: titles.implementation,
|
|
82
|
+
isRequestOptions,
|
|
83
|
+
isGlobalMutator,
|
|
84
|
+
isMutator,
|
|
85
|
+
provideIn,
|
|
86
|
+
hasAwaitedType,
|
|
87
|
+
output,
|
|
88
|
+
verbOptions,
|
|
89
|
+
tag,
|
|
90
|
+
isDefaultTagBucket,
|
|
91
|
+
clientImplementation
|
|
92
|
+
}) : "";
|
|
93
|
+
const normalizedHeader = typeof rawHeader === "string" ? { implementation: rawHeader } : rawHeader;
|
|
80
94
|
return {
|
|
81
|
-
implementation:
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
isGlobalMutator,
|
|
85
|
-
isMutator,
|
|
86
|
-
provideIn,
|
|
87
|
-
hasAwaitedType,
|
|
88
|
-
output,
|
|
89
|
-
verbOptions,
|
|
90
|
-
tag,
|
|
91
|
-
isDefaultTagBucket,
|
|
92
|
-
clientImplementation
|
|
93
|
-
}) : "",
|
|
94
|
-
implementationMock: `export const ${titles.implementationMock} = () => [\n`
|
|
95
|
+
implementation: normalizedHeader.implementation,
|
|
96
|
+
implementationMock: `export const ${titles.implementationMock} = () => [\n`,
|
|
97
|
+
sharedTypes: normalizedHeader.sharedTypes
|
|
95
98
|
};
|
|
96
99
|
};
|
|
97
100
|
const generateClientFooter = ({ outputClient, operationNames, hasMutator, hasAwaitedType, titles, output }) => {
|
|
@@ -888,7 +891,8 @@ function normalizeSchemasOption(schemas, workspace) {
|
|
|
888
891
|
return {
|
|
889
892
|
path: normalizePath(schemas.path, workspace),
|
|
890
893
|
type: schemas.type ?? "typescript",
|
|
891
|
-
importPath: schemas.importPath
|
|
894
|
+
importPath: schemas.importPath,
|
|
895
|
+
splitByTags: schemas.splitByTags ?? false
|
|
892
896
|
};
|
|
893
897
|
}
|
|
894
898
|
/**
|
|
@@ -1017,6 +1021,8 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
|
|
|
1017
1021
|
baseUrl: outputOptions.baseUrl,
|
|
1018
1022
|
unionAddMissingProperties: outputOptions.unionAddMissingProperties ?? false,
|
|
1019
1023
|
factoryMethods,
|
|
1024
|
+
tagsSplitDeduplication: outputOptions.tagsSplitDeduplication ?? false,
|
|
1025
|
+
commonTypesFileName: outputOptions.commonTypesFileName ?? "common-types",
|
|
1020
1026
|
override: {
|
|
1021
1027
|
...outputOptions.override,
|
|
1022
1028
|
mock: {
|
|
@@ -1027,8 +1033,8 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
|
|
|
1027
1033
|
fractionDigits: outputOptions.override?.mock?.fractionDigits ?? 2,
|
|
1028
1034
|
...outputOptions.override?.mock
|
|
1029
1035
|
},
|
|
1030
|
-
operations: normalizeOperationsAndTags(outputOptions.override?.operations ?? {}, outputWorkspace, { query: globalQueryOptions }),
|
|
1031
|
-
tags: normalizeOperationsAndTags(outputOptions.override?.tags ?? {}, outputWorkspace, { query: globalQueryOptions }),
|
|
1036
|
+
operations: normalizeOperationsAndTags(outputOptions.override?.operations ?? {}, outputWorkspace, { query: globalQueryOptions }, "operations"),
|
|
1037
|
+
tags: normalizeOperationsAndTags(outputOptions.override?.tags ?? {}, outputWorkspace, { query: globalQueryOptions }, "tags"),
|
|
1032
1038
|
mutator: normalizeMutator(outputWorkspace, outputOptions.override?.mutator),
|
|
1033
1039
|
formData: createFormData(outputWorkspace, outputOptions.override?.formData),
|
|
1034
1040
|
formUrlEncoded: (isBoolean(outputOptions.override?.formUrlEncoded) ? outputOptions.override.formUrlEncoded : normalizeMutator(outputWorkspace, outputOptions.override?.formUrlEncoded)) ?? true,
|
|
@@ -1090,6 +1096,7 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
|
|
|
1090
1096
|
...outputOptions.override?.zod?.preprocess?.response ? { response: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.response) } : {}
|
|
1091
1097
|
},
|
|
1092
1098
|
...outputOptions.override?.zod?.params ? { params: normalizeMutator(outputWorkspace, outputOptions.override.zod.params) } : {},
|
|
1099
|
+
version: outputOptions.override?.zod?.version ?? "auto",
|
|
1093
1100
|
generateEachHttpStatus: outputOptions.override?.zod?.generateEachHttpStatus ?? false,
|
|
1094
1101
|
useBrandedTypes: outputOptions.override?.zod?.useBrandedTypes ?? false,
|
|
1095
1102
|
generateReusableSchemas: outputOptions.override?.zod?.generateReusableSchemas ?? false,
|
|
@@ -1113,6 +1120,7 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
|
|
|
1113
1120
|
forceSuccessResponse: outputOptions.override?.fetch?.forceSuccessResponse ?? false,
|
|
1114
1121
|
runtimeValidation: outputOptions.override?.fetch?.runtimeValidation ?? false,
|
|
1115
1122
|
useRuntimeFetcher: outputOptions.override?.fetch?.useRuntimeFetcher ?? false,
|
|
1123
|
+
...outputOptions.override?.fetch?.arrayFormat ? { arrayFormat: outputOptions.override.fetch.arrayFormat } : {},
|
|
1116
1124
|
...outputOptions.override?.fetch,
|
|
1117
1125
|
...outputOptions.override?.fetch?.jsonReviver ? { jsonReviver: normalizeMutator(outputWorkspace, outputOptions.override.fetch.jsonReviver) } : {}
|
|
1118
1126
|
},
|
|
@@ -1227,8 +1235,19 @@ function normalizePath(path$1, workspace) {
|
|
|
1227
1235
|
if (!isString(path$1)) return path$1;
|
|
1228
1236
|
return path.resolve(workspace, path$1);
|
|
1229
1237
|
}
|
|
1230
|
-
function normalizeOperationsAndTags(operationsOrTags, workspace, global) {
|
|
1238
|
+
function normalizeOperationsAndTags(operationsOrTags, workspace, global, source) {
|
|
1239
|
+
const unsupportedZodKeys = [
|
|
1240
|
+
"version",
|
|
1241
|
+
"dateTimeOptions",
|
|
1242
|
+
"timeOptions",
|
|
1243
|
+
"generateEachHttpStatus",
|
|
1244
|
+
"generateReusableSchemas",
|
|
1245
|
+
"generateMeta"
|
|
1246
|
+
];
|
|
1231
1247
|
return Object.fromEntries(Object.entries(operationsOrTags).map(([key, { transformer, mutator, formData, formUrlEncoded, paramsSerializer, paramsFilter, query, angular, zod, effect, ...rest }]) => {
|
|
1248
|
+
const unsupportedOperationZodKeys = zod && unsupportedZodKeys.filter((unsupportedKey) => zod[unsupportedKey] !== void 0);
|
|
1249
|
+
if (unsupportedOperationZodKeys && unsupportedOperationZodKeys.length) logWarning(`⚠️ override.${source}.${key}.zod only supports strict, generate, coerce, preprocess, params, and useBrandedTypes. Ignoring unsupported ${unsupportedOperationZodKeys.length === 1 ? "field" : "fields"}: ${unsupportedOperationZodKeys.map((unsupportedKey) => `zod.${unsupportedKey}`).join(", ")}.`);
|
|
1250
|
+
const hasSupportedOperationZodConfig = !!zod && (zod.strict !== void 0 || zod.generate !== void 0 || zod.coerce !== void 0 || zod.preprocess !== void 0 || zod.params !== void 0 || zod.useBrandedTypes !== void 0);
|
|
1232
1251
|
return [key, {
|
|
1233
1252
|
...rest,
|
|
1234
1253
|
...angular ? { angular: {
|
|
@@ -1238,7 +1257,7 @@ function normalizeOperationsAndTags(operationsOrTags, workspace, global) {
|
|
|
1238
1257
|
...angular.httpResource ? { httpResource: angular.httpResource } : {}
|
|
1239
1258
|
} } : {},
|
|
1240
1259
|
...query ? { query: normalizeQueryOptions(query, workspace, global.query) } : {},
|
|
1241
|
-
...zod ? { zod: {
|
|
1260
|
+
...hasSupportedOperationZodConfig && zod ? { zod: {
|
|
1242
1261
|
strict: {
|
|
1243
1262
|
param: zod.strict?.param ?? false,
|
|
1244
1263
|
query: zod.strict?.query ?? false,
|
|
@@ -1268,12 +1287,7 @@ function normalizeOperationsAndTags(operationsOrTags, workspace, global) {
|
|
|
1268
1287
|
...zod.preprocess?.response ? { response: normalizeMutator(workspace, zod.preprocess.response) } : {}
|
|
1269
1288
|
},
|
|
1270
1289
|
...zod.params ? { params: normalizeMutator(workspace, zod.params) } : {},
|
|
1271
|
-
|
|
1272
|
-
useBrandedTypes: zod.useBrandedTypes ?? false,
|
|
1273
|
-
generateReusableSchemas: zod.generateReusableSchemas ?? false,
|
|
1274
|
-
generateMeta: zod.generateMeta ?? false,
|
|
1275
|
-
dateTimeOptions: zod.dateTimeOptions ?? { offset: true },
|
|
1276
|
-
timeOptions: zod.timeOptions ?? {}
|
|
1290
|
+
useBrandedTypes: zod.useBrandedTypes ?? false
|
|
1277
1291
|
} } : {},
|
|
1278
1292
|
...effect ? { effect: normalizeEffectOptions(effect) } : {},
|
|
1279
1293
|
...transformer ? { transformer: normalizePath(transformer, workspace) } : {},
|
|
@@ -1608,6 +1622,23 @@ const rewriteReusableSchemas = (entries) => {
|
|
|
1608
1622
|
function buildMutatorImportStatement(mutator) {
|
|
1609
1623
|
return `import ${mutator.default ? mutator.name : `{ ${mutator.name} }`} from '${mutator.path}';`;
|
|
1610
1624
|
}
|
|
1625
|
+
const ROOT_DIR = ".";
|
|
1626
|
+
function getSchemaDir(schemaTagMap, name) {
|
|
1627
|
+
return schemaTagMap?.get(name) ?? ROOT_DIR;
|
|
1628
|
+
}
|
|
1629
|
+
function computeCrossDirImportPath(schemasPath, fromDir, toDir, fileName, importExt) {
|
|
1630
|
+
if (fromDir === toDir) return `./${fileName}${importExt}`;
|
|
1631
|
+
const fromPath = fromDir === ROOT_DIR ? schemasPath : path.join(schemasPath, fromDir);
|
|
1632
|
+
const toPath = toDir === ROOT_DIR ? schemasPath : path.join(schemasPath, toDir);
|
|
1633
|
+
const relDir = upath.relativeSafe(fromPath, toPath);
|
|
1634
|
+
return `${upath.joinSafe(relDir, fileName)}${importExt}`;
|
|
1635
|
+
}
|
|
1636
|
+
function adjustMutatorPathForDir(mutatorPath, tagDir) {
|
|
1637
|
+
if (tagDir === ROOT_DIR) return mutatorPath;
|
|
1638
|
+
if (mutatorPath.startsWith("./")) return `../${mutatorPath.slice(2)}`;
|
|
1639
|
+
if (mutatorPath.startsWith("../")) return `../${mutatorPath}`;
|
|
1640
|
+
return mutatorPath;
|
|
1641
|
+
}
|
|
1611
1642
|
/**
|
|
1612
1643
|
* Whole-word substring check for a resolved mutator alias inside generated
|
|
1613
1644
|
* code. Plain `String.includes` would false-positive when the user names the
|
|
@@ -1677,7 +1708,7 @@ const isValidSchemaIdentifier = (name) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
|
1677
1708
|
* `resolveValue` producer surfaces aliases here today, so the integration
|
|
1678
1709
|
* tests can't exercise it.
|
|
1679
1710
|
*/
|
|
1680
|
-
function buildSiblingImports({ usedRefs, extraImports, entryName, componentNames, namingConvention, importExt }) {
|
|
1711
|
+
function buildSiblingImports({ usedRefs, extraImports, entryName, componentNames, namingConvention, importExt, schemaTagMap, currentDir, schemasPath }) {
|
|
1681
1712
|
const importsByName = /* @__PURE__ */ new Map();
|
|
1682
1713
|
for (const name of usedRefs) {
|
|
1683
1714
|
if (name === entryName) continue;
|
|
@@ -1689,7 +1720,7 @@ function buildSiblingImports({ usedRefs, extraImports, entryName, componentNames
|
|
|
1689
1720
|
}
|
|
1690
1721
|
return [...importsByName.values()].toSorted((a, b) => a.name.localeCompare(b.name)).map(({ name, alias }) => {
|
|
1691
1722
|
const importedFile = conventionName(name, namingConvention);
|
|
1692
|
-
return `import { ${alias ? `${name} as ${alias}` : name} } from '
|
|
1723
|
+
return `import { ${alias ? `${name} as ${alias}` : name} } from '${schemaTagMap && currentDir && schemasPath ? computeCrossDirImportPath(schemasPath, currentDir, getSchemaDir(schemaTagMap, name), importedFile, importExt) : `./${importedFile}${importExt}`}';`;
|
|
1693
1724
|
}).join("\n");
|
|
1694
1725
|
}
|
|
1695
1726
|
const isPrimitiveSchemaName = (name) => [
|
|
@@ -1732,11 +1763,34 @@ async function writeZodSchemaIndex(schemasPath, fileExtension, header, schemaNam
|
|
|
1732
1763
|
const uniqueExports = [...new Set(allExports.split("\n"))].filter((line) => line.trim()).toSorted().join("\n");
|
|
1733
1764
|
await fs.outputFile(indexPath, `${header}\n${uniqueExports}\n`);
|
|
1734
1765
|
}
|
|
1766
|
+
async function writeZodSchemaTagsSplitBarrel(schemasPath, fileExtension, header, componentDirs, verbDirs, namingConvention, tsconfig) {
|
|
1767
|
+
const importExt = getImportExtension(fileExtension, tsconfig);
|
|
1768
|
+
const indexImportExt = getImportExtension(".ts", tsconfig);
|
|
1769
|
+
const allDirs = /* @__PURE__ */ new Map();
|
|
1770
|
+
for (const [dir, names] of componentDirs) allDirs.set(dir, [...names]);
|
|
1771
|
+
for (const [dir, names] of verbDirs) if (allDirs.has(dir)) allDirs.get(dir).push(...names);
|
|
1772
|
+
else allDirs.set(dir, [...names]);
|
|
1773
|
+
for (const [dir, schemaNames] of allDirs) {
|
|
1774
|
+
if (dir === ROOT_DIR) continue;
|
|
1775
|
+
await writeZodSchemaIndex(path.join(schemasPath, dir), fileExtension, header, schemaNames, namingConvention, false, tsconfig);
|
|
1776
|
+
}
|
|
1777
|
+
const rootSchemas = allDirs.get(ROOT_DIR) ?? [];
|
|
1778
|
+
const rootExports = [...new Set(rootSchemas)].map((name) => {
|
|
1779
|
+
return `export * from './${conventionName(name, namingConvention)}${importExt}';`;
|
|
1780
|
+
}).toSorted();
|
|
1781
|
+
const tagExports = [...allDirs.keys()].filter((dir) => dir !== ROOT_DIR).toSorted((a, b) => a.localeCompare(b, "en", { numeric: true })).map((dir) => {
|
|
1782
|
+
return `export * from '${indexImportExt ? `./${dir}/index${indexImportExt}` : `./${dir}`}';`;
|
|
1783
|
+
});
|
|
1784
|
+
const allExports = [...rootExports, ...tagExports];
|
|
1785
|
+
const rootIndexPath = path.join(schemasPath, "index.ts");
|
|
1786
|
+
const content = `${header}\n${allExports.join("\n")}\n`;
|
|
1787
|
+
await fs.outputFile(rootIndexPath, content);
|
|
1788
|
+
}
|
|
1735
1789
|
function generateZodSchemasInline(builder, output, includeZodImport = true, paramsMutator, includeParamsImport = false) {
|
|
1736
1790
|
if (output.override.zod.generateReusableSchemas === true) return generateZodSchemasInlineReusable(builder, output, includeZodImport, paramsMutator, includeParamsImport);
|
|
1737
1791
|
const schemasWithOpenApiDef = builder.schemas.filter((s) => s.schema);
|
|
1738
1792
|
if (schemasWithOpenApiDef.length === 0) return "";
|
|
1739
|
-
const isZodV4 =
|
|
1793
|
+
const isZodV4 = resolveIsZodV4(output.override.zod.version, output.packageJson);
|
|
1740
1794
|
const strict = output.override.zod.strict.body;
|
|
1741
1795
|
const coerce = output.override.zod.coerce.body;
|
|
1742
1796
|
const schemas = [];
|
|
@@ -1762,7 +1816,7 @@ function generateZodSchemasInline(builder, output, includeZodImport = true, para
|
|
|
1762
1816
|
return generateZodSchemaFileContent("", schemas, includeZodImport);
|
|
1763
1817
|
}
|
|
1764
1818
|
function generateZodSchemasInlineReusable(builder, output, includeZodImport = true, paramsMutator, includeParamsImport = false) {
|
|
1765
|
-
const isZodV4 =
|
|
1819
|
+
const isZodV4 = resolveIsZodV4(output.override.zod.version, output.packageJson);
|
|
1766
1820
|
const strict = output.override.zod.strict.body;
|
|
1767
1821
|
const coerce = output.override.zod.coerce.body;
|
|
1768
1822
|
const context = {
|
|
@@ -1786,21 +1840,20 @@ function generateZodSchemasInlineReusable(builder, output, includeZodImport = tr
|
|
|
1786
1840
|
const paramsImport = paramsMutator && includeParamsImport && bodyReferencesMutator(body, paramsMutator) ? `${buildMutatorImportStatement(paramsMutator)}\n` : "";
|
|
1787
1841
|
return `${zodImport || paramsImport ? `${zodImport}${paramsImport}\n` : ""}${body}\n`;
|
|
1788
1842
|
}
|
|
1789
|
-
async function writeZodSchemas(builder, schemasPath, fileExtension, header, output, paramsMutator) {
|
|
1790
|
-
if (output.override.zod.generateReusableSchemas)
|
|
1791
|
-
|
|
1792
|
-
return;
|
|
1793
|
-
}
|
|
1843
|
+
async function writeZodSchemas(builder, schemasPath, fileExtension, header, output, paramsMutator, schemaTagMap) {
|
|
1844
|
+
if (output.override.zod.generateReusableSchemas) return writeZodSchemasReusable(builder, schemasPath, fileExtension, header, output, paramsMutator, schemaTagMap);
|
|
1845
|
+
const isSplit = !!schemaTagMap;
|
|
1794
1846
|
const schemasWithOpenApiDef = builder.schemas.filter((s) => s.schema);
|
|
1795
1847
|
const schemasToWrite = [];
|
|
1796
|
-
const isZodV4 =
|
|
1848
|
+
const isZodV4 = resolveIsZodV4(output.override.zod.version, output.packageJson);
|
|
1797
1849
|
const strict = output.override.zod.strict.body;
|
|
1798
1850
|
const coerce = output.override.zod.coerce.body;
|
|
1799
1851
|
for (const generatorSchema of schemasWithOpenApiDef) {
|
|
1800
1852
|
const { name, schema: schemaObject } = generatorSchema;
|
|
1801
1853
|
if (!schemaObject) continue;
|
|
1802
1854
|
const fileName = conventionName(name, output.namingConvention);
|
|
1803
|
-
const
|
|
1855
|
+
const tagDir = getSchemaDir(schemaTagMap, name);
|
|
1856
|
+
const filePath = isSplit ? path.join(schemasPath, tagDir, `${fileName}${fileExtension}`) : path.join(schemasPath, `${fileName}${fileExtension}`);
|
|
1804
1857
|
const context = {
|
|
1805
1858
|
spec: builder.spec,
|
|
1806
1859
|
target: builder.target,
|
|
@@ -1823,10 +1876,22 @@ async function writeZodSchemas(builder, schemasPath, fileExtension, header, outp
|
|
|
1823
1876
|
const fileContent = generateZodSchemaFileContent(header, schemaGroup);
|
|
1824
1877
|
await fs.outputFile(schemaGroup[0].filePath, fileContent);
|
|
1825
1878
|
}
|
|
1826
|
-
|
|
1879
|
+
const writtenSchemaNames = groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName);
|
|
1880
|
+
if (output.indexFiles && !isSplit) await writeZodSchemaIndex(schemasPath, fileExtension, header, writtenSchemaNames, output.namingConvention, false, output.tsconfig);
|
|
1881
|
+
if (isSplit) {
|
|
1882
|
+
const dirSchemas = /* @__PURE__ */ new Map();
|
|
1883
|
+
for (const name of writtenSchemaNames) {
|
|
1884
|
+
const dir = getSchemaDir(schemaTagMap, name);
|
|
1885
|
+
if (!dirSchemas.has(dir)) dirSchemas.set(dir, []);
|
|
1886
|
+
dirSchemas.get(dir).push(name);
|
|
1887
|
+
}
|
|
1888
|
+
return dirSchemas;
|
|
1889
|
+
}
|
|
1890
|
+
return new Map([[ROOT_DIR, writtenSchemaNames]]);
|
|
1827
1891
|
}
|
|
1828
|
-
async function writeZodSchemasReusable(builder, schemasPath, fileExtension, header, output, paramsMutator) {
|
|
1829
|
-
const
|
|
1892
|
+
async function writeZodSchemasReusable(builder, schemasPath, fileExtension, header, output, paramsMutator, schemaTagMap) {
|
|
1893
|
+
const isSplit = !!schemaTagMap;
|
|
1894
|
+
const isZodV4 = resolveIsZodV4(output.override.zod.version, output.packageJson);
|
|
1830
1895
|
const strict = output.override.zod.strict.body;
|
|
1831
1896
|
const coerce = output.override.zod.coerce.body;
|
|
1832
1897
|
const context = {
|
|
@@ -1846,10 +1911,10 @@ async function writeZodSchemasReusable(builder, schemasPath, fileExtension, head
|
|
|
1846
1911
|
paramsMutator
|
|
1847
1912
|
}));
|
|
1848
1913
|
const componentNames = new Set(Object.keys(builder.spec.components?.schemas ?? {}).map((schemaName) => resolveSchemaName(`#/components/schemas/${schemaName}`, context)));
|
|
1849
|
-
const paramsMutatorImport = paramsMutator ? buildMutatorImportStatement(paramsMutator) : void 0;
|
|
1850
1914
|
for (const entry of rewritten) {
|
|
1851
1915
|
const fileName = conventionName(entry.name, output.namingConvention);
|
|
1852
|
-
const
|
|
1916
|
+
const tagDir = getSchemaDir(schemaTagMap, entry.name);
|
|
1917
|
+
const filePath = isSplit ? path.join(schemasPath, tagDir, `${fileName}${fileExtension}`) : path.join(schemasPath, `${fileName}${fileExtension}`);
|
|
1853
1918
|
const importExt = getImportExtension(fileExtension, output.tsconfig);
|
|
1854
1919
|
const rendered = renderReusableSchemaEntry(entry, context);
|
|
1855
1920
|
const refImports = buildSiblingImports({
|
|
@@ -1858,19 +1923,39 @@ async function writeZodSchemasReusable(builder, schemasPath, fileExtension, head
|
|
|
1858
1923
|
entryName: entry.name,
|
|
1859
1924
|
componentNames,
|
|
1860
1925
|
namingConvention: output.namingConvention,
|
|
1861
|
-
importExt
|
|
1926
|
+
importExt,
|
|
1927
|
+
...isSplit ? {
|
|
1928
|
+
schemaTagMap,
|
|
1929
|
+
currentDir: tagDir,
|
|
1930
|
+
schemasPath
|
|
1931
|
+
} : {}
|
|
1862
1932
|
});
|
|
1863
|
-
const
|
|
1933
|
+
const mutatorImportStr = !!paramsMutator && bodyReferencesMutator(entry.zod, paramsMutator) ? buildMutatorImportStatement({
|
|
1934
|
+
...paramsMutator,
|
|
1935
|
+
path: isSplit ? adjustMutatorPathForDir(paramsMutator.path, tagDir) : paramsMutator.path
|
|
1936
|
+
}) : void 0;
|
|
1937
|
+
const imports = [...mutatorImportStr ? [mutatorImportStr] : [], ...refImports ? [refImports] : []].join("\n");
|
|
1864
1938
|
const fileContent = `${header}import { z as zod } from 'zod';\n` + (imports ? `${imports}\n\n` : "\n") + `${rendered.content}\n`;
|
|
1865
1939
|
await fs.outputFile(filePath, fileContent);
|
|
1866
1940
|
}
|
|
1867
|
-
if (output.indexFiles && rewritten.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, rewritten.map((e) => e.name), output.namingConvention, true, output.tsconfig);
|
|
1941
|
+
if (output.indexFiles && !isSplit && rewritten.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, rewritten.map((e) => e.name), output.namingConvention, true, output.tsconfig);
|
|
1942
|
+
if (isSplit) {
|
|
1943
|
+
const dirSchemas = /* @__PURE__ */ new Map();
|
|
1944
|
+
for (const entry of rewritten) {
|
|
1945
|
+
const dir = getSchemaDir(schemaTagMap, entry.name);
|
|
1946
|
+
if (!dirSchemas.has(dir)) dirSchemas.set(dir, []);
|
|
1947
|
+
dirSchemas.get(dir).push(entry.name);
|
|
1948
|
+
}
|
|
1949
|
+
return dirSchemas;
|
|
1950
|
+
}
|
|
1951
|
+
return new Map([[ROOT_DIR, rewritten.map((e) => e.name)]]);
|
|
1868
1952
|
}
|
|
1869
|
-
async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension, header, output, context) {
|
|
1953
|
+
async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension, header, output, context, schemaTagMap) {
|
|
1954
|
+
const isSplit = !!schemaTagMap;
|
|
1870
1955
|
const zodContext = context;
|
|
1871
1956
|
const verbOptionsArray = Object.values(verbOptions);
|
|
1872
|
-
if (verbOptionsArray.length === 0) return;
|
|
1873
|
-
const isZodV4 =
|
|
1957
|
+
if (verbOptionsArray.length === 0) return /* @__PURE__ */ new Map();
|
|
1958
|
+
const isZodV4 = resolveIsZodV4(output.override.zod.version, output.packageJson);
|
|
1874
1959
|
const strict = output.override.zod.strict.body;
|
|
1875
1960
|
const coerce = output.override.zod.coerce.body;
|
|
1876
1961
|
const useReusableSchemas = output.override.zod.generateReusableSchemas === true;
|
|
@@ -1932,14 +2017,18 @@ async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension,
|
|
|
1932
2017
|
...queryParamsSchemas,
|
|
1933
2018
|
...headerParamsSchemas,
|
|
1934
2019
|
...responseSchemas
|
|
1935
|
-
])
|
|
2020
|
+
]).map((s) => ({
|
|
2021
|
+
...s,
|
|
2022
|
+
verbTagDir: isSplit ? kebab(verbOption.tags?.[0] ?? DefaultTag) : ROOT_DIR
|
|
2023
|
+
}));
|
|
1936
2024
|
}));
|
|
1937
2025
|
const schemasToWrite = [];
|
|
1938
2026
|
for (const entry of uniqueVerbsSchemas) {
|
|
1939
2027
|
if (useReusableSchemas && entry.schema && typeof entry.schema.$ref === "string" && Object.keys(entry.schema).length === 1) continue;
|
|
1940
2028
|
const { name, schema } = entry;
|
|
1941
2029
|
const fileName = conventionName(name, output.namingConvention);
|
|
1942
|
-
const
|
|
2030
|
+
const tagDir = entry.verbTagDir ?? ROOT_DIR;
|
|
2031
|
+
const filePath = isSplit ? path.join(schemasPath, tagDir, `${fileName}${fileExtension}`) : path.join(schemasPath, `${fileName}${fileExtension}`);
|
|
1943
2032
|
const parsedZodDefinition = parseZodValidationSchemaDefinition("bodyContentType" in entry && entry.bodyContentType === "multipart/form-data" ? generateFormDataZodSchema(schema, zodContext, name, strict, isZodV4, "encoding" in entry ? entry.encoding : void 0, useReusableSchemas) : generateZodValidationSchemaDefinition(schema, zodContext, name, strict, isZodV4, {
|
|
1944
2033
|
required: true,
|
|
1945
2034
|
useReusableSchemas
|
|
@@ -1950,7 +2039,8 @@ async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension,
|
|
|
1950
2039
|
zodExpression = rewriteSentinelsToDirect(zodExpression);
|
|
1951
2040
|
const importExt = getImportExtension(fileExtension, output.tsconfig);
|
|
1952
2041
|
importStatements = [...parsedZodDefinition.usedRefs].filter((refName) => refName !== name).toSorted().map((refName) => {
|
|
1953
|
-
|
|
2042
|
+
const importedFile = conventionName(refName, output.namingConvention);
|
|
2043
|
+
return `import { ${refName} } from '${isSplit ? computeCrossDirImportPath(schemasPath, tagDir, getSchemaDir(schemaTagMap, refName), importedFile, importExt) : `./${importedFile}${importExt}`}';`;
|
|
1954
2044
|
});
|
|
1955
2045
|
}
|
|
1956
2046
|
schemasToWrite.push({
|
|
@@ -1966,7 +2056,19 @@ async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension,
|
|
|
1966
2056
|
const fileContent = generateZodSchemaFileContent(header, schemaGroup);
|
|
1967
2057
|
await fs.outputFile(schemaGroup[0].filePath, fileContent);
|
|
1968
2058
|
}
|
|
1969
|
-
|
|
2059
|
+
const writtenSchemaNames = groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName);
|
|
2060
|
+
if (output.indexFiles && !isSplit && uniqueVerbsSchemas.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, writtenSchemaNames, output.namingConvention, true, output.tsconfig);
|
|
2061
|
+
if (isSplit) {
|
|
2062
|
+
const dirSchemas = /* @__PURE__ */ new Map();
|
|
2063
|
+
for (const entry of uniqueVerbsSchemas) {
|
|
2064
|
+
if (useReusableSchemas && entry.schema && typeof entry.schema.$ref === "string" && Object.keys(entry.schema).length === 1) continue;
|
|
2065
|
+
const dir = entry.verbTagDir ?? ROOT_DIR;
|
|
2066
|
+
if (!dirSchemas.has(dir)) dirSchemas.set(dir, []);
|
|
2067
|
+
dirSchemas.get(dir).push(entry.name);
|
|
2068
|
+
}
|
|
2069
|
+
return dirSchemas;
|
|
2070
|
+
}
|
|
2071
|
+
return new Map([[ROOT_DIR, writtenSchemaNames]]);
|
|
1970
2072
|
}
|
|
1971
2073
|
//#endregion
|
|
1972
2074
|
//#region src/write-specs.ts
|
|
@@ -2031,7 +2133,7 @@ async function addOperationSchemasReExport(schemaPath, operationSchemasPath, hea
|
|
|
2031
2133
|
* file path so callers can include it in formatter / hook runs, or
|
|
2032
2134
|
* `undefined` if no file was written.
|
|
2033
2135
|
*/
|
|
2034
|
-
async function writeFakerSchemaMocks(builder, options, header) {
|
|
2136
|
+
async function writeFakerSchemaMocks(builder, options, header, schemaTagMap) {
|
|
2035
2137
|
const { output } = options;
|
|
2036
2138
|
const fakerEntry = output.mock.generators.find((g) => !isFunction(g) && g.type === OutputMockType.FAKER && g.schemas === true);
|
|
2037
2139
|
if (!fakerEntry) return;
|
|
@@ -2062,9 +2164,32 @@ async function writeFakerSchemaMocks(builder, options, header) {
|
|
|
2062
2164
|
filePath = path.join(dir, `schemas.faker${fileExtension}`);
|
|
2063
2165
|
schemaImportPath = targetInfo ? `./${targetInfo.filename}${getImportExtension(fileExtension, output.tsconfig)}` : void 0;
|
|
2064
2166
|
}
|
|
2065
|
-
const
|
|
2066
|
-
|
|
2067
|
-
|
|
2167
|
+
const isZodSchemaOutput = isObject(output.schemas) && output.schemas.type === "zod";
|
|
2168
|
+
const importExtension = getImportExtension(fileExtension, output.tsconfig);
|
|
2169
|
+
const schemaSuffix = isZodSchemaOutput ? ".zod" : "";
|
|
2170
|
+
const perSchemaImportPath = /* @__PURE__ */ new Map();
|
|
2171
|
+
if (schemaImportPath === "." && !output.indexFiles && isObject(output.schemas)) for (const schema of builder.schemas) {
|
|
2172
|
+
const tsName = pascal(schema.name);
|
|
2173
|
+
const fileName = conventionName(schema.name, output.namingConvention);
|
|
2174
|
+
const tagDir = schemaTagMap?.get(schema.name);
|
|
2175
|
+
const tagSegment = tagDir && tagDir !== "." ? `${tagDir}/` : "";
|
|
2176
|
+
perSchemaImportPath.set(tsName, `./${tagSegment}${fileName}${schemaSuffix}${importExtension}`);
|
|
2177
|
+
}
|
|
2178
|
+
const reroutedImports = imports.map((imp) => {
|
|
2179
|
+
if (imp.importPath) return imp;
|
|
2180
|
+
if (imp.schemaFactory) return {
|
|
2181
|
+
...imp,
|
|
2182
|
+
importPath: "."
|
|
2183
|
+
};
|
|
2184
|
+
const resolved = perSchemaImportPath.get(imp.name);
|
|
2185
|
+
if (resolved) return {
|
|
2186
|
+
...imp,
|
|
2187
|
+
importPath: resolved
|
|
2188
|
+
};
|
|
2189
|
+
return {
|
|
2190
|
+
...imp,
|
|
2191
|
+
importPath: schemaImportPath
|
|
2192
|
+
};
|
|
2068
2193
|
});
|
|
2069
2194
|
const grouped = /* @__PURE__ */ new Map();
|
|
2070
2195
|
for (const imp of reroutedImports) {
|
|
@@ -2101,28 +2226,62 @@ function shouldGenerateSchemas(output, hasOperations) {
|
|
|
2101
2226
|
async function writeSpecs(builder, workspace, options, projectName) {
|
|
2102
2227
|
const { info, schemas, target } = builder;
|
|
2103
2228
|
const { output } = options;
|
|
2229
|
+
const shouldSplitSchemasByTags = isObject(output.schemas) && output.schemas.splitByTags;
|
|
2230
|
+
const schemaTagMap = shouldSplitSchemasByTags ? buildSchemaTagMap(Object.values(builder.operations).map((op) => ({
|
|
2231
|
+
imports: op.imports,
|
|
2232
|
+
tags: op.tags
|
|
2233
|
+
})), schemas) : void 0;
|
|
2104
2234
|
const projectTitle = projectName ?? info.title;
|
|
2105
2235
|
const header = getHeader(output.override.header, info);
|
|
2106
2236
|
if (output.schemas) {
|
|
2107
2237
|
const schemasPath = isString(output.schemas) ? output.schemas : output.schemas.path;
|
|
2108
|
-
|
|
2238
|
+
const isZodSchemas = !isString(output.schemas) && output.schemas.type === "zod" || isString(output.schemas) && output.client === "zod" && output.override.zod.generateReusableSchemas;
|
|
2239
|
+
if (shouldSplitSchemasByTags && output.operationSchemas) throw new Error("schemas.splitByTags cannot be used with output.operationSchemas. The tags-split schema mode handles operation type placement within tag directories.");
|
|
2240
|
+
if (isZodSchemas) {
|
|
2109
2241
|
const fileExtension = output.schemaFileExtension;
|
|
2110
|
-
|
|
2242
|
+
const schemasParamsMutator = output.override.zod.params ? await generateMutator({
|
|
2111
2243
|
output: path.join(schemasPath, `__params__${fileExtension}`),
|
|
2112
2244
|
mutator: output.override.zod.params,
|
|
2113
2245
|
name: "zodParams",
|
|
2114
2246
|
workspace,
|
|
2115
2247
|
tsconfig: output.tsconfig
|
|
2116
|
-
}) : void 0
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2248
|
+
}) : void 0;
|
|
2249
|
+
if (shouldSplitSchemasByTags) {
|
|
2250
|
+
const componentDirs = await writeZodSchemas(builder, schemasPath, fileExtension, header, output, schemasParamsMutator, schemaTagMap);
|
|
2251
|
+
const verbDirs = await writeZodSchemasFromVerbs(builder.verbOptions, schemasPath, fileExtension, header, output, {
|
|
2252
|
+
spec: builder.spec,
|
|
2253
|
+
target: builder.target,
|
|
2254
|
+
workspace,
|
|
2255
|
+
output
|
|
2256
|
+
}, schemaTagMap);
|
|
2257
|
+
if (output.indexFiles) await writeZodSchemaTagsSplitBarrel(schemasPath, fileExtension, header, componentDirs, verbDirs, output.namingConvention, output.tsconfig);
|
|
2258
|
+
} else {
|
|
2259
|
+
await writeZodSchemas(builder, schemasPath, fileExtension, header, output, schemasParamsMutator);
|
|
2260
|
+
await writeZodSchemasFromVerbs(builder.verbOptions, schemasPath, fileExtension, header, output, {
|
|
2261
|
+
spec: builder.spec,
|
|
2262
|
+
target: builder.target,
|
|
2263
|
+
workspace,
|
|
2264
|
+
output
|
|
2265
|
+
});
|
|
2266
|
+
}
|
|
2123
2267
|
} else {
|
|
2124
2268
|
const fileExtension = output.fileExtension || ".ts";
|
|
2125
|
-
if (
|
|
2269
|
+
if (shouldSplitSchemasByTags) await writeSchemasTagsSplit({
|
|
2270
|
+
schemaPath: schemasPath,
|
|
2271
|
+
schemas,
|
|
2272
|
+
target,
|
|
2273
|
+
namingConvention: output.namingConvention,
|
|
2274
|
+
fileExtension,
|
|
2275
|
+
header,
|
|
2276
|
+
indexFiles: output.indexFiles,
|
|
2277
|
+
tsconfig: output.tsconfig,
|
|
2278
|
+
factoryOutputDirectory: output.factoryMethods?.outputDirectory,
|
|
2279
|
+
operations: Object.values(builder.operations).map((op) => ({
|
|
2280
|
+
imports: op.imports,
|
|
2281
|
+
tags: op.tags
|
|
2282
|
+
}))
|
|
2283
|
+
});
|
|
2284
|
+
else if (output.operationSchemas) {
|
|
2126
2285
|
const { regularSchemas, operationSchemas: opSchemas } = splitSchemasByType(schemas);
|
|
2127
2286
|
const regularSchemaNames = new Set(regularSchemas.map((s) => s.name));
|
|
2128
2287
|
const operationSchemaNames = new Set(opSchemas.map((s) => s.name));
|
|
@@ -2166,7 +2325,7 @@ async function writeSpecs(builder, workspace, options, projectName) {
|
|
|
2166
2325
|
});
|
|
2167
2326
|
}
|
|
2168
2327
|
}
|
|
2169
|
-
const fakerSchemaPath = await writeFakerSchemaMocks(builder, options, header);
|
|
2328
|
+
const fakerSchemaPath = await writeFakerSchemaMocks(builder, options, header, schemaTagMap);
|
|
2170
2329
|
let implementationPaths = [];
|
|
2171
2330
|
if (output.target) {
|
|
2172
2331
|
const writeMode = getWriteMode(output.mode);
|
|
@@ -2189,6 +2348,7 @@ async function writeSpecs(builder, workspace, options, projectName) {
|
|
|
2189
2348
|
projectName,
|
|
2190
2349
|
header,
|
|
2191
2350
|
needSchema: shouldGenerateSchemas(output, hasOperations),
|
|
2351
|
+
schemaTagMap,
|
|
2192
2352
|
generateSchemasInline: needZodSchemasInline ? () => generateZodSchemasInline(builder, output, includeZodImport, inlineSchemasParamsMutator, includeParamsImport) : void 0
|
|
2193
2353
|
});
|
|
2194
2354
|
}
|
|
@@ -2352,4 +2512,4 @@ async function loadConfigFile(configFilePath) {
|
|
|
2352
2512
|
//#endregion
|
|
2353
2513
|
export { defineConfig as a, description as c, startWatcher as i, name as l, loadConfigFile as n, defineTransformer as o, generateSpec as r, normalizeOptions as s, findConfigFile as t, version as u };
|
|
2354
2514
|
|
|
2355
|
-
//# sourceMappingURL=config-
|
|
2515
|
+
//# sourceMappingURL=config-D-TQRn-G.mjs.map
|