@orval/core 8.18.0 → 8.20.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
@@ -74,12 +74,13 @@ const FormDataArrayHandling = {
74
74
  SERIALIZE_WITH_BRACKETS: "serialize-with-brackets"
75
75
  };
76
76
  const Verbs = {
77
- POST: "post",
78
- PUT: "put",
79
77
  GET: "get",
80
- PATCH: "patch",
78
+ PUT: "put",
79
+ POST: "post",
81
80
  DELETE: "delete",
82
- HEAD: "head"
81
+ OPTIONS: "options",
82
+ HEAD: "head",
83
+ PATCH: "patch"
83
84
  };
84
85
  /**
85
86
  * Canonical tag name used for the generated bucket that collects untagged operations.
@@ -369,10 +370,17 @@ function conventionName(name, convention) {
369
370
  }
370
371
  //#endregion
371
372
  //#region src/utils/compare-version.ts
373
+ const getComparableVersion = (version) => {
374
+ const npmAliasVersion = version.match(/^npm:(?:@[^/]+\/)?[^@]+@(.+)$/)?.[1];
375
+ if (npmAliasVersion) return npmAliasVersion;
376
+ if (version.startsWith("npm:")) return "latest";
377
+ return version;
378
+ };
372
379
  function compareVersions(firstVersion, secondVersions, operator = ">=") {
373
- if (firstVersion === "latest" || firstVersion === "*") return true;
374
- if (firstVersion.startsWith("catalog:")) return true;
375
- return compare(firstVersion.replace(/(\s(.*))/, ""), secondVersions, operator);
380
+ const comparableVersion = getComparableVersion(firstVersion);
381
+ if (comparableVersion === "latest" || comparableVersion === "*") return true;
382
+ if (comparableVersion.startsWith("catalog:")) return true;
383
+ return compare(comparableVersion.replace(/(\s(.*))/, ""), secondVersions, operator);
376
384
  }
377
385
  //#endregion
378
386
  //#region src/utils/content-type.ts
@@ -1159,6 +1167,55 @@ function dedupeUnionType(unionType) {
1159
1167
  return [...new Set(parts)].join(" | ");
1160
1168
  }
1161
1169
  //#endregion
1170
+ //#region src/utils/tags.ts
1171
+ /**
1172
+ * Canonical bucket key for a single OpenAPI tag.
1173
+ *
1174
+ * In `tags` / `tags-split` mode operations are routed into files by their first
1175
+ * tag. This function is the **single source of truth** for turning a tag (or a
1176
+ * missing tag) into the key that identifies that file bucket. Every place that
1177
+ * groups operations by tag, derives a per-tag file/directory name, or checks
1178
+ * whether an operation belongs to a tag MUST go through here so that the
1179
+ * "build the key" side and the "look the key up" side can never disagree.
1180
+ *
1181
+ * The result is `kebab`-cased. `kebab` is idempotent
1182
+ * (`kebab(kebab(x)) === kebab(x)`), so it is always safe to call this on a value
1183
+ * that is already a canonical key. Other case functions (`camel`, `pascal`) are
1184
+ * NOT safe here: they do not round-trip through the bucket key for tags
1185
+ * containing acronyms or spaces (e.g. `"AB Widget"`), which is exactly the class
1186
+ * of bug this module exists to prevent.
1187
+ *
1188
+ * Missing or empty tags map to the implicit {@link DefaultTag} bucket.
1189
+ */
1190
+ function getTagKey(tag) {
1191
+ const normalizedTag = tag?.trim();
1192
+ return kebab(normalizedTag ? normalizedTag : DefaultTag);
1193
+ }
1194
+ /**
1195
+ * Canonical bucket key for an operation, derived from its primary (first) tag.
1196
+ *
1197
+ * Untagged operations resolve to the {@link DefaultTag} bucket.
1198
+ */
1199
+ function getOperationTagKey(operation) {
1200
+ return getTagKey(operation.tags[0]);
1201
+ }
1202
+ /**
1203
+ * Whether an operation belongs to the given tag bucket.
1204
+ *
1205
+ * Both sides are normalised through {@link getTagKey}, so the comparison is
1206
+ * correct regardless of how `tagKey` was spelled or cased by the caller. An
1207
+ * absent (`undefined`) `tagKey` matches every operation (the "no tag filter"
1208
+ * case); an empty/whitespace `tagKey` is normalised to the {@link DefaultTag}
1209
+ * bucket like any other tag.
1210
+ *
1211
+ * Prefer this over hand-rolling `operation.tags[0] === tagKey`: a raw tag
1212
+ * compared against a canonical key silently fails for multi-word/acronym tags.
1213
+ */
1214
+ function isOperationInTagBucket(operation, tagKey) {
1215
+ if (tagKey == null) return true;
1216
+ return getOperationTagKey(operation) === getTagKey(tagKey);
1217
+ }
1218
+ //#endregion
1162
1219
  //#region src/utils/tsconfig.ts
