@orval/core 8.9.0 → 8.10.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 +8 -6
- package/dist/index.mjs +139 -97
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -836,7 +836,7 @@ interface Tsconfig {
|
|
|
836
836
|
target?: TsConfigTarget;
|
|
837
837
|
};
|
|
838
838
|
}
|
|
839
|
-
type TsConfigTarget = 'es3' | 'es5' | 'es6' | 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'esnext';
|
|
839
|
+
type TsConfigTarget = 'es3' | 'es5' | 'es6' | 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'es2023' | 'es2024' | 'es2025' | 'esnext';
|
|
840
840
|
interface PackageJson {
|
|
841
841
|
dependencies?: Record<string, string>;
|
|
842
842
|
devDependencies?: Record<string, string>;
|
|
@@ -959,6 +959,8 @@ interface GeneratorClient {
|
|
|
959
959
|
implementation: string;
|
|
960
960
|
imports: GeneratorImport[];
|
|
961
961
|
mutators?: GeneratorMutator[];
|
|
962
|
+
/** When set, overrides the default verbOption.doc prepended to the implementation */
|
|
963
|
+
docComment?: string;
|
|
962
964
|
}
|
|
963
965
|
interface GeneratorMutatorParsingInfo {
|
|
964
966
|
numberOfParams: number;
|
|
@@ -1367,7 +1369,7 @@ interface GenerateFormDataAndUrlEncodedFunctionOptions {
|
|
|
1367
1369
|
isFormData: boolean;
|
|
1368
1370
|
isFormUrlEncoded: boolean;
|
|
1369
1371
|
}
|
|
1370
|
-
declare function generateBodyOptions(body: GetterBody, isFormData: boolean, isFormUrlEncoded: boolean): string;
|
|
1372
|
+
declare function generateBodyOptions(body: GetterBody, isFormData: boolean, isFormUrlEncoded: boolean): string | undefined;
|
|
1371
1373
|
interface GenerateAxiosOptions {
|
|
1372
1374
|
response: GetterResponse;
|
|
1373
1375
|
isExactOptionalPropertyTypes: boolean;
|
|
@@ -1643,10 +1645,10 @@ declare function combineSchemas({
|
|
|
1643
1645
|
declare function resolveDiscriminators(schemas: OpenApiSchemasObject, context: ContextSpec): OpenApiSchemasObject;
|
|
1644
1646
|
//#endregion
|
|
1645
1647
|
//#region src/getters/enum.d.ts
|
|
1646
|
-
declare function getEnumNames(schemaObject: OpenApiSchemaObject | undefined): string[] | undefined;
|
|
1647
|
-
declare function getEnumDescriptions(schemaObject: OpenApiSchemaObject | undefined): string[] | undefined;
|
|
1648
|
-
declare function getEnum(value: string, enumName: string, names: string[] | undefined, enumGenerationType: EnumGeneration, descriptions?: string[], enumNamingConvention?: NamingConvention): string;
|
|
1649
|
-
declare function getEnumImplementation(value: string, names?: string[], descriptions?: string[], enumNamingConvention?: NamingConvention): string;
|
|
1648
|
+
declare function getEnumNames(schemaObject: OpenApiSchemaObject | undefined): (string | undefined)[] | undefined;
|
|
1649
|
+
declare function getEnumDescriptions(schemaObject: OpenApiSchemaObject | undefined): (string | undefined)[] | undefined;
|
|
1650
|
+
declare function getEnum(value: string, enumName: string, names: (string | undefined)[] | undefined, enumGenerationType: EnumGeneration, descriptions?: (string | undefined)[], enumNamingConvention?: NamingConvention): string;
|
|
1651
|
+
declare function getEnumImplementation(value: string, names?: (string | undefined)[], descriptions?: (string | undefined)[], enumNamingConvention?: NamingConvention): string;
|
|
1650
1652
|
interface CombinedEnumInput {
|
|
1651
1653
|
value: string;
|
|
1652
1654
|
isRef: boolean;
|
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 path from "node:path";
|
|
6
6
|
import { compare } from "compare-versions";
|
|
7
7
|
import debug from "debug";
|
|
8
8
|
import { pathToFileURL } from "node:url";
|
|
@@ -137,7 +137,7 @@ function isReference(obj) {
|
|
|
137
137
|
return !isNullish$1(obj) && Object.hasOwn(obj, "$ref");
|
|
138
138
|
}
|
|
139
139
|
function isDirectory(pathValue) {
|
|
140
|
-
return !
|
|
140
|
+
return !path.extname(pathValue);
|
|
141
141
|
}
|
|
142
142
|
function isObject(x) {
|
|
143
143
|
return Object.prototype.toString.call(x) === "[object Object]";
|
|
@@ -450,8 +450,8 @@ async function dynamicImport(toImport, from = process.cwd(), takeDefault = true)
|
|
|
450
450
|
if (!toImport) return toImport;
|
|
451
451
|
try {
|
|
452
452
|
if (isString(toImport)) {
|
|
453
|
-
const filePath =
|
|
454
|
-
const extension =
|
|
453
|
+
const filePath = path.resolve(from, toImport);
|
|
454
|
+
const extension = path.extname(filePath);
|
|
455
455
|
if (TS_MODULE_EXTENSIONS.has(extension)) {
|
|
456
456
|
const data = await createJiti(from, { interopDefault: true }).import(filePath);
|
|
457
457
|
if (takeDefault && (isObject(data) || isModule(data)) && data.default) return data.default;
|
|
@@ -476,14 +476,14 @@ function getExtension(path) {
|
|
|
476
476
|
//#region src/utils/file.ts
|
|
477
477
|
function getFileInfo(target = "", { backupFilename = "filename", extension = ".ts" } = {}) {
|
|
478
478
|
const isDir = isDirectory(target);
|
|
479
|
-
const filePath = isDir ?
|
|
479
|
+
const filePath = isDir ? path.join(target, backupFilename + extension) : target;
|
|
480
480
|
return {
|
|
481
481
|
path: filePath,
|
|
482
482
|
pathWithoutExtension: filePath.replace(/\.[^/.]+$/, ""),
|
|
483
483
|
extension,
|
|
484
484
|
isDirectory: isDir,
|
|
485
|
-
dirname:
|
|
486
|
-
filename:
|
|
485
|
+
dirname: path.dirname(filePath),
|
|
486
|
+
filename: path.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
|
|
487
487
|
};
|
|
488
488
|
}
|
|
489
489
|
async function removeFilesAndEmptyFolders(patterns, dir) {
|
|
@@ -691,13 +691,13 @@ function toUnix(value) {
|
|
|
691
691
|
return value;
|
|
692
692
|
}
|
|
693
693
|
function join(...args) {
|
|
694
|
-
return toUnix(
|
|
694
|
+
return toUnix(path.join(...args.map((a) => toUnix(a))));
|
|
695
695
|
}
|
|
696
696
|
/**
|
|
697
697
|
* Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
|
|
698
698
|
*/
|
|
699
699
|
function relativeSafe(from, to) {
|
|
700
|
-
return normalizeSafe(`./${toUnix(
|
|
700
|
+
return normalizeSafe(`./${toUnix(path.relative(toUnix(from), toUnix(to)))}`);
|
|
701
701
|
}
|
|
702
702
|
function getSchemaFileName(path) {
|
|
703
703
|
return path.replace(`.${getExtension(path)}`, "").slice(path.lastIndexOf("/") + 1);
|
|
@@ -705,13 +705,13 @@ function getSchemaFileName(path) {
|
|
|
705
705
|
function normalizeSafe(value) {
|
|
706
706
|
let result;
|
|
707
707
|
value = toUnix(value);
|
|
708
|
-
result = toUnix(
|
|
708
|
+
result = toUnix(path.normalize(value));
|
|
709
709
|
if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
710
710
|
else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
|
|
711
711
|
return result;
|
|
712
712
|
}
|
|
713
713
|
function joinSafe(...values) {
|
|
714
|
-
let result = toUnix(
|
|
714
|
+
let result = toUnix(path.join(...values.map((v) => toUnix(v))));
|
|
715
715
|
if (values.length > 0) {
|
|
716
716
|
const firstValue = toUnix(values[0]);
|
|
717
717
|
if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
|
|
@@ -742,14 +742,14 @@ function joinSafe(...values) {
|
|
|
742
742
|
* @returns The relative import path string.
|
|
743
743
|
*/
|
|
744
744
|
function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileExtension = false) {
|
|
745
|
-
if (!
|
|
746
|
-
if (!
|
|
747
|
-
const importerDir =
|
|
748
|
-
const relativePath =
|
|
749
|
-
let posixPath =
|
|
745
|
+
if (!path.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
|
|
746
|
+
if (!path.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
|
|
747
|
+
const importerDir = path.dirname(importerFilePath);
|
|
748
|
+
const relativePath = path.relative(importerDir, exporterFilePath);
|
|
749
|
+
let posixPath = path.posix.join(...relativePath.split(path.sep));
|
|
750
750
|
if (!posixPath.startsWith("./") && !posixPath.startsWith("../")) posixPath = `./${posixPath}`;
|
|
751
751
|
if (!includeFileExtension) {
|
|
752
|
-
const ext =
|
|
752
|
+
const ext = path.extname(posixPath);
|
|
753
753
|
if (ext && posixPath.endsWith(ext)) posixPath = posixPath.slice(0, -ext.length);
|
|
754
754
|
}
|
|
755
755
|
return posixPath;
|
|
@@ -758,20 +758,20 @@ function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileEx
|
|
|
758
758
|
//#region src/utils/resolve-version.ts
|
|
759
759
|
function resolveInstalledVersion(packageName, fromDir) {
|
|
760
760
|
try {
|
|
761
|
-
const require = createRequire(
|
|
761
|
+
const require = createRequire(path.join(fromDir, "noop.js"));
|
|
762
762
|
try {
|
|
763
763
|
return require(`${packageName}/package.json`).version;
|
|
764
764
|
} catch (directError) {
|
|
765
765
|
if (directError instanceof Error && "code" in directError && directError.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
766
766
|
const entryPath = require.resolve(packageName);
|
|
767
|
-
let dir =
|
|
768
|
-
while (dir !==
|
|
769
|
-
const pkgPath =
|
|
767
|
+
let dir = path.dirname(entryPath);
|
|
768
|
+
while (dir !== path.parse(dir).root) {
|
|
769
|
+
const pkgPath = path.join(dir, "package.json");
|
|
770
770
|
if (existsSync(pkgPath)) {
|
|
771
771
|
const pkgData = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
772
772
|
if (pkgData.name === packageName) return pkgData.version;
|
|
773
773
|
}
|
|
774
|
-
dir =
|
|
774
|
+
dir = path.dirname(dir);
|
|
775
775
|
}
|
|
776
776
|
return;
|
|
777
777
|
}
|
|
@@ -1038,12 +1038,20 @@ function replaceSpecialCharacters(key) {
|
|
|
1038
1038
|
function getEnumNames(schemaObject) {
|
|
1039
1039
|
const names = schemaObject?.["x-enumNames"] ?? schemaObject?.["x-enumnames"] ?? schemaObject?.["x-enum-varnames"];
|
|
1040
1040
|
if (!names) return;
|
|
1041
|
-
return names.map((name) => jsStringEscape(name));
|
|
1041
|
+
if (Array.isArray(names)) return names.map((name) => jsStringEscape(name));
|
|
1042
|
+
if (typeof names === "object") return (schemaObject?.enum ?? []).map((enumVal) => {
|
|
1043
|
+
const key = String(enumVal);
|
|
1044
|
+
return key in names ? jsStringEscape(names[key]) : void 0;
|
|
1045
|
+
});
|
|
1042
1046
|
}
|
|
1043
1047
|
function getEnumDescriptions(schemaObject) {
|
|
1044
1048
|
const descriptions = schemaObject?.["x-enumDescriptions"] ?? schemaObject?.["x-enumdescriptions"] ?? schemaObject?.["x-enum-descriptions"];
|
|
1045
1049
|
if (!descriptions) return;
|
|
1046
|
-
return descriptions.map((description) => jsStringEscape(description));
|
|
1050
|
+
if (Array.isArray(descriptions)) return descriptions.map((description) => jsStringEscape(description));
|
|
1051
|
+
if (typeof descriptions === "object") return (schemaObject?.enum ?? []).map((enumVal) => {
|
|
1052
|
+
const key = String(enumVal);
|
|
1053
|
+
return key in descriptions ? jsStringEscape(descriptions[key]) : void 0;
|
|
1054
|
+
});
|
|
1047
1055
|
}
|
|
1048
1056
|
function getEnum(value, enumName, names, enumGenerationType, descriptions, enumNamingConvention) {
|
|
1049
1057
|
if (enumGenerationType === EnumGeneration.CONST) return getTypeConstEnum(value, enumName, names, descriptions, enumNamingConvention);
|
|
@@ -1535,7 +1543,7 @@ function getArray({ schema, name, context, formDataContext }) {
|
|
|
1535
1543
|
formDataContext
|
|
1536
1544
|
});
|
|
1537
1545
|
return {
|
|
1538
|
-
value: `${schema.readOnly === true && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${resolvedObject.value.includes("|") ? `(${resolvedObject.value})[]` : `${resolvedObject.value}[]`}`,
|
|
1546
|
+
value: `${schema.readOnly === true && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${resolvedObject.value.includes("|") || resolvedObject.value.includes("&") ? `(${resolvedObject.value})[]` : `${resolvedObject.value}[]`}`,
|
|
1539
1547
|
imports: resolvedObject.imports,
|
|
1540
1548
|
schemas: resolvedObject.schemas,
|
|
1541
1549
|
dependencies: resolvedObject.dependencies,
|
|
@@ -2100,30 +2108,59 @@ function getKey(key) {
|
|
|
2100
2108
|
}
|
|
2101
2109
|
//#endregion
|
|
2102
2110
|
//#region src/getters/object.ts
|
|
2111
|
+
function getPropertyNamesEnumKeyType(item) {
|
|
2112
|
+
if (!("propertyNames" in item) || !item.propertyNames) return;
|
|
2113
|
+
const propertyNames = item.propertyNames;
|
|
2114
|
+
if (Array.isArray(propertyNames.enum)) {
|
|
2115
|
+
const enumValues = propertyNames.enum.filter((val) => isString(val));
|
|
2116
|
+
if (enumValues.length > 0) return {
|
|
2117
|
+
value: enumValues.map((val) => `'${escape(val)}'`).join(" | "),
|
|
2118
|
+
imports: [],
|
|
2119
|
+
dependencies: []
|
|
2120
|
+
};
|
|
2121
|
+
}
|
|
2122
|
+
if (isString(propertyNames.const)) return {
|
|
2123
|
+
value: `'${escape(propertyNames.const)}'`,
|
|
2124
|
+
imports: [],
|
|
2125
|
+
dependencies: []
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2103
2128
|
/**
|
|
2104
|
-
*
|
|
2105
|
-
*
|
|
2106
|
-
* Returns undefined if propertyNames has neither
|
|
2129
|
+
* Resolve a narrowed key type from OpenAPI 3.1 propertyNames.
|
|
2130
|
+
* Supports inline enum/const and $ref string enums.
|
|
2107
2131
|
*/
|
|
2108
|
-
function
|
|
2109
|
-
|
|
2132
|
+
function getPropertyNamesKeyType(item, context) {
|
|
2133
|
+
const inlineKeyType = getPropertyNamesEnumKeyType(item);
|
|
2134
|
+
if (inlineKeyType) return inlineKeyType;
|
|
2110
2135
|
const propertyNames = item.propertyNames;
|
|
2111
|
-
if (
|
|
2112
|
-
|
|
2136
|
+
if (!propertyNames || !isReference(propertyNames)) return;
|
|
2137
|
+
const resolvedValue = resolveValue({
|
|
2138
|
+
schema: propertyNames,
|
|
2139
|
+
context
|
|
2140
|
+
});
|
|
2141
|
+
const resolvedConst = resolvedValue.originalSchema.const;
|
|
2142
|
+
const isStringConst = resolvedValue.type === "string" && isString(resolvedConst);
|
|
2143
|
+
if (!resolvedValue.isEnum && !isStringConst) return;
|
|
2144
|
+
return {
|
|
2145
|
+
value: resolvedValue.value,
|
|
2146
|
+
imports: resolvedValue.imports,
|
|
2147
|
+
dependencies: resolvedValue.dependencies
|
|
2148
|
+
};
|
|
2113
2149
|
}
|
|
2114
2150
|
/**
|
|
2115
2151
|
* Generate index signature key type based on propertyNames enum or const
|
|
2116
2152
|
* Returns union type string like "'foo' | 'bar'", "'x'", or 'string' if neither
|
|
2117
2153
|
*/
|
|
2118
2154
|
function getIndexSignatureKey(item) {
|
|
2119
|
-
|
|
2120
|
-
if (enumValues && enumValues.length > 0) return enumValues.map((val) => `'${val}'`).join(" | ");
|
|
2121
|
-
return "string";
|
|
2155
|
+
return getPropertyNamesEnumKeyType(item)?.value ?? "string";
|
|
2122
2156
|
}
|
|
2123
|
-
function getPropertyNamesRecordType(item, valueType) {
|
|
2124
|
-
const
|
|
2125
|
-
if (!
|
|
2126
|
-
return
|
|
2157
|
+
function getPropertyNamesRecordType(item, valueType, context) {
|
|
2158
|
+
const keyType = getPropertyNamesKeyType(item, context);
|
|
2159
|
+
if (!keyType) return;
|
|
2160
|
+
return {
|
|
2161
|
+
...keyType,
|
|
2162
|
+
value: `Partial<Record<${keyType.value}, ${valueType}>>`
|
|
2163
|
+
};
|
|
2127
2164
|
}
|
|
2128
2165
|
/**
|
|
2129
2166
|
* Return the output type from an object
|
|
@@ -2177,7 +2214,7 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2177
2214
|
if (itemProperties && Object.entries(itemProperties).length > 0) {
|
|
2178
2215
|
const entries = Object.entries(itemProperties);
|
|
2179
2216
|
if (context.output.propertySortOrder === PropertySortOrder.ALPHABETICAL) entries.sort((a, b) => {
|
|
2180
|
-
return a[0].localeCompare(b[0]);
|
|
2217
|
+
return a[0].localeCompare(b[0], "en", { numeric: true });
|
|
2181
2218
|
});
|
|
2182
2219
|
const acc = {
|
|
2183
2220
|
imports: [],
|
|
@@ -2249,11 +2286,13 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2249
2286
|
if (entries.length - 1 === index) {
|
|
2250
2287
|
const additionalProps = schemaItem.additionalProperties;
|
|
2251
2288
|
if (additionalProps) if (additionalProps === true) {
|
|
2252
|
-
const recordType = getPropertyNamesRecordType(schemaItem, "unknown");
|
|
2289
|
+
const recordType = getPropertyNamesRecordType(schemaItem, "unknown", context);
|
|
2253
2290
|
if (recordType) {
|
|
2254
2291
|
acc.value += "\n}";
|
|
2255
|
-
acc.value += ` & ${recordType}`;
|
|
2292
|
+
acc.value += ` & ${recordType.value}`;
|
|
2256
2293
|
acc.useTypeAlias = true;
|
|
2294
|
+
acc.imports.push(...recordType.imports);
|
|
2295
|
+
acc.dependencies.push(...recordType.dependencies);
|
|
2257
2296
|
} else {
|
|
2258
2297
|
const keyType = getIndexSignatureKey(schemaItem);
|
|
2259
2298
|
acc.value += `\n [key: ${keyType}]: unknown;\n }`;
|
|
@@ -2264,15 +2303,19 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2264
2303
|
name,
|
|
2265
2304
|
context
|
|
2266
2305
|
});
|
|
2267
|
-
const recordType = getPropertyNamesRecordType(schemaItem, resolvedValue.value);
|
|
2306
|
+
const recordType = getPropertyNamesRecordType(schemaItem, resolvedValue.value, context);
|
|
2268
2307
|
if (recordType) {
|
|
2269
2308
|
acc.value += "\n}";
|
|
2270
|
-
acc.value += ` & ${recordType}`;
|
|
2309
|
+
acc.value += ` & ${recordType.value}`;
|
|
2271
2310
|
acc.useTypeAlias = true;
|
|
2311
|
+
acc.imports.push(...recordType.imports);
|
|
2312
|
+
acc.dependencies.push(...recordType.dependencies);
|
|
2272
2313
|
} else {
|
|
2273
2314
|
const keyType = getIndexSignatureKey(schemaItem);
|
|
2274
2315
|
acc.value += `\n [key: ${keyType}]: ${resolvedValue.value};\n}`;
|
|
2275
2316
|
}
|
|
2317
|
+
acc.imports.push(...resolvedValue.imports);
|
|
2318
|
+
acc.schemas.push(...resolvedValue.schemas);
|
|
2276
2319
|
acc.dependencies.push(...resolvedValue.dependencies);
|
|
2277
2320
|
}
|
|
2278
2321
|
else acc.value += "\n}";
|
|
@@ -2285,17 +2328,17 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2285
2328
|
const readOnlyFlag = schemaItem.readOnly;
|
|
2286
2329
|
if (outerAdditionalProps) {
|
|
2287
2330
|
if (outerAdditionalProps === true) {
|
|
2288
|
-
const recordType = getPropertyNamesRecordType(schemaItem, "unknown");
|
|
2331
|
+
const recordType = getPropertyNamesRecordType(schemaItem, "unknown", context);
|
|
2289
2332
|
if (recordType) return {
|
|
2290
|
-
value: recordType + nullable,
|
|
2291
|
-
imports:
|
|
2333
|
+
value: recordType.value + nullable,
|
|
2334
|
+
imports: recordType.imports,
|
|
2292
2335
|
schemas: [],
|
|
2293
2336
|
isEnum: false,
|
|
2294
2337
|
type: "object",
|
|
2295
2338
|
isRef: false,
|
|
2296
2339
|
hasReadonlyProps: readOnlyFlag ?? false,
|
|
2297
2340
|
useTypeAlias: true,
|
|
2298
|
-
dependencies:
|
|
2341
|
+
dependencies: recordType.dependencies
|
|
2299
2342
|
};
|
|
2300
2343
|
return {
|
|
2301
2344
|
value: `{ [key: ${getIndexSignatureKey(schemaItem)}]: unknown }` + nullable,
|
|
@@ -2314,17 +2357,17 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2314
2357
|
name,
|
|
2315
2358
|
context
|
|
2316
2359
|
});
|
|
2317
|
-
const recordType = getPropertyNamesRecordType(schemaItem, resolvedValue.value);
|
|
2360
|
+
const recordType = getPropertyNamesRecordType(schemaItem, resolvedValue.value, context);
|
|
2318
2361
|
if (recordType) return {
|
|
2319
|
-
value: recordType + nullable,
|
|
2320
|
-
imports: resolvedValue.imports,
|
|
2362
|
+
value: recordType.value + nullable,
|
|
2363
|
+
imports: [...recordType.imports, ...resolvedValue.imports],
|
|
2321
2364
|
schemas: resolvedValue.schemas,
|
|
2322
2365
|
isEnum: false,
|
|
2323
2366
|
type: "object",
|
|
2324
2367
|
isRef: false,
|
|
2325
2368
|
hasReadonlyProps: resolvedValue.hasReadonlyProps,
|
|
2326
2369
|
useTypeAlias: true,
|
|
2327
|
-
dependencies: resolvedValue.dependencies
|
|
2370
|
+
dependencies: [...recordType.dependencies, ...resolvedValue.dependencies]
|
|
2328
2371
|
};
|
|
2329
2372
|
return {
|
|
2330
2373
|
value: `{[key: ${getIndexSignatureKey(schemaItem)}]: ${resolvedValue.value}}` + nullable,
|
|
@@ -2359,17 +2402,17 @@ function getObject({ item, name, context, nullable, formDataContext }) {
|
|
|
2359
2402
|
};
|
|
2360
2403
|
}
|
|
2361
2404
|
const keyType = itemType === "object" ? getIndexSignatureKey(schemaItem) : "string";
|
|
2362
|
-
const recordType = getPropertyNamesRecordType(schemaItem, "unknown");
|
|
2405
|
+
const recordType = getPropertyNamesRecordType(schemaItem, "unknown", context);
|
|
2363
2406
|
if (itemType === "object" && recordType) return {
|
|
2364
|
-
value: recordType + nullable,
|
|
2365
|
-
imports:
|
|
2407
|
+
value: recordType.value + nullable,
|
|
2408
|
+
imports: recordType.imports,
|
|
2366
2409
|
schemas: [],
|
|
2367
2410
|
isEnum: false,
|
|
2368
2411
|
type: "object",
|
|
2369
2412
|
isRef: false,
|
|
2370
2413
|
hasReadonlyProps: readOnlyFlag ?? false,
|
|
2371
2414
|
useTypeAlias: true,
|
|
2372
|
-
dependencies:
|
|
2415
|
+
dependencies: recordType.dependencies
|
|
2373
2416
|
};
|
|
2374
2417
|
return {
|
|
2375
2418
|
value: (itemType === "object" ? `{ [key: ${keyType}]: unknown }` : "unknown") + nullable,
|
|
@@ -3066,7 +3109,7 @@ function getResponse({ responses, operationName, context, contentType }) {
|
|
|
3066
3109
|
success: success || (defaultType ?? "unknown"),
|
|
3067
3110
|
errors: errors || (defaultType ?? "unknown")
|
|
3068
3111
|
},
|
|
3069
|
-
isBlob: groupedByStatus.success.some((t) => !!t.contentType && isBinaryContentType(t.contentType)),
|
|
3112
|
+
isBlob: groupedByStatus.success.some((t) => !!t.contentType && isBinaryContentType(t.contentType) || t.value === "Blob" && !t.isRef),
|
|
3070
3113
|
types: groupedByStatus,
|
|
3071
3114
|
contentTypes,
|
|
3072
3115
|
schemas,
|
|
@@ -3203,7 +3246,7 @@ function generateImports({ imports, namingConvention = NamingConvention.CAMEL_CA
|
|
|
3203
3246
|
...imp,
|
|
3204
3247
|
importPath: imp.importPath ?? `./${conventionName(imp.name, namingConvention)}`
|
|
3205
3248
|
})), (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)}`);
|
|
3206
|
-
return Object.entries(grouped).toSorted(([a], [b]) => a.localeCompare(b)).map(([, group]) => {
|
|
3249
|
+
return Object.entries(grouped).toSorted(([a], [b]) => a.localeCompare(b, "en", { numeric: true })).map(([, group]) => {
|
|
3207
3250
|
const sample = group[0];
|
|
3208
3251
|
if (!sample.default && !sample.namespaceImport && !sample.syntheticDefaultImport && !sample.values && !sample.isConstant) return `import type { ${[...new Set(group.map(({ name, alias }) => `${name}${alias ? ` as ${alias}` : ""}`))].toSorted().join(", ")} } from '${sample.importPath}';`;
|
|
3209
3252
|
const { name, values, alias, isConstant, importPath } = sample;
|
|
@@ -3274,18 +3317,18 @@ function addDependency({ implementation, exports, dependency, projectName, isAll
|
|
|
3274
3317
|
});
|
|
3275
3318
|
if (types.length > 0) {
|
|
3276
3319
|
let uniqueTypes = types;
|
|
3277
|
-
if (values.length > 0)
|
|
3278
|
-
|
|
3279
|
-
dep += "\n";
|
|
3320
|
+
if (values.length > 0) uniqueTypes = types.filter((t) => !values.some((v) => v.name === t.name && (v.alias ?? "") === (t.alias ?? "")));
|
|
3321
|
+
if (uniqueTypes.length > 0) {
|
|
3322
|
+
if (values.length > 0) dep += "\n";
|
|
3323
|
+
dep += generateDependency({
|
|
3324
|
+
deps: uniqueTypes,
|
|
3325
|
+
isAllowSyntheticDefaultImports,
|
|
3326
|
+
dependency,
|
|
3327
|
+
projectName,
|
|
3328
|
+
key,
|
|
3329
|
+
onlyTypes: true
|
|
3330
|
+
});
|
|
3280
3331
|
}
|
|
3281
|
-
dep += generateDependency({
|
|
3282
|
-
deps: uniqueTypes,
|
|
3283
|
-
isAllowSyntheticDefaultImports,
|
|
3284
|
-
dependency,
|
|
3285
|
-
projectName,
|
|
3286
|
-
key,
|
|
3287
|
-
onlyTypes: true
|
|
3288
|
-
});
|
|
3289
3332
|
}
|
|
3290
3333
|
return dep;
|
|
3291
3334
|
}).join("\n") + "\n";
|
|
@@ -3650,10 +3693,9 @@ function filterParams(
|
|
|
3650
3693
|
*/
|
|
3651
3694
|
const getAngularFilteredParamsCallExpression = (paramsExpression, requiredNullableParamKeys = [], preserveRequiredNullables = false) => `filterParams(${paramsExpression}, new Set<string>(${JSON.stringify(requiredNullableParamKeys)})${preserveRequiredNullables ? ", true" : ""})`;
|
|
3652
3695
|
function generateBodyOptions(body, isFormData, isFormUrlEncoded) {
|
|
3653
|
-
if (isFormData && body.formData) return "
|
|
3654
|
-
if (isFormUrlEncoded && body.formUrlEncoded) return "
|
|
3655
|
-
if (body.implementation) return
|
|
3656
|
-
return "";
|
|
3696
|
+
if (isFormData && body.formData) return "formData";
|
|
3697
|
+
if (isFormUrlEncoded && body.formUrlEncoded) return "formUrlEncoded";
|
|
3698
|
+
if (body.implementation) return body.implementation;
|
|
3657
3699
|
}
|
|
3658
3700
|
function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions }) {
|
|
3659
3701
|
const isRequestOptions = requestOptions !== false;
|
|
@@ -3700,7 +3742,7 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
|
|
|
3700
3742
|
return value;
|
|
3701
3743
|
}
|
|
3702
3744
|
function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions }) {
|
|
3703
|
-
const
|
|
3745
|
+
const bodyIdentifier = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : void 0;
|
|
3704
3746
|
const axiosOptions = generateAxiosOptions({
|
|
3705
3747
|
response,
|
|
3706
3748
|
angularObserve,
|
|
@@ -3721,11 +3763,11 @@ function generateOptions({ route, body, angularObserve, angularParamsRef, header
|
|
|
3721
3763
|
const isRawOptionsArgument = trimmedAxiosOptions === "options" || trimmedAxiosOptions.startsWith("(") && trimmedAxiosOptions.endsWith(")") || trimmedAxiosOptions.startsWith("{") && trimmedAxiosOptions.endsWith("}");
|
|
3722
3764
|
const optionsArgument = axiosOptions ? isRawOptionsArgument ? axiosOptions : `{${axiosOptions}}` : "";
|
|
3723
3765
|
if (verb === Verbs.DELETE) {
|
|
3724
|
-
if (!
|
|
3766
|
+
if (!bodyIdentifier) return `\n \`${route}\`${optionsArgument ? `,${optionsArgument}` : ""}\n `;
|
|
3725
3767
|
const deleteBodyOptions = isRawOptionsArgument ? `...${optionsArgument}` : axiosOptions;
|
|
3726
|
-
return `\n \`${route}\`,{${isAngular ? "body" : "data"}
|
|
3768
|
+
return `\n \`${route}\`,{${`${isAngular ? "body" : "data"}: ${bodyIdentifier}`}${axiosOptions ? `,${deleteBodyOptions}` : ""}}\n `;
|
|
3727
3769
|
}
|
|
3728
|
-
const bodyOrOptions = getIsBodyVerb(verb) ?
|
|
3770
|
+
const bodyOrOptions = getIsBodyVerb(verb) ? `\n ${bodyIdentifier ?? "undefined"},` : "";
|
|
3729
3771
|
return `\n \`${route}\`${bodyOrOptions || optionsArgument ? "," : ""}${bodyOrOptions}${optionsArgument}\n `;
|
|
3730
3772
|
}
|
|
3731
3773
|
function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
|
|
@@ -4323,8 +4365,8 @@ function getSchema({ schema: { imports, model }, header, namingConvention = Nami
|
|
|
4323
4365
|
file += model;
|
|
4324
4366
|
return file;
|
|
4325
4367
|
}
|
|
4326
|
-
function getPath(path, name, fileExtension) {
|
|
4327
|
-
return
|
|
4368
|
+
function getPath(path$1, name, fileExtension) {
|
|
4369
|
+
return path.join(path$1, `${name}${fileExtension}`);
|
|
4328
4370
|
}
|
|
4329
4371
|
function writeModelInline(acc, model) {
|
|
4330
4372
|
return acc + `${model}\n`;
|
|
@@ -4373,12 +4415,12 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
|
|
|
4373
4415
|
});
|
|
4374
4416
|
}
|
|
4375
4417
|
if (indexFiles) {
|
|
4376
|
-
const schemaFilePath =
|
|
4418
|
+
const schemaFilePath = path.join(schemaPath, `index.ts`);
|
|
4377
4419
|
await fs$1.ensureFile(schemaFilePath);
|
|
4378
4420
|
const ext = fileExtension.endsWith(".ts") ? fileExtension.slice(0, -3) : fileExtension;
|
|
4379
4421
|
const conventionNamesSet = new Set(Object.values(schemaGroups).map((group) => conventionName(group[0].name, namingConvention)));
|
|
4380
4422
|
try {
|
|
4381
|
-
await writeGeneratedFile(schemaFilePath, `${header}\n${[...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b)).join("\n")}\n`);
|
|
4423
|
+
await writeGeneratedFile(schemaFilePath, `${header}\n${[...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b, "en", { numeric: true })).join("\n")}\n`);
|
|
4382
4424
|
} catch (error) {
|
|
4383
4425
|
throw new Error(`Oups... 🍻. An Error occurred while writing schema index file ${schemaFilePath} => ${String(error)}`, { cause: error });
|
|
4384
4426
|
}
|
|
@@ -4644,8 +4686,8 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4644
4686
|
isAllowSyntheticDefaultImports,
|
|
4645
4687
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
4646
4688
|
});
|
|
4647
|
-
const schemasPath = output.schemas
|
|
4648
|
-
if (schemasPath
|
|
4689
|
+
const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
4690
|
+
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
4649
4691
|
if (mutators) implementationData += generateMutatorImports({
|
|
4650
4692
|
mutators,
|
|
4651
4693
|
implementation
|
|
@@ -4666,9 +4708,9 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
|
|
|
4666
4708
|
implementationData += `\n${implementation}`;
|
|
4667
4709
|
mockData += `\n${implementationMock}`;
|
|
4668
4710
|
const implementationFilename = filename + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
|
|
4669
|
-
const implementationPath =
|
|
4711
|
+
const implementationPath = path.join(dirname, implementationFilename);
|
|
4670
4712
|
await writeGeneratedFile(implementationPath, implementationData);
|
|
4671
|
-
const mockPath = output.mock ?
|
|
4713
|
+
const mockPath = output.mock ? path.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
|
|
4672
4714
|
if (mockPath) await writeGeneratedFile(mockPath, mockData);
|
|
4673
4715
|
return [
|
|
4674
4716
|
implementationPath,
|
|
@@ -4803,7 +4845,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4803
4845
|
const target = generateTargetForTags(builder, output);
|
|
4804
4846
|
const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
|
|
4805
4847
|
const mockOption = output.mock && !isFunction(output.mock) ? output.mock : void 0;
|
|
4806
|
-
const indexFilePath = mockOption?.indexMockFiles ?
|
|
4848
|
+
const indexFilePath = mockOption?.indexMockFiles ? path.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
|
|
4807
4849
|
if (indexFilePath) await fs$1.outputFile(indexFilePath, "");
|
|
4808
4850
|
const tagEntries = Object.entries(target);
|
|
4809
4851
|
const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
|
|
@@ -4811,19 +4853,19 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4811
4853
|
const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer } = target;
|
|
4812
4854
|
let implementationData = header;
|
|
4813
4855
|
let mockData = header;
|
|
4814
|
-
const importerPath =
|
|
4856
|
+
const importerPath = path.join(dirname, tag, tag + extension);
|
|
4815
4857
|
const relativeSchemasPath = output.schemas ? getRelativeImportPath(importerPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas" + extension.replace(/\.ts$/, "");
|
|
4816
4858
|
const tagNames = new Set(tagEntries.map(([t]) => t));
|
|
4817
4859
|
const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
|
|
4818
4860
|
const importsForBuilder = generateImportsForBuilder(output, imports.map((imp) => {
|
|
4819
4861
|
if (!imp.importPath) return imp;
|
|
4820
4862
|
if (!imp.importPath.startsWith(".")) return imp;
|
|
4821
|
-
const resolvedPath =
|
|
4822
|
-
const targetBasename =
|
|
4863
|
+
const resolvedPath = path.resolve(dirname, imp.importPath);
|
|
4864
|
+
const targetBasename = path.basename(resolvedPath);
|
|
4823
4865
|
let targetFile;
|
|
4824
4866
|
if (tagNames.has(targetBasename)) {
|
|
4825
4867
|
const tagFilename = targetBasename + serviceSuffix + extension;
|
|
4826
|
-
targetFile =
|
|
4868
|
+
targetFile = path.join(resolvedPath, tagFilename);
|
|
4827
4869
|
} else targetFile = resolvedPath + extension;
|
|
4828
4870
|
const adjustedPath = getRelativeImportPath(importerPath, targetFile);
|
|
4829
4871
|
return {
|
|
@@ -4853,8 +4895,8 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4853
4895
|
isAllowSyntheticDefaultImports,
|
|
4854
4896
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
4855
4897
|
});
|
|
4856
|
-
const schemasPath = output.schemas
|
|
4857
|
-
if (schemasPath
|
|
4898
|
+
const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
4899
|
+
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
4858
4900
|
if (mutators) implementationData += generateMutatorImports({
|
|
4859
4901
|
mutators,
|
|
4860
4902
|
implementation,
|
|
@@ -4891,9 +4933,9 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
|
|
|
4891
4933
|
implementationData += `\n${implementation}`;
|
|
4892
4934
|
mockData += `\n${implementationMock}`;
|
|
4893
4935
|
const implementationFilename = tag + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
|
|
4894
|
-
const implementationPath =
|
|
4936
|
+
const implementationPath = path.join(dirname, tag, implementationFilename);
|
|
4895
4937
|
await writeGeneratedFile(implementationPath, implementationData);
|
|
4896
|
-
const mockPath = output.mock ?
|
|
4938
|
+
const mockPath = output.mock ? path.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
|
|
4897
4939
|
if (mockPath) await writeGeneratedFile(mockPath, mockData);
|
|
4898
4940
|
return [
|
|
4899
4941
|
implementationPath,
|
|
@@ -4962,8 +5004,8 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
4962
5004
|
options: isFunction(output.mock) ? void 0 : output.mock
|
|
4963
5005
|
});
|
|
4964
5006
|
}
|
|
4965
|
-
const schemasPath = output.schemas
|
|
4966
|
-
if (schemasPath
|
|
5007
|
+
const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
|
|
5008
|
+
if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
|
|
4967
5009
|
if (mutators) data += generateMutatorImports({
|
|
4968
5010
|
mutators,
|
|
4969
5011
|
implementation
|
|
@@ -4987,7 +5029,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
|
|
|
4987
5029
|
data += "\n\n";
|
|
4988
5030
|
data += implementationMock;
|
|
4989
5031
|
}
|
|
4990
|
-
const implementationPath =
|
|
5032
|
+
const implementationPath = path.join(dirname, `${kebab(tag)}${extension}`);
|
|
4991
5033
|
await writeGeneratedFile(implementationPath, data);
|
|
4992
5034
|
return [implementationPath, ...schemasPath ? [schemasPath] : []];
|
|
4993
5035
|
} catch (error) {
|