@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.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 path from "node:path";
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 !path.extname(pathValue);
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 = path.resolve(from, toImport);
454
- const extension = path.extname(filePath);
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 ? path.join(target, backupFilename + extension) : target;
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: path.dirname(filePath),
486
- filename: path.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
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(path.join(...args.map((a) => toUnix(a))));
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(path.relative(toUnix(from), toUnix(to)))}`);
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(path.normalize(value));
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(path.join(...values.map((v) => toUnix(v))));
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 (!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));
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 = path.extname(posixPath);
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(path.join(fromDir, "noop.js"));
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 = path.dirname(entryPath);
768
- while (dir !== path.parse(dir).root) {
769
- const pkgPath = path.join(dir, "package.json");
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 = path.dirname(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 path = `${oneMore ? "../" : ""}${mutator.path}`;
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 filteredParamValueType = `string | number | boolean${preserveRequiredNullables ? " | null" : ""} | Array<string | number | boolean>`;
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
- ): Record<string, AngularHttpParamValueWithNullable> {
3661
- const filteredParams: Record<string, AngularHttpParamValueWithNullable> = {};
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) => `filterParams(${paramsExpression}, new Set<string>(${JSON.stringify(requiredNullableParamKeys)})${preserveRequiredNullables ? ", true" : ""})`;
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 = getAngularFilteredParamsExpression("params ?? {}", requiredNullableQueryParamKeys, !!paramsSerializer);
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 = getAngularFilteredParamsCallExpression("{...params, ...options?.params}", requiredNullableQueryParamKeys, true);
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) value += `\n params: ${getAngularFilteredParamsCallExpression("{...params, ...options?.params}", requiredNullableQueryParamKeys)},`;
3735
- else value += "\n params: {...params, ...options?.params},";
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) value += `,\n params: ${getAngularFilteredParamsExpression("params ?? {}", requiredNullableQueryParamKeys)}`;
3784
- else value += ",\n params";
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 importPath = removeTSExtension(relativeSafe(schemaPath, canonical.importPath.replaceAll("\\", "/")));
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 removeTSExtension(path) {
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$1, name, fileExtension) {
4369
- return path.join(path$1, `${name}${fileExtension}`);
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 = path.join(schemaPath, `index.ts`);
4650
+ const schemaFilePath = nodePath.join(schemaPath, `index.ts`);
4419
4651
  await fs$1.ensureFile(schemaFilePath);
4420
- const ext = fileExtension.endsWith(".ts") ? fileExtension.slice(0, -3) : fileExtension;
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.replace(/\.ts$/, "") || ""}`);
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 ? path.join(dirname, filename + ".schemas" + extension) : void 0;
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 = path.join(dirname, implementationFilename);
4947
+ const implementationPath = nodePath.join(dirname, implementationFilename);
4712
4948
  await writeGeneratedFile(implementationPath, implementationData);
4713
- const mockPath = output.mock ? path.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
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 : ["default"]
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 ? path.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
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 = path.join(dirname, tag, tag + extension);
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 = path.resolve(dirname, imp.importPath);
4864
- const targetBasename = path.basename(resolvedPath);
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 = path.join(resolvedPath, tagFilename);
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 ? path.join(dirname, filename + ".schemas" + extension) : void 0;
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 = path.join(dirname, tag, implementationFilename);
5186
+ const implementationPath = nodePath.join(dirname, tag, implementationFilename);
4937
5187
  await writeGeneratedFile(implementationPath, implementationData);
4938
- const mockPath = output.mock ? path.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
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 ? path.join(dirname, filename + ".schemas" + extension) : void 0;
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 = path.join(dirname, `${kebab(tag)}${extension}`);
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