@orval/core 8.11.0 → 8.12.2

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
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
2
  import { createRequire } from "node:module";
3
- import { entries, groupBy, isArray, isBoolean, isBoolean as isBoolean$1, isEmptyish, isFunction, isNullish, isNullish as isNullish$1, isNumber, isString, isString as isString$1, prop, unique, uniqueBy, uniqueWith } from "remeda";
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
5
  import nodePath from "node:path";
6
6
  import { compare } from "compare-versions";
@@ -8,7 +8,7 @@ import debug from "debug";
8
8
  import { pathToFileURL } from "node:url";
9
9
  import { createJiti } from "jiti";
10
10
  import fs, { existsSync, readFileSync } from "node:fs";
11
- import { globby } from "globby";
11
+ import { glob } from "tinyglobby";
12
12
  import readline from "node:readline";
13
13
  import { styleText } from "node:util";
14
14
  import { isDereferenced } from "@scalar/openapi-types/helpers";
@@ -63,7 +63,10 @@ const OutputMode = {
63
63
  TAGS: "tags",
64
64
  TAGS_SPLIT: "tags-split"
65
65
  };
66
- const OutputMockType = { MSW: "msw" };
66
+ const OutputMockType = {
67
+ MSW: "msw",
68
+ FAKER: "faker"
69
+ };
67
70
  const FormDataArrayHandling = {
68
71
  SERIALIZE: "serialize",
69
72
  EXPLODE: "explode",
@@ -177,6 +180,20 @@ function isUrl(str) {
177
180
  return false;
178
181
  }
179
182
  }
183
+ /**
184
+ * Type guard for the MSW mock generator. Use to narrow a
185
+ * `GlobalMockOptions | ClientMockBuilder` value to `MswMockOptions`.
186
+ */
187
+ function isMswMock(mock) {
188
+ return !isFunction$1(mock) && mock.type === OutputMockType.MSW;
189
+ }
190
+ /**
191
+ * Type guard for the Faker mock generator. Use to narrow a
192
+ * `GlobalMockOptions | ClientMockBuilder` value to `FakerMockOptions`.
193
+ */
194
+ function isFakerMock(mock) {
195
+ return !isFunction$1(mock) && mock.type === OutputMockType.FAKER;
196
+ }
180
197
  //#endregion
181
198
  //#region src/utils/async-reduce.ts
