@orval/core 8.10.0 → 8.11.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.d.mts +114 -20
- package/dist/index.mjs +352 -101
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { entries, groupBy, isArray, isBoolean, isBoolean as isBoolean$1, isEmptyish, isFunction, isNullish, isNullish as isNullish$1, isNumber, isString, isString as isString$1, prop, unique, uniqueBy, uniqueWith } from "remeda";
|
|
4
4
|
import { keyword } from "esutils";
|
|
5
|
-
import
|
|
5
|
+
import nodePath from "node:path";
|
|
6
6
|
import { compare } from "compare-versions";
|
|
7
7
|
import debug from "debug";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
@@ -77,6 +77,10 @@ const Verbs = {
|
|
|
77
77
|
DELETE: "delete",
|
|
78
78
|
HEAD: "head"
|
|
79
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Canonical tag name used for the generated bucket that collects untagged operations.
|
|
82
|
+
*/
|
|
83
|
+
const DefaultTag = "default";
|
|
80
84
|
const GetterPropType = {
|
|
81
85
|
PARAM: "param",
|
|
82
86
|
NAMED_PATH_PARAMS: "namedPathParams",
|
|
@@ -137,7 +141,7 @@ function isReference(obj) {
|
|
|
137
141
|
return !isNullish$1(obj) && Object.hasOwn(obj, "$ref");
|
|
138
142
|
}
|
|
139
143
|
function isDirectory(pathValue) {
|
|
140
|
-
return !
|
|
144
|
+
return !nodePath.extname(pathValue);
|
|
141
145
|
}
|
|
142
146
|
function isObject(x) {
|
|
143
147
|
return Object.prototype.toString.call(x) === "[object Object]";
|
|
@@ -362,6 +366,29 @@ function createDebugger(ns, options = {}) {
|
|
|
362
366
|
const search = String.raw`\*/`;
|
|
363
367
|
const replacement = String.raw`*\/`;
|
|
364
368
|
const regex$1 = new RegExp(search, "g");
|
|
369
|
+
const itemValidationKeys = [
|
|
370
|
+
"minLength",
|
|
371
|
+
"maxLength",
|
|
372
|
+
"minimum",
|
|
373
|
+
"maximum",
|
|
374
|
+
"exclusiveMinimum",
|
|
375
|
+
"exclusiveMaximum",
|
|
376
|
+
"minItems",
|
|
377
|
+
"maxItems",
|
|
378
|
+
"pattern"
|
|
379
|
+
];
|
|
380
|
+
function getItemValidationDocEntries(schema, prefix = "items", visited = /* @__PURE__ */ new WeakSet()) {
|
|
381
|
+
if (!schema) return [];
|
|
382
|
+
if (visited.has(schema)) return [];
|
|
383
|
+
visited.add(schema);
|
|
384
|
+
return [...itemValidationKeys.flatMap((key) => {
|
|
385
|
+
const value = schema[key];
|
|
386
|
+
return value === void 0 ? [] : [{
|
|
387
|
+
key: `${prefix}.${key}`,
|
|
388
|
+
value
|
|
389
|
+
}];
|
|
390
|
+
}), ...getItemValidationDocEntries(schema.items, `${prefix}.items`, visited)];
|
|
391
|
+
}
|
|
365
392
|
function jsDoc(schema, tryOneLine = false, context) {
|
|
366
393
|
if (context?.output.override.jsDoc) {
|
|
367
394
|
const { filter } = context.output.override.jsDoc;
|
|
@@ -369,6 +396,7 @@ function jsDoc(schema, tryOneLine = false, context) {
|
|
|
369
396
|
}
|
|
370
397
|
const { description, deprecated, summary, minLength, maxLength, minimum, maximum, exclusiveMinimum, exclusiveMaximum, minItems, maxItems, pattern } = schema;
|
|
371
398
|
const isNullable = schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null");
|
|
399
|
+
const itemValidationDocEntries = getItemValidationDocEntries(schema.items);
|
|
372
400
|
const lines = (Array.isArray(description) ? description.filter((d) => !d.includes("eslint-disable")) : [description ?? ""]).map((line) => line.replaceAll(regex$1, replacement));
|
|
373
401
|
const count = [
|
|
374
402
|
description,
|
|
@@ -383,7 +411,8 @@ function jsDoc(schema, tryOneLine = false, context) {
|
|
|
383
411
|
minItems?.toString(),
|
|
384
412
|
maxItems?.toString(),
|
|
385
413
|
isNullable ? "null" : "",
|
|
386
|
-
pattern
|
|
414
|
+
pattern,
|
|
415
|
+
...itemValidationDocEntries.map(({ value }) => value.toString())
|
|
387
416
|
].filter(Boolean).length;
|
|
388
417
|
if (!count) return "";
|
|
389
418
|
const oneLine = count === 1 && tryOneLine;
|
|
@@ -426,6 +455,17 @@ function jsDoc(schema, tryOneLine = false, context) {
|
|
|
426
455
|
tryAppendNumberDocLine("maxItems", maxItems);
|
|
427
456
|
tryAppendBooleanDocLine("nullable", isNullable);
|
|
428
457
|
tryAppendStringDocLine("pattern", pattern);
|
|
458
|
+
for (const { key, value } of itemValidationDocEntries) {
|
|
459
|
+
if (typeof value === "string") {
|
|
460
|
+
tryAppendStringDocLine(key, value);
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
if (typeof value === "number") {
|
|
464
|
+
tryAppendNumberDocLine(key, value);
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
tryAppendBooleanDocLine(key, value);
|
|
468
|
+
}
|
|
429
469
|
doc += oneLine ? " " : `\n ${tryOneLine ? " " : ""}`;
|
|
430
470
|
doc += "*/\n";
|
|
431
471
|
return doc;
|
|
@@ -450,8 +490,8 @@ async function dynamicImport(toImport, from = process.cwd(), takeDefault = true)
|
|
|
450
490
|
if (!toImport) return toImport;
|
|
451
491
|
try {
|
|
452
492
|
if (isString(toImport)) {
|
|
453
|
-
const filePath =
|
|
454
|
-
const extension =
|
|
493
|
+
const filePath = nodePath.resolve(from, toImport);
|
|
494
|
+
const extension = nodePath.extname(filePath);
|
|
455
495
|
if (TS_MODULE_EXTENSIONS.has(extension)) {
|
|
456
496
|
const data = await createJiti(from, { interopDefault: true }).import(filePath);
|
|
457
497
|
if (takeDefault && (isObject(data) || isModule(data)) && data.default) return data.default;
|
|
@@ -476,14 +516,14 @@ function getExtension(path) {
|
|
|
476
516
|
//#region src/utils/file.ts
|
|
477
517
|
function getFileInfo(target = "", { backupFilename = "filename", extension = ".ts" } = {}) {
|
|
478
518
|
const isDir = isDirectory(target);
|
|
479
|
-
const filePath = isDir ?
|
|
519
|
+
const filePath = isDir ? nodePath.join(target, backupFilename + extension) : target;
|
|
480
520
|
return {
|
|
481
521
|
path: filePath,
|
|
482
522
|
pathWithoutExtension: filePath.replace(/\.[^/.]+$/, ""),
|
|
483
523
|
extension,
|
|
484
524
|
isDirectory: isDir,
|
|
485
|
-
dirname:
|
|
486
|
-
filename:
|
|
525
|
+
dirname: nodePath.dirname(filePath),
|
|
526
|
+
filename: nodePath.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
|
|
487
527
|
};
|
|
488
528
|
}
|
|
489
529
|
async function removeFilesAndEmptyFolders(patterns, dir) {
|
|
@@ -691,13 +731,13 @@ function toUnix(value) {
|
|
|
691
731
|
return value;
|
|
692
732
|
}
|
|
693
733
|
function join(...args) {
|
|
694
|
-
return toUnix(
|
|
734
|
+
return toUnix(nodePath.join(...args.map((a) => toUnix(a))));
|
|
695
735
|
}
|
|
696
736
|
/**
|
|
697
737
|
* Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
|
|
698
738
|
*/
|
|
699
739
|
function relativeSafe(from, to) {
|
|
700
|
-
return normalizeSafe(`./${toUnix(
|
|
740
|
+
return normalizeSafe(`./${toUnix(nodePath.relative(toUnix(from), toUnix(to)))}`);
|
|
701
741
|
}
|
|
702
742
|
function getSchemaFileName(path) {
|
|
703
743
|
return path.replace(`.${getExtension(path)}`, "").slice(path.lastIndexOf("/") + 1);
|
|
@@ -705,13 +745,13 @@ function getSchemaFileName(path) {
|
|
|
705
745
|
function normalizeSafe(value) {
|
|
706
746
|
let result;
|
|
707
747
|
value = toUnix(value);
|
|
708
|
-
result = toUnix(
|
|
748
|
+
result = toUnix(nodePath.normalize(value));
|
|
709
749
|
if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
710
750
|
else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
|
|
711
751
|
return result;
|
|
712
752
|
}
|
|
713
753
|
function joinSafe(...values) {
|
|
714
|
-
let result = toUnix(
|
|
754
|
+
let result = toUnix(nodePath.join(...values.map((v) => toUnix(v))));
|
|
715
755
|
if (values.length > 0) {
|
|
716
756
|
const firstValue = toUnix(values[0]);
|
|
717
757
|
if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
@@ -742,14 +782,14 @@ function joinSafe(...values) {
|
|
|
742
782
|
* @returns The relative import path string.
|
|
743
783
|
*/
|
|
744
784
|
function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileExtension = false) {
|
|
745
|
-
if (!
|
|
746
|
-
if (!
|
|
747
|
-
const importerDir =
|
|
748
|
-
const relativePath =
|
|
749
|
-
let posixPath =
|
|
785
|
+
if (!nodePath.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
|
|
786
|
+
if (!nodePath.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
|
|
787
|
+
const importerDir = nodePath.dirname(importerFilePath);
|
|
788
|
+
const relativePath = nodePath.relative(importerDir, exporterFilePath);
|
|
789
|
+
let posixPath = nodePath.posix.join(...relativePath.split(nodePath.sep));
|
|
750
790
|
if (!posixPath.startsWith("./") && !posixPath.startsWith("../")) posixPath = `./${posixPath}`;
|
|
751
791
|
if (!includeFileExtension) {
|
|
752
|
-
const ext =
|
|
792
|
+
const ext = nodePath.extname(posixPath);
|
|
753
793
|
if (ext && posixPath.endsWith(ext)) posixPath = posixPath.slice(0, -ext.length);
|
|
754
794
|
}
|
|
755
795
|
return posixPath;
|
|
@@ -758,20 +798,20 @@ function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileEx
|
|
|
758
798
|
//#region src/utils/resolve-version.ts
|
|
759
799
|
function resolveInstalledVersion(packageName, fromDir) {
|
|
760
800
|
try {
|
|
761
|
-
const require = createRequire(
|
|
801
|
+
const require = createRequire(nodePath.join(fromDir, "noop.js"));
|
|
762
802
|
try {
|
|
763
803
|
return require(`${packageName}/package.json`).version;
|
|
764
804
|
} catch (directError) {
|
|
765
805
|
if (directError instanceof Error && "code" in directError && directError.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
766
806
|
const entryPath = require.resolve(packageName);
|
|
767
|
-
let dir =
|
|
768
|
-
while (dir !==
|
|
769
|
-
const pkgPath =
|
|
807
|
+
let dir = nodePath.dirname(entryPath);
|
|
808
|
+
while (dir !== nodePath.parse(dir).root) {
|
|
809
|
+
const pkgPath = nodePath.join(dir, "package.json");
|
|
770
810
|
if (existsSync(pkgPath)) {
|
|
771
811
|
const pkgData = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
772
812
|
if (pkgData.name === packageName) return pkgData.version;
|
|
773
813
|
}
|
|
774
|
-
dir =
|
|
814
|
+
dir = nodePath.dirname(dir);
|
|
775
815
|
}
|
|
776
816
|
return;
|
|
777
817
|
}
|
|
@@ -1001,6 +1041,24 @@ function isSyntheticDefaultImportsAllow(config) {
|
|
|
1001
1041
|
if (!config) return true;
|
|
1002
1042
|
return !!(config.compilerOptions?.allowSyntheticDefaultImports ?? config.compilerOptions?.esModuleInterop);
|
|
1003
1043
|
}
|
|
1044
|
+
const NODE_NEXT_MODULES = new Set(["nodenext", "node16"]);
|
|
1045
|
+
const NODE_NEXT_EXTENSION_MAP = [
|
|
1046
|
+
[".tsx", ".jsx"],
|
|
1047
|
+
[".mts", ".mjs"],
|
|
1048
|
+
[".cts", ".cjs"],
|
|
1049
|
+
[".ts", ".js"]
|
|
1050
|
+
];
|
|
1051
|
+
function getImportExtension(fileExtension, tsconfig) {
|
|
1052
|
+
const compilerOptions = tsconfig?.compilerOptions;
|
|
1053
|
+
if (compilerOptions?.allowImportingTsExtensions) return fileExtension;
|
|
1054
|
+
const module = compilerOptions?.module?.toLowerCase();
|
|
1055
|
+
const moduleResolution = compilerOptions?.moduleResolution?.toLowerCase();
|
|
1056
|
+
if (module && NODE_NEXT_MODULES.has(module) || moduleResolution && NODE_NEXT_MODULES.has(moduleResolution)) {
|
|
1057
|
+
for (const [from, to] of NODE_NEXT_EXTENSION_MAP) if (fileExtension.endsWith(from)) return `${fileExtension.slice(0, -from.length)}${to}`;
|
|
1058
|
+
return fileExtension;
|
|
1059
|
+
}
|
|
1060
|
+
return fileExtension.replace(/\.ts$/, "") || "";
|
|
1061
|
+
}
|
|
1004
1062
|
//#endregion
|
|
1005
1063
|
//#region src/getters/enum.ts
|
|
1006
1064
|
/**
|
|
@@ -1210,12 +1268,34 @@ function getCombinedEnumValue(inputs) {
|
|
|
1210
1268
|
}
|
|
1211
1269
|
//#endregion
|
|
1212
1270
|
//#region src/getters/ref.ts
|
|
1271
|
+
/**
|
|
1272
|
+
* `$ref`s targeting these sections under `#/components/...` are emitted as
|
|
1273
|
+
* named TypeScript imports (e.g. `import type { Pet } from './model'`).
|
|
1274
|
+
* Refs to any other location — for example `#/paths/.../schema` produced by
|
|
1275
|
+
* JSON-Schema-Ref-Parser `bundle()` — have no corresponding `export type`
|
|
1276
|
+
* and must be inlined by the resolver. See issue #398.
|
|
1277
|
+
*/
|
|
1278
|
+
const NAMED_COMPONENT_SECTIONS = [
|
|
1279
|
+
"schemas",
|
|
1280
|
+
"responses",
|
|
1281
|
+
"parameters",
|
|
1282
|
+
"requestBodies"
|
|
1283
|
+
];
|
|
1213
1284
|
const RefComponentSuffix = {
|
|
1214
1285
|
schemas: "",
|
|
1215
1286
|
responses: "Response",
|
|
1216
1287
|
parameters: "Parameter",
|
|
1217
1288
|
requestBodies: "Body"
|
|
1218
1289
|
};
|
|
1290
|
+
const COMPONENT_REF_PATTERN = new RegExp(String.raw`^#\/components\/(${NAMED_COMPONENT_SECTIONS.join("|")})\/[^/]+$`);
|
|
1291
|
+
/**
|
|
1292
|
+
* True iff `ref` targets a named slot eligible for emission as a TypeScript
|
|
1293
|
+
* import. Used by `resolveValue` to decide between named import vs inlining
|
|
1294
|
+
* the resolved schema.
|
|
1295
|
+
*/
|
|
1296
|
+
function isComponentRef(ref) {
|
|
1297
|
+
return COMPONENT_REF_PATTERN.test(ref);
|
|
1298
|
+
}
|
|
1219
1299
|
const regex = /* @__PURE__ */ new RegExp("~1", "g");
|
|
1220
1300
|
/**
|
|
1221
1301
|
* Return the output type from the $ref
|
|
@@ -1358,7 +1438,34 @@ function resolveExampleRefs(examples, context) {
|
|
|
1358
1438
|
//#region src/resolvers/value.ts
|
|
1359
1439
|
function resolveValue({ schema, name, context, formDataContext }) {
|
|
1360
1440
|
if (isReference(schema)) {
|
|
1441
|
+
const refValue = schema.$ref;
|
|
1361
1442
|
const { schema: schemaObject, imports } = resolveRef(schema, context);
|
|
1443
|
+
if (refValue && !isComponentRef(refValue)) {
|
|
1444
|
+
if (context.parents?.includes(refValue)) return {
|
|
1445
|
+
value: "unknown",
|
|
1446
|
+
imports: [],
|
|
1447
|
+
schemas: [],
|
|
1448
|
+
type: "unknown",
|
|
1449
|
+
isEnum: false,
|
|
1450
|
+
originalSchema: schemaObject,
|
|
1451
|
+
hasReadonlyProps: false,
|
|
1452
|
+
isRef: false,
|
|
1453
|
+
dependencies: []
|
|
1454
|
+
};
|
|
1455
|
+
return {
|
|
1456
|
+
...getScalar({
|
|
1457
|
+
item: schemaObject,
|
|
1458
|
+
name,
|
|
1459
|
+
context: {
|
|
1460
|
+
...context,
|
|
1461
|
+
parents: [...context.parents ?? [], refValue]
|
|
1462
|
+
},
|
|
1463
|
+
formDataContext
|
|
1464
|
+
}),
|
|
1465
|
+
originalSchema: schemaObject,
|
|
1466
|
+
isRef: false
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1362
1469
|
const resolvedImport = imports[0];
|
|
1363
1470
|
let hasReadonlyProps = false;
|
|
1364
1471
|
const refName = resolvedImport.name;
|
|
@@ -1568,7 +1675,7 @@ function getArray({ schema, name, context, formDataContext }) {
|
|
|
1568
1675
|
}
|
|
1569
1676
|
//#endregion
|
|
1570
1677
|
//#region src/getters/res-req-types.ts
|
|
1571
|
-
const getSchemaType = (s) => s.type;
|
|
1678
|
+
const getSchemaType$1 = (s) => s.type;
|
|
1572
1679
|
const getSchemaCombined = (s) => s.oneOf ?? s.anyOf ?? s.allOf;
|
|
1573
1680
|
const getSchemaOneOf = (s) => s.oneOf;
|
|
1574
1681
|
const getSchemaAnyOf = (s) => s.anyOf;
|
|
@@ -1957,7 +2064,7 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
|
|
|
1957
2064
|
${resolvedValue}});\n`;
|
|
1958
2065
|
} else valueStr = "JSON.stringify(value)";
|
|
1959
2066
|
else {
|
|
1960
|
-
const itemType = getSchemaType(itemSchema);
|
|
2067
|
+
const itemType = getSchemaType$1(itemSchema);
|
|
1961
2068
|
if (itemType === "number" || Array.isArray(itemType) && itemType.includes("number") || itemType === "integer" || Array.isArray(itemType) && itemType.includes("integer") || itemType === "boolean" || Array.isArray(itemType) && itemType.includes("boolean")) valueStr = "value.toString()";
|
|
1962
2069
|
}
|
|
1963
2070
|
}
|
|
@@ -1965,7 +2072,7 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
|
|
|
1965
2072
|
if (!hasNonPrimitiveChild) formDataValue = `${valueKey}.forEach((value, index${depth > 0 ? depth : ""}) => ${variableName}.append(\`${keyPrefix}${key}[\${index${depth > 0 ? depth : ""}}]\`, ${valueStr}));\n`;
|
|
1966
2073
|
} else formDataValue = `${valueKey}.forEach(value => ${variableName}.append(\`${keyPrefix}${key}${context.output.override.formData.arrayHandling === FormDataArrayHandling.SERIALIZE_WITH_BRACKETS ? "[]" : ""}\`, ${valueStr}));\n`;
|
|
1967
2074
|
} else if ((() => {
|
|
1968
|
-
const propType = getSchemaType(property);
|
|
2075
|
+
const propType = getSchemaType$1(property);
|
|
1969
2076
|
return propType === "number" || Array.isArray(propType) && propType.includes("number") || propType === "integer" || Array.isArray(propType) && propType.includes("integer") || propType === "boolean" || Array.isArray(propType) && propType.includes("boolean");
|
|
1970
2077
|
})()) formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey}.toString())\n`;
|
|
1971
2078
|
else formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey});\n`;
|
|
@@ -1989,7 +2096,7 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
|
|
|
1989
2096
|
})) existSubSchemaNullable = true;
|
|
1990
2097
|
}
|
|
1991
2098
|
const isRequired = getSchemaRequired(schema)?.includes(key) && !isRequestBodyOptional;
|
|
1992
|
-
const propType = getSchemaType(property);
|
|
2099
|
+
const propType = getSchemaType$1(property);
|
|
1993
2100
|
if (property.nullable || Array.isArray(propType) && propType.includes("null") || existSubSchemaNullable) {
|
|
1994
2101
|
if (isRequired) {
|
|
1995
2102
|
formDataValues += `if(${valueKey} !== null) {\n ${formDataValue} }\n`;
|
|
@@ -2253,7 +2360,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2253
2360
|
if (!index) acc.value += "{";
|
|
2254
2361
|
const doc = jsDoc(schema, true, context);
|
|
2255
2362
|
const propertyDoc = doc ? `${doc.trimEnd().split("\n").map((line) => ` ${line}`).join("\n")}\n` : "";
|
|
2256
|
-
if (isReadOnly) acc.hasReadonlyProps = true;
|
|
2363
|
+
if (isReadOnly || resolvedValue.hasReadonlyProps) acc.hasReadonlyProps = true;
|
|
2257
2364
|
const constValue = "const" in schema ? schema.const : void 0;
|
|
2258
2365
|
const hasConst = constValue !== void 0;
|
|
2259
2366
|
let constLiteral;
|
|
@@ -2999,6 +3106,50 @@ const isOpenApiSchemaObject = (value) => {
|
|
|
2999
3106
|
if (!value || typeof value !== "object") return false;
|
|
3000
3107
|
return !("$ref" in value);
|
|
3001
3108
|
};
|
|
3109
|
+
/**
|
|
3110
|
+
* A `$ref` schema object (e.g. array `items` or a oneOf/anyOf/allOf variant
|
|
3111
|
+
* pointing at a component). We don't resolve the reference here, but a query
|
|
3112
|
+
* parameter behind a `$ref` is virtually always a complex (object-like) type,
|
|
3113
|
+
* so it must be treated as non-primitive. Over-flagging is harmless: the only
|
|
3114
|
+
* consumer (the Angular `nonPrimitiveKeys` passthrough) is gated on a
|
|
3115
|
+
* configured `paramsSerializer`, which is precisely what handles raw values.
|
|
3116
|
+
*/
|
|
3117
|
+
const isRefObject = (value) => !!value && typeof value === "object" && "$ref" in value;
|
|
3118
|
+
const getSchemaType = (schema) => {
|
|
3119
|
+
const type = schema.type;
|
|
3120
|
+
if (typeof type === "string") return type;
|
|
3121
|
+
if (Array.isArray(type) && type.every((variant) => typeof variant === "string")) return type;
|
|
3122
|
+
};
|
|
3123
|
+
/**
|
|
3124
|
+
* Detects whether a query parameter's resolved schema is non-primitive — i.e.
|
|
3125
|
+
* an object, an array of objects, or a composition (oneOf/anyOf/allOf) that
|
|
3126
|
+
* resolves to a non-primitive shape.
|
|
3127
|
+
*
|
|
3128
|
+
* Used by Angular generators so the default `filterParams` helper preserves
|
|
3129
|
+
* such values instead of silently dropping them. Angular's `HttpParams` only
|
|
3130
|
+
* accepts primitives, but a user-provided `paramsSerializer`, `mutator`, or
|
|
3131
|
+
* `paramsFilter` may need the raw object to flatten or stringify it.
|
|
3132
|
+
*/
|
|
3133
|
+
const isSchemaNonPrimitive = (schema) => {
|
|
3134
|
+
const schemaType = getSchemaType(schema);
|
|
3135
|
+
const type = Array.isArray(schemaType) ? schemaType.filter((variant) => variant !== "null") : schemaType;
|
|
3136
|
+
const additionalProperties = schema.additionalProperties;
|
|
3137
|
+
if (type === "object") return true;
|
|
3138
|
+
if (Array.isArray(type) && type.includes("object")) return true;
|
|
3139
|
+
if (type === "array" || Array.isArray(type) && type.includes("array")) {
|
|
3140
|
+
const items = schema.items;
|
|
3141
|
+
if (isOpenApiSchemaObject(items)) return isSchemaNonPrimitive(items);
|
|
3142
|
+
return true;
|
|
3143
|
+
}
|
|
3144
|
+
const compositions = [
|
|
3145
|
+
...Array.isArray(schema.oneOf) ? schema.oneOf : [],
|
|
3146
|
+
...Array.isArray(schema.anyOf) ? schema.anyOf : [],
|
|
3147
|
+
...Array.isArray(schema.allOf) ? schema.allOf : []
|
|
3148
|
+
];
|
|
3149
|
+
if (compositions.length > 0) return compositions.some((variant) => isOpenApiSchemaObject(variant) ? isSchemaNonPrimitive(variant) : isRefObject(variant));
|
|
3150
|
+
if (!type && (schema.properties !== void 0 || additionalProperties !== void 0 && additionalProperties !== false)) return true;
|
|
3151
|
+
return false;
|
|
3152
|
+
};
|
|
3002
3153
|
const isSchemaNullable = (schema) => {
|
|
3003
3154
|
if (schema.nullable === true) return true;
|
|
3004
3155
|
if (schema.type === "null") return true;
|
|
@@ -3076,6 +3227,7 @@ function getQueryParams({ queryParams, operationName, context, suffix = "params"
|
|
|
3076
3227
|
const type = types.map(({ definition }) => definition).join("\n");
|
|
3077
3228
|
const allOptional = queryParams.every(({ parameter }) => !parameter.required);
|
|
3078
3229
|
const requiredNullableKeys = types.filter(({ required, originalSchema }) => required && isSchemaNullable(originalSchema)).map(({ name }) => name);
|
|
3230
|
+
const nonPrimitiveKeys = types.filter(({ originalSchema }) => isSchemaNonPrimitive(originalSchema)).map(({ name }) => name);
|
|
3079
3231
|
return {
|
|
3080
3232
|
schema: {
|
|
3081
3233
|
name,
|
|
@@ -3084,7 +3236,8 @@ function getQueryParams({ queryParams, operationName, context, suffix = "params"
|
|
|
3084
3236
|
},
|
|
3085
3237
|
deps: schemas,
|
|
3086
3238
|
isOptional: allOptional,
|
|
3087
|
-
requiredNullableKeys
|
|
3239
|
+
requiredNullableKeys,
|
|
3240
|
+
...nonPrimitiveKeys.length > 0 ? { nonPrimitiveKeys } : {}
|
|
3088
3241
|
};
|
|
3089
3242
|
}
|
|
3090
3243
|
//#endregion
|
|
@@ -3240,11 +3393,11 @@ function generateComponentDefinition(responses = {}, context, suffix) {
|
|
|
3240
3393
|
}
|
|
3241
3394
|
//#endregion
|
|
3242
3395
|
//#region src/generators/imports.ts
|
|
3243
|
-
function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CASE }) {
|
|
3396
|
+
function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CASE, importExtension = "" }) {
|
|
3244
3397
|
if (imports.length === 0) return "";
|
|
3245
3398
|
const grouped = groupBy(uniqueWith(imports, (a, b) => a.name === b.name && a.default === b.default && a.alias === b.alias && a.values === b.values && a.isConstant === b.isConstant && a.namespaceImport === b.namespaceImport && a.syntheticDefaultImport === b.syntheticDefaultImport && a.importPath === b.importPath).map((imp) => ({
|
|
3246
3399
|
...imp,
|
|
3247
|
-
importPath: imp.importPath ?? `./${conventionName(imp.name, namingConvention)}`
|
|
3400
|
+
importPath: imp.importPath ?? `./${conventionName(imp.name, namingConvention)}${importExtension}`
|
|
3248
3401
|
})), (imp) => !imp.default && !imp.namespaceImport && !imp.syntheticDefaultImport && !imp.values && !imp.isConstant ? `aggregate|${imp.importPath}` : `single|${imp.importPath}|${imp.name}|${imp.alias ?? ""}|${String(imp.default)}|${String(imp.namespaceImport)}|${String(imp.syntheticDefaultImport)}|${String(imp.values)}|${String(imp.isConstant)}`);
|
|
3249
3402
|
return Object.entries(grouped).toSorted(([a], [b]) => a.localeCompare(b, "en", { numeric: true })).map(([, group]) => {
|
|
3250
3403
|
const sample = group[0];
|
|
@@ -3256,7 +3409,8 @@ function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CA
|
|
|
3256
3409
|
function generateMutatorImports({ mutators, implementation, oneMore }) {
|
|
3257
3410
|
let imports = "";
|
|
3258
3411
|
for (const mutator of uniqueWith(mutators, (a, b) => a.name === b.name && a.default === b.default)) {
|
|
3259
|
-
const
|
|
3412
|
+
const isRelativeImport = mutator.path.startsWith(".");
|
|
3413
|
+
const path = `${oneMore && isRelativeImport ? "../" : ""}${mutator.path}`;
|
|
3260
3414
|
const importDefault = mutator.default ? mutator.name : `{ ${mutator.name} }`;
|
|
3261
3415
|
imports += `import ${importDefault} from '${path}';`;
|
|
3262
3416
|
imports += "\n";
|
|
@@ -3603,16 +3757,24 @@ function removeComments(file) {
|
|
|
3603
3757
|
* (e.g. observe-mode branches), prefer getAngularFilteredParamsCallExpression +
|
|
3604
3758
|
* getAngularFilteredParamsHelperBody instead.
|
|
3605
3759
|
*/
|
|
3606
|
-
const getAngularFilteredParamsExpression = (paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false) => {
|
|
3607
|
-
const
|
|
3760
|
+
const getAngularFilteredParamsExpression = (paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false, nonPrimitiveKeys = []) => {
|
|
3761
|
+
const hasPassthrough = nonPrimitiveKeys.length > 0;
|
|
3762
|
+
const filteredParamValueType = hasPassthrough ? "unknown" : `string | number | boolean${preserveRequiredNullables ? " | null" : ""} | Array<string | number | boolean>`;
|
|
3763
|
+
const passthroughBranch = hasPassthrough ? ` if (passthroughKeys.has(key)) {
|
|
3764
|
+
if (value !== undefined) {
|
|
3765
|
+
filteredParams[key] = value;
|
|
3766
|
+
}
|
|
3767
|
+
continue;
|
|
3768
|
+
}
|
|
3769
|
+
` : "";
|
|
3608
3770
|
const preserveNullableBranch = preserveRequiredNullables ? ` } else if (value === null && requiredNullableParamKeys.has(key)) {
|
|
3609
3771
|
filteredParams[key] = null;
|
|
3610
3772
|
` : "";
|
|
3611
3773
|
return `(() => {
|
|
3612
|
-
const requiredNullableParamKeys = new Set<string>(${JSON.stringify(requiredNullableParamKeys)});
|
|
3774
|
+
${hasPassthrough ? ` const passthroughKeys = new Set<string>(${JSON.stringify(nonPrimitiveKeys)});\n` : ""} const requiredNullableParamKeys = new Set<string>(${JSON.stringify(requiredNullableParamKeys)});
|
|
3613
3775
|
const filteredParams: Record<string, ${filteredParamValueType}> = {};
|
|
3614
3776
|
for (const [key, value] of Object.entries(${paramsExpression})) {
|
|
3615
|
-
if (Array.isArray(value)) {
|
|
3777
|
+
${passthroughBranch} if (Array.isArray(value)) {
|
|
3616
3778
|
const filtered = value.filter(
|
|
3617
3779
|
(item) =>
|
|
3618
3780
|
item != null &&
|
|
@@ -3647,19 +3809,34 @@ function filterParams(
|
|
|
3647
3809
|
params: Record<string, unknown>,
|
|
3648
3810
|
requiredNullableKeys?: ReadonlySet<string>,
|
|
3649
3811
|
preserveRequiredNullables?: false,
|
|
3812
|
+
passthroughKeys?: undefined,
|
|
3650
3813
|
): Record<string, AngularHttpParamValue>;
|
|
3651
3814
|
function filterParams(
|
|
3652
3815
|
params: Record<string, unknown>,
|
|
3653
3816
|
requiredNullableKeys: ReadonlySet<string> | undefined,
|
|
3654
3817
|
preserveRequiredNullables: true,
|
|
3818
|
+
passthroughKeys?: undefined,
|
|
3655
3819
|
): Record<string, AngularHttpParamValueWithNullable>;
|
|
3820
|
+
function filterParams(
|
|
3821
|
+
params: Record<string, unknown>,
|
|
3822
|
+
requiredNullableKeys: ReadonlySet<string> | undefined,
|
|
3823
|
+
preserveRequiredNullables: boolean | undefined,
|
|
3824
|
+
passthroughKeys: ReadonlySet<string>,
|
|
3825
|
+
): Record<string, unknown>;
|
|
3656
3826
|
function filterParams(
|
|
3657
3827
|
params: Record<string, unknown>,
|
|
3658
3828
|
requiredNullableKeys: ReadonlySet<string> = new Set(),
|
|
3659
3829
|
preserveRequiredNullables = false,
|
|
3660
|
-
|
|
3661
|
-
|
|
3830
|
+
passthroughKeys: ReadonlySet<string> = new Set(),
|
|
3831
|
+
): Record<string, unknown> {
|
|
3832
|
+
const filteredParams: Record<string, unknown> = {};
|
|
3662
3833
|
for (const [key, value] of Object.entries(params)) {
|
|
3834
|
+
if (passthroughKeys.has(key)) {
|
|
3835
|
+
if (value !== undefined) {
|
|
3836
|
+
filteredParams[key] = value;
|
|
3837
|
+
}
|
|
3838
|
+
continue;
|
|
3839
|
+
}
|
|
3663
3840
|
if (Array.isArray(value)) {
|
|
3664
3841
|
const filtered = value.filter(
|
|
3665
3842
|
(item) =>
|
|
@@ -3691,14 +3868,34 @@ function filterParams(
|
|
|
3691
3868
|
/**
|
|
3692
3869
|
* Returns a call expression to the `filterParams` helper function.
|
|
3693
3870
|
*/
|
|
3694
|
-
const getAngularFilteredParamsCallExpression = (paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false
|
|
3871
|
+
const getAngularFilteredParamsCallExpression = (paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false, nonPrimitiveKeys = []) => {
|
|
3872
|
+
const baseArgs = `${paramsExpression}, new Set<string>(${JSON.stringify(requiredNullableParamKeys)})`;
|
|
3873
|
+
if (nonPrimitiveKeys.length > 0) return `filterParams(${baseArgs}, ${preserveRequiredNullables}, new Set<string>(${JSON.stringify(nonPrimitiveKeys)}))`;
|
|
3874
|
+
return `filterParams(${baseArgs}${preserveRequiredNullables ? ", true" : ""})`;
|
|
3875
|
+
};
|
|
3876
|
+
/**
|
|
3877
|
+
* Returns the filter call/IIFE used to massage query params before passing
|
|
3878
|
+
* them to Angular's HttpParams. When the user supplied a `paramsFilter`
|
|
3879
|
+
* mutator, the built-in `filterParams` is bypassed entirely and the user's
|
|
3880
|
+
* function is called with the raw params — they own nullish-stripping and
|
|
3881
|
+
* any object/array handling. Otherwise the built-in filter is used (either
|
|
3882
|
+
* the shared helper or an inline IIFE), and callers should only pass
|
|
3883
|
+
* `nonPrimitiveKeys` when a downstream serializer or custom consumer can
|
|
3884
|
+
* legally handle raw object/array values.
|
|
3885
|
+
*/
|
|
3886
|
+
const buildAngularParamsFilterExpression = ({ paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false, nonPrimitiveKeys = [], paramsFilter, useSharedHelper }) => {
|
|
3887
|
+
if (paramsFilter) return `${paramsFilter.name}(${paramsExpression})`;
|
|
3888
|
+
if (useSharedHelper) return getAngularFilteredParamsCallExpression(paramsExpression, requiredNullableParamKeys, preserveRequiredNullables, nonPrimitiveKeys);
|
|
3889
|
+
return getAngularFilteredParamsExpression(paramsExpression, requiredNullableParamKeys, preserveRequiredNullables, nonPrimitiveKeys);
|
|
3890
|
+
};
|
|
3695
3891
|
function generateBodyOptions(body, isFormData, isFormUrlEncoded) {
|
|
3696
3892
|
if (isFormData && body.formData) return "formData";
|
|
3697
3893
|
if (isFormUrlEncoded && body.formUrlEncoded) return "formUrlEncoded";
|
|
3698
3894
|
if (body.implementation) return body.implementation;
|
|
3699
3895
|
}
|
|
3700
|
-
function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions }) {
|
|
3896
|
+
function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, nonPrimitiveQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
|
|
3701
3897
|
const isRequestOptions = requestOptions !== false;
|
|
3898
|
+
const angularPassthroughQueryParamKeys = paramsSerializer ? nonPrimitiveQueryParamKeys : [];
|
|
3702
3899
|
const signalVar = hasSignalParam ? "querySignal" : "signal";
|
|
3703
3900
|
const signalProp = hasSignalParam ? `signal: ${signalVar}` : "signal";
|
|
3704
3901
|
if (!queryParams && !headers && !response.isBlob && response.definition.success !== "string") {
|
|
@@ -3712,7 +3909,14 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
|
|
|
3712
3909
|
let value = "";
|
|
3713
3910
|
if (!isRequestOptions) {
|
|
3714
3911
|
if (queryParams) if (isAngular) {
|
|
3715
|
-
const iifeExpr =
|
|
3912
|
+
const iifeExpr = buildAngularParamsFilterExpression({
|
|
3913
|
+
paramsExpression: "params ?? {}",
|
|
3914
|
+
requiredNullableParamKeys: requiredNullableQueryParamKeys,
|
|
3915
|
+
preserveRequiredNullables: !!paramsSerializer,
|
|
3916
|
+
nonPrimitiveKeys: angularPassthroughQueryParamKeys,
|
|
3917
|
+
paramsFilter,
|
|
3918
|
+
useSharedHelper: false
|
|
3919
|
+
});
|
|
3716
3920
|
value += paramsSerializer ? `\n params: ${paramsSerializer.name}(${iifeExpr}),` : `\n params: ${iifeExpr},`;
|
|
3717
3921
|
} else value += "\n params,";
|
|
3718
3922
|
if (headers) value += "\n headers,";
|
|
@@ -3729,10 +3933,25 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
|
|
|
3729
3933
|
if (queryParams) if (isVue) value += "\n params: {...unref(params), ...options?.params},";
|
|
3730
3934
|
else if (isAngular && angularParamsRef) value += `\n params: ${angularParamsRef},`;
|
|
3731
3935
|
else if (isAngular && paramsSerializer) {
|
|
3732
|
-
const callExpr =
|
|
3936
|
+
const callExpr = buildAngularParamsFilterExpression({
|
|
3937
|
+
paramsExpression: "{...params, ...options?.params}",
|
|
3938
|
+
requiredNullableParamKeys: requiredNullableQueryParamKeys,
|
|
3939
|
+
preserveRequiredNullables: true,
|
|
3940
|
+
nonPrimitiveKeys: angularPassthroughQueryParamKeys,
|
|
3941
|
+
paramsFilter,
|
|
3942
|
+
useSharedHelper: true
|
|
3943
|
+
});
|
|
3733
3944
|
value += `\n params: ${paramsSerializer.name}(${callExpr}),`;
|
|
3734
|
-
} else if (isAngular)
|
|
3735
|
-
|
|
3945
|
+
} else if (isAngular) {
|
|
3946
|
+
const callExpr = buildAngularParamsFilterExpression({
|
|
3947
|
+
paramsExpression: "{...params, ...options?.params}",
|
|
3948
|
+
requiredNullableParamKeys: requiredNullableQueryParamKeys,
|
|
3949
|
+
nonPrimitiveKeys: angularPassthroughQueryParamKeys,
|
|
3950
|
+
paramsFilter,
|
|
3951
|
+
useSharedHelper: true
|
|
3952
|
+
});
|
|
3953
|
+
value += `\n params: ${callExpr},`;
|
|
3954
|
+
} else value += "\n params: {...params, ...options?.params},";
|
|
3736
3955
|
if (headers) value += "\n headers: {...headers, ...options?.headers},";
|
|
3737
3956
|
}
|
|
3738
3957
|
if (!isAngular && queryParams && (paramsSerializer || paramsSerializerOptions?.qs)) {
|
|
@@ -3741,13 +3960,14 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
|
|
|
3741
3960
|
}
|
|
3742
3961
|
return value;
|
|
3743
3962
|
}
|
|
3744
|
-
function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions }) {
|
|
3963
|
+
function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
|
|
3745
3964
|
const bodyIdentifier = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : void 0;
|
|
3746
3965
|
const axiosOptions = generateAxiosOptions({
|
|
3747
3966
|
response,
|
|
3748
3967
|
angularObserve,
|
|
3749
3968
|
angularParamsRef,
|
|
3750
3969
|
requiredNullableQueryParamKeys: queryParams?.requiredNullableKeys,
|
|
3970
|
+
nonPrimitiveQueryParamKeys: queryParams?.nonPrimitiveKeys,
|
|
3751
3971
|
queryParams: queryParams?.schema,
|
|
3752
3972
|
headers: headers?.schema,
|
|
3753
3973
|
requestOptions,
|
|
@@ -3757,7 +3977,8 @@ function generateOptions({ route, body, angularObserve, angularParamsRef, header
|
|
|
3757
3977
|
isVue: isVue ?? false,
|
|
3758
3978
|
isAngular: isAngular ?? false,
|
|
3759
3979
|
paramsSerializer,
|
|
3760
|
-
paramsSerializerOptions
|
|
3980
|
+
paramsSerializerOptions,
|
|
3981
|
+
paramsFilter
|
|
3761
3982
|
});
|
|
3762
3983
|
const trimmedAxiosOptions = axiosOptions.trim();
|
|
3763
3984
|
const isRawOptionsArgument = trimmedAxiosOptions === "options" || trimmedAxiosOptions.startsWith("(") && trimmedAxiosOptions.endsWith(")") || trimmedAxiosOptions.startsWith("{") && trimmedAxiosOptions.endsWith("}");
|
|
@@ -3776,18 +3997,26 @@ function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
|
|
|
3776
3997
|
if (body.implementation) return `,\n data: ${body.implementation}`;
|
|
3777
3998
|
return "";
|
|
3778
3999
|
}
|
|
3779
|
-
function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNullableQueryParamKeys, queryParams) {
|
|
4000
|
+
function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNullableQueryParamKeys, queryParams, paramsFilter) {
|
|
3780
4001
|
if (!queryParams && !response.isBlob) return "";
|
|
3781
4002
|
let value = "";
|
|
3782
4003
|
if (queryParams) if (isVue) value += ",\n params: unref(params)";
|
|
3783
|
-
else if (isAngular)
|
|
3784
|
-
|
|
4004
|
+
else if (isAngular) {
|
|
4005
|
+
const paramsExpr = buildAngularParamsFilterExpression({
|
|
4006
|
+
paramsExpression: "params ?? {}",
|
|
4007
|
+
requiredNullableParamKeys: requiredNullableQueryParamKeys,
|
|
4008
|
+
nonPrimitiveKeys: queryParams.nonPrimitiveKeys,
|
|
4009
|
+
paramsFilter,
|
|
4010
|
+
useSharedHelper: false
|
|
4011
|
+
});
|
|
4012
|
+
value += `,\n params: ${paramsExpr}`;
|
|
4013
|
+
} else value += ",\n params";
|
|
3785
4014
|
if (response.isBlob) value += `,\n responseType: 'blob'`;
|
|
3786
4015
|
return value;
|
|
3787
4016
|
}
|
|
3788
|
-
function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue, isAngular }) {
|
|
4017
|
+
function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue, isAngular, paramsFilter }) {
|
|
3789
4018
|
const bodyOptions = getIsBodyVerb(verb) ? generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) : "";
|
|
3790
|
-
const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams);
|
|
4019
|
+
const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams, paramsFilter);
|
|
3791
4020
|
const ignoreContentTypes = isAngular ? ["multipart/form-data"] : [];
|
|
3792
4021
|
const headerOptions = body.contentType && !ignoreContentTypes.includes(body.contentType) ? `,\n headers: {'Content-Type': '${body.contentType}', ${headers ? "...headers" : ""}}` : headers ? ",\n headers" : "";
|
|
3793
4022
|
const signalVar = hasSignalParam ? "querySignal" : "signal";
|
|
@@ -4100,6 +4329,13 @@ async function buildVerbOption({ verb, output, operation, route, pathRoute, verb
|
|
|
4100
4329
|
workspace: context.workspace,
|
|
4101
4330
|
tsconfig: context.output.tsconfig
|
|
4102
4331
|
}) : void 0,
|
|
4332
|
+
paramsFilter: isString(override.paramsFilter) || isObject(override.paramsFilter) ? await generateMutator({
|
|
4333
|
+
output: output.target,
|
|
4334
|
+
name: "paramsFilter",
|
|
4335
|
+
mutator: override.paramsFilter,
|
|
4336
|
+
workspace: context.workspace,
|
|
4337
|
+
tsconfig: context.output.tsconfig
|
|
4338
|
+
}) : void 0,
|
|
4103
4339
|
fetchReviver: isString(override.fetch.jsonReviver) || isObject(override.fetch.jsonReviver) ? await generateMutator({
|
|
4104
4340
|
output: output.target,
|
|
4105
4341
|
name: "fetchReviver",
|
|
@@ -4264,19 +4500,12 @@ function splitSchemasByType(schemas) {
|
|
|
4264
4500
|
};
|
|
4265
4501
|
}
|
|
4266
4502
|
/**
|
|
4267
|
-
* Get the import extension from a file extension.
|
|
4268
|
-
* Removes `.ts` suffix since TypeScript doesn't need it in imports.
|
|
4269
|
-
*/
|
|
4270
|
-
function getImportExtension(fileExtension) {
|
|
4271
|
-
return fileExtension.replace(/\.ts$/, "") || "";
|
|
4272
|
-
}
|
|
4273
|
-
/**
|
|
4274
4503
|
* Fix cross-directory imports when schemas reference other schemas in a different directory.
|
|
4275
4504
|
* Updates import paths to use correct relative paths between directories.
|
|
4276
4505
|
*/
|
|
4277
|
-
function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingConvention, fileExtension) {
|
|
4506
|
+
function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingConvention, fileExtension, tsconfig) {
|
|
4278
4507
|
const relativePath = relativeSafe(fromPath, toPath);
|
|
4279
|
-
const importExtension = getImportExtension(fileExtension);
|
|
4508
|
+
const importExtension = getImportExtension(fileExtension, tsconfig);
|
|
4280
4509
|
for (const schema of schemas) schema.imports = schema.imports.map((imp) => {
|
|
4281
4510
|
if (targetSchemaNames.has(imp.name)) {
|
|
4282
4511
|
const fileName = conventionName(imp.name, namingConvention);
|
|
@@ -4291,14 +4520,14 @@ function fixSchemaImports(schemas, targetSchemaNames, fromPath, toPath, namingCo
|
|
|
4291
4520
|
/**
|
|
4292
4521
|
* Fix imports in operation schemas that reference regular schemas.
|
|
4293
4522
|
*/
|
|
4294
|
-
function fixCrossDirectoryImports(operationSchemas, regularSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension) {
|
|
4295
|
-
fixSchemaImports(operationSchemas, regularSchemaNames, operationSchemaPath, schemaPath, namingConvention, fileExtension);
|
|
4523
|
+
function fixCrossDirectoryImports(operationSchemas, regularSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension, tsconfig) {
|
|
4524
|
+
fixSchemaImports(operationSchemas, regularSchemaNames, operationSchemaPath, schemaPath, namingConvention, fileExtension, tsconfig);
|
|
4296
4525
|
}
|
|
4297
4526
|
/**
|
|
4298
4527
|
* Fix imports in regular schemas that reference operation schemas.
|
|
4299
4528
|
*/
|
|
4300
|
-
function fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension) {
|
|
4301
|
-
fixSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension);
|
|
4529
|
+
function fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension, tsconfig) {
|
|
4530
|
+
fixSchemaImports(regularSchemas, operationSchemaNames, schemaPath, operationSchemaPath, namingConvention, fileExtension, tsconfig);
|
|
4302
4531
|
}
|
|
4303
4532
|
function getSchemaKey(schemaPath, schemaName, namingConvention, fileExtension) {
|
|
4304
4533
|
return getPath(schemaPath, conventionName(schemaName, namingConvention), fileExtension).toLowerCase().replaceAll("\\", "/");
|
|
@@ -4322,14 +4551,16 @@ function getCanonicalMap(schemaGroups, schemaPath, namingConvention, fileExtensi
|
|
|
4322
4551
|
canonicalNameMap
|
|
4323
4552
|
};
|
|
4324
4553
|
}
|
|
4325
|
-
function normalizeCanonicalImportPaths(schemas, canonicalPathMap, canonicalNameMap, schemaPath, namingConvention, fileExtension) {
|
|
4554
|
+
function normalizeCanonicalImportPaths(schemas, canonicalPathMap, canonicalNameMap, schemaPath, namingConvention, fileExtension, tsconfig) {
|
|
4555
|
+
const importExtension = getImportExtension(fileExtension, tsconfig);
|
|
4326
4556
|
for (const schema of schemas) schema.imports = schema.imports.map((imp) => {
|
|
4327
4557
|
const canonicalByName = canonicalNameMap.get(imp.name);
|
|
4328
4558
|
const resolvedImportKey = resolveImportKey(schemaPath, imp.importPath ?? `./${conventionName(imp.name, namingConvention)}`, fileExtension);
|
|
4329
4559
|
const canonicalByPath = canonicalPathMap.get(resolvedImportKey);
|
|
4330
4560
|
const canonical = canonicalByName ?? canonicalByPath;
|
|
4331
4561
|
if (!canonical?.importPath) return imp;
|
|
4332
|
-
const
|
|
4562
|
+
const relative = relativeSafe(schemaPath, canonical.importPath.replaceAll("\\", "/"));
|
|
4563
|
+
const importPath = `${relative.endsWith(fileExtension) ? relative.slice(0, -fileExtension.length) : relative.replace(/\.ts$/, "")}${importExtension}`;
|
|
4333
4564
|
return {
|
|
4334
4565
|
...imp,
|
|
4335
4566
|
importPath
|
|
@@ -4352,21 +4583,19 @@ function mergeSchemaGroup(schemas) {
|
|
|
4352
4583
|
function resolveImportKey(schemaPath, importPath, fileExtension) {
|
|
4353
4584
|
return join(schemaPath, `${importPath}${fileExtension}`).toLowerCase().replaceAll("\\", "/");
|
|
4354
4585
|
}
|
|
4355
|
-
function
|
|
4356
|
-
return path.endsWith(".ts") ? path.slice(0, -3) : path;
|
|
4357
|
-
}
|
|
4358
|
-
function getSchema({ schema: { imports, model }, header, namingConvention = NamingConvention.CAMEL_CASE }) {
|
|
4586
|
+
function getSchema({ schema: { imports, model }, header, namingConvention = NamingConvention.CAMEL_CASE, importExtension }) {
|
|
4359
4587
|
let file = header;
|
|
4360
4588
|
file += generateImports({
|
|
4361
4589
|
imports: imports.filter((imp) => !model.includes(`type ${imp.alias ?? imp.name} =`) && !model.includes(`interface ${imp.alias ?? imp.name} {`)),
|
|
4362
|
-
namingConvention
|
|
4590
|
+
namingConvention,
|
|
4591
|
+
importExtension
|
|
4363
4592
|
});
|
|
4364
4593
|
file += imports.length > 0 ? "\n\n" : "\n";
|
|
4365
4594
|
file += model;
|
|
4366
4595
|
return file;
|
|
4367
4596
|
}
|
|
4368
|
-
function getPath(path
|
|
4369
|
-
return
|
|
4597
|
+
function getPath(path, name, fileExtension) {
|
|
4598
|
+
return nodePath.join(path, `${name}${fileExtension}`);
|
|
4370
4599
|
}
|
|
4371
4600
|
function writeModelInline(acc, model) {
|
|
4372
4601
|
return acc + `${model}\n`;
|
|
@@ -4376,23 +4605,24 @@ function writeModelsInline(array) {
|
|
|
4376
4605
|
for (const { model } of array) acc = writeModelInline(acc, model);
|
|
4377
4606
|
return acc;
|
|
4378
4607
|
}
|
|
4379
|
-
async function writeSchema({ path, schema, target, namingConvention, fileExtension, header }) {
|
|
4608
|
+
async function writeSchema({ path, schema, target, namingConvention, fileExtension, header, tsconfig }) {
|
|
4380
4609
|
const name = conventionName(schema.name, namingConvention);
|
|
4381
4610
|
try {
|
|
4382
4611
|
await writeGeneratedFile(getPath(path, name, fileExtension), getSchema({
|
|
4383
4612
|
schema,
|
|
4384
4613
|
target,
|
|
4385
4614
|
header,
|
|
4386
|
-
namingConvention
|
|
4615
|
+
namingConvention,
|
|
4616
|
+
importExtension: getImportExtension(fileExtension, tsconfig)
|
|
4387
4617
|
}));
|
|
4388
4618
|
} catch (error) {
|
|
4389
4619
|
throw new Error(`Oups... 🍻. An Error occurred while writing schema ${name} => ${String(error)}`, { cause: error });
|
|
4390
4620
|
}
|
|
4391
4621
|
}
|
|
4392
|
-
async function writeSchemas({ schemaPath, schemas, target, namingConvention, fileExtension, header, indexFiles }) {
|
|
4622
|
+
async function writeSchemas({ schemaPath, schemas, target, namingConvention, fileExtension, header, indexFiles, tsconfig }) {
|
|
4393
4623
|
const schemaGroups = getSchemaGroups(schemaPath, schemas, namingConvention, fileExtension);
|
|
4394
4624
|
const { canonicalPathMap, canonicalNameMap } = getCanonicalMap(schemaGroups, schemaPath, namingConvention, fileExtension);
|
|
4395
|
-
normalizeCanonicalImportPaths(schemas, canonicalPathMap, canonicalNameMap, schemaPath, namingConvention, fileExtension);
|
|
4625
|
+
normalizeCanonicalImportPaths(schemas, canonicalPathMap, canonicalNameMap, schemaPath, namingConvention, fileExtension, tsconfig);
|
|
4396
4626
|
for (const groupSchemas of Object.values(schemaGroups)) {
|
|
4397
4627
|
if (groupSchemas.length === 1) {
|
|
4398
4628
|
await writeSchema({
|
|
@@ -4401,7 +4631,8 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
|
|
|
4401
4631
|
target,
|
|
4402
4632
|
namingConvention,
|
|
4403
4633
|
fileExtension,
|
|
4404
|
-
header
|
|
4634
|
+
header,
|
|
4635
|
+
tsconfig
|
|
4405
4636
|
});
|
|
4406
4637
|
continue;
|
|
4407
4638
|
}
|
|
@@ -4411,13 +4642,14 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
|
|
|
4411
4642
|
target,
|
|
4412
4643
|
namingConvention,
|
|
4413
4644
|
fileExtension,
|
|
4414
|
-
header
|
|
4645
|
+
header,
|
|
4646
|
+
tsconfig
|
|
4415
4647
|
});
|
|
4416
4648
|
}
|
|
4417
4649
|
if (indexFiles) {
|
|
4418
|
-
const schemaFilePath =
|
|
4650
|
+
const schemaFilePath = nodePath.join(schemaPath, `index.ts`);
|
|
4419
4651
|
await fs$1.ensureFile(schemaFilePath);
|
|
4420
|
-
const ext =
|
|
4652
|
+
const ext = getImportExtension(fileExtension, tsconfig);
|
|
4421
4653
|
const conventionNamesSet = new Set(Object.values(schemaGroups).map((group) => conventionName(group[0].name, namingConvention)));
|
|
4422
4654
|
try {
|
|
4423
4655
|
await writeGeneratedFile(schemaFilePath, `${header}\n${[...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b, "en", { numeric: true })).join("\n")}\n`);
|
|
@@ -4441,7 +4673,7 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
|
|
|
4441
4673
|
else {
|
|
4442
4674
|
const importsByDependency = /* @__PURE__ */ new Map();
|
|
4443
4675
|
for (const schemaImport of imports.filter((i) => !i.importPath)) {
|
|
4444
|
-
const dependency = joinSafe(relativeSchemasPath, `${conventionName(isZodSchemaOutput ? schemaImport.name : schemaImport.schemaName ?? schemaImport.name, output.namingConvention)}${isZodSchemaOutput ? ".zod" : ""}${output.fileExtension.
|
|
4676
|
+
const dependency = joinSafe(relativeSchemasPath, `${conventionName(isZodSchemaOutput ? schemaImport.name : schemaImport.schemaName ?? schemaImport.name, output.namingConvention)}${isZodSchemaOutput ? ".zod" : ""}${getImportExtension(output.fileExtension, output.tsconfig)}`);
|
|
4445
4677
|
if (!importsByDependency.has(dependency)) importsByDependency.set(dependency, []);
|
|
4446
4678
|
importsByDependency.get(dependency)?.push(schemaImport);
|
|
4447
4679
|
}
|
|
@@ -4483,6 +4715,7 @@ function generateTarget(builder, options) {
|
|
|
4483
4715
|
formData: [],
|
|
4484
4716
|
formUrlEncoded: [],
|
|
4485
4717
|
paramsSerializer: [],
|
|
4718
|
+
paramsFilter: [],
|
|
4486
4719
|
fetchReviver: []
|
|
4487
4720
|
};
|
|
4488
4721
|
const operations = Object.values(builder.operations);
|
|
@@ -4498,6 +4731,7 @@ function generateTarget(builder, options) {
|
|
|
4498
4731
|
if (operation.formData) target.formData.push(operation.formData);
|
|
4499
4732
|
if (operation.formUrlEncoded) target.formUrlEncoded.push(operation.formUrlEncoded);
|
|
4500
4733
|
if (operation.paramsSerializer) target.paramsSerializer.push(operation.paramsSerializer);
|
|
4734
|
+
if (operation.paramsFilter) target.paramsFilter.push(operation.paramsFilter);
|
|
4501
4735
|
if (operation.clientMutators) target.clientMutators.push(...operation.clientMutators);
|
|
4502
4736
|
if (operation.fetchReviver) target.fetchReviver.push(operation.fetchReviver);
|
|
4503
4737
|
if (index === operations.length - 1) {
|
|
@@ -4580,7 +4814,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
|
|
|
4580
4814
|
backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
|
|
4581
4815
|
extension: output.fileExtension
|
|
4582
4816
|
});
|
|
4583
|
-
const { imports, importsMock, implementation, implementationMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
|
|
4817
|
+
const { imports, importsMock, implementation, implementationMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
|
|
4584
4818
|
let data = header;
|
|
4585
4819
|
const schemasPath = output.schemas ? getRelativeImportPath(path, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : void 0;
|
|
4586
4820
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
@@ -4628,6 +4862,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
|
|
|
4628
4862
|
if (formData) data += generateMutatorImports({ mutators: formData });
|
|
4629
4863
|
if (formUrlEncoded) data += generateMutatorImports({ mutators: formUrlEncoded });
|
|
4630
4864
|
if (paramsSerializer) data += generateMutatorImports({ mutators: paramsSerializer });
|
|
4865
|
+
if (paramsFilter) data += generateMutatorImports({ mutators: paramsFilter });
|
|
4631
4866
|
if (fetchReviver) data += generateMutatorImports({ mutators: fetchReviver });
|
|
4632
4867
|
if (implementation.includes("NonReadonly<")) {
|
|
4633
4868
|
data += getOrvalGeneratedTypes();
|
|
@@ -4658,7 +4893,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4658
4893
|
backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
|
|
4659
4894
|
extension: output.fileExtension
|
|
4660
4895
|
});
|
|
4661
|
-
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
|
|
4896
|
+
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
|
|
4662
4897
|
let implementationData = header;
|
|
4663
4898
|
let mockData = header;
|
|
4664
4899
|
const relativeSchemasPath = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + extension.replace(/\.ts$/, "");
|
|
@@ -4686,7 +4921,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4686
4921
|
isAllowSyntheticDefaultImports,
|
|
4687
4922
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
4688
4923
|
});
|
|
4689
|
-
const schemasPath = !output.schemas && needSchema ?
|
|
4924
|
+
const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
4690
4925
|
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
4691
4926
|
if (mutators) implementationData += generateMutatorImports({
|
|
4692
4927
|
mutators,
|
|
@@ -4696,6 +4931,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4696
4931
|
if (formData) implementationData += generateMutatorImports({ mutators: formData });
|
|
4697
4932
|
if (formUrlEncoded) implementationData += generateMutatorImports({ mutators: formUrlEncoded });
|
|
4698
4933
|
if (paramsSerializer) implementationData += generateMutatorImports({ mutators: paramsSerializer });
|
|
4934
|
+
if (paramsFilter) implementationData += generateMutatorImports({ mutators: paramsFilter });
|
|
4699
4935
|
if (fetchReviver) implementationData += generateMutatorImports({ mutators: fetchReviver });
|
|
4700
4936
|
if (implementation.includes("NonReadonly<")) {
|
|
4701
4937
|
implementationData += getOrvalGeneratedTypes();
|
|
@@ -4708,9 +4944,9 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4708
4944
|
implementationData += `\n${implementation}`;
|
|
4709
4945
|
mockData += `\n${implementationMock}`;
|
|
4710
4946
|
const implementationFilename = filename + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
|
|
4711
|
-
const implementationPath =
|
|
4947
|
+
const implementationPath = nodePath.join(dirname, implementationFilename);
|
|
4712
4948
|
await writeGeneratedFile(implementationPath, implementationData);
|
|
4713
|
-
const mockPath = output.mock ?
|
|
4949
|
+
const mockPath = output.mock ? nodePath.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
|
|
4714
4950
|
if (mockPath) await writeGeneratedFile(mockPath, mockData);
|
|
4715
4951
|
return [
|
|
4716
4952
|
implementationPath,
|
|
@@ -4723,10 +4959,16 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4723
4959
|
}
|
|
4724
4960
|
//#endregion
|
|
4725
4961
|
//#region src/writers/target-tags.ts
|
|
4962
|
+
/**
|
|
4963
|
+
* Ensures every operation has at least one tag by falling back to the
|
|
4964
|
+
* {@link DefaultTag} constant for untagged operations, so the tag-routing
|
|
4965
|
+
* logic in {@link generateTargetTags} always has a bucket to assign the
|
|
4966
|
+
* operation to.
|
|
4967
|
+
*/
|
|
4726
4968
|
function addDefaultTagIfEmpty(operation) {
|
|
4727
4969
|
return {
|
|
4728
4970
|
...operation,
|
|
4729
|
-
tags: operation.tags.length > 0 ? operation.tags : [
|
|
4971
|
+
tags: operation.tags.length > 0 ? operation.tags : [DefaultTag]
|
|
4730
4972
|
};
|
|
4731
4973
|
}
|
|
4732
4974
|
function generateTargetTags(currentAcc, operation) {
|
|
@@ -4740,6 +4982,7 @@ function generateTargetTags(currentAcc, operation) {
|
|
|
4740
4982
|
formData: operation.formData ? [operation.formData] : [],
|
|
4741
4983
|
formUrlEncoded: operation.formUrlEncoded ? [operation.formUrlEncoded] : [],
|
|
4742
4984
|
paramsSerializer: operation.paramsSerializer ? [operation.paramsSerializer] : [],
|
|
4985
|
+
paramsFilter: operation.paramsFilter ? [operation.paramsFilter] : [],
|
|
4743
4986
|
fetchReviver: operation.fetchReviver ? [operation.fetchReviver] : [],
|
|
4744
4987
|
implementation: operation.implementation,
|
|
4745
4988
|
implementationMock: {
|
|
@@ -4765,6 +5008,7 @@ function generateTargetTags(currentAcc, operation) {
|
|
|
4765
5008
|
formData: operation.formData ? [...currentOperation.formData ?? [], operation.formData] : currentOperation.formData,
|
|
4766
5009
|
formUrlEncoded: operation.formUrlEncoded ? [...currentOperation.formUrlEncoded ?? [], operation.formUrlEncoded] : currentOperation.formUrlEncoded,
|
|
4767
5010
|
paramsSerializer: operation.paramsSerializer ? [...currentOperation.paramsSerializer ?? [], operation.paramsSerializer] : currentOperation.paramsSerializer,
|
|
5011
|
+
paramsFilter: operation.paramsFilter ? [...currentOperation.paramsFilter ?? [], operation.paramsFilter] : currentOperation.paramsFilter,
|
|
4768
5012
|
fetchReviver: operation.fetchReviver ? [...currentOperation.fetchReviver ?? [], operation.fetchReviver] : currentOperation.fetchReviver
|
|
4769
5013
|
};
|
|
4770
5014
|
return currentAcc;
|
|
@@ -4806,6 +5050,7 @@ function generateTargetForTags(builder, options) {
|
|
|
4806
5050
|
output: options,
|
|
4807
5051
|
verbOptions: builder.verbOptions,
|
|
4808
5052
|
tag,
|
|
5053
|
+
isDefaultTagBucket: tag === "default" && Object.values(builder.operations).some((operation) => operation.tags.length === 0),
|
|
4809
5054
|
clientImplementation: target.implementation
|
|
4810
5055
|
});
|
|
4811
5056
|
transformed[tag] = {
|
|
@@ -4822,6 +5067,7 @@ function generateTargetForTags(builder, options) {
|
|
|
4822
5067
|
formData: target.formData,
|
|
4823
5068
|
formUrlEncoded: target.formUrlEncoded,
|
|
4824
5069
|
paramsSerializer: target.paramsSerializer,
|
|
5070
|
+
paramsFilter: target.paramsFilter,
|
|
4825
5071
|
fetchReviver: target.fetchReviver
|
|
4826
5072
|
};
|
|
4827
5073
|
}
|
|
@@ -4845,27 +5091,27 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4845
5091
|
const target = generateTargetForTags(builder, output);
|
|
4846
5092
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
4847
5093
|
const mockOption = output.mock && !isFunction(output.mock) ? output.mock : void 0;
|
|
4848
|
-
const indexFilePath = mockOption?.indexMockFiles ?
|
|
5094
|
+
const indexFilePath = mockOption?.indexMockFiles ? nodePath.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
|
|
4849
5095
|
if (indexFilePath) await fs$1.outputFile(indexFilePath, "");
|
|
4850
5096
|
const tagEntries = Object.entries(target);
|
|
4851
5097
|
const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
|
|
4852
5098
|
try {
|
|
4853
|
-
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer } = target;
|
|
5099
|
+
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer, paramsFilter } = target;
|
|
4854
5100
|
let implementationData = header;
|
|
4855
5101
|
let mockData = header;
|
|
4856
|
-
const importerPath =
|
|
5102
|
+
const importerPath = nodePath.join(dirname, tag, tag + extension);
|
|
4857
5103
|
const relativeSchemasPath = output.schemas ? getRelativeImportPath(importerPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas" + extension.replace(/\.ts$/, "");
|
|
4858
5104
|
const tagNames = new Set(tagEntries.map(([t]) => t));
|
|
4859
5105
|
const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
|
|
4860
5106
|
const importsForBuilder = generateImportsForBuilder(output, imports.map((imp) => {
|
|
4861
5107
|
if (!imp.importPath) return imp;
|
|
4862
5108
|
if (!imp.importPath.startsWith(".")) return imp;
|
|
4863
|
-
const resolvedPath =
|
|
4864
|
-
const targetBasename =
|
|
5109
|
+
const resolvedPath = nodePath.resolve(dirname, imp.importPath);
|
|
5110
|
+
const targetBasename = nodePath.basename(resolvedPath);
|
|
4865
5111
|
let targetFile;
|
|
4866
5112
|
if (tagNames.has(targetBasename)) {
|
|
4867
5113
|
const tagFilename = targetBasename + serviceSuffix + extension;
|
|
4868
|
-
targetFile =
|
|
5114
|
+
targetFile = nodePath.join(resolvedPath, tagFilename);
|
|
4869
5115
|
} else targetFile = resolvedPath + extension;
|
|
4870
5116
|
const adjustedPath = getRelativeImportPath(importerPath, targetFile);
|
|
4871
5117
|
return {
|
|
@@ -4895,7 +5141,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4895
5141
|
isAllowSyntheticDefaultImports,
|
|
4896
5142
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
4897
5143
|
});
|
|
4898
|
-
const schemasPath = !output.schemas && needSchema ?
|
|
5144
|
+
const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
4899
5145
|
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
4900
5146
|
if (mutators) implementationData += generateMutatorImports({
|
|
4901
5147
|
mutators,
|
|
@@ -4918,6 +5164,10 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4918
5164
|
mutators: paramsSerializer,
|
|
4919
5165
|
oneMore: true
|
|
4920
5166
|
});
|
|
5167
|
+
if (paramsFilter) implementationData += generateMutatorImports({
|
|
5168
|
+
mutators: paramsFilter,
|
|
5169
|
+
oneMore: true
|
|
5170
|
+
});
|
|
4921
5171
|
if (fetchReviver) implementationData += generateMutatorImports({
|
|
4922
5172
|
mutators: fetchReviver,
|
|
4923
5173
|
oneMore: true
|
|
@@ -4933,9 +5183,9 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4933
5183
|
implementationData += `\n${implementation}`;
|
|
4934
5184
|
mockData += `\n${implementationMock}`;
|
|
4935
5185
|
const implementationFilename = tag + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
|
|
4936
|
-
const implementationPath =
|
|
5186
|
+
const implementationPath = nodePath.join(dirname, tag, implementationFilename);
|
|
4937
5187
|
await writeGeneratedFile(implementationPath, implementationData);
|
|
4938
|
-
const mockPath = output.mock ?
|
|
5188
|
+
const mockPath = output.mock ? nodePath.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
|
|
4939
5189
|
if (mockPath) await writeGeneratedFile(mockPath, mockData);
|
|
4940
5190
|
return [
|
|
4941
5191
|
implementationPath,
|
|
@@ -4966,7 +5216,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
4966
5216
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
4967
5217
|
return (await Promise.all(Object.entries(target).map(async ([tag, target]) => {
|
|
4968
5218
|
try {
|
|
4969
|
-
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer } = target;
|
|
5219
|
+
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer, paramsFilter } = target;
|
|
4970
5220
|
let data = header;
|
|
4971
5221
|
const schemasPathRelative = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + extension.replace(/\.ts$/, "");
|
|
4972
5222
|
const normalizedImports = imports.filter((imp) => {
|
|
@@ -5004,7 +5254,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
5004
5254
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
5005
5255
|
});
|
|
5006
5256
|
}
|
|
5007
|
-
const schemasPath = !output.schemas && needSchema ?
|
|
5257
|
+
const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
5008
5258
|
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
5009
5259
|
if (mutators) data += generateMutatorImports({
|
|
5010
5260
|
mutators,
|
|
@@ -5014,6 +5264,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
5014
5264
|
if (formData) data += generateMutatorImports({ mutators: formData });
|
|
5015
5265
|
if (formUrlEncoded) data += generateMutatorImports({ mutators: formUrlEncoded });
|
|
5016
5266
|
if (paramsSerializer) data += generateMutatorImports({ mutators: paramsSerializer });
|
|
5267
|
+
if (paramsFilter) data += generateMutatorImports({ mutators: paramsFilter });
|
|
5017
5268
|
if (fetchReviver) data += generateMutatorImports({ mutators: fetchReviver });
|
|
5018
5269
|
data += "\n\n";
|
|
5019
5270
|
if (implementation.includes("NonReadonly<")) {
|
|
@@ -5029,7 +5280,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
5029
5280
|
data += "\n\n";
|
|
5030
5281
|
data += implementationMock;
|
|
5031
5282
|
}
|
|
5032
|
-
const implementationPath =
|
|
5283
|
+
const implementationPath = nodePath.join(dirname, `${kebab(tag)}${extension}`);
|
|
5033
5284
|
await writeGeneratedFile(implementationPath, data);
|
|
5034
5285
|
return [implementationPath, ...schemasPath ? [schemasPath] : []];
|
|
5035
5286
|
} catch (error) {
|
|
@@ -5038,6 +5289,6 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
5038
5289
|
}))).flat();
|
|
5039
5290
|
}
|
|
5040
5291
|
//#endregion
|
|
5041
|
-
export { BODY_TYPE_NAME, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, SupportedFormatter, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, addDependency, asyncReduce, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, escapeRegExp, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getAngularFilteredParamsCallExpression, getAngularFilteredParamsExpression, getAngularFilteredParamsHelperBody, getArray, getBaseUrlRuntimeImports, getBodiesByContentType, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSuccessResponseType, getTypedResponse, getWarningCount, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
|
|
5292
|
+
export { BODY_TYPE_NAME, DefaultTag, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NAMED_COMPONENT_SECTIONS, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, SupportedFormatter, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, addDependency, asyncReduce, buildAngularParamsFilterExpression, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, escapeRegExp, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getAngularFilteredParamsCallExpression, getAngularFilteredParamsExpression, getAngularFilteredParamsHelperBody, getArray, getBaseUrlRuntimeImports, getBodiesByContentType, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getImportExtension, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSuccessResponseType, getTypedResponse, getWarningCount, isBinaryContentType, isBoolean, isComponentRef, isDirectory, isFunction, isModule, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
|
|
5042
5293
|
|
|
5043
5294
|
//# sourceMappingURL=index.mjs.map
|