@orval/core 8.18.0 → 8.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./chunk-8H4AJuhK.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { entries, groupBy, isArray, isBoolean, isBoolean as isBoolean$1, isEmptyish, isFunction, isFunction as isFunction$1, 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";
@@ -168,7 +168,7 @@ function isDynamicReference(obj) {
168
168
  * @param pathValue - Path string to inspect.
169
169
  */
170
170
  function isDirectory(pathValue) {
171
- return !nodePath.extname(pathValue);
171
+ return !path.extname(pathValue);
172
172
  }
173
173
  /**
174
174
  * Type guard for plain objects created with `{}` or `new Object()`.
@@ -560,8 +560,8 @@ async function dynamicImport(toImport, from = process.cwd(), takeDefault = true)
560
560
  if (!toImport) return toImport;
561
561
  try {
562
562
  if (isString(toImport)) {
563
- const filePath = nodePath.resolve(from, toImport);
564
- const extension = nodePath.extname(filePath);
563
+ const filePath = path.resolve(from, toImport);
564
+ const extension = path.extname(filePath);
565
565
  if (TS_MODULE_EXTENSIONS.has(extension)) {
566
566
  const data = await createJiti(from, { interopDefault: true }).import(filePath);
567
567
  if (takeDefault && (isObject(data) || isModule(data)) && data.default) return data.default;
@@ -586,14 +586,14 @@ function getExtension(path) {
586
586
  //#region src/utils/file.ts
587
587
  function getFileInfo(target = "", { backupFilename = "filename", extension = ".ts" } = {}) {
588
588
  const isDir = isDirectory(target);
589
- const filePath = isDir ? nodePath.join(target, backupFilename + extension) : target;
589
+ const filePath = isDir ? path.join(target, backupFilename + extension) : target;
590
590
  return {
591
591
  path: filePath,
592
592
  pathWithoutExtension: filePath.replace(/\.[^/.]+$/, ""),
593
593
  extension,
594
594
  isDirectory: isDir,
595
- dirname: nodePath.dirname(filePath),
596
- filename: nodePath.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
595
+ dirname: path.dirname(filePath),
596
+ filename: path.basename(filePath, extension.startsWith(".") ? extension : `.${extension}`)
597
597
  };
598
598
  }
599
599
  async function removeFilesAndEmptyFolders(patterns, dir) {
@@ -804,10 +804,10 @@ var path_exports = /* @__PURE__ */ __exportAll({
804
804
  toUnix: () => toUnix
805
805
  });
806
806
  function isAbsolute(value) {
807
- return nodePath.isAbsolute(value);
807
+ return path.isAbsolute(value);
808
808
  }
809
809
  function resolve(...args) {
810
- return toUnix(nodePath.resolve(...args));
810
+ return toUnix(path.resolve(...args));
811
811
  }
812
812
  function toUnix(value) {
813
813
  value = value.replaceAll("\\", "/");
@@ -815,13 +815,13 @@ function toUnix(value) {
815
815
  return value;
816
816
  }
817
817
  function join(...args) {
818
- return toUnix(nodePath.join(...args.map((a) => toUnix(a))));
818
+ return toUnix(path.join(...args.map((a) => toUnix(a))));
819
819
  }
820
820
  /**
821
821
  * Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
822
822
  */
823
823
  function relativeSafe(from, to) {
824
- return normalizeSafe(`./${toUnix(nodePath.relative(toUnix(from), toUnix(to)))}`);
824
+ return normalizeSafe(`./${toUnix(path.relative(toUnix(from), toUnix(to)))}`);
825
825
  }
826
826
  function getSchemaFileName(path) {
827
827
  return path.replace(`.${getExtension(path)}`, "").slice(path.lastIndexOf("/") + 1);
@@ -829,13 +829,13 @@ function getSchemaFileName(path) {
829
829
  function normalizeSafe(value) {
830
830
  let result;
831
831
  value = toUnix(value);
832
- result = toUnix(nodePath.normalize(value));
832
+ result = toUnix(path.normalize(value));
833
833
  if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
834
834
  else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
835
835
  return result;
836
836
  }
837
837
  function joinSafe(...values) {
838
- let result = toUnix(nodePath.join(...values.map((v) => toUnix(v))));
838
+ let result = toUnix(path.join(...values.map((v) => toUnix(v))));
839
839
  if (values.length > 0) {
840
840
  const firstValue = toUnix(values[0]);
841
841
  if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
@@ -866,14 +866,14 @@ function joinSafe(...values) {
866
866
  * @returns The relative import path string.
867
867
  */
868
868
  function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileExtension = false) {
869
- if (!nodePath.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
870
- if (!nodePath.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
871
- const importerDir = nodePath.dirname(importerFilePath);
872
- const relativePath = nodePath.relative(importerDir, exporterFilePath);
873
- let posixPath = nodePath.posix.join(...relativePath.split(nodePath.sep));
869
+ if (!path.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
870
+ if (!path.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
871
+ const importerDir = path.dirname(importerFilePath);
872
+ const relativePath = path.relative(importerDir, exporterFilePath);
873
+ let posixPath = path.posix.join(...relativePath.split(path.sep));
874
874
  if (!posixPath.startsWith("./") && !posixPath.startsWith("../")) posixPath = `./${posixPath}`;
875
875
  if (!includeFileExtension) {
876
- const ext = nodePath.extname(posixPath);
876
+ const ext = path.extname(posixPath);
877
877
  if (ext && posixPath.endsWith(ext)) posixPath = posixPath.slice(0, -ext.length);
878
878
  }
879
879
  return posixPath;
@@ -882,20 +882,20 @@ function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileEx
882
882
  //#region src/utils/resolve-version.ts
883
883
  function resolveInstalledVersion(packageName, fromDir) {
884
884
  try {
885
- const require = createRequire(nodePath.join(fromDir, "noop.js"));
885
+ const require = createRequire(path.join(fromDir, "noop.js"));
886
886
  try {
887
887
  return require(`${packageName}/package.json`).version;
888
888
  } catch (directError) {
889
889
  if (directError instanceof Error && "code" in directError && directError.code === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
890
890
  const entryPath = require.resolve(packageName);
891
- let dir = nodePath.dirname(entryPath);
892
- while (dir !== nodePath.parse(dir).root) {
893
- const pkgPath = nodePath.join(dir, "package.json");
891
+ let dir = path.dirname(entryPath);
892
+ while (dir !== path.parse(dir).root) {
893
+ const pkgPath = path.join(dir, "package.json");
894
894
  if (existsSync(pkgPath)) {
895
895
  const pkgData = JSON.parse(readFileSync(pkgPath, "utf8"));
896
896
  if (pkgData.name === packageName) return pkgData.version;
897
897
  }
898
- dir = nodePath.dirname(dir);
898
+ dir = path.dirname(dir);
899
899
  }
900
900
  return;
901
901
  }
@@ -1159,6 +1159,55 @@ function dedupeUnionType(unionType) {
1159
1159
  return [...new Set(parts)].join(" | ");
1160
1160
  }
1161
1161
  //#endregion
1162
+ //#region src/utils/tags.ts
1163
+ /**
1164
+ * Canonical bucket key for a single OpenAPI tag.
1165
+ *
1166
+ * In `tags` / `tags-split` mode operations are routed into files by their first
1167
+ * tag. This function is the **single source of truth** for turning a tag (or a
1168
+ * missing tag) into the key that identifies that file bucket. Every place that
1169
+ * groups operations by tag, derives a per-tag file/directory name, or checks
1170
+ * whether an operation belongs to a tag MUST go through here so that the
1171
+ * "build the key" side and the "look the key up" side can never disagree.
1172
+ *
1173
+ * The result is `kebab`-cased. `kebab` is idempotent
1174
+ * (`kebab(kebab(x)) === kebab(x)`), so it is always safe to call this on a value
1175
+ * that is already a canonical key. Other case functions (`camel`, `pascal`) are
1176
+ * NOT safe here: they do not round-trip through the bucket key for tags
1177
+ * containing acronyms or spaces (e.g. `"AB Widget"`), which is exactly the class
1178
+ * of bug this module exists to prevent.
1179
+ *
1180
+ * Missing or empty tags map to the implicit {@link DefaultTag} bucket.
1181
+ */
1182
+ function getTagKey(tag) {
1183
+ const normalizedTag = tag?.trim();
1184
+ return kebab(normalizedTag ? normalizedTag : DefaultTag);
1185
+ }
1186
+ /**
1187
+ * Canonical bucket key for an operation, derived from its primary (first) tag.
1188
+ *
1189
+ * Untagged operations resolve to the {@link DefaultTag} bucket.
1190
+ */
1191
+ function getOperationTagKey(operation) {
1192
+ return getTagKey(operation.tags[0]);
1193
+ }
1194
+ /**
1195
+ * Whether an operation belongs to the given tag bucket.
1196
+ *
1197
+ * Both sides are normalised through {@link getTagKey}, so the comparison is
1198
+ * correct regardless of how `tagKey` was spelled or cased by the caller. An
1199
+ * absent (`undefined`) `tagKey` matches every operation (the "no tag filter"
1200
+ * case); an empty/whitespace `tagKey` is normalised to the {@link DefaultTag}
1201
+ * bucket like any other tag.
1202
+ *
1203
+ * Prefer this over hand-rolling `operation.tags[0] === tagKey`: a raw tag
1204
+ * compared against a canonical key silently fails for multi-word/acronym tags.
1205
+ */
1206
+ function isOperationInTagBucket(operation, tagKey) {
1207
+ if (tagKey == null) return true;
1208
+ return getOperationTagKey(operation) === getTagKey(tagKey);
1209
+ }
1210
+ //#endregion
1162
1211
  //#region src/utils/tsconfig.ts
1163
1212
  function isSyntheticDefaultImportsAllow(config) {
1164
1213
  if (!config) return true;
@@ -2486,6 +2535,52 @@ function buildDynamicScope(schemaName, schema, context) {
2486
2535
  return scope;
2487
2536
  }
2488
2537
  /**
2538
+ * Build dynamic scope entries for an **anonymous inline** subschema that declares
2539
+ * `$dynamicAnchor` without a `$ref` (e.g. inside `allOf`, `items`, nested props).
2540
+ *
2541
+ * Unlike {@link buildDynamicScope}, entries carry the concrete `inlineSchema` so
2542
+ * that a descendant `$dynamicRef` resolves to the inline override rather than the
2543
+ * outer/global component. Used when `dereference` enters a subschema without a
2544
+ * named component `$ref`.
2545
+ *
2546
+ * Scope of handling (deliberate, see #3492):
2547
+ * - Direct `$dynamicAnchor` on the subschema → inline entry.
2548
+ * - `$defs` `$dynamicAnchor` *without* a `$ref` → inline entry. Note this
2549
+ * differs from `buildDynamicScope`, which treats unbound `$defs` anchors as
2550
+ * generic parameters (`isParameter`); inline subschemas are concrete
2551
+ * instances, so the anchor resolves to the inline schema object itself.
2552
+ * - `$defs` `$dynamicAnchor` *with* a `$ref` → intentionally NOT collected
2553
+ * here. Such anchors rely on `resolveDynamicRef`'s global fallback (which
2554
+ * finds them when the `$ref` target declares the same anchor). Fully
2555
+ * resolving them would duplicate `buildDynamicScope`'s `$defs` logic.
2556
+ */
2557
+ function buildInlineDynamicScope(schema) {
2558
+ const scope = {};
2559
+ const schemaRecord = schema;
2560
+ if (typeof schemaRecord.$dynamicAnchor === "string") {
2561
+ const anchor = schemaRecord.$dynamicAnchor;
2562
+ scope[anchor] = {
2563
+ name: anchor,
2564
+ schemaName: anchor,
2565
+ inlineSchema: schema
2566
+ };
2567
+ }
2568
+ const defs = schemaRecord.$defs;
2569
+ if (defs && typeof defs === "object") for (const defSchema of Object.values(defs)) {
2570
+ if (!defSchema || typeof defSchema !== "object") continue;
2571
+ const defRecord = defSchema;
2572
+ if (typeof defRecord.$dynamicAnchor === "string" && !defSchema.$ref) {
2573
+ const anchor = defRecord.$dynamicAnchor;
2574
+ scope[anchor] = {
2575
+ name: anchor,
2576
+ schemaName: anchor,
2577
+ inlineSchema: defSchema
2578
+ };
2579
+ }
2580
+ }
2581
+ return scope;
2582
+ }
2583
+ /**
2489
2584
  * Resolve a `$dynamicRef` anchor to its concrete type using the current dynamic scope.
2490
2585
  * Returns `{ schema: {}, resolvedTypeName: 'unknown' }` when no scope override exists.
2491
2586
  */
@@ -2521,6 +2616,12 @@ function resolveDynamicRef(anchorName, context, imports = []) {
2521
2616
  resolvedTypeName: scopeEntry.name,
2522
2617
  schemaName: void 0
2523
2618
  };
2619
+ if (scopeEntry.inlineSchema) return {
2620
+ schema: scopeEntry.inlineSchema,
2621
+ imports,
2622
+ resolvedTypeName: scopeEntry.name,
2623
+ schemaName: void 0
2624
+ };
2524
2625
  const resolvedTypeName = scopeEntry.name;
2525
2626
  const schemaRef = `#/components/schemas/${encodeJsonPointerSegment(scopeEntry.schemaName)}`;
2526
2627
  try {
@@ -2713,7 +2814,7 @@ function resolveValue({ schema, name, context, formDataContext }) {
2713
2814
  const refName = resolvedImport.name;
2714
2815
  let effectiveContext = context;
2715
2816
  const refAnchor = schemaObject.$dynamicAnchor;
2716
- if (typeof refAnchor === "string" && context.dynamicScope?.[refAnchor] && context.dynamicScope[refAnchor].name !== refName && !context.dynamicScope[refAnchor].isParameter) {
2817
+ if (typeof refAnchor === "string" && context.dynamicScope?.[refAnchor] && context.dynamicScope[refAnchor].name !== refName && !context.dynamicScope[refAnchor].isParameter && !context.dynamicScope[refAnchor].inlineSchema) {
2717
2818
  const scopeEntry = context.dynamicScope[refAnchor];
2718
2819
  const allOf = ((context.spec.components?.schemas)?.[scopeEntry.schemaName])?.allOf;
2719
2820
  if (!(Array.isArray(allOf) && allOf.some((el) => {
@@ -4621,7 +4722,7 @@ function parseFunction(ast, funcName) {
4621
4722
  const BODY_TYPE_NAME = "BodyType";
4622
4723
  const getImport = (output, mutator, tsconfig) => {
4623
4724
  const outputFile = getFileInfo(output).path;
4624
- const ext = mutator.extension ?? getImportExtension(nodePath.extname(mutator.path), tsconfig);
4725
+ const ext = mutator.extension ?? getImportExtension(path.extname(mutator.path), tsconfig);
4625
4726
  return `${getRelativeImportPath(outputFile, mutator.path)}${ext}`;
4626
4727
  };
4627
4728
  async function generateMutator({ output, mutator, name, workspace, tsconfig }) {
@@ -4821,7 +4922,7 @@ function generateBodyOptions(body, isFormData, isFormUrlEncoded) {
4821
4922
  if (isFormUrlEncoded && body.formUrlEncoded) return "formUrlEncoded";
4822
4923
  if (body.implementation) return body.implementation;
4823
4924
  }
4824
- function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, nonPrimitiveQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4925
+ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, nonPrimitiveQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isAngular, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4825
4926
  const isRequestOptions = requestOptions !== false;
4826
4927
  const angularPassthroughQueryParamKeys = paramsSerializer ? nonPrimitiveQueryParamKeys : [];
4827
4928
  const signalVar = hasSignalParam ? "querySignal" : "signal";
@@ -4858,8 +4959,7 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
4858
4959
  if (isRequestOptions) {
4859
4960
  value += isAngular ? "\n ...(options as Omit<NonNullable<typeof options>, 'observe'>)," : "\n ...options,";
4860
4961
  if (isAngular && angularObserve) value += `\n observe: '${angularObserve}',`;
4861
- if (queryParams) if (isVue) value += "\n params: {...unref(params), ...options?.params},";
4862
- else if (isAngular && angularParamsRef) value += `\n params: ${angularParamsRef},`;
4962
+ if (queryParams) if (isAngular && angularParamsRef) value += `\n params: ${angularParamsRef},`;
4863
4963
  else if (isAngular && paramsSerializer) {
4864
4964
  const callExpr = buildAngularParamsFilterExpression({
4865
4965
  paramsExpression: "{...params, ...options?.params}",
@@ -4888,7 +4988,7 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
4888
4988
  }
4889
4989
  return value;
4890
4990
  }
4891
- function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4991
+ function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4892
4992
  const bodyIdentifier = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : void 0;
4893
4993
  const axiosOptions = generateAxiosOptions({
4894
4994
  response,
@@ -4902,7 +5002,6 @@ function generateOptions({ route, body, angularObserve, angularParamsRef, header
4902
5002
  isExactOptionalPropertyTypes,
4903
5003
  hasSignal,
4904
5004
  hasSignalParam,
4905
- isVue: isVue ?? false,
4906
5005
  isAngular: isAngular ?? false,
4907
5006
  paramsSerializer,
4908
5007
  paramsSerializerOptions,
@@ -4925,11 +5024,10 @@ function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
4925
5024
  if (body.implementation) return `,\n data: ${body.implementation}`;
4926
5025
  return "";
4927
5026
  }
4928
- function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNullableQueryParamKeys, queryParams, paramsFilter) {
5027
+ function generateQueryParamsAxiosConfig(response, isAngular, requiredNullableQueryParamKeys, queryParams, paramsFilter) {
4929
5028
  if (!queryParams && !response.isBlob) return "";
4930
5029
  let value = "";
4931
- if (queryParams) if (isVue) value += ",\n params: unref(params)";
4932
- else if (isAngular) {
5030
+ if (queryParams) if (isAngular) {
4933
5031
  const paramsExpr = buildAngularParamsFilterExpression({
4934
5032
  paramsExpression: "params ?? {}",
4935
5033
  requiredNullableParamKeys: requiredNullableQueryParamKeys,
@@ -4942,9 +5040,9 @@ function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNull
4942
5040
  if (response.isBlob) value += `,\n responseType: 'blob'`;
4943
5041
  return value;
4944
5042
  }
4945
- function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue, isAngular, paramsFilter }) {
5043
+ function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isAngular, paramsFilter }) {
4946
5044
  const bodyOptions = getIsBodyVerb(verb) ? generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) : "";
4947
- const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams, paramsFilter);
5045
+ const queryParamsOptions = generateQueryParamsAxiosConfig(response, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams, paramsFilter);
4948
5046
  const ignoreContentTypes = isAngular ? ["multipart/form-data"] : [];
4949
5047
  const headerOptions = body.contentType && !ignoreContentTypes.includes(body.contentType) ? `,\n headers: {'Content-Type': '${body.contentType}', ${headers ? "...headers" : ""}}` : headers ? ",\n headers" : "";
4950
5048
  const signalVar = hasSignalParam ? "querySignal" : "signal";
@@ -5479,6 +5577,50 @@ async function writeGeneratedFile(filePath, content) {
5479
5577
  await fs$1.outputFile(filePath, content.replaceAll(TRAILING_WHITESPACE_RE, ""));
5480
5578
  }
5481
5579
  //#endregion
5580
+ //#region src/writers/schema-tag-mapper.ts
5581
+ const SHARED_DIR = ".";
5582
+ function buildSchemaTagMap(operations, schemas) {
5583
+ const schemaNames = new Set(schemas.map((s) => s.name));
5584
+ const schemaToTags = /* @__PURE__ */ new Map();
5585
+ for (const schema of schemas) if (!schemaToTags.has(schema.name)) schemaToTags.set(schema.name, /* @__PURE__ */ new Set());
5586
+ for (const operation of operations) {
5587
+ const tag = kebab(operation.tags[0] ?? "default");
5588
+ for (const imp of operation.imports) if (!imp.importPath && schemaNames.has(imp.name)) addTag(schemaToTags, imp.name, tag);
5589
+ }
5590
+ propagateTransitiveTags(schemaToTags, new Map(schemas.map((s) => [s.name, s])));
5591
+ const result = /* @__PURE__ */ new Map();
5592
+ for (const [name, tags] of schemaToTags) if (tags.size === 0 || tags.size > 1) result.set(name, ".");
5593
+ else result.set(name, [...tags][0]);
5594
+ return result;
5595
+ }
5596
+ function addTag(schemaToTags, schemaName, tag) {
5597
+ if (!schemaToTags.has(schemaName)) schemaToTags.set(schemaName, /* @__PURE__ */ new Set());
5598
+ schemaToTags.get(schemaName).add(tag);
5599
+ }
5600
+ function propagateTransitiveTags(schemaToTags, schemaByName) {
5601
+ let changed = true;
5602
+ while (changed) {
5603
+ changed = false;
5604
+ for (const [name, tags] of schemaToTags) {
5605
+ const schema = schemaByName.get(name);
5606
+ if (!schema) continue;
5607
+ for (const imp of schema.imports) {
5608
+ if (!isSchemaImport(imp)) continue;
5609
+ if (!schemaByName.has(imp.name)) continue;
5610
+ const targetTags = schemaToTags.get(imp.name);
5611
+ if (!targetTags) continue;
5612
+ for (const tag of tags) if (!targetTags.has(tag)) {
5613
+ targetTags.add(tag);
5614
+ changed = true;
5615
+ }
5616
+ }
5617
+ }
5618
+ }
5619
+ }
5620
+ function isSchemaImport(imp) {
5621
+ return !imp.importPath;
5622
+ }
5623
+ //#endregion
5482
5624
  //#region src/writers/schemas.ts
5483
5625
  /**
5484
5626
  * Patterns to detect operation-derived types (params, bodies, responses).
@@ -5631,8 +5773,8 @@ function getSchema({ schema: { imports, model }, header, namingConvention = Nami
5631
5773
  file += model;
5632
5774
  return file;
5633
5775
  }
5634
- function getPath(path, name, fileExtension) {
5635
- return nodePath.join(path, `${name}${fileExtension}`);
5776
+ function getPath(path$1, name, fileExtension) {
5777
+ return path.join(path$1, `${name}${fileExtension}`);
5636
5778
  }
5637
5779
  function writeModelInline(acc, model) {
5638
5780
  return acc + `${model}\n`;
@@ -5725,14 +5867,14 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
5725
5867
  await writeGeneratedFile(getPath(factoryDir, factoryFileName, fileExtension), factoryFile);
5726
5868
  }
5727
5869
  if (indexFiles) {
5728
- const schemaFilePath = nodePath.join(schemaPath, `index.ts`);
5870
+ const schemaFilePath = path.join(schemaPath, `index.ts`);
5729
5871
  await fs$1.ensureFile(schemaFilePath);
5730
5872
  const ext = getImportExtension(fileExtension, tsconfig);
5731
5873
  const conventionNamesSet = new Set(Object.values(schemaGroups).map((group) => conventionName(group[0].name, namingConvention)));
5732
5874
  try {
5733
5875
  const currentExports = [...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`);
5734
5876
  if (factoryOutputDirectory && normalizeSafe(factoryOutputDirectory) !== normalizeSafe(schemaPath) && (isCombined.value || separateFactoryNames.length > 0)) {
5735
- const factoryIndexFilePath = nodePath.join(factoryOutputDirectory, `index.ts`);
5877
+ const factoryIndexFilePath = path.join(factoryOutputDirectory, `index.ts`);
5736
5878
  await fs$1.ensureFile(factoryIndexFilePath);
5737
5879
  const factoryExports = [];
5738
5880
  if (isCombined.value) {
@@ -5755,6 +5897,61 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
5755
5897
  }
5756
5898
  }
5757
5899
  //#endregion
5900
+ //#region src/writers/schemas-tags-split.ts
5901
+ async function writeSchemasTagsSplit({ schemaPath, schemas, target, namingConvention, fileExtension, header, indexFiles, tsconfig, factoryOutputDirectory, operations }) {
5902
+ const schemaTagMap = buildSchemaTagMap(operations, schemas);
5903
+ const importExtension = getImportExtension(fileExtension, tsconfig);
5904
+ const groups = /* @__PURE__ */ new Map();
5905
+ for (const schema of schemas) {
5906
+ const group = schemaTagMap.get(schema.name) ?? ".";
5907
+ if (!groups.has(group)) groups.set(group, []);
5908
+ groups.get(group).push(schema);
5909
+ }
5910
+ for (const [groupDir, groupSchemas] of groups) {
5911
+ const isRoot = groupDir === ".";
5912
+ const groupPath = isRoot ? schemaPath : path.join(schemaPath, groupDir);
5913
+ fixCrossTagImports(groupSchemas, schemaTagMap, schemaPath, groupDir, namingConvention, importExtension);
5914
+ const groupFactoryDir = factoryOutputDirectory ? isRoot ? factoryOutputDirectory : path.join(factoryOutputDirectory, groupDir) : void 0;
5915
+ await writeSchemas({
5916
+ schemaPath: groupPath,
5917
+ schemas: groupSchemas,
5918
+ target,
5919
+ namingConvention,
5920
+ fileExtension,
5921
+ header,
5922
+ indexFiles: !isRoot && indexFiles,
5923
+ tsconfig,
5924
+ factoryOutputDirectory: groupFactoryDir
5925
+ });
5926
+ }
5927
+ if (indexFiles && groups.size > 0) {
5928
+ const rootIndexPath = path.join(schemaPath, "index.ts");
5929
+ const rootExports = (groups.get(".") ?? []).map((s) => {
5930
+ return `export * from './${conventionName(s.name, namingConvention)}${importExtension}';`;
5931
+ });
5932
+ const tagExports = [...groups.keys()].filter((dir) => dir !== ".").toSorted((a, b) => a.localeCompare(b, "en", { numeric: true })).map((dir) => {
5933
+ return `export * from '${importExtension ? `./${dir}/index${importExtension}` : `./${dir}`}';`;
5934
+ });
5935
+ await writeGeneratedFile(rootIndexPath, `${header}\n${[...rootExports, ...tagExports].join("\n")}\n`);
5936
+ }
5937
+ }
5938
+ function fixCrossTagImports(schemas, schemaTagMap, schemaPath, currentGroupDir, namingConvention, importExtension) {
5939
+ const fromPath = currentGroupDir === "." ? schemaPath : path.join(schemaPath, currentGroupDir);
5940
+ for (const schema of schemas) {
5941
+ const fixImports = (imports) => imports.map((imp) => {
5942
+ const targetGroup = schemaTagMap.get(imp.name);
5943
+ if (targetGroup === void 0 || targetGroup === currentGroupDir) return imp;
5944
+ const importPath = joinSafe(relativeSafe(fromPath, targetGroup === "." ? schemaPath : path.join(schemaPath, targetGroup)), conventionName(imp.name, namingConvention)) + importExtension;
5945
+ return {
5946
+ ...imp,
5947
+ importPath
5948
+ };
5949
+ });
5950
+ schema.imports = fixImports(schema.imports);
5951
+ if (schema.factoryImports) schema.factoryImports = fixImports(schema.factoryImports);
5952
+ }
5953
+ }
5954
+ //#endregion
5758
5955
  //#region src/writers/finalize-mock-implementation.ts
5759
5956
  function getFinalizeMockImplementationOptions(output, mockOutputs) {
5760
5957
  const outputs = Array.isArray(mockOutputs) ? mockOutputs : [mockOutputs];
@@ -5778,7 +5975,7 @@ function filterLocalStrictMockTypeImports(imports, strictSchemaTypeNames) {
5778
5975
  }
5779
5976
  //#endregion
5780
5977
  //#region src/writers/generate-imports-for-builder.ts
5781
- function generateImportsForBuilder(output, imports, relativeSchemasPath) {
5978
+ function generateImportsForBuilder(output, imports, relativeSchemasPath, schemaTagMap) {
5782
5979
  const isPackageImport = isObject(output.schemas) && !!output.schemas.importPath;
5783
5980
  const isZodSchemaOutput = isObject(output.schemas) && output.schemas.type === "zod";
5784
5981
  const schemaFactoryImports = imports.filter((i) => i.schemaFactory);
@@ -5800,7 +5997,11 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
5800
5997
  else {
5801
5998
  const importsByDependency = /* @__PURE__ */ new Map();
5802
5999
  for (const schemaImport of imports.filter((i) => !i.importPath)) {
5803
- const dependency = joinSafe(relativeSchemasPath, `${conventionName(isZodSchemaOutput ? schemaImport.name : schemaImport.schemaName ?? schemaImport.name, output.namingConvention)}${isZodSchemaOutput ? ".zod" : ""}${isPackageImport ? "" : getImportExtension(output.fileExtension, output.tsconfig)}`);
6000
+ const normalizedName = conventionName(isZodSchemaOutput ? schemaImport.name : schemaImport.schemaName ?? schemaImport.name, output.namingConvention);
6001
+ const suffix = isZodSchemaOutput ? ".zod" : "";
6002
+ const importExtension = isPackageImport ? "" : getImportExtension(output.fileExtension, output.tsconfig);
6003
+ const tagDir = schemaTagMap?.get(schemaImport.name);
6004
+ const dependency = joinSafe(relativeSchemasPath, `${tagDir && tagDir !== "." ? `${tagDir}/` : ""}${normalizedName}${suffix}${importExtension}`);
5804
6005
  if (!importsByDependency.has(dependency)) importsByDependency.set(dependency, []);
5805
6006
  importsByDependency.get(dependency)?.push(schemaImport);
5806
6007
  }
@@ -5832,6 +6033,78 @@ function getFakerSchemasImportPath(mock) {
5832
6033
  return mock.generators.find((g) => !isFunction(g) && g.type === OutputMockType.FAKER && g.schemas === true)?.schemasImportPath;
5833
6034
  }
5834
6035
  //#endregion
6036
+ //#region src/writers/mock-imports.ts
6037
+ /** Maps `components/schemas` names to consolidated index.faker import symbols. */
6038
+ function buildKnownSchemaFactoryImportSets(schemaNames) {
6039
+ const factoryNames = /* @__PURE__ */ new Set();
6040
+ const typeNames = /* @__PURE__ */ new Set();
6041
+ for (const name of schemaNames) {
6042
+ const typeName = pascal(name);
6043
+ factoryNames.add(`get${typeName}Mock`);
6044
+ typeNames.add(`${typeName}Mock`);
6045
+ }
6046
+ return {
6047
+ factoryNames,
6048
+ typeNames
6049
+ };
6050
+ }
6051
+ /**
6052
+ * Recover schema-factory imports referenced in generated mock bodies but
6053
+ * missing from the collected import list (e.g. after shared-array import
6054
+ * aggregation on large specs). Scans for `get<Schema>Mock()` calls and
6055
+ * `as <Schema>Mock` casts emitted by strict schema delegation (#3590).
6056
+ *
6057
+ * When `knownSets` is provided, only symbols that exist in the consolidated
6058
+ * schemas faker file are recovered — this avoids importing one-off split
6059
+ * response helper factories that live in the tag file itself.
6060
+ */
6061
+ function collectSchemaFactoryImportsFromImplementation(implementation, knownSets) {
6062
+ const imports = [];
6063
+ const seen = /* @__PURE__ */ new Set();
6064
+ for (const match of implementation.matchAll(/\b(get[A-Za-z0-9]+Mock)\(\)/g)) {
6065
+ const factoryName = match[1];
6066
+ if (knownSets && !knownSets.factoryNames.has(factoryName)) continue;
6067
+ const key = `value::${factoryName}`;
6068
+ if (seen.has(key)) continue;
6069
+ seen.add(key);
6070
+ imports.push({
6071
+ name: factoryName,
6072
+ values: true,
6073
+ schemaFactory: true
6074
+ });
6075
+ }
6076
+ for (const match of implementation.matchAll(/\bas ([A-Za-z0-9]+Mock)\b/g)) {
6077
+ const typeName = match[1];
6078
+ if (knownSets && !knownSets.typeNames.has(typeName)) continue;
6079
+ const key = `type::${typeName}`;
6080
+ if (seen.has(key)) continue;
6081
+ seen.add(key);
6082
+ imports.push({
6083
+ name: typeName,
6084
+ values: false,
6085
+ schemaFactory: true
6086
+ });
6087
+ }
6088
+ return imports;
6089
+ }
6090
+ function mergeGeneratorImports(...groups) {
6091
+ const merged = /* @__PURE__ */ new Map();
6092
+ for (const group of groups) for (const imp of group) {
6093
+ const key = `${imp.name}::${imp.alias ?? ""}`;
6094
+ const existing = merged.get(key);
6095
+ if (!existing) {
6096
+ merged.set(key, imp);
6097
+ continue;
6098
+ }
6099
+ if (!existing.values && imp.values) merged.set(key, imp);
6100
+ }
6101
+ return [...merged.values()];
6102
+ }
6103
+ /** Recover missing index.faker imports when `schemas: true` is enabled. */
6104
+ function collectRecoveredSchemaFactoryImports(implementation, componentSchemaNames) {
6105
+ return collectSchemaFactoryImportsFromImplementation(implementation, buildKnownSchemaFactoryImportSets(componentSchemaNames));
6106
+ }
6107
+ //#endregion
5835
6108
  //#region src/writers/mock-outputs.ts
5836
6109
  /**
5837
6110
  * Collapses the per-generator mock outputs for "inline" writer modes
@@ -5856,8 +6129,8 @@ function hasAnyMockPath(mockConfig) {
5856
6129
  return mockConfig.generators.some((g) => !isFunction(g) && !!g.path);
5857
6130
  }
5858
6131
  function resolveMockSchemasPath(mockFilePath, schemasTarget) {
5859
- const ext = nodePath.extname(mockFilePath);
5860
- const targetExt = nodePath.extname(schemasTarget);
6132
+ const ext = path.extname(mockFilePath);
6133
+ const targetExt = path.extname(schemasTarget);
5861
6134
  return getRelativeImportPath(mockFilePath, targetExt === ".schemas" ? schemasTarget + ext : targetExt ? schemasTarget : schemasTarget + ext);
5862
6135
  }
5863
6136
  //#endregion
@@ -5901,7 +6174,8 @@ function generateTarget(builder, options) {
5901
6174
  formUrlEncoded: [],
5902
6175
  paramsSerializer: [],
5903
6176
  paramsFilter: [],
5904
- fetchReviver: []
6177
+ fetchReviver: [],
6178
+ sharedTypes: []
5905
6179
  };
5906
6180
  const operations = Object.values(builder.operations);
5907
6181
  for (const [index, operation] of operations.entries()) {
@@ -5948,7 +6222,7 @@ function generateTarget(builder, options) {
5948
6222
  verbOptions: builder.verbOptions,
5949
6223
  clientImplementation: target.implementation
5950
6224
  });
5951
- target.implementation = header.implementation + target.implementation;
6225
+ target.implementation = (header.sharedTypes && header.sharedTypes.length > 0 ? header.sharedTypes.map((t) => `${t.exported ? "export " : ""}${t.code}`).join("\n") + "\n\n" : "") + header.implementation + target.implementation;
5952
6226
  const footer = builder.footer({
5953
6227
  outputClient: options.client,
5954
6228
  operationNames,
@@ -6014,7 +6288,7 @@ interface TypedResponse<T> extends Response {
6014
6288
  }
6015
6289
  //#endregion
6016
6290
  //#region src/writers/single-mode.ts
6017
- async function writeSingleMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6291
+ async function writeSingleMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6018
6292
  try {
6019
6293
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6020
6294
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
@@ -6042,7 +6316,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6042
6316
  }
6043
6317
  }
6044
6318
  let data = header;
6045
- const importsForBuilder = schemasPath ? generateImportsForBuilder(output, normalizedImports, relativeSchemasPath) : generateImportsForBuilder(output, normalizedImports.filter((imp) => !!imp.importPath), ".");
6319
+ const importsForBuilder = schemasPath ? generateImportsForBuilder(output, normalizedImports, relativeSchemasPath, schemaTagMap) : generateImportsForBuilder(output, normalizedImports.filter((imp) => !!imp.importPath), ".");
6046
6320
  data += builder.imports({
6047
6321
  client: output.client,
6048
6322
  implementation,
@@ -6059,10 +6333,12 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6059
6333
  if (!shouldDeinlineMocks) for (const mockOutput of collapsedMockOutputs) {
6060
6334
  const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
6061
6335
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6062
- const filteredMockImports = filterLocalStrictMockTypeImports(mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), finalizeMockOptions.strictSchemaTypeNames);
6063
- const importsMockForBuilder = schemasPath ? generateImportsForBuilder(output, filteredMockImports, relativeSchemasPath) : generateImportsForBuilder(output, filteredMockImports.filter((imp) => !!imp.importPath), ".");
6336
+ const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6337
+ const recoveredSchemaFactoryImports = !!entry && !isFunction(entry) && entry.type === OutputMockType.FAKER && entry.schemas === true && output.schemas ? collectRecoveredSchemaFactoryImports(finalizedMockImplementation, builder.schemas.filter((s) => s.schema).map((s) => s.name)) : [];
6338
+ const filteredMockImports = filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports).filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), finalizeMockOptions.strictSchemaTypeNames);
6339
+ const importsMockForBuilder = schemasPath ? generateImportsForBuilder(output, filteredMockImports, relativeSchemasPath, schemaTagMap) : generateImportsForBuilder(output, filteredMockImports.filter((imp) => !!imp.importPath), ".");
6064
6340
  data += builder.importsMock({
6065
- implementation: mockOutput.implementation,
6341
+ implementation: finalizedMockImplementation,
6066
6342
  imports: importsMockForBuilder,
6067
6343
  projectName,
6068
6344
  hasSchemaDir: !!output.schemas,
@@ -6111,11 +6387,13 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6111
6387
  if (!rawEntry) continue;
6112
6388
  const mockExtension = isFunction(rawEntry) ? OutputMockType.MSW : getMockFileExtensionByTypeName(rawEntry);
6113
6389
  const mockDir = getMockDir(rawEntry, output.mock) ?? dirname;
6114
- const mockFilePath = nodePath.join(mockDir, filename + "." + mockExtension + extension);
6390
+ const mockFilePath = path.join(mockDir, filename + "." + mockExtension + extension);
6115
6391
  const mockRelativeSchemasPath = schemaCustomImportPath ?? resolveMockSchemasPath(mockFilePath, schemasTarget);
6116
- const importsMockForBuilder = schemasPath || mockDir !== dirname ? generateImportsForBuilder(output, mockOutput.imports, mockRelativeSchemasPath) : generateImportsForBuilder(output, mockOutput.imports.filter((imp) => !!imp.importPath), ".");
6392
+ const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6393
+ const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6394
+ const recoveredSchemaFactoryImports = !isFunction(rawEntry) && rawEntry.type === OutputMockType.FAKER && rawEntry.schemas === true && output.schemas ? collectRecoveredSchemaFactoryImports(finalizedMockImplementation, builder.schemas.filter((s) => s.schema).map((s) => s.name)) : [];
6395
+ const importsMockForBuilder = schemasPath || mockDir !== dirname ? generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap) : generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames).filter((imp) => !!imp.importPath), ".");
6117
6396
  let mockData = header;
6118
- const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, getFinalizeMockImplementationOptions(output, mockOutput)) : mockOutput.implementation;
6119
6397
  mockData += builder.importsMock({
6120
6398
  implementation: finalizedMockImplementation,
6121
6399
  imports: importsMockForBuilder,
@@ -6139,7 +6417,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6139
6417
  if (output.mock.indexMockFiles) {
6140
6418
  const importExtension = getImportExtension(output.fileExtension, output.tsconfig);
6141
6419
  for (const { extension: mockExt, mockDir } of writtenMockEntries) {
6142
- const indexMockPath = nodePath.join(mockDir, `index.${mockExt}${extension}`);
6420
+ const indexMockPath = path.join(mockDir, `index.${mockExt}${extension}`);
6143
6421
  await writeGeneratedFile(indexMockPath, `export * from './${filename}.${mockExt}${importExtension}'\n`);
6144
6422
  extraPaths.push(indexMockPath);
6145
6423
  }
@@ -6152,80 +6430,8 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6152
6430
  }
6153
6431
  }
6154
6432
  //#endregion
6155
- //#region src/writers/mock-imports.ts
6156
- /** Maps `components/schemas` names to consolidated index.faker import symbols. */
6157
- function buildKnownSchemaFactoryImportSets(schemaNames) {
6158
- const factoryNames = /* @__PURE__ */ new Set();
6159
- const typeNames = /* @__PURE__ */ new Set();
6160
- for (const name of schemaNames) {
6161
- const typeName = pascal(name);
6162
- factoryNames.add(`get${typeName}Mock`);
6163
- typeNames.add(`${typeName}Mock`);
6164
- }
6165
- return {
6166
- factoryNames,
6167
- typeNames
6168
- };
6169
- }
6170
- /**
6171
- * Recover schema-factory imports referenced in generated mock bodies but
6172
- * missing from the collected import list (e.g. after shared-array import
6173
- * aggregation on large specs). Scans for `get<Schema>Mock()` calls and
6174
- * `as <Schema>Mock` casts emitted by strict schema delegation (#3590).
6175
- *
6176
- * When `knownSets` is provided, only symbols that exist in the consolidated
6177
- * schemas faker file are recovered — this avoids importing one-off split
6178
- * response helper factories that live in the tag file itself.
6179
- */
6180
- function collectSchemaFactoryImportsFromImplementation(implementation, knownSets) {
6181
- const imports = [];
6182
- const seen = /* @__PURE__ */ new Set();
6183
- for (const match of implementation.matchAll(/\b(get[A-Za-z0-9]+Mock)\(\)/g)) {
6184
- const factoryName = match[1];
6185
- if (knownSets && !knownSets.factoryNames.has(factoryName)) continue;
6186
- const key = `value::${factoryName}`;
6187
- if (seen.has(key)) continue;
6188
- seen.add(key);
6189
- imports.push({
6190
- name: factoryName,
6191
- values: true,
6192
- schemaFactory: true
6193
- });
6194
- }
6195
- for (const match of implementation.matchAll(/\bas ([A-Za-z0-9]+Mock)\b/g)) {
6196
- const typeName = match[1];
6197
- if (knownSets && !knownSets.typeNames.has(typeName)) continue;
6198
- const key = `type::${typeName}`;
6199
- if (seen.has(key)) continue;
6200
- seen.add(key);
6201
- imports.push({
6202
- name: typeName,
6203
- values: false,
6204
- schemaFactory: true
6205
- });
6206
- }
6207
- return imports;
6208
- }
6209
- function mergeGeneratorImports(...groups) {
6210
- const merged = /* @__PURE__ */ new Map();
6211
- for (const group of groups) for (const imp of group) {
6212
- const key = `${imp.name}::${imp.alias ?? ""}`;
6213
- const existing = merged.get(key);
6214
- if (!existing) {
6215
- merged.set(key, imp);
6216
- continue;
6217
- }
6218
- if (!existing.values && imp.values) merged.set(key, imp);
6219
- }
6220
- return [...merged.values()];
6221
- }
6222
- /** Recover missing index.faker imports when `schemas: true` is enabled. */
6223
- function collectRecoveredSchemaFactoryImports(implementation, componentSchemaNames) {
6224
- return collectSchemaFactoryImportsFromImplementation(implementation, buildKnownSchemaFactoryImportSets(componentSchemaNames));
6225
- }
6226
- //#endregion
6227
6433
  //#region src/writers/split-mode.ts
6228
- async function writeSplitMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6434
+ async function writeSplitMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6229
6435
  try {
6230
6436
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6231
6437
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
@@ -6234,10 +6440,10 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6234
6440
  const { imports, implementation, mockOutputs, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
6235
6441
  let implementationData = header;
6236
6442
  const schemaCustomImportPath = getSchemasImportPath(output.schemas);
6237
- const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6238
- const schemasTarget = output.schemas ? getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname : nodePath.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6443
+ const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(targetPath, isString(output.schemas) ? output.schemas : output.schemas.path, true) : "./" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6444
+ const schemasTarget = output.schemas ? isString(output.schemas) ? output.schemas : output.schemas.path : path.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6239
6445
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
6240
- const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
6446
+ const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath, schemaTagMap);
6241
6447
  implementationData += builder.imports({
6242
6448
  client: output.client,
6243
6449
  implementation,
@@ -6251,7 +6457,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6251
6457
  packageJson: output.packageJson,
6252
6458
  output
6253
6459
  });
6254
- const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
6460
+ const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
6255
6461
  if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
6256
6462
  if (mutators) implementationData += generateMutatorImports({
6257
6463
  mutators,
@@ -6273,7 +6479,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6273
6479
  }
6274
6480
  implementationData += `\n${implementation}`;
6275
6481
  const implementationFilename = filename + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
6276
- const implementationPath = nodePath.join(dirname, implementationFilename);
6482
+ const implementationPath = path.join(dirname, implementationFilename);
6277
6483
  await writeGeneratedFile(implementationPath, implementationData);
6278
6484
  const mockPaths = [];
6279
6485
  const seenMockIndexKeys = /* @__PURE__ */ new Set();
@@ -6286,12 +6492,12 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6286
6492
  if (!rawEntry) continue;
6287
6493
  const mockExtension = isFunction(rawEntry) ? OutputMockType.MSW : getMockFileExtensionByTypeName(rawEntry);
6288
6494
  const mockDir = getMockDir(rawEntry, output.mock) ?? dirname;
6289
- const mockFilePath = nodePath.join(mockDir, filename + "." + mockExtension + extension);
6495
+ const mockFilePath = path.join(mockDir, filename + "." + mockExtension + extension);
6290
6496
  const mockRelativeSchemasPath = schemaCustomImportPath ?? resolveMockSchemasPath(mockFilePath, schemasTarget);
6291
6497
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6292
6498
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6293
6499
  const recoveredSchemaFactoryImports = !isFunction(rawEntry) && rawEntry.type === OutputMockType.FAKER && rawEntry.schemas === true && output.schemas ? collectRecoveredSchemaFactoryImports(finalizedMockImplementation, builder.schemas.filter((s) => s.schema).map((s) => s.name)) : [];
6294
- const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath);
6500
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6295
6501
  let mockData = header;
6296
6502
  mockData += builder.importsMock({
6297
6503
  implementation: finalizedMockImplementation,
@@ -6317,7 +6523,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6317
6523
  if (output.mock.indexMockFiles) {
6318
6524
  const importExtension = getImportExtension(output.fileExtension, output.tsconfig);
6319
6525
  for (const { extension: mockExt, mockDir } of writtenMockEntries) {
6320
- const indexMockPath = nodePath.join(mockDir, `index.${mockExt}${extension}`);
6526
+ const indexMockPath = path.join(mockDir, `index.${mockExt}${extension}`);
6321
6527
  await writeGeneratedFile(indexMockPath, `export * from './${filename}.${mockExt}${importExtension}'\n`);
6322
6528
  indexMockPaths.push(indexMockPath);
6323
6529
  }
@@ -6409,7 +6615,7 @@ function initialMockOutputsForOperation(op) {
6409
6615
  }));
6410
6616
  }
6411
6617
  function generateTargetTags(currentAcc, operation) {
6412
- const tag = kebab(operation.tags[0]);
6618
+ const tag = getOperationTagKey(operation);
6413
6619
  if (!(tag in currentAcc)) {
6414
6620
  currentAcc[tag] = {
6415
6621
  imports: operation.imports,
@@ -6450,7 +6656,7 @@ function generateTargetForTags(builder, options) {
6450
6656
  const transformed = {};
6451
6657
  for (const [tag, target] of Object.entries(allTargetTags)) {
6452
6658
  const isMutator = !!target.mutators?.some((mutator) => isAngularClient ? mutator.hasThirdArg : mutator.hasSecondArg);
6453
- const operationNames = Object.values(builder.operations).filter(({ tags }) => tags.map((tag) => kebab(tag)).indexOf(kebab(tag)) === 0).map(({ operationName }) => operationName);
6659
+ const operationNames = operations.filter((operation) => isOperationInTagBucket(operation, tag)).map(({ operationName }) => operationName);
6454
6660
  const hasAwaitedType = compareVersions(options.packageJson?.dependencies?.typescript ?? options.packageJson?.devDependencies?.typescript ?? "4.4.0", "4.5.0");
6455
6661
  const titles = builder.title({
6456
6662
  outputClient: options.client,
@@ -6480,6 +6686,9 @@ function generateTargetForTags(builder, options) {
6480
6686
  isDefaultTagBucket: tag === "default" && Object.values(builder.operations).some((operation) => operation.tags.length === 0),
6481
6687
  clientImplementation: target.implementation
6482
6688
  });
6689
+ const sharedTypes = header.sharedTypes;
6690
+ const deduplicationActive = options.tagsSplitDeduplication && !options.workspace;
6691
+ const inlinedSharedTypes = !deduplicationActive && sharedTypes && sharedTypes.length > 0 ? sharedTypes.map((t) => `${t.exported ? "export " : ""}${t.code}`).join("\n") + "\n\n" : "";
6483
6692
  const wrappedMockOutputs = target.mockOutputs.map((m) => ({
6484
6693
  type: m.type,
6485
6694
  implementation: {
@@ -6492,7 +6701,7 @@ function generateTargetForTags(builder, options) {
6492
6701
  strictMockSchemaKinds: m.strictMockSchemaKinds
6493
6702
  }));
6494
6703
  transformed[tag] = {
6495
- implementation: header.implementation + target.implementation + footer.implementation,
6704
+ implementation: inlinedSharedTypes + header.implementation + target.implementation + footer.implementation,
6496
6705
  mockOutputs: wrappedMockOutputs,
6497
6706
  imports: target.imports,
6498
6707
  mutators: target.mutators,
@@ -6501,7 +6710,8 @@ function generateTargetForTags(builder, options) {
6501
6710
  formUrlEncoded: target.formUrlEncoded,
6502
6711
  paramsSerializer: target.paramsSerializer,
6503
6712
  paramsFilter: target.paramsFilter,
6504
- fetchReviver: target.fetchReviver
6713
+ fetchReviver: target.fetchReviver,
6714
+ sharedTypes: deduplicationActive ? sharedTypes : void 0
6505
6715
  };
6506
6716
  }
6507
6717
  allTargetTags = transformed;
@@ -6516,7 +6726,7 @@ function generateTargetForTags(builder, options) {
6516
6726
  }
6517
6727
  //#endregion
6518
6728
  //#region src/writers/split-tags-mode.ts
6519
- async function writeSplitTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6729
+ async function writeSplitTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6520
6730
  const { filename, dirname, extension } = getFileInfo(output.target, {
6521
6731
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
6522
6732
  extension: output.fileExtension
@@ -6525,33 +6735,51 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6525
6735
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
6526
6736
  const mockIndexEntries = [];
6527
6737
  const seenMockIndexKeys = /* @__PURE__ */ new Set();
6528
- const schemasTarget = output.schemas ? getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname : nodePath.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6738
+ const schemasTarget = output.schemas ? isString(output.schemas) ? output.schemas : output.schemas.path : path.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6529
6739
  const tagEntries = Object.entries(target).toSorted(([a], [b]) => a.localeCompare(b));
6740
+ const deduplicationEnabled = output.tagsSplitDeduplication && !output.workspace;
6741
+ const collectedSharedTypes = [];
6742
+ const seenSharedTypeNames = /* @__PURE__ */ new Set();
6743
+ for (const [, target] of tagEntries) {
6744
+ if (!target.sharedTypes) continue;
6745
+ for (const t of target.sharedTypes) if (!seenSharedTypeNames.has(t.name)) {
6746
+ seenSharedTypeNames.add(t.name);
6747
+ collectedSharedTypes.push(t);
6748
+ }
6749
+ }
6750
+ const commonTypesImportExtension = getImportExtension(extension, output.tsconfig);
6751
+ const commonTypesBasename = output.commonTypesFileName;
6752
+ const commonTypesPath = path.join(dirname, commonTypesBasename + extension);
6753
+ const commonTypesRelativeImport = "../" + commonTypesBasename + (deduplicationEnabled ? commonTypesImportExtension : "");
6530
6754
  const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
6531
6755
  try {
6532
6756
  const { imports, implementation, mockOutputs, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer, paramsFilter } = target;
6533
6757
  let implementationData = header;
6534
- const importerPath = nodePath.join(dirname, tag, tag + extension);
6758
+ if (deduplicationEnabled && target.sharedTypes && target.sharedTypes.length > 0) {
6759
+ const typeNames = target.sharedTypes.map((t) => t.name).join(", ");
6760
+ implementationData += `import type { ${typeNames} } from '${commonTypesRelativeImport}';\n`;
6761
+ }
6762
+ const importerPath = path.join(dirname, tag, tag + extension);
6535
6763
  const schemaCustomImportPath = getSchemasImportPath(output.schemas);
6536
- const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(importerPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6764
+ const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(importerPath, isString(output.schemas) ? output.schemas : output.schemas.path, true) : "../" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6537
6765
  const tagNames = new Set(tagEntries.map(([t]) => t));
6538
6766
  const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
6539
6767
  const importsForBuilder = generateImportsForBuilder(output, imports.map((imp) => {
6540
6768
  if (!imp.importPath) return imp;
6541
6769
  if (!imp.importPath.startsWith(".")) return imp;
6542
- const resolvedPath = nodePath.resolve(dirname, imp.importPath);
6543
- const targetBasename = nodePath.basename(resolvedPath);
6770
+ const resolvedPath = path.resolve(dirname, imp.importPath);
6771
+ const targetBasename = path.basename(resolvedPath);
6544
6772
  let targetFile;
6545
6773
  if (tagNames.has(targetBasename)) {
6546
6774
  const tagFilename = targetBasename + serviceSuffix + extension;
6547
- targetFile = nodePath.join(resolvedPath, tagFilename);
6775
+ targetFile = path.join(resolvedPath, tagFilename);
6548
6776
  } else targetFile = resolvedPath + extension;
6549
6777
  const adjustedPath = getRelativeImportPath(importerPath, targetFile);
6550
6778
  return {
6551
6779
  ...imp,
6552
6780
  importPath: adjustedPath
6553
6781
  };
6554
- }), relativeSchemasPath);
6782
+ }), relativeSchemasPath, schemaTagMap);
6555
6783
  implementationData += builder.imports({
6556
6784
  client: output.client,
6557
6785
  implementation,
@@ -6565,7 +6793,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6565
6793
  packageJson: output.packageJson,
6566
6794
  output
6567
6795
  });
6568
- const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
6796
+ const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
6569
6797
  if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
6570
6798
  if (mutators) implementationData += generateMutatorImports({
6571
6799
  mutators,
@@ -6606,7 +6834,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6606
6834
  }
6607
6835
  implementationData += `\n${implementation}`;
6608
6836
  const implementationFilename = tag + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
6609
- const implementationPath = nodePath.join(dirname, tag, implementationFilename);
6837
+ const implementationPath = path.join(dirname, tag, implementationFilename);
6610
6838
  await writeGeneratedFile(implementationPath, implementationData);
6611
6839
  const mockPaths = [];
6612
6840
  for (const mockOutput of mockOutputs) {
@@ -6617,12 +6845,12 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6617
6845
  if (!rawEntry) continue;
6618
6846
  const mockExtension = isFunction(rawEntry) ? OutputMockType.MSW : getMockFileExtensionByTypeName(rawEntry);
6619
6847
  const mockDir = getMockDir(rawEntry, output.mock) ?? dirname;
6620
- const mockFilePath = nodePath.join(mockDir, tag, tag + "." + mockExtension + extension);
6848
+ const mockFilePath = path.join(mockDir, tag, tag + "." + mockExtension + extension);
6621
6849
  const mockRelativeSchemasPath = schemaCustomImportPath ?? resolveMockSchemasPath(mockFilePath, schemasTarget);
6622
6850
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6623
6851
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6624
6852
  const recoveredSchemaFactoryImports = !isFunction(rawEntry) && rawEntry.type === OutputMockType.FAKER && rawEntry.schemas === true && output.schemas ? collectRecoveredSchemaFactoryImports(finalizedMockImplementation, builder.schemas.filter((s) => s.schema).map((s) => s.name)) : [];
6625
- const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath);
6853
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6626
6854
  let mockData = header;
6627
6855
  mockData += builder.importsMock({
6628
6856
  implementation: finalizedMockImplementation,
@@ -6659,16 +6887,38 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6659
6887
  }));
6660
6888
  if (output.mock.indexMockFiles) {
6661
6889
  const mockImportExtension = getImportExtension(extension, output.tsconfig);
6662
- for (const { ext, mockDir, tags } of mockIndexEntries) await writeGeneratedFile(nodePath.join(mockDir, `index.${ext}${extension}`), tags.toSorted((a, b) => a.localeCompare(b)).map((tag) => {
6890
+ for (const { ext, mockDir, tags } of mockIndexEntries) await writeGeneratedFile(path.join(mockDir, `index.${ext}${extension}`), tags.toSorted((a, b) => a.localeCompare(b)).map((tag) => {
6663
6891
  const localMockPath = joinSafe("./", tag, tag + "." + ext + mockImportExtension);
6664
6892
  return ext === OutputMockType.MSW ? `export { get${pascal(tag)}Mock } from '${localMockPath}'\n` : `export * from '${localMockPath}'\n`;
6665
6893
  }).join(""));
6666
6894
  }
6667
- return [...new Set([...output.mock.indexMockFiles ? mockIndexEntries.map(({ mockDir, ext }) => nodePath.join(mockDir, `index.${ext}${extension}`)) : [], ...generatedFilePathsArray.flat()])];
6895
+ let commonTypesFilePath;
6896
+ if (deduplicationEnabled && collectedSharedTypes.length > 0) {
6897
+ const commonTypesContent = collectedSharedTypes.map((t) => `export ${t.code}`).join("\n") + "\n";
6898
+ commonTypesFilePath = commonTypesPath;
6899
+ await writeGeneratedFile(commonTypesPath, commonTypesContent);
6900
+ }
6901
+ let indexFilePath;
6902
+ if (output.indexFiles && deduplicationEnabled && tagEntries.length > 0) {
6903
+ const importExtension = getImportExtension(output.fileExtension, output.tsconfig);
6904
+ const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
6905
+ const publicSharedTypeNames = collectedSharedTypes.filter((t) => t.exported).map((t) => t.name);
6906
+ const indexContent = (publicSharedTypeNames.length > 0 ? `export type { ${publicSharedTypeNames.join(", ")} } from './${commonTypesBasename}${importExtension}';\n` : "") + tagEntries.map(([tag]) => {
6907
+ return `export * from '${joinSafe("./", tag, tag + serviceSuffix + importExtension)}';\n`;
6908
+ }).join("");
6909
+ indexFilePath = path.join(dirname, `index${extension}`);
6910
+ await writeGeneratedFile(indexFilePath, indexContent);
6911
+ }
6912
+ return [...new Set([
6913
+ ...output.mock.indexMockFiles ? mockIndexEntries.map(({ mockDir, ext }) => path.join(mockDir, `index.${ext}${extension}`)) : [],
6914
+ ...commonTypesFilePath ? [commonTypesFilePath] : [],
6915
+ ...indexFilePath ? [indexFilePath] : [],
6916
+ ...generatedFilePathsArray.flat()
6917
+ ])];
6668
6918
  }
6669
6919
  //#endregion
6670
6920
  //#region src/writers/tags-mode.ts
6671
- async function writeTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6921
+ async function writeTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6672
6922
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6673
6923
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
6674
6924
  extension: output.fileExtension
@@ -6680,7 +6930,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6680
6930
  const seenMockIndexKeys = /* @__PURE__ */ new Set();
6681
6931
  const schemaCustomImportPath = getSchemasImportPath(output.schemas);
6682
6932
  const schemasPathRelative = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6683
- const schemasTarget = output.schemas ? getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname : nodePath.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6933
+ const schemasTarget = output.schemas ? getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname : path.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6684
6934
  const tagEntries = Object.entries(target).toSorted(([a], [b]) => a.localeCompare(b));
6685
6935
  const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
6686
6936
  try {
@@ -6700,7 +6950,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6700
6950
  if (!!mockImport.values || !!mockImport.isConstant || !!mockImport.default || !!mockImport.namespaceImport || !!mockImport.syntheticDefaultImport) matchingImport.values = true;
6701
6951
  }
6702
6952
  }
6703
- const importsForBuilder = generateImportsForBuilder(output, normalizedImports, schemasPathRelative);
6953
+ const importsForBuilder = generateImportsForBuilder(output, normalizedImports, schemasPathRelative, schemaTagMap);
6704
6954
  data += builder.imports({
6705
6955
  client: output.client,
6706
6956
  implementation,
@@ -6716,7 +6966,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6716
6966
  });
6717
6967
  if (!shouldDeinlineMocks) for (const mockOutput of collapsedMockOutputs) {
6718
6968
  const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
6719
- const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), schemasPathRelative);
6969
+ const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), schemasPathRelative, schemaTagMap);
6720
6970
  data += builder.importsMock({
6721
6971
  implementation: mockOutput.implementation,
6722
6972
  imports: importsMockForBuilder,
@@ -6726,7 +6976,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6726
6976
  options: entry && !isFunction(entry) ? entry : void 0
6727
6977
  });
6728
6978
  }
6729
- const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
6979
+ const schemasPath = !output.schemas && needSchema ? path.join(dirname, filename + ".schemas" + extension) : void 0;
6730
6980
  if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
6731
6981
  if (mutators) data += generateMutatorImports({
6732
6982
  mutators,
@@ -6757,7 +7007,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6757
7007
  }
6758
7008
  }
6759
7009
  const kebabTag = kebab(tag);
6760
- const implementationPath = nodePath.join(dirname, `${kebabTag}${extension}`);
7010
+ const implementationPath = path.join(dirname, `${kebabTag}${extension}`);
6761
7011
  await writeGeneratedFile(implementationPath, data);
6762
7012
  const extraPaths = [];
6763
7013
  if (shouldDeinlineMocks) for (const mockOutput of rawMockOutputs) {
@@ -6768,12 +7018,12 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6768
7018
  if (!rawEntry) continue;
6769
7019
  const mockExtension = isFunction(rawEntry) ? OutputMockType.MSW : getMockFileExtensionByTypeName(rawEntry);
6770
7020
  const mockDir = getMockDir(rawEntry, output.mock) ?? dirname;
6771
- const mockFilePath = nodePath.join(mockDir, kebabTag, kebabTag + "." + mockExtension + extension);
7021
+ const mockFilePath = path.join(mockDir, kebabTag, kebabTag + "." + mockExtension + extension);
6772
7022
  const mockRelativeSchemasPath = schemaCustomImportPath ?? resolveMockSchemasPath(mockFilePath, schemasTarget);
6773
7023
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6774
7024
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6775
7025
  const recoveredSchemaFactoryImports = !isFunction(rawEntry) && rawEntry.type === OutputMockType.FAKER && rawEntry.schemas === true && output.schemas ? collectRecoveredSchemaFactoryImports(finalizedMockImplementation, builder.schemas.filter((s) => s.schema).map((s) => s.name)) : [];
6776
- const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath);
7026
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6777
7027
  let mockData = header;
6778
7028
  mockData += builder.importsMock({
6779
7029
  implementation: finalizedMockImplementation,
@@ -6811,7 +7061,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6811
7061
  if (shouldDeinlineMocks && output.mock.indexMockFiles) {
6812
7062
  const mockImportExtension = getImportExtension(extension, output.tsconfig);
6813
7063
  for (const { ext, mockDir, tags } of mockIndexEntries) {
6814
- const indexPath = nodePath.join(mockDir, `index.${ext}${extension}`);
7064
+ const indexPath = path.join(mockDir, `index.${ext}${extension}`);
6815
7065
  await writeGeneratedFile(indexPath, tags.toSorted((a, b) => a.localeCompare(b)).map((kebabTag) => {
6816
7066
  const localMockPath = joinSafe("./", kebabTag, kebabTag + "." + ext + mockImportExtension);
6817
7067
  return ext === OutputMockType.MSW ? `export { get${pascal(kebabTag)}Mock } from '${localMockPath}'\n` : `export * from '${localMockPath}'\n`;
@@ -6822,6 +7072,6 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6822
7072
  return generatedFilePathsArray.flat();
6823
7073
  }
6824
7074
  //#endregion
6825
- 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, buildDynamicScope, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicAnchorToParamName, dynamicAnchorsToUniqueParamNames, dynamicImport, escape, escapeRegExp, extractBoundAliasInfo, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFactory, 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, getDynamicAnchorName, 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, getSchemasImportPath, getSuccessResponseType, getTypedResponse, getWarningCount, isBinaryContentType, isBinaryScalarSchema, isBoolean, isComponentRef, isDirectory, isDynamicReference, isFakerMock, isFunction, isModule, isMswMock, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, jsStringLiteralEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, makeRouteSafe, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveDynamicRef, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, wrapRouteParameters, writeGeneratedFile, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
7075
+ export { BODY_TYPE_NAME, DefaultTag, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NAMED_COMPONENT_SECTIONS, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SHARED_DIR, SchemaType, SupportedFormatter, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, addDependency, asyncReduce, buildAngularParamsFilterExpression, buildDynamicScope, buildInlineDynamicScope, buildSchemaTagMap, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicAnchorToParamName, dynamicAnchorsToUniqueParamNames, dynamicImport, escape, escapeRegExp, extractBoundAliasInfo, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFactory, 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, getDynamicAnchorName, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getImportExtension, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOperationTagKey, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSchemasImportPath, getSuccessResponseType, getTagKey, getTypedResponse, getWarningCount, isBinaryContentType, isBinaryScalarSchema, isBoolean, isComponentRef, isDirectory, isDynamicReference, isFakerMock, isFunction, isModule, isMswMock, isNullish, isNumber, isNumeric, isObject, isOperationInTagBucket, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, jsStringLiteralEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, makeRouteSafe, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveDynamicRef, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, wrapRouteParameters, writeGeneratedFile, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSchemasTagsSplit, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
6826
7076
 
6827
7077
  //# sourceMappingURL=index.mjs.map