182
199
  async function asyncReduce(array, reducer, initValue) {
@@ -365,7 +382,7 @@ function createDebugger(ns, options = {}) {
365
382
  //#region src/utils/doc.ts
366
383
  const search = String.raw`\*/`;
367
384
  const replacement = String.raw`*\/`;
368
- const regex$1 = new RegExp(search, "g");
385
+ const regex = new RegExp(search, "g");
369
386
  const itemValidationKeys = [
370
387
  "minLength",
371
388
  "maxLength",
@@ -397,7 +414,7 @@ function jsDoc(schema, tryOneLine = false, context) {
397
414
  const { description, deprecated, summary, minLength, maxLength, minimum, maximum, exclusiveMinimum, exclusiveMaximum, minItems, maxItems, pattern } = schema;
398
415
  const isNullable = schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null");
399
416
  const itemValidationDocEntries = getItemValidationDocEntries(schema.items);
400
- const lines = (Array.isArray(description) ? description.filter((d) => !d.includes("eslint-disable")) : [description ?? ""]).map((line) => line.replaceAll(regex$1, replacement));
417
+ const lines = (Array.isArray(description) ? description.filter((d) => !d.includes("eslint-disable")) : [description ?? ""]).flatMap((line) => line.split(/\r?\n/)).map((line) => line.replaceAll(regex, replacement));
401
418
  const count = [
402
419
  description,
403
420
  deprecated,
@@ -416,7 +433,7 @@ function jsDoc(schema, tryOneLine = false, context) {
416
433
  ].filter(Boolean).length;
417
434
  if (!count) return "";
418
435
  const oneLine = count === 1 && tryOneLine;
419
- const eslintDisable = Array.isArray(description) ? description.find((d) => d.includes("eslint-disable"))?.replaceAll(regex$1, replacement) : void 0;
436
+ const eslintDisable = Array.isArray(description) ? description.find((d) => d.includes("eslint-disable"))?.replaceAll(regex, replacement) : void 0;
420
437
  let doc = `${eslintDisable ? `/* ${eslintDisable} */\n` : ""}/**`;
421
438
  if (description) {
422
439
  if (!oneLine) doc += `\n${tryOneLine ? " " : ""} *`;
@@ -428,7 +445,7 @@ function jsDoc(schema, tryOneLine = false, context) {
428
445
  function tryAppendStringDocLine(key, value) {
429
446
  if (value) {
430
447
  appendPrefix();
431
- doc += ` @${key} ${value.replaceAll(regex$1, replacement)}`;
448
+ doc += ` @${key} ${value.replaceAll(regex, replacement)}`;
432
449
  }
433
450
  }
434
451
  function tryAppendBooleanDocLine(key, value) {
@@ -444,7 +461,7 @@ function jsDoc(schema, tryOneLine = false, context) {
444
461
  }
445
462
  }
446
463
  tryAppendBooleanDocLine("deprecated", deprecated);
447
- tryAppendStringDocLine("summary", summary?.replaceAll(regex$1, replacement));
464
+ tryAppendStringDocLine("summary", summary?.replaceAll(regex, replacement));
448
465
  tryAppendNumberDocLine("minLength", minLength);
449
466
  tryAppendNumberDocLine("maxLength", maxLength);
450
467
  tryAppendNumberDocLine("minimum", minimum);
@@ -527,12 +544,12 @@ function getFileInfo(target = "", { backupFilename = "filename", extension = ".t
527
544
  };
528
545
  }
529
546
  async function removeFilesAndEmptyFolders(patterns, dir) {
530
- const files = await globby(patterns, {
547
+ const files = await glob(patterns, {
531
548
  cwd: dir,
532
549
  absolute: true
533
550
  });
534
551
  await Promise.all(files.map((file) => fs.promises.unlink(file)));
535
- const sortedDirectories = (await globby(["**/*"], {
552
+ const sortedDirectories = (await glob(["**/*"], {
536
553
  cwd: dir,
537
554
  absolute: true,
538
555
  onlyDirectories: true
@@ -546,11 +563,17 @@ async function removeFilesAndEmptyFolders(patterns, dir) {
546
563
  }
547
564
  //#endregion
548
565
  //#region src/utils/file-extensions.ts
566
+ /**
567
+ * Returns the filename suffix for a given mock entry's output file. For
568
+ * example a `{ type: OutputMockType.MSW }` entry produces `<file>.msw.ts` and
569
+ * a `{ type: OutputMockType.FAKER }` entry produces `<file>.faker.ts`.
570
+ *
571
+ * Custom `ClientMockBuilder` functions default to the `msw` suffix to preserve
572
+ * the historical behavior.
573
+ */
549
574
  function getMockFileExtensionByTypeName(mock) {
550
- if (isFunction(mock)) return "msw";
551
- switch (mock.type) {
552
- default: return "msw";
553
- }
575
+ if (isFunction(mock)) return OutputMockType.MSW;
576
+ return mock.type;
554
577
  }
555
578
  //#endregion
556
579
  //#region src/utils/get-property-safe.ts
@@ -1296,7 +1319,8 @@ const COMPONENT_REF_PATTERN = new RegExp(String.raw`^#\/components\/(${NAMED_COM
1296
1319
  function isComponentRef(ref) {
1297
1320
  return COMPONENT_REF_PATTERN.test(ref);
1298
1321
  }
1299
- const regex = /* @__PURE__ */ new RegExp("~1", "g");
1322
+ const TILDE_1 = /~1/g;
1323
+ const TILDE_0 = /~0/g;
1300
1324
  /**
1301
1325
  * Return the output type from the $ref
1302
1326
  *
@@ -1304,7 +1328,7 @@ const regex = /* @__PURE__ */ new RegExp("~1", "g");
1304
1328
  */
1305
1329
  function getRefInfo($ref, context) {
1306
1330
  const [pathname, ref] = $ref.split("#");
1307
- const refPaths = ref.slice(1).split("/").map((part) => decodeURIComponent(part.replaceAll(regex, "/")));
1331
+ const refPaths = ref.slice(1).split("/").map((part) => decodeURIComponent(part).replaceAll(TILDE_1, "/").replaceAll(TILDE_0, "~"));
1308
1332
  const getOverrideSuffix = (override, paths) => {
1309
1333
  const firstLevel = override[paths[0]];
1310
1334
  if (!firstLevel) return "";
@@ -1688,9 +1712,14 @@ const formDataContentTypes = new Set(["multipart/form-data"]);
1688
1712
  const formUrlEncodedContentTypes = new Set(["application/x-www-form-urlencoded"]);
1689
1713
  function getResReqContentTypes({ mediaType, propName, context, isFormData, contentType }) {
1690
1714
  if (!mediaType.schema) return;
1715
+ const isFormUrlEncoded = formUrlEncodedContentTypes.has(contentType);
1691
1716
  const formDataContext = isFormData ? {
1692
1717
  atPart: false,
1693
1718
  encoding: mediaType.encoding ?? {}
1719
+ } : isFormUrlEncoded ? {
1720
+ atPart: false,
1721
+ encoding: mediaType.encoding ?? {},
1722
+ urlEncoded: true
1694
1723
  } : void 0;
1695
1724
  const resolvedObject = resolveObject({
1696
1725
  schema: mediaType.schema,
@@ -1956,25 +1985,37 @@ function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequest
1956
1985
  form += `Object.entries(${propName} ?? {}).forEach(([key, value]) => {\n`;
1957
1986
  form += skipLine;
1958
1987
  form += ` if (value !== undefined && value !== null) {\n`;
1959
- form += ` if ((typeof File !== 'undefined' && value instanceof File) || value instanceof Blob) {\n`;
1960
- form += ` ${variableName}.append(key, value);\n`;
1961
- form += ` } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n`;
1962
- form += ` ${variableName}.append(key, new Blob([Uint8Array.from(value)]));\n`;
1963
- form += ` } else if (Array.isArray(value)) {\n`;
1964
- form += ` value.forEach(v => {\n`;
1965
- form += ` if ((typeof File !== 'undefined' && v instanceof File) || v instanceof Blob) {\n`;
1966
- form += ` ${variableName}.append(key, v);\n`;
1967
- form += ` } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(v)) {\n`;
1968
- form += ` ${variableName}.append(key, new Blob([Uint8Array.from(v)]));\n`;
1969
- form += ` } else {\n`;
1970
- form += ` ${variableName}.append(key, typeof v === 'object' ? JSON.stringify(v) : String(v));\n`;
1971
- form += ` }\n`;
1972
- form += ` });\n`;
1973
- form += ` } else if (typeof value === 'object') {\n`;
1974
- form += ` ${variableName}.append(key, JSON.stringify(value));\n`;
1975
- form += ` } else {\n`;
1976
- form += ` ${variableName}.append(key, String(value));\n`;
1977
- form += ` }\n`;
1988
+ if (isUrlEncoded) {
1989
+ form += ` if (Array.isArray(value)) {\n`;
1990
+ form += ` value.forEach(v => {\n`;
1991
+ form += ` ${variableName}.append(key, typeof v === 'object' ? JSON.stringify(v) : String(v));\n`;
1992
+ form += ` });\n`;
1993
+ form += ` } else if (typeof value === 'object') {\n`;
1994
+ form += ` ${variableName}.append(key, JSON.stringify(value));\n`;
1995
+ form += ` } else {\n`;
1996
+ form += ` ${variableName}.append(key, String(value));\n`;
1997
+ form += ` }\n`;
1998
+ } else {
1999
+ form += ` if ((typeof File !== 'undefined' && value instanceof File) || value instanceof Blob) {\n`;
2000
+ form += ` ${variableName}.append(key, value);\n`;
2001
+ form += ` } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {\n`;
2002
+ form += ` ${variableName}.append(key, new Blob([Uint8Array.from(value)]));\n`;
2003
+ form += ` } else if (Array.isArray(value)) {\n`;
2004
+ form += ` value.forEach(v => {\n`;
2005
+ form += ` if ((typeof File !== 'undefined' && v instanceof File) || v instanceof Blob) {\n`;
2006
+ form += ` ${variableName}.append(key, v);\n`;
2007
+ form += ` } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(v)) {\n`;
2008
+ form += ` ${variableName}.append(key, new Blob([Uint8Array.from(v)]));\n`;
2009
+ form += ` } else {\n`;
2010
+ form += ` ${variableName}.append(key, typeof v === 'object' ? JSON.stringify(v) : String(v));\n`;
2011
+ form += ` }\n`;
2012
+ form += ` });\n`;
2013
+ form += ` } else if (typeof value === 'object') {\n`;
2014
+ form += ` ${variableName}.append(key, JSON.stringify(value));\n`;
2015
+ form += ` } else {\n`;
2016
+ form += ` ${variableName}.append(key, String(value));\n`;
2017
+ form += ` }\n`;
2018
+ }
1978
2019
  form += ` }\n`;
1979
2020
  form += `});\n`;
1980
2021
  } else {
@@ -2019,6 +2060,7 @@ function getSchemaFormDataAndUrlEncoded({ name, schemaObject, context, isRequest
2019
2060
  }
2020
2061
  function resolveSchemaPropertiesToFormData({ schema, variableName, propName, context, isRequestBodyOptional, keyPrefix = "", depth = 0, encoding }) {
2021
2062
  let formDataValues = "";
2063
+ const isUrlEncoded = variableName === "formUrlEncoded";
2022
2064
  const schemaProps = getSchemaProperties(schema) ?? {};
2023
2065
  for (const [key, value] of Object.entries(schemaProps)) {
2024
2066
  const { schema: property } = resolveSchemaRef(value, context);
@@ -2031,9 +2073,10 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
2031
2073
  const nonOptionalValueKey = `${propName}${formattedKey}`;
2032
2074
  const fileType = getFormDataFieldFileType(property, partContentType);
2033
2075
  const effectiveContentType = partContentType ?? property.contentMediaType;
2034
- if (fileType === "binary" || property.format === "binary") formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey});\n`;
2076
+ if (isUrlEncoded && (fileType || property.format === "binary")) formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey});\n`;
2077
+ else if (fileType === "binary" || property.format === "binary") formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey});\n`;
2035
2078
  else if (fileType === "text") formDataValue = `${variableName}.append(\`${keyPrefix}${key}\`, ${nonOptionalValueKey} instanceof Blob ? ${nonOptionalValueKey} : new Blob([${nonOptionalValueKey}], { type: '${effectiveContentType}' }));\n`;
2036
- else if (property.type === "object") formDataValue = context.output.override.formData.arrayHandling === FormDataArrayHandling.EXPLODE ? resolveSchemaPropertiesToFormData({
2079
+ else if (property.type === "object" || Array.isArray(property.type) && property.type.includes("object")) formDataValue = context.output.override.formData.arrayHandling === FormDataArrayHandling.EXPLODE ? resolveSchemaPropertiesToFormData({
2037
2080
  schema: property,
2038
2081
  variableName,
2039
2082
  propName: nonOptionalValueKey,
@@ -2043,7 +2086,7 @@ function resolveSchemaPropertiesToFormData({ schema, variableName, propName, con
2043
2086
  depth: depth + 1,
2044
2087
  encoding
2045
2088
  }) : `${variableName}.append(\`${keyPrefix}${key}\`, JSON.stringify(${nonOptionalValueKey}));\n`;
2046
- else if (property.type === "array") {
2089
+ else if (property.type === "array" || Array.isArray(property.type) && property.type.includes("array")) {
2047
2090
  let valueStr = "value";
2048
2091
  let hasNonPrimitiveChild = false;
2049
2092
  const propertyItems = getSchemaItems(property);
@@ -2348,7 +2391,8 @@ function getObject({ item, name, context, nullable, formDataContext }) {
2348
2391
  if (Object.keys(allSpecSchemas).some((schemaName) => pascal(schemaName) === propName)) propName = propName + "Property";
2349
2392
  const propertyFormDataContext = formDataContext && !formDataContext.atPart ? {
2350
2393
  atPart: true,
2351
- partContentType: formDataContext.encoding[key]?.contentType
2394
+ partContentType: formDataContext.encoding[key]?.contentType,
2395
+ urlEncoded: formDataContext.urlEncoded
2352
2396
  } : void 0;
2353
2397
  const resolvedValue = resolveObject({
2354
2398
  schema,
@@ -2625,11 +2669,13 @@ function getScalar({ item, name, context, formDataContext }) {
2625
2669
  value = enumItems.map((enumItem) => isString(enumItem) ? `'${escape(enumItem)}'` : `${enumItem}`).filter(Boolean).join(` | `);
2626
2670
  isEnum = true;
2627
2671
  }
2628
- if (schemaFormat === "binary") value = "Blob";
2629
- else if (formDataContext?.atPart) {
2630
- const fileType = getFormDataFieldFileType(item, formDataContext.partContentType);
2631
- if (fileType) value = fileType === "binary" ? "Blob" : "Blob | string";
2632
- } else if (schemaContentMediaType === "application/octet-stream" && !schemaContentEncoding) value = "Blob";
2672
+ if (!formDataContext?.urlEncoded) {
2673
+ if (schemaFormat === "binary") value = "Blob";
2674
+ else if (formDataContext?.atPart) {
2675
+ const fileType = getFormDataFieldFileType(item, formDataContext.partContentType);
2676
+ if (fileType) value = fileType === "binary" ? "Blob" : "Blob | string";
2677
+ } else if (schemaContentMediaType === "application/octet-stream" && !schemaContentEncoding) value = "Blob";
2678
+ }
2633
2679
  if (context.output.override.useDates && (schemaFormat === "date" || schemaFormat === "date-time")) value = "Date";
2634
2680
  value += nullable;
2635
2681
  if (schemaConst) value = `'${schemaConst}'`;
@@ -2970,10 +3016,13 @@ function getParameters({ parameters, context }) {
2970
3016
  const { schema, imports } = resolveRef(p, context);
2971
3017
  const parameter = schema;
2972
3018
  const location = parameter.in;
2973
- if (location === "path" || location === "query" || location === "header") result[location].push({
2974
- parameter,
2975
- imports
2976
- });
3019
+ if (location === "path" || location === "query" || location === "header") {
3020
+ const safeImports = p.$ref && isComponentRef(p.$ref) ? imports : [];
3021
+ result[location].push({
3022
+ parameter,
3023
+ imports: safeImports
3024
+ });
3025
+ }
2977
3026
  } else if (p.in === "query" || p.in === "path" || p.in === "header") result[p.in].push({
2978
3027
  parameter: p,
2979
3028
  imports: []
@@ -3262,7 +3311,7 @@ function getResponse({ responses, operationName, context, contentType }) {
3262
3311
  success: success || (defaultType ?? "unknown"),
3263
3312
  errors: errors || (defaultType ?? "unknown")
3264
3313
  },
3265
- isBlob: groupedByStatus.success.some((t) => !!t.contentType && isBinaryContentType(t.contentType) || t.value === "Blob" && !t.isRef),
3314
+ isBlob: groupedByStatus.success.some((t) => !!t.contentType && isBinaryContentType(t.contentType) || t.originalSchema?.format === "binary" || t.originalSchema?.contentMediaType === "application/octet-stream" && !t.originalSchema.contentEncoding),
3266
3315
  types: groupedByStatus,
3267
3316
  contentTypes,
3268
3317
  schemas,
@@ -3355,6 +3404,8 @@ function getBaseUrlRuntimeImports(baseUrl) {
3355
3404
  values: imp.values ?? true
3356
3405
  }));
3357
3406
  }
3407
+ const wrapRouteParameters = (route, prepend, append) => route.replaceAll(TEMPLATE_TAG_REGEX, `\${${prepend}$1${append}}`);
3408
+ const makeRouteSafe = (route) => wrapRouteParameters(route, "encodeURIComponent(String(", "))");
3358
3409
  function getRouteAsArray(route) {
3359
3410
  return route.split("/").filter((i) => i !== "").flatMap((segment) => {
3360
3411
  if (!segment.includes("${")) return [`'${segment}'`];
@@ -3605,7 +3656,7 @@ function generateModelsInline(obj) {
3605
3656
  //#region src/generators/mutator-info.ts
3606
3657
  async function getMutatorInfo(filePath, options) {
3607
3658
  const { root = process.cwd(), namedExport = "default", alias, external, tsconfig } = options ?? {};
3608
- return parseFile(await bundleFile(root, filePath, alias, external, tsconfig?.compilerOptions), namedExport, getEcmaVersion(tsconfig?.compilerOptions?.target));
3659
+ return parseFile(await bundleFile(root, filePath, alias, external, tsconfig?.compilerOptions), namedExport);
3609
3660
  }
3610
3661
  async function bundleFile(root, fileName, alias, external, compilerOptions) {
3611
3662
  const { text } = (await build({
@@ -3628,10 +3679,10 @@ async function bundleFile(root, fileName, alias, external, compilerOptions) {
3628
3679
  })).outputFiles[0];
3629
3680
  return text;
3630
3681
  }
3631
- function parseFile(file, name, ecmaVersion = 6) {
3682
+ function parseFile(file, name) {
3632
3683
  try {
3633
3684
  const ast = Parser.parse(file, {
3634
- ecmaVersion,
3685
+ ecmaVersion: "latest",
3635
3686
  sourceType: "module"
3636
3687
  });
3637
3688
  const foundSpecifier = ast.body.filter((x) => x.type === "ExportNamedDeclaration").flatMap((x) => x.specifiers).find((x) => x.exported.type === "Identifier" && x.exported.name === name && x.local.type === "Identifier");
@@ -3688,15 +3739,6 @@ function parseFunction(ast, funcName) {
3688
3739
  }
3689
3740
  }
3690
3741
  }
3691
- function getEcmaVersion(target) {
3692
- if (!target) return;
3693
- if (target.toLowerCase() === "esnext") return "latest";
3694
- try {
3695
- return Number(target.toLowerCase().replace("es", ""));
3696
- } catch {
3697
- return;
3698
- }
3699
- }
3700
3742
  //#endregion
3701
3743
  //#region src/generators/mutator.ts
3702
3744
  const BODY_TYPE_NAME = "BodyType";
@@ -4691,7 +4733,39 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
4691
4733
  return [...schemaImports, ...otherImports];
4692
4734
  }
4693
4735
  //#endregion
4736
+ //#region src/writers/mock-outputs.ts
4737
+ /**
4738
+ * Collapses the per-generator mock outputs for "inline" writer modes
4739
+ * (`single`, `tags`) where every mock generator's content is concatenated
4740
+ * into the implementation file. The MSW generator already emits the
4741
+ * response-factory functions (`get<Op>ResponseMock`) that Faker would emit,
4742
+ * so when both generators are configured we keep MSW and drop Faker to
4743
+ * avoid duplicate function declarations and re-imported faker bindings.
4744
+ */
4745
+ function collapseInlineMockOutputs(mockOutputs) {
4746
+ if (!mockOutputs.some((m) => m.type === OutputMockType.MSW)) return mockOutputs;
4747
+ return mockOutputs.filter((m) => m.type !== OutputMockType.FAKER);
4748
+ }
4749
+ //#endregion
4694
4750
  //#region src/writers/target.ts
4751
+ function emptyMockOutputFull$1(type) {
4752
+ return {
4753
+ type,
4754
+ implementation: {
4755
+ function: "",
4756
+ handler: "",
4757
+ handlerName: ""
4758
+ },
4759
+ imports: []
4760
+ };
4761
+ }
4762
+ function flattenMockOutput$1(full) {
4763
+ return {
4764
+ type: full.type,
4765
+ implementation: full.implementation.function + full.implementation.handler,
4766
+ imports: full.imports
4767
+ };
4768
+ }
4695
4769
  function generateTarget(builder, options) {
4696
4770
  const operationNames = Object.values(builder.operations).map(({ operationName }) => operationName);
4697
4771
  const isAngularClient = options.client === OutputClient.ANGULAR;
@@ -4704,12 +4778,7 @@ function generateTarget(builder, options) {
4704
4778
  const target = {
4705
4779
  imports: [],
4706
4780
  implementation: "",
4707
- implementationMock: {
4708
- function: "",
4709
- handler: "",
4710
- handlerName: ""
4711
- },
4712
- importsMock: [],
4781
+ mockOutputs: [],
4713
4782
  mutators: [],
4714
4783
  clientMutators: [],
4715
4784
  formData: [],
@@ -4721,12 +4790,21 @@ function generateTarget(builder, options) {
4721
4790
  const operations = Object.values(builder.operations);
4722
4791
  for (const [index, operation] of operations.entries()) {
4723
4792
  target.imports.push(...operation.imports);
4724
- target.importsMock.push(...operation.importsMock);
4725
4793
  target.implementation += operation.implementation + "\n";
4726
- target.implementationMock.function += operation.implementationMock.function;
4727
- target.implementationMock.handler += operation.implementationMock.handler;
4728
- const handlerNameSeparator = target.implementationMock.handlerName.length > 0 ? ",\n " : " ";
4729
- target.implementationMock.handlerName += handlerNameSeparator + operation.implementationMock.handlerName + "()";
4794
+ for (const opMock of operation.mockOutputs) {
4795
+ let acc = target.mockOutputs.find((m) => m.type === opMock.type);
4796
+ if (!acc) {
4797
+ acc = emptyMockOutputFull$1(opMock.type);
4798
+ target.mockOutputs.push(acc);
4799
+ }
4800
+ acc.imports.push(...opMock.imports);
4801
+ acc.implementation.function += opMock.implementation.function;
4802
+ acc.implementation.handler += opMock.implementation.handler;
4803
+ if (opMock.implementation.handlerName) {
4804
+ const separator = acc.implementation.handlerName.length > 0 ? ",\n " : " ";
4805
+ acc.implementation.handlerName += separator + opMock.implementation.handlerName + "()";
4806
+ }
4807
+ }
4730
4808
  if (operation.mutator) target.mutators.push(operation.mutator);
4731
4809
  if (operation.formData) target.formData.push(operation.formData);
4732
4810
  if (operation.formUrlEncoded) target.formUrlEncoded.push(operation.formUrlEncoded);
@@ -4750,7 +4828,6 @@ function generateTarget(builder, options) {
4750
4828
  clientImplementation: target.implementation
4751
4829
  });
4752
4830
  target.implementation = header.implementation + target.implementation;
4753
- target.implementationMock.handler = target.implementationMock.handler + header.implementationMock + target.implementationMock.handlerName;
4754
4831
  const footer = builder.footer({
4755
4832
  outputClient: options.client,
4756
4833
  operationNames,
@@ -4760,12 +4837,20 @@ function generateTarget(builder, options) {
4760
4837
  output: options
4761
4838
  });
4762
4839
  target.implementation += footer.implementation;
4763
- target.implementationMock.handler += footer.implementationMock;
4840
+ for (const acc of target.mockOutputs) if (acc.implementation.handlerName) acc.implementation.handler = acc.implementation.handler + header.implementationMock + acc.implementation.handlerName + footer.implementationMock;
4764
4841
  }
4765
4842
  }
4766
4843
  return {
4767
- ...target,
4768
- implementationMock: target.implementationMock.function + target.implementationMock.handler
4844
+ imports: target.imports,
4845
+ implementation: target.implementation,
4846
+ mockOutputs: target.mockOutputs.map((m) => flattenMockOutput$1(m)),
4847
+ mutators: target.mutators,
4848
+ clientMutators: target.clientMutators,
4849
+ formData: target.formData,
4850
+ formUrlEncoded: target.formUrlEncoded,
4851
+ paramsSerializer: target.paramsSerializer,
4852
+ paramsFilter: target.paramsFilter,
4853
+ fetchReviver: target.fetchReviver
4769
4854
  };
4770
4855
  }
4771
4856
  //#endregion
@@ -4814,7 +4899,10 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
4814
4899
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
4815
4900
  extension: output.fileExtension
4816
4901
  });
4817
- const { imports, importsMock, implementation, implementationMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
4902
+ const { imports, mockOutputs: rawMockOutputs, implementation, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
4903
+ const mockOutputs = collapseInlineMockOutputs(rawMockOutputs);
4904
+ const implementationMock = mockOutputs.map((m) => m.implementation).join("\n\n");
4905
+ const importsMock = mockOutputs.flatMap((m) => m.imports);
4818
4906
  let data = header;
4819
4907
  const schemasPath = output.schemas ? getRelativeImportPath(path, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : void 0;
4820
4908
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
@@ -4842,16 +4930,17 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
4842
4930
  packageJson: output.packageJson,
4843
4931
  output
4844
4932
  });
4845
- if (output.mock) {
4846
- const filteredMockImports = importsMock.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? "")));
4933
+ for (const mockOutput of mockOutputs) {
4934
+ const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
4935
+ const filteredMockImports = mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? "")));
4847
4936
  const importsMockForBuilder = schemasPath ? generateImportsForBuilder(output, filteredMockImports, schemasPath) : generateImportsForBuilder(output, filteredMockImports.filter((imp) => !!imp.importPath), ".");
4848
4937
  data += builder.importsMock({
4849
- implementation: implementationMock,
4938
+ implementation: mockOutput.implementation,
4850
4939
  imports: importsMockForBuilder,
4851
4940
  projectName,
4852
4941
  hasSchemaDir: !!output.schemas,
4853
4942
  isAllowSyntheticDefaultImports,
4854
- options: isFunction(output.mock) ? void 0 : output.mock
4943
+ options: entry && !isFunction(entry) ? entry : void 0
4855
4944
  });
4856
4945
  }
4857
4946
  if (mutators) data += generateMutatorImports({
@@ -4874,7 +4963,7 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
4874
4963
  }
4875
4964
  if (!output.schemas && needSchema) data += generateSchemasInline ? generateSchemasInline() : generateModelsInline(builder.schemas);
4876
4965
  data += `${implementation.trim()}\n`;
4877
- if (output.mock) {
4966
+ if (mockOutputs.length > 0) {
4878
4967
  data += "\n\n";
4879
4968
  data += implementationMock;
4880
4969
  }
@@ -4893,9 +4982,8 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
4893
4982
  backupFilename: conventionName(builder.info.title ?? "filename", output.namingConvention),
4894
4983
  extension: output.fileExtension
4895
4984
  });
4896
- const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
4985
+ const { imports, implementation, mockOutputs, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, paramsFilter, fetchReviver } = generateTarget(builder, output);
4897
4986
  let implementationData = header;
4898
- let mockData = header;
4899
4987
  const relativeSchemasPath = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + extension.replace(/\.ts$/, "");
4900
4988
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
4901
4989
  const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
@@ -4912,15 +5000,6 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
4912
5000
  packageJson: output.packageJson,
4913
5001
  output
4914
5002
  });
4915
- const importsMockForBuilder = generateImportsForBuilder(output, importsMock, relativeSchemasPath);
4916
- mockData += builder.importsMock({
4917
- implementation: implementationMock,
4918
- imports: importsMockForBuilder,
4919
- projectName,
4920
- hasSchemaDir: !!output.schemas,
4921
- isAllowSyntheticDefaultImports,
4922
- options: isFunction(output.mock) ? void 0 : output.mock
4923
- });
4924
5003
  const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
4925
5004
  if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
4926
5005
  if (mutators) implementationData += generateMutatorImports({
@@ -4942,16 +5021,32 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
4942
5021
  implementationData += "\n";
4943
5022
  }
4944
5023
  implementationData += `\n${implementation}`;
4945
- mockData += `\n${implementationMock}`;
4946
5024
  const implementationFilename = filename + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
4947
5025
  const implementationPath = nodePath.join(dirname, implementationFilename);
4948
5026
  await writeGeneratedFile(implementationPath, implementationData);
4949
- const mockPath = output.mock ? nodePath.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
4950
- if (mockPath) await writeGeneratedFile(mockPath, mockData);
5027
+ const mockPaths = [];
5028
+ for (const mockOutput of mockOutputs) {
5029
+ const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
5030
+ if (!entry) continue;
5031
+ const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports, relativeSchemasPath);
5032
+ let mockData = header;
5033
+ mockData += builder.importsMock({
5034
+ implementation: mockOutput.implementation,
5035
+ imports: importsMockForBuilder,
5036
+ projectName,
5037
+ hasSchemaDir: !!output.schemas,
5038
+ isAllowSyntheticDefaultImports,
5039
+ options: entry
5040
+ });
5041
+ mockData += `\n${mockOutput.implementation}`;
5042
+ const mockPath = nodePath.join(dirname, filename + "." + getMockFileExtensionByTypeName(entry) + extension);
5043
+ await writeGeneratedFile(mockPath, mockData);
5044
+ mockPaths.push(mockPath);
5045
+ }
4951
5046
  return [
4952
5047
  implementationPath,
4953
5048
  ...schemasPath ? [schemasPath] : [],
4954
- ...mockPath ? [mockPath] : []
5049
+ ...mockPaths
4955
5050
  ];
4956
5051
  } catch (error) {
4957
5052
  throw new Error(`Oups... 🍻. An Error occurred while splitting => ${String(error)}`, { cause: error });
@@ -4971,12 +5066,63 @@ function addDefaultTagIfEmpty(operation) {
4971
5066
  tags: operation.tags.length > 0 ? operation.tags : [DefaultTag]
4972
5067
  };
4973
5068
  }
5069
+ function emptyMockOutputFull(type) {
5070
+ return {
5071
+ type,
5072
+ implementation: {
5073
+ function: "",
5074
+ handler: "",
5075
+ handlerName: ""
5076
+ },
5077
+ imports: []
5078
+ };
5079
+ }
5080
+ function flattenMockOutput(full) {
5081
+ return {
5082
+ type: full.type,
5083
+ implementation: full.implementation.function + full.implementation.handler,
5084
+ imports: full.imports
5085
+ };
5086
+ }
5087
+ function mergeOperationMockOutputs(accMockOutputs, opMockOutputs) {
5088
+ const result = accMockOutputs.map((m) => ({
5089
+ type: m.type,
5090
+ implementation: { ...m.implementation },
5091
+ imports: [...m.imports]
5092
+ }));
5093
+ for (const op of opMockOutputs) {
5094
+ let acc = result.find((m) => m.type === op.type);
5095
+ if (!acc) {
5096
+ acc = emptyMockOutputFull(op.type);
5097
+ result.push(acc);
5098
+ }
5099
+ acc.imports.push(...op.imports);
5100
+ acc.implementation.function += op.implementation.function;
5101
+ acc.implementation.handler += op.implementation.handler;
5102
+ if (op.implementation.handlerName) {
5103
+ const separator = acc.implementation.handlerName.length > 0 ? ",\n " : " ";
5104
+ acc.implementation.handlerName += separator + op.implementation.handlerName + "()";
5105
+ }
5106
+ }
5107
+ return result;
5108
+ }
5109
+ function initialMockOutputsForOperation(op) {
5110
+ return op.mockOutputs.map((m) => ({
5111
+ type: m.type,
5112
+ implementation: {
5113
+ function: m.implementation.function,
5114
+ handler: m.implementation.handler,
5115
+ handlerName: m.implementation.handlerName ? " " + m.implementation.handlerName + "()" : ""
5116
+ },
5117
+ imports: [...m.imports]
5118
+ }));
5119
+ }
4974
5120
  function generateTargetTags(currentAcc, operation) {
4975
5121
  const tag = kebab(operation.tags[0]);
4976
5122
  if (!(tag in currentAcc)) {
4977
5123
  currentAcc[tag] = {
4978
5124
  imports: operation.imports,
4979
- importsMock: operation.importsMock,
5125
+ mockOutputs: initialMockOutputsForOperation(operation),
4980
5126
  mutators: operation.mutator ? [operation.mutator] : [],
4981
5127
  clientMutators: operation.clientMutators ?? [],
4982
5128
  formData: operation.formData ? [operation.formData] : [],
@@ -4984,12 +5130,7 @@ function generateTargetTags(currentAcc, operation) {
4984
5130
  paramsSerializer: operation.paramsSerializer ? [operation.paramsSerializer] : [],
4985
5131
  paramsFilter: operation.paramsFilter ? [operation.paramsFilter] : [],
4986
5132
  fetchReviver: operation.fetchReviver ? [operation.fetchReviver] : [],
4987
- implementation: operation.implementation,
4988
- implementationMock: {
4989
- function: operation.implementationMock.function,
4990
- handler: operation.implementationMock.handler,
4991
- handlerName: " " + operation.implementationMock.handlerName + "()"
4992
- }
5133
+ implementation: operation.implementation
4993
5134
  };
4994
5135
  return currentAcc;
4995
5136
  }
@@ -4997,12 +5138,7 @@ function generateTargetTags(currentAcc, operation) {
4997
5138
  currentAcc[tag] = {
4998
5139
  implementation: currentOperation.implementation + operation.implementation,
4999
5140
  imports: [...currentOperation.imports, ...operation.imports],
5000
- importsMock: [...currentOperation.importsMock, ...operation.importsMock],
5001
- implementationMock: {
5002
- function: currentOperation.implementationMock.function + operation.implementationMock.function,
5003
- handler: currentOperation.implementationMock.handler + operation.implementationMock.handler,
5004
- handlerName: currentOperation.implementationMock.handlerName + ",\n " + operation.implementationMock.handlerName + "()"
5005
- },
5141
+ mockOutputs: mergeOperationMockOutputs(currentOperation.mockOutputs, operation.mockOutputs),
5006
5142
  mutators: operation.mutator ? [...currentOperation.mutators ?? [], operation.mutator] : currentOperation.mutators,
5007
5143
  clientMutators: operation.clientMutators ? [...currentOperation.clientMutators ?? [], ...operation.clientMutators] : currentOperation.clientMutators,
5008
5144
  formData: operation.formData ? [...currentOperation.formData ?? [], operation.formData] : currentOperation.formData,
@@ -5053,15 +5189,19 @@ function generateTargetForTags(builder, options) {
5053
5189
  isDefaultTagBucket: tag === "default" && Object.values(builder.operations).some((operation) => operation.tags.length === 0),
5054
5190
  clientImplementation: target.implementation
5055
5191
  });
5192
+ const wrappedMockOutputs = target.mockOutputs.map((m) => ({
5193
+ type: m.type,
5194
+ implementation: {
5195
+ function: m.implementation.function,
5196
+ handler: m.implementation.handlerName ? m.implementation.handler + header.implementationMock + m.implementation.handlerName + footer.implementationMock : m.implementation.handler,
5197
+ handlerName: m.implementation.handlerName
5198
+ },
5199
+ imports: m.imports
5200
+ }));
5056
5201
  transformed[tag] = {
5057
5202
  implementation: header.implementation + target.implementation + footer.implementation,
5058
- implementationMock: {
5059
- function: target.implementationMock.function,
5060
- handler: target.implementationMock.handler + header.implementationMock + target.implementationMock.handlerName + footer.implementationMock,
5061
- handlerName: target.implementationMock.handlerName
5062
- },
5203
+ mockOutputs: wrappedMockOutputs,
5063
5204
  imports: target.imports,
5064
- importsMock: target.importsMock,
5065
5205
  mutators: target.mutators,
5066
5206
  clientMutators: target.clientMutators,
5067
5207
  formData: target.formData,
@@ -5077,7 +5217,7 @@ function generateTargetForTags(builder, options) {
5077
5217
  const result = {};
5078
5218
  for (const [tag, target] of Object.entries(allTargetTags)) result[tag] = {
5079
5219
  ...target,
5080
- implementationMock: target.implementationMock.function + target.implementationMock.handler
5220
+ mockOutputs: target.mockOutputs.map((m) => flattenMockOutput(m))
5081
5221
  };
5082
5222
  return result;
5083
5223
  }
@@ -5090,15 +5230,20 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
5090
5230
  });
5091
5231
  const target = generateTargetForTags(builder, output);
5092
5232
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
5093
- const mockOption = output.mock && !isFunction(output.mock) ? output.mock : void 0;
5094
- const indexFilePath = mockOption?.indexMockFiles ? nodePath.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
5095
- if (indexFilePath) await fs$1.outputFile(indexFilePath, "");
5233
+ if (output.mock.generators.some((g) => isFunction(g))) throw new Error("Function mock generators (ClientMockBuilder) are not supported in tags-split mode. Use typed generators ({ type: \"msw\" } or { type: \"faker\" }).");
5234
+ const generatorEntries = output.mock.generators.filter((g) => !isFunction(g));
5235
+ const indexFilePathsByType = /* @__PURE__ */ new Map();
5236
+ if (output.mock.indexMockFiles) for (const entry of generatorEntries) {
5237
+ const ext = getMockFileExtensionByTypeName(entry);
5238
+ const indexPath = nodePath.join(dirname, `index.${ext}${extension}`);
5239
+ indexFilePathsByType.set(ext, indexPath);
5240
+ await fs$1.outputFile(indexPath, "");
5241
+ }
5096
5242
  const tagEntries = Object.entries(target);
5097
5243
  const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
5098
5244
  try {
5099
- const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer, paramsFilter } = target;
5245
+ const { imports, implementation, mockOutputs, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer, paramsFilter } = target;
5100
5246
  let implementationData = header;
5101
- let mockData = header;
5102
5247
  const importerPath = nodePath.join(dirname, tag, tag + extension);
5103
5248
  const relativeSchemasPath = output.schemas ? getRelativeImportPath(importerPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas" + extension.replace(/\.ts$/, "");
5104
5249
  const tagNames = new Set(tagEntries.map(([t]) => t));
@@ -5132,15 +5277,6 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
5132
5277
  packageJson: output.packageJson,
5133
5278
  output
5134
5279
  });
5135
- const importsMockForBuilder = generateImportsForBuilder(output, importsMock, relativeSchemasPath);
5136
- mockData += builder.importsMock({
5137
- implementation: implementationMock,
5138
- imports: importsMockForBuilder,
5139
- projectName,
5140
- hasSchemaDir: !!output.schemas,
5141
- isAllowSyntheticDefaultImports,
5142
- options: isFunction(output.mock) ? void 0 : output.mock
5143
- });
5144
5280
  const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
5145
5281
  if (schemasPath) await writeGeneratedFile(schemasPath, generateSchemasInline ? header + generateSchemasInline() : header + generateModelsInline(builder.schemas));
5146
5282
  if (mutators) implementationData += generateMutatorImports({
@@ -5181,29 +5317,48 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
5181
5317
  implementationData += "\n";
5182
5318
  }
5183
5319
  implementationData += `\n${implementation}`;
5184
- mockData += `\n${implementationMock}`;
5185
5320
  const implementationFilename = tag + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
5186
5321
  const implementationPath = nodePath.join(dirname, tag, implementationFilename);
5187
5322
  await writeGeneratedFile(implementationPath, implementationData);
5188
- const mockPath = output.mock ? nodePath.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
5189
- if (mockPath) await writeGeneratedFile(mockPath, mockData);
5323
+ const mockPaths = [];
5324
+ for (const mockOutput of mockOutputs) {
5325
+ const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
5326
+ if (!entry) continue;
5327
+ const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports, relativeSchemasPath);
5328
+ let mockData = header;
5329
+ mockData += builder.importsMock({
5330
+ implementation: mockOutput.implementation,
5331
+ imports: importsMockForBuilder,
5332
+ projectName,
5333
+ hasSchemaDir: !!output.schemas,
5334
+ isAllowSyntheticDefaultImports,
5335
+ options: entry
5336
+ });
5337
+ mockData += `\n${mockOutput.implementation}`;
5338
+ const mockPath = nodePath.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(entry) + extension);
5339
+ await writeGeneratedFile(mockPath, mockData);
5340
+ mockPaths.push(mockPath);
5341
+ }
5190
5342
  return [
5191
5343
  implementationPath,
5192
5344
  ...schemasPath ? [schemasPath] : [],
5193
- ...mockPath ? [mockPath] : []
5345
+ ...mockPaths
5194
5346
  ];
5195
5347
  } catch (error) {
5196
5348
  throw new Error(`Oups... 🍻. An Error occurred while splitting tag ${tag} => ${String(error)}`, { cause: error });
5197
5349
  }
5198
5350
  }));
5199
- if (indexFilePath && mockOption) {
5351
+ if (output.mock.indexMockFiles) for (const entry of generatorEntries) {
5352
+ const ext = getMockFileExtensionByTypeName(entry);
5353
+ const indexFilePath = indexFilePathsByType.get(ext);
5354
+ if (!indexFilePath) continue;
5200
5355
  const indexContent = tagEntries.map(([tag]) => {
5201
- const localMockPath = joinSafe("./", tag, tag + "." + getMockFileExtensionByTypeName(mockOption));
5202
- return `export { get${pascal(tag)}Mock } from '${localMockPath}'\n`;
5356
+ const localMockPath = joinSafe("./", tag, tag + "." + ext);
5357
+ return ext === OutputMockType.MSW ? `export { get${pascal(tag)}Mock } from '${localMockPath}'\n` : `export * from '${localMockPath}'\n`;
5203
5358
  }).join("");
5204
5359
  await fs$1.appendFile(indexFilePath, indexContent);
5205
5360
  }
5206
- return [...new Set([...indexFilePath ? [indexFilePath] : [], ...generatedFilePathsArray.flat()])];
5361
+ return [...new Set([...indexFilePathsByType.values(), ...generatedFilePathsArray.flat()])];
5207
5362
  }
5208
5363
  //#endregion
5209
5364
  //#region src/writers/tags-mode.ts
@@ -5216,7 +5371,10 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
5216
5371
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
5217
5372
  return (await Promise.all(Object.entries(target).map(async ([tag, target]) => {
5218
5373
  try {
5219
- const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer, paramsFilter } = target;
5374
+ const { imports, implementation, mockOutputs: rawMockOutputs, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer, paramsFilter } = target;
5375
+ const mockOutputs = collapseInlineMockOutputs(rawMockOutputs);
5376
+ const importsMock = mockOutputs.flatMap((m) => m.imports);
5377
+ const implementationMock = mockOutputs.map((m) => m.implementation).join("\n\n");
5220
5378
  let data = header;
5221
5379
  const schemasPathRelative = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas" + extension.replace(/\.ts$/, "");
5222
5380
  const normalizedImports = imports.filter((imp) => {
@@ -5243,15 +5401,16 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
5243
5401
  packageJson: output.packageJson,
5244
5402
  output
5245
5403
  });
5246
- if (output.mock) {
5247
- const importsMockForBuilder = generateImportsForBuilder(output, importsMock.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), schemasPathRelative);
5404
+ for (const mockOutput of mockOutputs) {
5405
+ const entry = output.mock.generators.find((g) => !isFunction(g) && g.type === mockOutput.type);
5406
+ const importsMockForBuilder = generateImportsForBuilder(output, mockOutput.imports.filter((impMock) => !normalizedImports.some((imp) => imp.name === impMock.name && (imp.alias ?? "") === (impMock.alias ?? ""))), schemasPathRelative);
5248
5407
  data += builder.importsMock({
5249
- implementation: implementationMock,
5408
+ implementation: mockOutput.implementation,
5250
5409
  imports: importsMockForBuilder,
5251
5410
  projectName,
5252
5411
  hasSchemaDir: !!output.schemas,
5253
5412
  isAllowSyntheticDefaultImports,
5254
- options: isFunction(output.mock) ? void 0 : output.mock
5413
+ options: entry && !isFunction(entry) ? entry : void 0
5255
5414
  });
5256
5415
  }
5257
5416
  const schemasPath = !output.schemas && needSchema ? nodePath.join(dirname, filename + ".schemas" + extension) : void 0;
@@ -5276,7 +5435,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
5276
5435
  data += "\n";
5277
5436
  }
5278
5437
  data += implementation;
5279
- if (output.mock) {
5438
+ if (mockOutputs.length > 0) {
5280
5439
  data += "\n\n";
5281
5440
  data += implementationMock;
5282
5441
  }
@@ -5289,6 +5448,6 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema,
5289
5448
  }))).flat();
5290
5449
  }
5291
5450
  //#endregion
5292
- export { BODY_TYPE_NAME, DefaultTag, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NAMED_COMPONENT_SECTIONS, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, SupportedFormatter, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, addDependency, asyncReduce, buildAngularParamsFilterExpression, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, escapeRegExp, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getAngularFilteredParamsCallExpression, getAngularFilteredParamsExpression, getAngularFilteredParamsHelperBody, getArray, getBaseUrlRuntimeImports, getBodiesByContentType, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getImportExtension, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSuccessResponseType, getTypedResponse, getWarningCount, isBinaryContentType, isBoolean, isComponentRef, isDirectory, isFunction, isModule, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
5451
+ export { BODY_TYPE_NAME, DefaultTag, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NAMED_COMPONENT_SECTIONS, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, SupportedFormatter, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, addDependency, asyncReduce, buildAngularParamsFilterExpression, camel, collectReferencedComponents, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, escapeRegExp, filterByContentType, filteredVerbs, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getAngularFilteredParamsCallExpression, getAngularFilteredParamsExpression, getAngularFilteredParamsHelperBody, getArray, getBaseUrlRuntimeImports, getBodiesByContentType, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getImportExtension, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getSuccessResponseType, getTypedResponse, getWarningCount, isBinaryContentType, isBoolean, isComponentRef, isDirectory, isFakerMock, isFunction, isModule, isMswMock, isNullish, isNumber, isNumeric, isObject, isReference, isSchema, isString, isStringLike, isSyntheticDefaultImportsAllow, isUrl, isVerb, isVerbose, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, logVerbose, logWarning, makeRouteSafe, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resetWarnings, resolveDiscriminators, resolveExampleRefs, resolveInstalledVersion, resolveInstalledVersions, resolveObject, resolveRef, resolveValue, sanitize, setVerbose, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, wrapRouteParameters, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
5293
5452
 
5294
5453
  //# sourceMappingURL=index.mjs.map