1163
1220
  function isSyntheticDefaultImportsAllow(config) {
1164
1221
  if (!config) return true;
@@ -1586,7 +1643,7 @@ function combineSchemas({ name, schema, separator, context, nullable, formDataCo
1586
1643
  hasReadonlyProps: false,
1587
1644
  example: schema.example,
1588
1645
  examples: resolveExampleRefs(schema.examples, context),
1589
- requiredProperties: separator === "allOf" ? schema.required ?? [] : []
1646
+ requiredProperties: separator === "allOf" ? [...normalizedSchema.required ?? []] : []
1590
1647
  };
1591
1648
  for (const subSchema of items) {
1592
1649
  let propName;
@@ -1594,7 +1651,6 @@ function combineSchemas({ name, schema, separator, context, nullable, formDataCo
1594
1651
  propName = name ? name + pascal(separator) : void 0;
1595
1652
  if (propName && resolvedData.schemas.length > 0) propName = propName + pascal(getNumberWord(resolvedData.schemas.length + 1));
1596
1653
  }
1597
- if (separator === "allOf" && isSchema(subSchema) && subSchema.required) resolvedData.requiredProperties.push(...subSchema.required);
1598
1654
  const resolvedValue = resolveObject({
1599
1655
  schema: subSchema,
1600
1656
  propName,
@@ -1602,6 +1658,10 @@ function combineSchemas({ name, schema, separator, context, nullable, formDataCo
1602
1658
  context,
1603
1659
  formDataContext
1604
1660
  });
1661
+ if (separator === "allOf") {
1662
+ const memberRequired = resolvedValue.originalSchema?.required;
1663
+ if (Array.isArray(memberRequired)) resolvedData.requiredProperties.push(...memberRequired);
1664
+ }
1605
1665
  const aliasedImports = getAliasedImports({
1606
1666
  context,
1607
1667
  name,
@@ -2486,27 +2546,105 @@ function buildDynamicScope(schemaName, schema, context) {
2486
2546
  return scope;
2487
2547
  }
2488
2548
  /**
2549
+ * Build dynamic scope entries for an **anonymous inline** subschema that declares
2550
+ * `$dynamicAnchor` without a `$ref` (e.g. inside `allOf`, `items`, nested props).
2551
+ *
2552
+ * Unlike {@link buildDynamicScope}, entries carry the concrete `inlineSchema` so
2553
+ * that a descendant `$dynamicRef` resolves to the inline override rather than the
2554
+ * outer/global component. Used when `dereference` enters a subschema without a
2555
+ * named component `$ref`.
2556
+ *
2557
+ * Scope of handling (deliberate, see #3492):
2558
+ * - Direct `$dynamicAnchor` on the subschema → inline entry.
2559
+ * - `$defs` `$dynamicAnchor` *without* a `$ref` → inline entry. Note this
2560
+ * differs from `buildDynamicScope`, which treats unbound `$defs` anchors as
2561
+ * generic parameters (`isParameter`); inline subschemas are concrete
2562
+ * instances, so the anchor resolves to the inline schema object itself.
2563
+ * - `$defs` `$dynamicAnchor` *with* a `$ref` → intentionally NOT collected
2564
+ * here. Such anchors rely on `resolveDynamicRef`'s global fallback (which
2565
+ * finds them when the `$ref` target declares the same anchor). Fully
2566
+ * resolving them would duplicate `buildDynamicScope`'s `$defs` logic.
2567
+ */
2568
+ function buildInlineDynamicScope(schema) {
2569
+ const scope = {};
2570
+ const schemaRecord = schema;
2571
+ if (typeof schemaRecord.$dynamicAnchor === "string") {
2572
+ const anchor = schemaRecord.$dynamicAnchor;
2573
+ scope[anchor] = {
2574
+ name: anchor,
2575
+ schemaName: anchor,
2576
+ inlineSchema: schema
2577
+ };
2578
+ }
2579
+ const defs = schemaRecord.$defs;
2580
+ if (defs && typeof defs === "object") for (const defSchema of Object.values(defs)) {
2581
+ if (!defSchema || typeof defSchema !== "object") continue;
2582
+ const defRecord = defSchema;
2583
+ if (typeof defRecord.$dynamicAnchor === "string" && !defSchema.$ref) {
2584
+ const anchor = defRecord.$dynamicAnchor;
2585
+ scope[anchor] = {
2586
+ name: anchor,
2587
+ schemaName: anchor,
2588
+ inlineSchema: defSchema
2589
+ };
2590
+ }
2591
+ }
2592
+ return scope;
2593
+ }
2594
+ /**
2595
+ * Lazily build and memoize the `$dynamicAnchor` index on the context.
2596
+ *
2597
+ * Scans `components.schemas` once per spec and stores, per anchor name, the
2598
+ * compact match info required by the {@link resolveDynamicRef} fallback (see
2599
+ * {@link DynamicAnchorIndexEntry}). Subsequent fallback lookups are O(1)
2600
+ * instead of re-scanning every schema per `$dynamicRef`.
2601
+ *
2602
+ * Recording of non-exact matches stops once `count >= 2` — the fallback only
2603
+ * distinguishes "exactly one non-exact" from "ambiguous", so further non-exact
2604
+ * names are irrelevant. Iteration continues regardless because a later schema
2605
+ * whose key equals the anchor name is still the definitive (`exactName`)
2606
+ * winner. This is the safe form of "bail early when ambiguous": a literal
2607
+ * early-return at `count === 2` would regress the exact-name rule when the
2608
+ * exact schema appears later in iteration order.
2609
+ */
2610
+ function getDynamicAnchorIndex(context) {
2611
+ const cached = context.dynamicAnchorIndex;
2612
+ if (cached) return cached;
2613
+ const index = /* @__PURE__ */ new Map();
2614
+ const schemas = context.spec.components?.schemas;
2615
+ if (schemas && typeof schemas === "object") for (const [schemaName, schemaObj] of Object.entries(schemas)) {
2616
+ if (!schemaObj || typeof schemaObj !== "object") continue;
2617
+ const anchor = schemaObj.$dynamicAnchor;
2618
+ if (typeof anchor !== "string") continue;
2619
+ let entry = index.get(anchor);
2620
+ if (!entry) {
2621
+ entry = { count: 0 };
2622
+ index.set(anchor, entry);
2623
+ }
2624
+ if (schemaName === anchor) entry.exactName = schemaName;
2625
+ else if (entry.count < 2) {
2626
+ entry.count += 1;
2627
+ if (!entry.firstName) entry.firstName = schemaName;
2628
+ }
2629
+ }
2630
+ context.dynamicAnchorIndex = index;
2631
+ return index;
2632
+ }
2633
+ /**
2489
2634
  * Resolve a `$dynamicRef` anchor to its concrete type using the current dynamic scope.
2490
2635
  * Returns `{ schema: {}, resolvedTypeName: 'unknown' }` when no scope override exists.
2491
2636
  */
2492
2637
  function resolveDynamicRef(anchorName, context, imports = []) {
2493
2638
  let scopeEntry = (context.dynamicScope ?? {})[anchorName];
2494
2639
  if (!scopeEntry) {
2495
- const schemas = context.spec.components?.schemas;
2496
- if (schemas && typeof schemas === "object") {
2497
- const matches = [];
2498
- for (const [schemaName, schemaObj] of Object.entries(schemas)) {
2499
- if (!schemaObj || typeof schemaObj !== "object") continue;
2500
- if (schemaObj.$dynamicAnchor === anchorName) matches.push(schemaName);
2501
- }
2502
- const match = matches.length === 1 ? matches[0] : matches.find((m) => m === anchorName);
2503
- if (match) {
2504
- const refInfo = getRefInfo(`#/components/schemas/${encodeJsonPointerSegment(match)}`, context);
2505
- scopeEntry = {
2506
- name: refInfo.name,
2507
- schemaName: refInfo.originalName
2508
- };
2509
- }
2640
+ const entry = getDynamicAnchorIndex(context).get(anchorName);
2641
+ const match = entry?.exactName ?? (entry?.count === 1 ? entry?.firstName : void 0);
2642
+ if (match) {
2643
+ const refInfo = getRefInfo(`#/components/schemas/${encodeJsonPointerSegment(match)}`, context);
2644
+ scopeEntry = {
2645
+ name: refInfo.name,
2646
+ schemaName: refInfo.originalName
2647
+ };
2510
2648
  }
2511
2649
  }
2512
2650
  if (!scopeEntry) return {
@@ -2521,6 +2659,12 @@ function resolveDynamicRef(anchorName, context, imports = []) {
2521
2659
  resolvedTypeName: scopeEntry.name,
2522
2660
  schemaName: void 0
2523
2661
  };
2662
+ if (scopeEntry.inlineSchema) return {
2663
+ schema: scopeEntry.inlineSchema,
2664
+ imports,
2665
+ resolvedTypeName: scopeEntry.name,
2666
+ schemaName: void 0
2667
+ };
2524
2668
  const resolvedTypeName = scopeEntry.name;
2525
2669
  const schemaRef = `#/components/schemas/${encodeJsonPointerSegment(scopeEntry.schemaName)}`;
2526
2670
  try {
@@ -2713,7 +2857,7 @@ function resolveValue({ schema, name, context, formDataContext }) {
2713
2857
  const refName = resolvedImport.name;
2714
2858
  let effectiveContext = context;
2715
2859
  const refAnchor = schemaObject.$dynamicAnchor;
2716
- if (typeof refAnchor === "string" && context.dynamicScope?.[refAnchor] && context.dynamicScope[refAnchor].name !== refName && !context.dynamicScope[refAnchor].isParameter) {
2860
+ if (typeof refAnchor === "string" && context.dynamicScope?.[refAnchor] && context.dynamicScope[refAnchor].name !== refName && !context.dynamicScope[refAnchor].isParameter && !context.dynamicScope[refAnchor].inlineSchema) {
2717
2861
  const scopeEntry = context.dynamicScope[refAnchor];
2718
2862
  const allOf = ((context.spec.components?.schemas)?.[scopeEntry.schemaName])?.allOf;
2719
2863
  if (!(Array.isArray(allOf) && allOf.some((el) => {
@@ -4620,6 +4764,7 @@ function parseFunction(ast, funcName) {
4620
4764
  //#region src/generators/mutator.ts
4621
4765
  const BODY_TYPE_NAME = "BodyType";
4622
4766
  const getImport = (output, mutator, tsconfig) => {
4767
+ if (mutator.resolvedPath || !nodePath.isAbsolute(mutator.path)) return mutator.path;
4623
4768
  const outputFile = getFileInfo(output).path;
4624
4769
  const ext = mutator.extension ?? getImportExtension(nodePath.extname(mutator.path), tsconfig);
4625
4770
  return `${getRelativeImportPath(outputFile, mutator.path)}${ext}`;
@@ -4629,15 +4774,16 @@ async function generateMutator({ output, mutator, name, workspace, tsconfig }) {
4629
4774
  const isDefault = mutator.default;
4630
4775
  const importName = mutator.name ?? `${name}Mutator`;
4631
4776
  const importPath = mutator.path;
4777
+ const inspectionPath = mutator.resolvedPath ?? mutator.path;
4632
4778
  const mutatorInfoName = isDefault ? "default" : mutator.name;
4633
4779
  if (mutatorInfoName === void 0) throw new Error(styleText("red", `Mutator ${importPath} must have a named or default export.`));
4634
- let rawFile = await fs$1.readFile(importPath, "utf8");
4780
+ let rawFile = nodePath.isAbsolute(inspectionPath) ? await fs$1.readFile(inspectionPath, "utf8") : "";
4635
4781
  rawFile = removeComments(rawFile);
4636
- const hasErrorType = rawFile.includes("export type ErrorType") || rawFile.includes("export interface ErrorType");
4637
- const hasBodyType = rawFile.includes(`export type BodyType`) || rawFile.includes(`export interface BodyType`);
4782
+ const hasErrorType = !!rawFile && (rawFile.includes("export type ErrorType") || rawFile.includes("export interface ErrorType"));
4783
+ const hasBodyType = !!rawFile && (rawFile.includes(`export type BodyType`) || rawFile.includes(`export interface BodyType`));
4638
4784
  const errorTypeName = mutator.default ? `${pascal(name)}ErrorType` : "ErrorType";
4639
4785
  const bodyTypeName = mutator.default ? `${pascal(name)}${BODY_TYPE_NAME}` : BODY_TYPE_NAME;
4640
- const mutatorInfo = await getMutatorInfo(importPath, {
4786
+ const mutatorInfo = await getMutatorInfo(inspectionPath, {
4641
4787
  root: workspace,
4642
4788
  namedExport: mutatorInfoName,
4643
4789
  alias: mutator.alias,
@@ -4821,7 +4967,7 @@ function generateBodyOptions(body, isFormData, isFormUrlEncoded) {
4821
4967
  if (isFormUrlEncoded && body.formUrlEncoded) return "formUrlEncoded";
4822
4968
  if (body.implementation) return body.implementation;
4823
4969
  }
4824
- function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, nonPrimitiveQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isVue, isAngular, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4970
+ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularObserve, angularParamsRef, requiredNullableQueryParamKeys, nonPrimitiveQueryParamKeys, queryParams, headers, requestOptions, hasSignal, hasSignalParam = false, isAngular, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4825
4971
  const isRequestOptions = requestOptions !== false;
4826
4972
  const angularPassthroughQueryParamKeys = paramsSerializer ? nonPrimitiveQueryParamKeys : [];
4827
4973
  const signalVar = hasSignalParam ? "querySignal" : "signal";
@@ -4858,8 +5004,7 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
4858
5004
  if (isRequestOptions) {
4859
5005
  value += isAngular ? "\n ...(options as Omit<NonNullable<typeof options>, 'observe'>)," : "\n ...options,";
4860
5006
  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},`;
5007
+ if (queryParams) if (isAngular && angularParamsRef) value += `\n params: ${angularParamsRef},`;
4863
5008
  else if (isAngular && paramsSerializer) {
4864
5009
  const callExpr = buildAngularParamsFilterExpression({
4865
5010
  paramsExpression: "{...params, ...options?.params}",
@@ -4888,7 +5033,7 @@ function generateAxiosOptions({ response, isExactOptionalPropertyTypes, angularO
4888
5033
  }
4889
5034
  return value;
4890
5035
  }
4891
- function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, isVue, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
5036
+ function generateOptions({ route, body, angularObserve, angularParamsRef, headers, queryParams, response, verb, requestOptions, isFormData, isFormUrlEncoded, isAngular, isExactOptionalPropertyTypes, hasSignal, hasSignalParam, paramsSerializer, paramsSerializerOptions, paramsFilter }) {
4892
5037
  const bodyIdentifier = getIsBodyVerb(verb) ? generateBodyOptions(body, isFormData, isFormUrlEncoded) : void 0;
4893
5038
  const axiosOptions = generateAxiosOptions({
4894
5039
  response,
@@ -4902,7 +5047,6 @@ function generateOptions({ route, body, angularObserve, angularParamsRef, header
4902
5047
  isExactOptionalPropertyTypes,
4903
5048
  hasSignal,
4904
5049
  hasSignalParam,
4905
- isVue: isVue ?? false,
4906
5050
  isAngular: isAngular ?? false,
4907
5051
  paramsSerializer,
4908
5052
  paramsSerializerOptions,
@@ -4925,11 +5069,10 @@ function generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) {
4925
5069
  if (body.implementation) return `,\n data: ${body.implementation}`;
4926
5070
  return "";
4927
5071
  }
4928
- function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNullableQueryParamKeys, queryParams, paramsFilter) {
5072
+ function generateQueryParamsAxiosConfig(response, isAngular, requiredNullableQueryParamKeys, queryParams, paramsFilter) {
4929
5073
  if (!queryParams && !response.isBlob) return "";
4930
5074
  let value = "";
4931
- if (queryParams) if (isVue) value += ",\n params: unref(params)";
4932
- else if (isAngular) {
5075
+ if (queryParams) if (isAngular) {
4933
5076
  const paramsExpr = buildAngularParamsFilterExpression({
4934
5077
  paramsExpression: "params ?? {}",
4935
5078
  requiredNullableParamKeys: requiredNullableQueryParamKeys,
@@ -4942,9 +5085,9 @@ function generateQueryParamsAxiosConfig(response, isVue, isAngular, requiredNull
4942
5085
  if (response.isBlob) value += `,\n responseType: 'blob'`;
4943
5086
  return value;
4944
5087
  }
4945
- function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isVue, isAngular, paramsFilter }) {
5088
+ function generateMutatorConfig({ route, body, headers, queryParams, response, verb, isFormData, isFormUrlEncoded, hasSignal, hasSignalParam = false, isExactOptionalPropertyTypes, isAngular, paramsFilter }) {
4946
5089
  const bodyOptions = getIsBodyVerb(verb) ? generateBodyMutatorConfig(body, isFormData, isFormUrlEncoded) : "";
4947
- const queryParamsOptions = generateQueryParamsAxiosConfig(response, isVue ?? false, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams, paramsFilter);
5090
+ const queryParamsOptions = generateQueryParamsAxiosConfig(response, isAngular ?? false, queryParams?.requiredNullableKeys, queryParams, paramsFilter);
4948
5091
  const ignoreContentTypes = isAngular ? ["multipart/form-data"] : [];
4949
5092
  const headerOptions = body.contentType && !ignoreContentTypes.includes(body.contentType) ? `,\n headers: {'Content-Type': '${body.contentType}', ${headers ? "...headers" : ""}}` : headers ? ",\n headers" : "";
4950
5093
  const signalVar = hasSignalParam ? "querySignal" : "signal";
@@ -5479,6 +5622,50 @@ async function writeGeneratedFile(filePath, content) {
5479
5622
  await fs$1.outputFile(filePath, content.replaceAll(TRAILING_WHITESPACE_RE, ""));
5480
5623
  }
5481
5624
  //#endregion
5625
+ //#region src/writers/schema-tag-mapper.ts
5626
+ const SHARED_DIR = ".";
5627
+ function buildSchemaTagMap(operations, schemas) {
5628
+ const schemaNames = new Set(schemas.map((s) => s.name));
5629
+ const schemaToTags = /* @__PURE__ */ new Map();
5630
+ for (const schema of schemas) if (!schemaToTags.has(schema.name)) schemaToTags.set(schema.name, /* @__PURE__ */ new Set());
5631
+ for (const operation of operations) {
5632
+ const tag = kebab(operation.tags[0] ?? "default");
5633
+ for (const imp of operation.imports) if (!imp.importPath && schemaNames.has(imp.name)) addTag(schemaToTags, imp.name, tag);
5634
+ }
5635
+ propagateTransitiveTags(schemaToTags, new Map(schemas.map((s) => [s.name, s])));
5636
+ const result = /* @__PURE__ */ new Map();
5637
+ for (const [name, tags] of schemaToTags) if (tags.size === 0 || tags.size > 1) result.set(name, ".");
5638
+ else result.set(name, [...tags][0]);
5639
+ return result;
5640
+ }
5641
+ function addTag(schemaToTags, schemaName, tag) {
5642
+ if (!schemaToTags.has(schemaName)) schemaToTags.set(schemaName, /* @__PURE__ */ new Set());
5643
+ schemaToTags.get(schemaName).add(tag);
5644
+ }
5645
+ function propagateTransitiveTags(schemaToTags, schemaByName) {
5646
+ let changed = true;
5647
+ while (changed) {
5648
+ changed = false;
5649
+ for (const [name, tags] of schemaToTags) {
5650
+ const schema = schemaByName.get(name);
5651
+ if (!schema) continue;
5652
+ for (const imp of schema.imports) {
5653
+ if (!isSchemaImport(imp)) continue;
5654
+ if (!schemaByName.has(imp.name)) continue;
5655
+ const targetTags = schemaToTags.get(imp.name);
5656
+ if (!targetTags) continue;
5657
+ for (const tag of tags) if (!targetTags.has(tag)) {
5658
+ targetTags.add(tag);
5659
+ changed = true;
5660
+ }
5661
+ }
5662
+ }
5663
+ }
5664
+ }
5665
+ function isSchemaImport(imp) {
5666
+ return !imp.importPath;
5667
+ }
5668
+ //#endregion
5482
5669
  //#region src/writers/schemas.ts
5483
5670
  /**
5484
5671
  * Patterns to detect operation-derived types (params, bodies, responses).
@@ -5755,6 +5942,61 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
5755
5942
  }
5756
5943
  }
5757
5944
  //#endregion
5945
+ //#region src/writers/schemas-tags-split.ts
5946
+ async function writeSchemasTagsSplit({ schemaPath, schemas, target, namingConvention, fileExtension, header, indexFiles, tsconfig, factoryOutputDirectory, operations }) {
5947
+ const schemaTagMap = buildSchemaTagMap(operations, schemas);
5948
+ const importExtension = getImportExtension(fileExtension, tsconfig);
5949
+ const groups = /* @__PURE__ */ new Map();
5950
+ for (const schema of schemas) {
5951
+ const group = schemaTagMap.get(schema.name) ?? ".";
5952
+ if (!groups.has(group)) groups.set(group, []);
5953
+ groups.get(group).push(schema);
5954
+ }
5955
+ for (const [groupDir, groupSchemas] of groups) {
5956
+ const isRoot = groupDir === ".";
5957
+ const groupPath = isRoot ? schemaPath : nodePath.join(schemaPath, groupDir);
5958
+ fixCrossTagImports(groupSchemas, schemaTagMap, schemaPath, groupDir, namingConvention, importExtension);
5959
+ const groupFactoryDir = factoryOutputDirectory ? isRoot ? factoryOutputDirectory : nodePath.join(factoryOutputDirectory, groupDir) : void 0;
5960
+ await writeSchemas({
5961
+ schemaPath: groupPath,
5962
+ schemas: groupSchemas,
5963
+ target,
5964
+ namingConvention,
5965
+ fileExtension,
5966
+ header,
5967
+ indexFiles: !isRoot && indexFiles,
5968
+ tsconfig,
5969
+ factoryOutputDirectory: groupFactoryDir
5970
+ });
5971
+ }
5972
+ if (indexFiles && groups.size > 0) {
5973
+ const rootIndexPath = nodePath.join(schemaPath, "index.ts");
5974
+ const rootExports = (groups.get(".") ?? []).map((s) => {
5975
+ return `export * from './${conventionName(s.name, namingConvention)}${importExtension}';`;
5976
+ });
5977
+ const tagExports = [...groups.keys()].filter((dir) => dir !== ".").toSorted((a, b) => a.localeCompare(b, "en", { numeric: true })).map((dir) => {
5978
+ return `export * from '${importExtension ? `./${dir}/index${importExtension}` : `./${dir}`}';`;
5979
+ });
5980
+ await writeGeneratedFile(rootIndexPath, `${header}\n${[...rootExports, ...tagExports].join("\n")}\n`);
5981
+ }
5982
+ }
5983
+ function fixCrossTagImports(schemas, schemaTagMap, schemaPath, currentGroupDir, namingConvention, importExtension) {
5984
+ const fromPath = currentGroupDir === "." ? schemaPath : nodePath.join(schemaPath, currentGroupDir);
5985
+ for (const schema of schemas) {
5986
+ const fixImports = (imports) => imports.map((imp) => {
5987
+ const targetGroup = schemaTagMap.get(imp.name);
5988
+ if (targetGroup === void 0 || targetGroup === currentGroupDir) return imp;
5989
+ const importPath = joinSafe(relativeSafe(fromPath, targetGroup === "." ? schemaPath : nodePath.join(schemaPath, targetGroup)), conventionName(imp.name, namingConvention)) + importExtension;
5990
+ return {
5991
+ ...imp,
5992
+ importPath
5993
+ };
5994
+ });
5995
+ schema.imports = fixImports(schema.imports);
5996
+ if (schema.factoryImports) schema.factoryImports = fixImports(schema.factoryImports);
5997
+ }
5998
+ }
5999
+ //#endregion
5758
6000
  //#region src/writers/finalize-mock-implementation.ts
5759
6001
  function getFinalizeMockImplementationOptions(output, mockOutputs) {
5760
6002
  const outputs = Array.isArray(mockOutputs) ? mockOutputs : [mockOutputs];
@@ -5778,7 +6020,7 @@ function filterLocalStrictMockTypeImports(imports, strictSchemaTypeNames) {
5778
6020
  }
5779
6021
  //#endregion
5780
6022
  //#region src/writers/generate-imports-for-builder.ts
5781
- function generateImportsForBuilder(output, imports, relativeSchemasPath) {
6023
+ function generateImportsForBuilder(output, imports, relativeSchemasPath, schemaTagMap) {
5782
6024
  const isPackageImport = isObject(output.schemas) && !!output.schemas.importPath;
5783
6025
  const isZodSchemaOutput = isObject(output.schemas) && output.schemas.type === "zod";
5784
6026
  const schemaFactoryImports = imports.filter((i) => i.schemaFactory);
@@ -5800,7 +6042,11 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
5800
6042
  else {
5801
6043
  const importsByDependency = /* @__PURE__ */ new Map();
5802
6044
  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)}`);
6045
+ const normalizedName = conventionName(isZodSchemaOutput ? schemaImport.name : schemaImport.schemaName ?? schemaImport.name, output.namingConvention);
6046
+ const suffix = isZodSchemaOutput ? ".zod" : "";
6047
+ const importExtension = isPackageImport ? "" : getImportExtension(output.fileExtension, output.tsconfig);
6048
+ const tagDir = schemaTagMap?.get(schemaImport.name);
6049
+ const dependency = joinSafe(relativeSchemasPath, `${tagDir && tagDir !== "." ? `${tagDir}/` : ""}${normalizedName}${suffix}${importExtension}`);
5804
6050
  if (!importsByDependency.has(dependency)) importsByDependency.set(dependency, []);
5805
6051
  importsByDependency.get(dependency)?.push(schemaImport);
5806
6052
  }
@@ -5832,6 +6078,78 @@ function getFakerSchemasImportPath(mock) {
5832
6078
  return mock.generators.find((g) => !isFunction(g) && g.type === OutputMockType.FAKER && g.schemas === true)?.schemasImportPath;
5833
6079
  }
5834
6080
  //#endregion
6081
+ //#region src/writers/mock-imports.ts
6082
+ /** Maps `components/schemas` names to consolidated index.faker import symbols. */
6083
+ function buildKnownSchemaFactoryImportSets(schemaNames) {
6084
+ const factoryNames = /* @__PURE__ */ new Set();
6085
+ const typeNames = /* @__PURE__ */ new Set();
6086
+ for (const name of schemaNames) {
6087
+ const typeName = pascal(name);
6088
+ factoryNames.add(`get${typeName}Mock`);
6089
+ typeNames.add(`${typeName}Mock`);
6090
+ }
6091
+ return {
6092
+ factoryNames,
6093
+ typeNames
6094
+ };
6095
+ }
6096
+ /**
6097
+ * Recover schema-factory imports referenced in generated mock bodies but
6098
+ * missing from the collected import list (e.g. after shared-array import
6099
+ * aggregation on large specs). Scans for `get<Schema>Mock()` calls and
6100
+ * `as <Schema>Mock` casts emitted by strict schema delegation (#3590).
6101
+ *
6102
+ * When `knownSets` is provided, only symbols that exist in the consolidated
6103
+ * schemas faker file are recovered — this avoids importing one-off split
6104
+ * response helper factories that live in the tag file itself.
6105
+ */
6106
+ function collectSchemaFactoryImportsFromImplementation(implementation, knownSets) {
6107
+ const imports = [];
6108
+ const seen = /* @__PURE__ */ new Set();
6109
+ for (const match of implementation.matchAll(/\b(get[A-Za-z0-9]+Mock)\(\)/g)) {
6110
+ const factoryName = match[1];
6111
+ if (knownSets && !knownSets.factoryNames.has(factoryName)) continue;
6112
+ const key = `value::${factoryName}`;
6113
+ if (seen.has(key)) continue;
6114
+ seen.add(key);
6115
+ imports.push({
6116
+ name: factoryName,
6117
+ values: true,
6118
+ schemaFactory: true
6119
+ });
6120
+ }
6121
+ for (const match of implementation.matchAll(/\bas ([A-Za-z0-9]+Mock)\b/g)) {
6122
+ const typeName = match[1];
6123
+ if (knownSets && !knownSets.typeNames.has(typeName)) continue;
6124
+ const key = `type::${typeName}`;
6125
+ if (seen.has(key)) continue;
6126
+ seen.add(key);
6127
+ imports.push({
6128
+ name: typeName,
6129
+ values: false,
6130
+ schemaFactory: true
6131
+ });
6132
+ }
6133
+ return imports;
6134
+ }
6135
+ function mergeGeneratorImports(...groups) {
6136
+ const merged = /* @__PURE__ */ new Map();
6137
+ for (const group of groups) for (const imp of group) {
6138
+ const key = `${imp.name}::${imp.alias ?? ""}`;
6139
+ const existing = merged.get(key);
6140
+ if (!existing) {
6141
+ merged.set(key, imp);
6142
+ continue;
6143
+ }
6144
+ if (!existing.values && imp.values) merged.set(key, imp);
6145
+ }
6146
+ return [...merged.values()];
6147
+ }
6148
+ /** Recover missing index.faker imports when `schemas: true` is enabled. */
6149
+ function collectRecoveredSchemaFactoryImports(implementation, componentSchemaNames) {
6150
+ return collectSchemaFactoryImportsFromImplementation(implementation, buildKnownSchemaFactoryImportSets(componentSchemaNames));
6151
+ }
6152
+ //#endregion
5835
6153
  //#region src/writers/mock-outputs.ts
5836
6154
  /**
5837
6155
  * Collapses the per-generator mock outputs for "inline" writer modes
@@ -5861,6 +6179,12 @@ function resolveMockSchemasPath(mockFilePath, schemasTarget) {
5861
6179
  return getRelativeImportPath(mockFilePath, targetExt === ".schemas" ? schemasTarget + ext : targetExt ? schemasTarget : schemasTarget + ext);
5862
6180
  }
5863
6181
  //#endregion
6182
+ //#region src/writers/typescript-version.ts
6183
+ const getTypeScriptVersion = (packageJson) => {
6184
+ return packageJson?.resolvedVersions?.typescript ?? packageJson?.dependencies?.typescript ?? packageJson?.devDependencies?.typescript ?? packageJson?.peerDependencies?.typescript ?? "4.4.0";
6185
+ };
6186
+ const hasTypeScriptAwaitedType = (packageJson) => compareVersions(getTypeScriptVersion(packageJson), "4.5.0");
6187
+ //#endregion
5864
6188
  //#region src/writers/target.ts
5865
6189
  function emptyMockOutputFull$1(type) {
5866
6190
  return {
@@ -5901,7 +6225,8 @@ function generateTarget(builder, options) {
5901
6225
  formUrlEncoded: [],
5902
6226
  paramsSerializer: [],
5903
6227
  paramsFilter: [],
5904
- fetchReviver: []
6228
+ fetchReviver: [],
6229
+ sharedTypes: []
5905
6230
  };
5906
6231
  const operations = Object.values(builder.operations);
5907
6232
  for (const [index, operation] of operations.entries()) {
@@ -5935,7 +6260,7 @@ function generateTarget(builder, options) {
5935
6260
  if (operation.fetchReviver) target.fetchReviver.push(operation.fetchReviver);
5936
6261
  if (index === operations.length - 1) {
5937
6262
  const isMutator = target.mutators.some((mutator) => isAngularClient ? mutator.hasThirdArg : mutator.hasSecondArg);
5938
- const hasAwaitedType = compareVersions(options.packageJson?.dependencies?.typescript ?? options.packageJson?.devDependencies?.typescript ?? "4.4.0", "4.5.0");
6263
+ const hasAwaitedType = hasTypeScriptAwaitedType(options.packageJson);
5939
6264
  const header = builder.header({
5940
6265
  outputClient: options.client,
5941
6266
  isRequestOptions: options.override.requestOptions !== false,
@@ -5948,7 +6273,7 @@ function generateTarget(builder, options) {
5948
6273
  verbOptions: builder.verbOptions,
5949
6274
  clientImplementation: target.implementation
5950
6275
  });
5951
- target.implementation = header.implementation + target.implementation;
6276
+ 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
6277
  const footer = builder.footer({
5953
6278
  outputClient: options.client,
5954
6279
  operationNames,
@@ -6014,7 +6339,7 @@ interface TypedResponse<T> extends Response {
6014
6339
  }
6015
6340
  //#endregion
6016
6341
  //#region src/writers/single-mode.ts
6017
- async function writeSingleMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6342
+ async function writeSingleMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6018
6343
  try {
6019
6344
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6020
6345
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
@@ -6042,7 +6367,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6042
6367
  }
6043
6368
  }
6044
6369
  let data = header;
6045
- const importsForBuilder = schemasPath ? generateImportsForBuilder(output, normalizedImports, relativeSchemasPath) : generateImportsForBuilder(output, normalizedImports.filter((imp) => !!imp.importPath), ".");
6370
+ const importsForBuilder = schemasPath ? generateImportsForBuilder(output, normalizedImports, relativeSchemasPath, schemaTagMap) : generateImportsForBuilder(output, normalizedImports.filter((imp) => !!imp.importPath), ".");
6046
6371
  data += builder.imports({
6047
6372
  client: output.client,
6048
6373
  implementation,
@@ -6059,10 +6384,12 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6059
6384
  if (!shouldDeinlineMocks) for (const mockOutput of collapsedMockOutputs) {
6060
6385
  const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
6061
6386
  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), ".");
6387
+ const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6388
+ 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)) : [];
6389
+ const filteredMockImports = filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports).filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), finalizeMockOptions.strictSchemaTypeNames);
6390
+ const importsMockForBuilder = schemasPath ? generateImportsForBuilder(output, filteredMockImports, relativeSchemasPath, schemaTagMap) : generateImportsForBuilder(output, filteredMockImports.filter((imp) => !!imp.importPath), ".");
6064
6391
  data += builder.importsMock({
6065
- implementation: mockOutput.implementation,
6392
+ implementation: finalizedMockImplementation,
6066
6393
  imports: importsMockForBuilder,
6067
6394
  projectName,
6068
6395
  hasSchemaDir: !!output.schemas,
@@ -6113,9 +6440,11 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6113
6440
  const mockDir = getMockDir(rawEntry, output.mock) ?? dirname;
6114
6441
  const mockFilePath = nodePath.join(mockDir, filename + "." + mockExtension + extension);
6115
6442
  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), ".");
6443
+ const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6444
+ const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6445
+ 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)) : [];
6446
+ 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
6447
  let mockData = header;
6118
- const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, getFinalizeMockImplementationOptions(output, mockOutput)) : mockOutput.implementation;
6119
6448
  mockData += builder.importsMock({
6120
6449
  implementation: finalizedMockImplementation,
6121
6450
  imports: importsMockForBuilder,
@@ -6152,80 +6481,8 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
6152
6481
  }
6153
6482
  }
6154
6483
  //#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
6484
  //#region src/writers/split-mode.ts
6228
- async function writeSplitMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6485
+ async function writeSplitMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6229
6486
  try {
6230
6487
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6231
6488
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
@@ -6234,10 +6491,10 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6234
6491
  const { imports, implementation, mockOutputs, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
6235
6492
  let implementationData = header;
6236
6493
  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));
6494
+ const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(targetPath, isString(output.schemas) ? output.schemas : output.schemas.path, true) : "./" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6495
+ const schemasTarget = output.schemas ? isString(output.schemas) ? output.schemas : output.schemas.path : nodePath.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6239
6496
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
6240
- const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
6497
+ const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath, schemaTagMap);
6241
6498
  implementationData += builder.imports({
6242
6499
  client: output.client,
6243
6500
  implementation,
@@ -6291,7 +6548,7 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
6291
6548
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6292
6549
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6293
6550
  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);
6551
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6295
6552
  let mockData = header;
6296
6553
  mockData += builder.importsMock({
6297
6554
  implementation: finalizedMockImplementation,
@@ -6409,7 +6666,7 @@ function initialMockOutputsForOperation(op) {
6409
6666
  }));
6410
6667
  }
6411
6668
  function generateTargetTags(currentAcc, operation) {
6412
- const tag = kebab(operation.tags[0]);
6669
+ const tag = getOperationTagKey(operation);
6413
6670
  if (!(tag in currentAcc)) {
6414
6671
  currentAcc[tag] = {
6415
6672
  imports: operation.imports,
@@ -6450,8 +6707,8 @@ function generateTargetForTags(builder, options) {
6450
6707
  const transformed = {};
6451
6708
  for (const [tag, target] of Object.entries(allTargetTags)) {
6452
6709
  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);
6454
- const hasAwaitedType = compareVersions(options.packageJson?.dependencies?.typescript ?? options.packageJson?.devDependencies?.typescript ?? "4.4.0", "4.5.0");
6710
+ const operationNames = operations.filter((operation) => isOperationInTagBucket(operation, tag)).map(({ operationName }) => operationName);
6711
+ const hasAwaitedType = hasTypeScriptAwaitedType(options.packageJson);
6455
6712
  const titles = builder.title({
6456
6713
  outputClient: options.client,
6457
6714
  title: pascal(tag),
@@ -6480,6 +6737,9 @@ function generateTargetForTags(builder, options) {
6480
6737
  isDefaultTagBucket: tag === "default" && Object.values(builder.operations).some((operation) => operation.tags.length === 0),
6481
6738
  clientImplementation: target.implementation
6482
6739
  });
6740
+ const sharedTypes = header.sharedTypes;
6741
+ const deduplicationActive = options.tagsSplitDeduplication && !options.workspace;
6742
+ const inlinedSharedTypes = !deduplicationActive && sharedTypes && sharedTypes.length > 0 ? sharedTypes.map((t) => `${t.exported ? "export " : ""}${t.code}`).join("\n") + "\n\n" : "";
6483
6743
  const wrappedMockOutputs = target.mockOutputs.map((m) => ({
6484
6744
  type: m.type,
6485
6745
  implementation: {
@@ -6492,7 +6752,7 @@ function generateTargetForTags(builder, options) {
6492
6752
  strictMockSchemaKinds: m.strictMockSchemaKinds
6493
6753
  }));
6494
6754
  transformed[tag] = {
6495
- implementation: header.implementation + target.implementation + footer.implementation,
6755
+ implementation: inlinedSharedTypes + header.implementation + target.implementation + footer.implementation,
6496
6756
  mockOutputs: wrappedMockOutputs,
6497
6757
  imports: target.imports,
6498
6758
  mutators: target.mutators,
@@ -6501,7 +6761,8 @@ function generateTargetForTags(builder, options) {
6501
6761
  formUrlEncoded: target.formUrlEncoded,
6502
6762
  paramsSerializer: target.paramsSerializer,
6503
6763
  paramsFilter: target.paramsFilter,
6504
- fetchReviver: target.fetchReviver
6764
+ fetchReviver: target.fetchReviver,
6765
+ sharedTypes: deduplicationActive ? sharedTypes : void 0
6505
6766
  };
6506
6767
  }
6507
6768
  allTargetTags = transformed;
@@ -6516,7 +6777,7 @@ function generateTargetForTags(builder, options) {
6516
6777
  }
6517
6778
  //#endregion
6518
6779
  //#region src/writers/split-tags-mode.ts
6519
- async function writeSplitTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6780
+ async function writeSplitTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6520
6781
  const { filename, dirname, extension } = getFileInfo(output.target, {
6521
6782
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
6522
6783
  extension: output.fileExtension
@@ -6525,15 +6786,33 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6525
6786
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
6526
6787
  const mockIndexEntries = [];
6527
6788
  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));
6789
+ const schemasTarget = output.schemas ? isString(output.schemas) ? output.schemas : output.schemas.path : nodePath.join(dirname, filename + ".schemas" + getImportExtension(extension, output.tsconfig));
6529
6790
  const tagEntries = Object.entries(target).toSorted(([a], [b]) => a.localeCompare(b));
6791
+ const deduplicationEnabled = output.tagsSplitDeduplication && !output.workspace;
6792
+ const collectedSharedTypes = [];
6793
+ const seenSharedTypeNames = /* @__PURE__ */ new Set();
6794
+ for (const [, target] of tagEntries) {
6795
+ if (!target.sharedTypes) continue;
6796
+ for (const t of target.sharedTypes) if (!seenSharedTypeNames.has(t.name)) {
6797
+ seenSharedTypeNames.add(t.name);
6798
+ collectedSharedTypes.push(t);
6799
+ }
6800
+ }
6801
+ const commonTypesImportExtension = getImportExtension(extension, output.tsconfig);
6802
+ const commonTypesBasename = output.commonTypesFileName;
6803
+ const commonTypesPath = nodePath.join(dirname, commonTypesBasename + extension);
6804
+ const commonTypesRelativeImport = "../" + commonTypesBasename + (deduplicationEnabled ? commonTypesImportExtension : "");
6530
6805
  const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
6531
6806
  try {
6532
6807
  const { imports, implementation, mockOutputs, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer, paramsFilter } = target;
6533
6808
  let implementationData = header;
6809
+ if (deduplicationEnabled && target.sharedTypes && target.sharedTypes.length > 0) {
6810
+ const typeNames = target.sharedTypes.map((t) => t.name).join(", ");
6811
+ implementationData += `import type { ${typeNames} } from '${commonTypesRelativeImport}';\n`;
6812
+ }
6534
6813
  const importerPath = nodePath.join(dirname, tag, tag + extension);
6535
6814
  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);
6815
+ const relativeSchemasPath = output.schemas ? schemaCustomImportPath ?? getRelativeImportPath(importerPath, isString(output.schemas) ? output.schemas : output.schemas.path, true) : "../" + filename + ".schemas" + getImportExtension(extension, output.tsconfig);
6537
6816
  const tagNames = new Set(tagEntries.map(([t]) => t));
6538
6817
  const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
6539
6818
  const importsForBuilder = generateImportsForBuilder(output, imports.map((imp) => {
@@ -6551,7 +6830,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6551
6830
  ...imp,
6552
6831
  importPath: adjustedPath
6553
6832
  };
6554
- }), relativeSchemasPath);
6833
+ }), relativeSchemasPath, schemaTagMap);
6555
6834
  implementationData += builder.imports({
6556
6835
  client: output.client,
6557
6836
  implementation,
@@ -6622,7 +6901,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6622
6901
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6623
6902
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6624
6903
  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);
6904
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6626
6905
  let mockData = header;
6627
6906
  mockData += builder.importsMock({
6628
6907
  implementation: finalizedMockImplementation,
@@ -6664,11 +6943,33 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
6664
6943
  return ext === OutputMockType.MSW ? `export { get${pascal(tag)}Mock } from '${localMockPath}'\n` : `export * from '${localMockPath}'\n`;
6665
6944
  }).join(""));
6666
6945
  }
6667
- return [...new Set([...output.mock.indexMockFiles ? mockIndexEntries.map(({ mockDir, ext }) => nodePath.join(mockDir, `index.${ext}${extension}`)) : [], ...generatedFilePathsArray.flat()])];
6946
+ let commonTypesFilePath;
6947
+ if (deduplicationEnabled && collectedSharedTypes.length > 0) {
6948
+ const commonTypesContent = collectedSharedTypes.map((t) => `export ${t.code}`).join("\n") + "\n";
6949
+ commonTypesFilePath = commonTypesPath;
6950
+ await writeGeneratedFile(commonTypesPath, commonTypesContent);
6951
+ }
6952
+ let indexFilePath;
6953
+ if (output.indexFiles && deduplicationEnabled && tagEntries.length > 0) {
6954
+ const importExtension = getImportExtension(output.fileExtension, output.tsconfig);
6955
+ const serviceSuffix = OutputClient.ANGULAR === output.client ? ".service" : "";
6956
+ const publicSharedTypeNames = collectedSharedTypes.filter((t) => t.exported).map((t) => t.name);
6957
+ const indexContent = (publicSharedTypeNames.length > 0 ? `export type { ${publicSharedTypeNames.join(", ")} } from './${commonTypesBasename}${importExtension}';\n` : "") + tagEntries.map(([tag]) => {
6958
+ return `export * from '${joinSafe("./", tag, tag + serviceSuffix + importExtension)}';\n`;
6959
+ }).join("");
6960
+ indexFilePath = nodePath.join(dirname, `index${extension}`);
6961
+ await writeGeneratedFile(indexFilePath, indexContent);
6962
+ }
6963
+ return [...new Set([
6964
+ ...output.mock.indexMockFiles ? mockIndexEntries.map(({ mockDir, ext }) => nodePath.join(mockDir, `index.${ext}${extension}`)) : [],
6965
+ ...commonTypesFilePath ? [commonTypesFilePath] : [],
6966
+ ...indexFilePath ? [indexFilePath] : [],
6967
+ ...generatedFilePathsArray.flat()
6968
+ ])];
6668
6969
  }
6669
6970
  //#endregion
6670
6971
  //#region src/writers/tags-mode.ts
6671
- async function writeTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline }) {
6972
+ async function writeTagsMode({ builder, output, projectName, header, needSchema, generateSchemasInline, schemaTagMap }) {
6672
6973
  const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
6673
6974
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
6674
6975
  extension: output.fileExtension
@@ -6700,7 +7001,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6700
7001
  if (!!mockImport.values || !!mockImport.isConstant || !!mockImport.default || !!mockImport.namespaceImport || !!mockImport.syntheticDefaultImport) matchingImport.values = true;
6701
7002
  }
6702
7003
  }
6703
- const importsForBuilder = generateImportsForBuilder(output, normalizedImports, schemasPathRelative);
7004
+ const importsForBuilder = generateImportsForBuilder(output, normalizedImports, schemasPathRelative, schemaTagMap);
6704
7005
  data += builder.imports({
6705
7006
  client: output.client,
6706
7007
  implementation,
@@ -6716,7 +7017,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6716
7017
  });
6717
7018
  if (!shouldDeinlineMocks) for (const mockOutput of collapsedMockOutputs) {
6718
7019
  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);
7020
+ const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), schemasPathRelative, schemaTagMap);
6720
7021
  data += builder.importsMock({
6721
7022
  implementation: mockOutput.implementation,
6722
7023
  imports: importsMockForBuilder,
@@ -6773,7 +7074,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6773
7074
  const finalizeMockOptions = getFinalizeMockImplementationOptions(output, mockOutput);
6774
7075
  const finalizedMockImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(mockOutput.implementation, finalizeMockOptions) : mockOutput.implementation;
6775
7076
  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);
7077
+ const importsMockForBuilder = generateImportsForBuilder(output, filterLocalStrictMockTypeImports(mergeGeneratorImports(mockOutput.imports, recoveredSchemaFactoryImports), finalizeMockOptions.strictSchemaTypeNames), mockRelativeSchemasPath, schemaTagMap);
6777
7078
  let mockData = header;
6778
7079
  mockData += builder.importsMock({
6779
7080
  implementation: finalizedMockImplementation,
@@ -6822,6 +7123,6 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
6822
7123
  return generatedFilePathsArray.flat();
6823
7124
  }
6824
7125
  //#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 };
7126
+ 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, getDynamicAnchorIndex, 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
7127
 
6827
7128
  //# sourceMappingURL=index.mjs.map