@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 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 nodePath from "node:path";
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 !nodePath.extname(pathValue);
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 = nodePath.resolve(from, toImport);
454
- const extension = nodePath.extname(filePath);
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 ? nodePath.join(target, backupFilename + extension) : target;
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: nodePath.dirname(filePath),
486
- filename: nodePath.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
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(nodePath.join(...args.map((a) => toUnix(a))));
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(nodePath.relative(toUnix(from), toUnix(to)))}`);
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(nodePath.normalize(value));
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(nodePath.join(...values.map((v) => toUnix(v))));
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 (!nodePath.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
746
- if (!nodePath.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
747
- const importerDir = nodePath.dirname(importerFilePath);
748
- const relativePath = nodePath.relative(importerDir, exporterFilePath);
749
- let posixPath = nodePath.posix.join(...relativePath.split(nodePath.sep));
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 = nodePath.extname(posixPath);
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(nodePath.join(fromDir, "noop.js"));
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 = nodePath.dirname(entryPath);
768
- while (dir !== nodePath.parse(dir).root) {
769
- const pkgPath = nodePath.join(dir, "package.json");
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 = nodePath.dirname(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
- * Extract enum values from propertyNames schema (OpenAPI 3.1)
2105
- * Handles both `enum` and `const` (treated as a single-element enum)
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 getPropertyNamesEnum(item) {
2109
- if (!("propertyNames" in item) || !item.propertyNames) return;
2132
+ function getPropertyNamesKeyType(item, context) {
2133
+ const inlineKeyType = getPropertyNamesEnumKeyType(item);
2134
+ if (inlineKeyType) return inlineKeyType;
2110
2135
  const propertyNames = item.propertyNames;
2111
- if (Array.isArray(propertyNames.enum)) return propertyNames.enum.filter((val) => isString(val));
2112
- if (isString(propertyNames.const)) return [propertyNames.const];
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
- const enumValues = getPropertyNamesEnum(item);
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 enumValues = getPropertyNamesEnum(item);
2125
- if (!enumValues || enumValues.length === 0) return;
2126
- return `Partial<Record<${enumValues.map((val) => `'${val}'`).join(" | ")}, ${valueType}>>`;
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
- uniqueTypes = types.filter((t) => !values.some((v) => v.name === t.name && (v.alias ?? "") === (t.alias ?? "")));
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 "\n formData,";
3654
- if (isFormUrlEncoded && body.formUrlEncoded) return "\n formUrlEncoded,";
3655
- if (body.implementation) return `\n ${body.implementation},`;
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 bodyOptions = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : "";
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 (!bodyOptions) return `\n \`${route}\`${optionsArgument ? `,${optionsArgument}` : ""}\n `;
3766
+ if (!bodyIdentifier) return `\n \`${route}\`${optionsArgument ? `,${optionsArgument}` : ""}\n `;
3725
3767
  const deleteBodyOptions = isRawOptionsArgument ? `...${optionsArgument}` : axiosOptions;
3726
- return `\n \`${route}\`,{${isAngular ? "body" : "data"}:${bodyOptions} ${axiosOptions ? deleteBodyOptions : ""}}\n `;
3768
+ return `\n \`${route}\`,{${`${isAngular ? "body" : "data"}: ${bodyIdentifier}`}${axiosOptions ? `,${deleteBodyOptions}` : ""}}\n `;
3727
3769
  }
3728
- const bodyOrOptions = getIsBodyVerb(verb) ? bodyOptions || "undefined," : "";
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 nodePath.join(path, `${name}${fileExtension}`);
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 = nodePath.join(schemaPath, `index.ts`);
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 ? void 0 : nodePath.join(dirname, filename + ".schemas" + extension);
4648
- if (schemasPath && needSchema) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
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 = nodePath.join(dirname, implementationFilename);
4711
+ const implementationPath = path.join(dirname, implementationFilename);
4670
4712
  await writeGeneratedFile(implementationPath, implementationData);
4671
- const mockPath = output.mock ? nodePath.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
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 ? nodePath.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
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 = nodePath.join(dirname, tag, tag + extension);
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 = nodePath.resolve(dirname, imp.importPath);
4822
- const targetBasename = nodePath.basename(resolvedPath);
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 = nodePath.join(resolvedPath, tagFilename);
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 ? void 0 : nodePath.join(dirname, filename + ".schemas" + extension);
4857
- if (schemasPath && needSchema) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
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 = nodePath.join(dirname, tag, implementationFilename);
4936
+ const implementationPath = path.join(dirname, tag, implementationFilename);
4895
4937
  await writeGeneratedFile(implementationPath, implementationData);
4896
- const mockPath = output.mock ? nodePath.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
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 ? void 0 : nodePath.join(dirname, filename + ".schemas" + extension);
4966
- if (schemasPath && needSchema) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
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 = nodePath.join(dirname, `${kebab(tag)}${extension}`);
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) {