@orval/mock 8.15.0 → 8.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,4 @@
1
- import * as _$_orval_core0 from "@orval/core";
2
- import { ClientMockGeneratorBuilder, ContextSpec, FakerMockOptions, GenerateMockImports, GeneratorImport, GeneratorOptions, GeneratorSchema, GeneratorVerbOptions, GlobalMockOptions, MswMockOptions } from "@orval/core";
1
+ import { ClientMockGeneratorBuilder, ContextSpec, FakerMockOptions, FinalizeMockImplementationOptions, GenerateMockImports, GeneratorImport, GeneratorOptions, GeneratorSchema, GeneratorVerbOptions, GlobalMockOptions, MswMockOptions } from "@orval/core";
3
2
 
4
3
  //#region src/faker/index.d.ts
5
4
  /**
@@ -18,6 +17,7 @@ declare function generateFaker(generatorVerbOptions: GeneratorVerbOptions, gener
18
17
  interface GenerateFakerForSchemasResult {
19
18
  implementation: string;
20
19
  imports: GeneratorImport[];
20
+ strictMockSchemaTypeNames?: string[];
21
21
  }
22
22
  /**
23
23
  * Builds the contents of a consolidated faker mock file for every entry under
@@ -30,6 +30,17 @@ interface GenerateFakerForSchemasResult {
30
30
  */
31
31
  declare function generateFakerForSchemas(schemas: GeneratorSchema[], context: ContextSpec, options: GlobalMockOptions): GenerateFakerForSchemasResult;
32
32
  //#endregion
33
+ //#region src/mock-types.d.ts
34
+ declare function buildStrictMockTypeFileHeader(schemaTypeNames: Iterable<string>): string;
35
+ /**
36
+ * Prepends shared strict-mock helper types and each `{Schema}Mock` alias once at
37
+ * the top of a mock file. Generators pass `strictSchemaTypeNames`; no scraping.
38
+ *
39
+ * Not idempotent — callers must invoke this exactly once per aggregated mock
40
+ * file (writers and `writeFakerSchemaMocks`), not from import hooks.
41
+ */
42
+ declare function dedupeStrictMockTypeDeclarations(implementation: string, options?: FinalizeMockImplementationOptions): string;
43
+ //#endregion
33
44
  //#region src/msw/index.d.ts
34
45
  declare const generateMSWImports: GenerateMockImports;
35
46
  declare function generateMSW(generatorVerbOptions: GeneratorVerbOptions, generatorOptions: GeneratorOptions): ClientMockGeneratorBuilder;
@@ -55,7 +66,7 @@ declare const generateMockImports: GenerateMockImports;
55
66
  */
56
67
  declare function generateMock(generatorVerbOptions: GeneratorVerbOptions, generatorOptions: Omit<GeneratorOptions, 'mock'> & {
57
68
  mock: GlobalMockOptions;
58
- }): _$_orval_core0.ClientMockGeneratorBuilder;
69
+ }): import("@orval/core").ClientMockGeneratorBuilder;
59
70
  //#endregion
60
- export { DEFAULT_FAKER_OPTIONS, DEFAULT_MSW_OPTIONS, type GenerateFakerForSchemasResult, generateFaker, generateFakerForSchemas, generateFakerImports, generateMSW, generateMSWImports, generateMock, generateMockImports, getDefaultMockOptionsForType };
71
+ export { DEFAULT_FAKER_OPTIONS, DEFAULT_MSW_OPTIONS, type GenerateFakerForSchemasResult, buildStrictMockTypeFileHeader, dedupeStrictMockTypeDeclarations, generateFaker, generateFakerForSchemas, generateFakerImports, generateMSW, generateMSWImports, generateMock, generateMockImports, getDefaultMockOptionsForType };
61
72
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,5 +1,134 @@
1
- import { DefaultTag, EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camel, compareVersions, escape, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getRefInfo, isBoolean, isFunction, isMswMock, isNumber, isObject, isReference, isSchema, isString, kebab, mergeDeep, pascal, resolveRef, sanitize, stringify } from "@orval/core";
1
+ import { DefaultTag, EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camel, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getRefInfo, isBoolean, isFunction, isMswMock, isNumber, isObject, isReference, isSchema, isString, jsStringLiteralEscape, kebab, mergeDeep, pascal, resolveRef, sanitize, stringify } from "@orval/core";
2
2
  import { prop } from "remeda";
3
+ //#region src/mock-types.ts
4
+ function isStrictMock(mockOptions) {
5
+ return Boolean(mockOptions && mockOptions.required && mockOptions.nonNullable);
6
+ }
7
+ function getStrictMockTypeName(typeName) {
8
+ return `${typeName}Mock`;
9
+ }
10
+ function getStrictMockHelperTypeDeclarations() {
11
+ return `export type KeysWithNull<O> = {
12
+ [K in keyof O]-?: null extends O[K] ? K : never;
13
+ }[keyof O];
14
+
15
+ export type MockWithNullableOverrides<
16
+ T,
17
+ O extends Partial<T>,
18
+ M extends Record<keyof T, unknown>,
19
+ > = Omit<M, Extract<KeysWithNull<O>, keyof T>> & {
20
+ [K in Extract<KeysWithNull<O>, keyof T>]: M[K] | null;
21
+ };`;
22
+ }
23
+ function getStrictMockTypeDeclaration(typeName) {
24
+ return `export type ${getStrictMockTypeName(typeName)} = {\n [K in keyof Required<${typeName}>]: NonNullable<Required<${typeName}>[K]>;\n};`;
25
+ }
26
+ function getStrictMockTypeDeclarations(typeNames) {
27
+ const unique = [...new Set(typeNames)];
28
+ if (unique.length === 0) return "";
29
+ return unique.map((typeName) => getStrictMockTypeDeclaration(typeName)).join("\n\n");
30
+ }
31
+ function getMockFactoryReturnType(typeName, mockOptions) {
32
+ return isStrictMock(mockOptions) ? getStrictMockTypeName(typeName) : typeName;
33
+ }
34
+ function getMockFactorySignatureParts(typeName, mockOptions, options = {}) {
35
+ const isOverridable = options.isOverridable ?? false;
36
+ const overrideType = options.overrideType ?? `Partial<${typeName}>`;
37
+ const mockTypeName = getStrictMockTypeName(typeName);
38
+ if (!isOverridable) return {
39
+ param: "",
40
+ returnType: getMockFactoryReturnType(typeName, mockOptions),
41
+ returnCast: ""
42
+ };
43
+ if (isStrictMock(mockOptions)) return {
44
+ param: `<O extends ${overrideType} = {}>(overrideResponse?: O)`,
45
+ returnType: `MockWithNullableOverrides<${typeName}, O, ${mockTypeName}>`,
46
+ returnCast: ` as MockWithNullableOverrides<${typeName}, O, ${mockTypeName}>`
47
+ };
48
+ return {
49
+ param: `overrideResponse: ${overrideType} = {}`,
50
+ returnType: typeName,
51
+ returnCast: ""
52
+ };
53
+ }
54
+ function getSimpleSchemaReturnType(returnType, schemaTypeNames) {
55
+ const trimmed = returnType.trim();
56
+ return schemaTypeNames.includes(trimmed) ? trimmed : void 0;
57
+ }
58
+ function formatMockFactoryDeclaration(factoryName, param, returnType, body, returnCast, options) {
59
+ return `${param ? param.startsWith("<") ? `export const ${factoryName} = ${param}` : `export const ${factoryName} = (${param})` : `export const ${factoryName} = ()`}${options?.omitReturnType || !returnType ? "" : `: ${returnType}`} => (${body})${returnCast}${returnCast || options?.terminateStatement ? ";" : ""}`;
60
+ }
61
+ function getSchemaTypeNamesFromResponses(responses) {
62
+ const names = /* @__PURE__ */ new Set();
63
+ for (const response of responses) {
64
+ for (const imp of response.imports) {
65
+ if (imp.values || imp.schemaFactory) continue;
66
+ const importName = imp.alias ?? imp.name;
67
+ if (/^[A-Z]\w*$/.test(importName)) names.add(importName);
68
+ }
69
+ const { value } = response;
70
+ if (!value) continue;
71
+ const baseType = value.endsWith("[]") ? value.slice(0, -2) : value;
72
+ if (/^[A-Z]\w*$/.test(baseType)) names.add(baseType);
73
+ }
74
+ return [...names];
75
+ }
76
+ function buildStrictMockTypeFileHeader(schemaTypeNames) {
77
+ const schemaBlock = getStrictMockTypeDeclarations([...new Set(schemaTypeNames)]);
78
+ return [getStrictMockHelperTypeDeclarations(), schemaBlock].filter(Boolean).join("\n\n");
79
+ }
80
+ /**
81
+ * Prepends shared strict-mock helper types and each `{Schema}Mock` alias once at
82
+ * the top of a mock file. Generators pass `strictSchemaTypeNames`; no scraping.
83
+ *
84
+ * Not idempotent — callers must invoke this exactly once per aggregated mock
85
+ * file (writers and `writeFakerSchemaMocks`), not from import hooks.
86
+ */
87
+ function dedupeStrictMockTypeDeclarations(implementation, options = {}) {
88
+ if (!isStrictMock(options.mockOptions)) return implementation;
89
+ const schemaTypeNames = options.strictSchemaTypeNames ? [...new Set(options.strictSchemaTypeNames)] : [];
90
+ if (schemaTypeNames.length === 0) return implementation;
91
+ return `${buildStrictMockTypeFileHeader(schemaTypeNames)}\n\n${implementation.trimStart()}`;
92
+ }
93
+ function applyStrictMockReturnType(returnType, schemaTypeNames) {
94
+ if (schemaTypeNames.length === 0) return returnType;
95
+ let result = returnType;
96
+ const sorted = [...schemaTypeNames].toSorted((a, b) => b.length - a.length);
97
+ for (const name of sorted) result = result.replaceAll(new RegExp(String.raw`\b${escapeRegExp(name)}\b`, "g"), getStrictMockTypeName(name));
98
+ return result;
99
+ }
100
+ const STRICT_MOCK_SCHEMA_TYPE_FROM_OVERRIDES = /MockWithNullableOverrides<([A-Z]\w*),/g;
101
+ const STRICT_MOCK_SCHEMA_TYPE_FROM_OVERRIDE_ALIAS = /MockWithNullableOverrides<[^,]+,\s*[^,]+,\s*([A-Z]\w*Mock)>/g;
102
+ const STRICT_MOCK_SCHEMA_TYPE_FROM_MOCK_ALIAS_RETURN = /\): ([A-Z]\w*Mock)(?:\[\]|;)/g;
103
+ /** Inverse of {@link getStrictMockTypeName}: `PetMock` → `Pet`, `WidgetMockMock` → `WidgetMock`. */
104
+ function getSchemaTypeNameFromStrictMockAlias(alias) {
105
+ return alias.endsWith("Mock") ? alias.slice(0, -4) : alias;
106
+ }
107
+ /**
108
+ * Collect schema type names referenced by strict mock factories in generated
109
+ * implementation text (nested split factories, array item helpers, etc.).
110
+ *
111
+ * This reverse-parses emitted factory syntax and is therefore coupled to the
112
+ * current `formatMockFactoryDeclaration` / `getMockFactorySignatureParts`
113
+ * shape. The structurally robust alternative is to record each nested item's
114
+ * schema name where split factories are generated (array-item / faker getters,
115
+ * where the `$ref` name is known) and thread it into `strictMockSchemaTypeNames`.
116
+ */
117
+ function collectStrictMockSchemaTypeNamesFromImplementation(implementation) {
118
+ const names = /* @__PURE__ */ new Set();
119
+ for (const match of implementation.matchAll(STRICT_MOCK_SCHEMA_TYPE_FROM_OVERRIDES)) names.add(match[1]);
120
+ for (const pattern of [STRICT_MOCK_SCHEMA_TYPE_FROM_OVERRIDE_ALIAS, STRICT_MOCK_SCHEMA_TYPE_FROM_MOCK_ALIAS_RETURN]) for (const match of implementation.matchAll(pattern)) names.add(getSchemaTypeNameFromStrictMockAlias(match[1]));
121
+ return [...names];
122
+ }
123
+ function mergeStrictMockSchemaTypeNames(...groups) {
124
+ const names = /* @__PURE__ */ new Set();
125
+ for (const group of groups) {
126
+ if (!group) continue;
127
+ for (const name of group) names.add(name);
128
+ }
129
+ return names.size > 0 ? [...names] : void 0;
130
+ }
131
+ //#endregion
3
132
  //#region src/delay.ts
4
133
  const getDelay = (override, options) => {
5
134
  const mswOptions = options && isMswMock(options) ? options : void 0;
@@ -55,7 +184,7 @@ function getReferenceName$1(ref, context) {
55
184
  if (!ref) return "";
56
185
  return getRefInfo(ref, context).name;
57
186
  }
58
- function getMockObject({ item, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, splitMockImplementations, allowOverride = false }) {
187
+ function getMockObject({ item, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride = false }) {
59
188
  if (isReference(item)) return resolveMockValue({
60
189
  schema: {
61
190
  ...item,
@@ -68,6 +197,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
68
197
  context,
69
198
  imports,
70
199
  existingReferencedProperties,
200
+ existingReferencedAllOfRefs,
71
201
  splitMockImplementations
72
202
  });
73
203
  const schemaItem = item;
@@ -88,6 +218,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
88
218
  context,
89
219
  imports,
90
220
  existingReferencedProperties,
221
+ existingReferencedAllOfRefs,
91
222
  splitMockImplementations
92
223
  });
93
224
  if (Array.isArray(itemType)) {
@@ -108,6 +239,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
108
239
  context,
109
240
  imports,
110
241
  existingReferencedProperties,
242
+ existingReferencedAllOfRefs,
111
243
  splitMockImplementations
112
244
  });
113
245
  }
@@ -140,6 +272,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
140
272
  context,
141
273
  imports,
142
274
  existingReferencedProperties,
275
+ existingReferencedAllOfRefs: [],
143
276
  splitMockImplementations
144
277
  });
145
278
  imports.push(...resolvedValue.imports);
@@ -187,6 +320,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
187
320
  context,
188
321
  imports,
189
322
  existingReferencedProperties,
323
+ existingReferencedAllOfRefs: [],
190
324
  splitMockImplementations
191
325
  });
192
326
  return {
@@ -211,9 +345,12 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
211
345
  */
212
346
  function getArrayItemMockFileScope(context, tags) {
213
347
  const mode = context.output.mode;
214
- if (mode === OutputMode.TAGS || mode === OutputMode.TAGS_SPLIT) return `tag:${kebab(tags.length > 0 ? tags[0] : DefaultTag)}`;
215
- if (mode === OutputMode.SPLIT) return "split";
216
- return "single";
348
+ const mockType = context.activeMockOutputType ?? OutputMockType.MSW;
349
+ let base;
350
+ if (mode === OutputMode.TAGS || mode === OutputMode.TAGS_SPLIT) base = `tag:${kebab(tags.length > 0 ? tags[0] : DefaultTag)}`;
351
+ else if (mode === OutputMode.SPLIT) base = "split";
352
+ else base = "single";
353
+ return `${base}:${mockType}`;
217
354
  }
218
355
  function getFileLevelExtractedFactories(context, scope) {
219
356
  context.arrayItemMockFactories ??= /* @__PURE__ */ new Map();
@@ -224,11 +361,11 @@ function getFileLevelExtractedFactories(context, scope) {
224
361
  return factories;
225
362
  }
226
363
  /**
227
- * True when the active faker generator entry opts into reusable array-item
228
- * mock factories for object-like array item schemas in operation responses.
364
+ * True when any mock generator entry opts into reusable array-item mock
365
+ * factories for object-like array item schemas in operation responses.
229
366
  */
230
367
  function shouldExtractArrayItemFactories(context) {
231
- return !!context.output.mock.generators.find((g) => !isFunction(g) && g.type === OutputMockType.FAKER && g.arrayItems === true);
368
+ return context.output.mock.generators.some((g) => !isFunction(g) && g.arrayItems === true);
232
369
  }
233
370
  /**
234
371
  * True when `schemas: true` already emits a consolidated factory for this
@@ -327,7 +464,12 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
327
464
  const { factoryName, typeName } = names;
328
465
  const fileLevelFactories = getFileLevelExtractedFactories(context, getArrayItemMockFileScope(context, tags));
329
466
  if (!(fileLevelFactories.has(factoryName) || splitMockImplementations.some((f) => f.includes(`export const ${factoryName}`)))) {
330
- const func = `export const ${factoryName} = (${`${overrideVarName}: Partial<${typeName}> = {}`}): ${typeName} => ({${mapValue.startsWith("...") ? "" : "..."}${mapValue}, ...${overrideVarName}});`;
467
+ const mockOptions = context.output.override.mock;
468
+ const { param, returnType, returnCast } = getMockFactorySignatureParts(typeName, mockOptions, {
469
+ isOverridable: true,
470
+ overrideType: `Partial<${typeName}>`
471
+ });
472
+ const func = formatMockFactoryDeclaration(factoryName, param, returnType, `{${mapValue.startsWith("...") ? "" : "..."}${mapValue}, ...${overrideVarName}}`, returnCast, { terminateStatement: true });
331
473
  splitMockImplementations.push(func);
332
474
  fileLevelFactories.add(factoryName);
333
475
  }
@@ -336,7 +478,7 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
336
478
  }
337
479
  //#endregion
338
480
  //#region src/faker/getters/scalar.ts
339
- function getMockScalar({ item, imports, mockOptions, operationId, tags, combine, context, existingReferencedProperties, splitMockImplementations, allowOverride = false }) {
481
+ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine, context, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride = false }) {
340
482
  const safeMockOptions = mockOptions ?? {};
341
483
  const nonNullableOption = safeMockOptions.nonNullable;
342
484
  if (item.isRef) existingReferencedProperties = [...existingReferencedProperties, item.name];
@@ -458,6 +600,7 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
458
600
  context,
459
601
  imports,
460
602
  existingReferencedProperties,
603
+ existingReferencedAllOfRefs,
461
604
  splitMockImplementations
462
605
  });
463
606
  if (enums) return {
@@ -559,6 +702,7 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
559
702
  context,
560
703
  imports,
561
704
  existingReferencedProperties,
705
+ existingReferencedAllOfRefs,
562
706
  splitMockImplementations,
563
707
  allowOverride
564
708
  });
@@ -590,7 +734,7 @@ function getItemType(item) {
590
734
  }
591
735
  function getEnum(item, imports, context, existingReferencedProperties, type) {
592
736
  if (!item.enum) return "";
593
- let enumValue = `[${item.enum.filter((e) => e !== null).map((e) => type === "string" || type === void 0 && isString(e) ? `'${escape(e)}'` : e).join(",")}]`;
737
+ let enumValue = `[${item.enum.filter((e) => e !== null).map((e) => type === "string" || type === void 0 && isString(e) ? `'${jsStringLiteralEscape(e)}'` : e).join(",")}]`;
594
738
  if (context.output.override.enumGenerationType === EnumGeneration.ENUM) if (item.isRef || existingReferencedProperties.length === 0) {
595
739
  enumValue += ` as ${item.name}${item.name.endsWith("[]") ? "" : "[]"}`;
596
740
  imports.push({ name: item.name });
@@ -622,7 +766,8 @@ function stripArrayMarkerSegments(s) {
622
766
  function resolveMockOverride(properties = {}, item, nonNullableOption) {
623
767
  const path = item.path ?? `#.${item.name}`;
624
768
  const normalizedPath = stripArrayMarkerSegments(path);
625
- const property = Object.entries(properties).find(([key]) => {
769
+ const entries = Object.entries(properties);
770
+ let property = entries.find(([key]) => {
626
771
  if (isRegex(key)) {
627
772
  const regex = new RegExp(key.slice(1, -1));
628
773
  if (regex.test(item.name) || regex.test(path)) return true;
@@ -630,6 +775,7 @@ function resolveMockOverride(properties = {}, item, nonNullableOption) {
630
775
  if (`#.${stripArrayMarkerSegments(key)}` === normalizedPath) return true;
631
776
  return false;
632
777
  });
778
+ if (!property) property = entries.find(([key]) => !isRegex(key) && !key.includes(".") && key === item.name);
633
779
  if (!property) return;
634
780
  return {
635
781
  value: getNullable(property[1], isNullableSchema(item), nonNullableOption),
@@ -696,7 +842,7 @@ function hasOverrideTouchingSchema(schemaProperties, mockOptions, operationId, t
696
842
  });
697
843
  });
698
844
  }
699
- function resolveMockValue({ schema, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, splitMockImplementations, allowOverride }) {
845
+ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride }) {
700
846
  if (isReference(schema)) {
701
847
  const schemaReference = schema;
702
848
  const { name, refPaths } = getRefInfo(typeof schema.$ref === "string" ? schema.$ref : "", context);
@@ -757,6 +903,7 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
757
903
  context,
758
904
  imports,
759
905
  existingReferencedProperties,
906
+ existingReferencedAllOfRefs,
760
907
  splitMockImplementations,
761
908
  allowOverride
762
909
  });
@@ -764,9 +911,13 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
764
911
  const funcName = `get${pascal(operationId)}Response${pascal(newSchema.name)}Mock`;
765
912
  if (!splitMockImplementations.some((f) => f.includes(`export const ${funcName}`))) {
766
913
  const discriminatedProperty = newSchema.discriminator?.propertyName;
767
- let type = `Partial<${newSchema.name}>`;
768
- if (discriminatedProperty) type = `Omit<${type}, '${discriminatedProperty}'>`;
769
- const func = `export const ${funcName} = (${`${overrideVarName}: ${type} = {}`}): ${newSchema.name} => ({${scalar.value.startsWith("...") ? "" : "..."}${scalar.value}, ...${overrideVarName}});`;
914
+ let overrideType = `Partial<${newSchema.name}>`;
915
+ if (discriminatedProperty) overrideType = `Omit<${overrideType}, '${discriminatedProperty}'>`;
916
+ const { param, returnType, returnCast } = getMockFactorySignatureParts(newSchema.name, mockOptions, {
917
+ isOverridable: true,
918
+ overrideType
919
+ });
920
+ const func = formatMockFactoryDeclaration(funcName, param, returnType, `{${scalar.value.startsWith("...") ? "" : "..."}${scalar.value}, ...${overrideVarName}}`, returnCast, { terminateStatement: true });
770
921
  splitMockImplementations.push(func);
771
922
  }
772
923
  scalar.value = newSchema.nullable ? `${funcName}()` : `{...${funcName}()}`;
@@ -787,6 +938,7 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
787
938
  context,
788
939
  imports,
789
940
  existingReferencedProperties,
941
+ existingReferencedAllOfRefs,
790
942
  splitMockImplementations,
791
943
  allowOverride
792
944
  }),
@@ -817,7 +969,7 @@ function getReferenceName(ref, context) {
817
969
  if (!ref) return "";
818
970
  return getRefInfo(ref, context).name;
819
971
  }
820
- function combineSchemasMock({ item, separator, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, splitMockImplementations }) {
972
+ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations }) {
821
973
  const combineImports = [];
822
974
  const includedProperties = [...combine?.includedProperties ?? []];
823
975
  const separatorItems = item[separator] ?? [];
@@ -854,6 +1006,7 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
854
1006
  context,
855
1007
  imports,
856
1008
  existingReferencedProperties,
1009
+ existingReferencedAllOfRefs,
857
1010
  splitMockImplementations
858
1011
  }) : void 0;
859
1012
  includedProperties.push(...itemResolvedValue?.includedProperties ?? []);
@@ -867,7 +1020,7 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
867
1020
  let value = separator === "allOf" ? "" : "faker.helpers.arrayElement([";
868
1021
  for (const val of separatorItems) {
869
1022
  const refName = isReference(val) ? getReferenceName(val.$ref, context) : "";
870
- if (separator === "allOf" ? refName && (refName === item.name || existingReferencedProperties.includes(refName) && !item.isRef) : refName && existingReferencedProperties.includes(refName)) {
1023
+ if (separator === "allOf" ? refName && (refName === item.name || existingReferencedProperties.includes(refName) && !item.isRef || existingReferencedAllOfRefs.includes(refName)) : refName && existingReferencedProperties.includes(refName)) {
871
1024
  if (separatorItems.length === 1) value = "undefined";
872
1025
  continue;
873
1026
  }
@@ -897,6 +1050,7 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
897
1050
  context,
898
1051
  imports,
899
1052
  existingReferencedProperties,
1053
+ existingReferencedAllOfRefs: separator === "allOf" && refName ? [...existingReferencedAllOfRefs, refName] : [],
900
1054
  splitMockImplementations
901
1055
  });
902
1056
  combineImports.push(...resolvedValue.imports);
@@ -992,6 +1146,7 @@ function getMockWithoutFunc(spec, override) {
992
1146
  numberMin: override?.mock?.numberMin,
993
1147
  numberMax: override?.mock?.numberMax,
994
1148
  required: override?.mock?.required,
1149
+ nonNullable: override?.mock?.nonNullable,
995
1150
  fractionDigits: override?.mock?.fractionDigits,
996
1151
  ...override?.mock?.properties ? { properties: getMockPropertiesWithoutFunc(override.mock.properties, spec) } : {},
997
1152
  ...override?.mock?.format ? { format: getMockPropertiesWithoutFunc(override.mock.format, spec) } : {},
@@ -1190,7 +1345,28 @@ function generateDefinition(name, route, getResponseMockFunctionNameBase, handle
1190
1345
  const overrideResponseType = `Partial<Extract<${nonVoidMockReturnType}, object>>`;
1191
1346
  const shouldPreferJsonResponse = hasJsonContentType && !hasStringReturnType;
1192
1347
  const needsRuntimeContentTypeSwitch = isTextResponse && hasJsonContentType && hasStringReturnType && mockReturnType !== "string";
1193
- const mockImplementation = isReturnHttpResponse ? `${mockImplementations}export const ${getResponseMockFunctionName} = (${isResponseOverridable ? `overrideResponse: ${overrideResponseType} = {}` : ""})${mockData ? "" : `: ${nonVoidMockReturnType}`} => (${value})\n\n` : mockImplementations;
1348
+ const mockOptionsFromOverride = override.mock;
1349
+ const strictMock = isStrictMock(mockOptionsFromOverride);
1350
+ const schemaTypeNames = strictMock ? getSchemaTypeNamesFromResponses(responses) : [];
1351
+ const strictMockReturnType = strictMock ? applyStrictMockReturnType(nonVoidMockReturnType, schemaTypeNames) : nonVoidMockReturnType;
1352
+ const simpleSchemaReturnType = strictMock ? getSimpleSchemaReturnType(nonVoidMockReturnType, schemaTypeNames) : void 0;
1353
+ let mockFactoryParam = "";
1354
+ let mockFactoryReturnType = nonVoidMockReturnType;
1355
+ let mockFactoryReturnCast = "";
1356
+ if (isResponseOverridable) if (strictMock && simpleSchemaReturnType) {
1357
+ const signature = getMockFactorySignatureParts(simpleSchemaReturnType, mockOptionsFromOverride, {
1358
+ isOverridable: true,
1359
+ overrideType: overrideResponseType
1360
+ });
1361
+ mockFactoryParam = signature.param;
1362
+ mockFactoryReturnType = signature.returnType;
1363
+ mockFactoryReturnCast = signature.returnCast;
1364
+ } else {
1365
+ mockFactoryParam = `overrideResponse: ${overrideResponseType} = {}`;
1366
+ mockFactoryReturnType = strictMock ? strictMockReturnType : nonVoidMockReturnType;
1367
+ }
1368
+ else if (strictMock) mockFactoryReturnType = strictMockReturnType;
1369
+ const mockImplementation = isReturnHttpResponse ? `${mockImplementations}${formatMockFactoryDeclaration(getResponseMockFunctionName, mockFactoryParam, mockFactoryReturnType, value, mockFactoryReturnCast, { omitReturnType: Boolean(mockData) })}\n\n` : mockImplementations;
1194
1370
  const delay = getDelay(override, isFunction(mock) ? void 0 : mock);
1195
1371
  const infoParam = "info";
1196
1372
  const resolvedResponseExpr = `overrideResponse !== undefined
@@ -1260,35 +1436,40 @@ export const ${handlerName} = (overrideResponse?: ${mockReturnType} | ((${infoPa
1260
1436
  handlerName,
1261
1437
  handler: handlerImplementation
1262
1438
  },
1263
- imports: includeResponseImports
1439
+ imports: includeResponseImports,
1440
+ strictMockSchemaTypeNames: strictMock ? mergeStrictMockSchemaTypeNames(schemaTypeNames, collectStrictMockSchemaTypeNamesFromImplementation(mockImplementation)) : void 0
1264
1441
  };
1265
1442
  }
1266
1443
  function generateMSW(generatorVerbOptions, generatorOptions) {
1267
1444
  const { pathRoute, override, mock } = generatorOptions;
1268
- const { operationId, response } = generatorVerbOptions;
1445
+ const { operationName, response } = generatorVerbOptions;
1269
1446
  const overrideBaseUrl = override.mock && "baseUrl" in override.mock ? override.mock.baseUrl : void 0;
1270
1447
  const mockBaseUrl = mock && isMswMock(mock) ? mock.baseUrl : void 0;
1271
1448
  const route = getRouteMSW(pathRoute, overrideBaseUrl ?? mockBaseUrl);
1272
- const handlerName = `get${pascal(operationId)}MockHandler`;
1273
- const getResponseMockFunctionName = `get${pascal(operationId)}ResponseMock`;
1449
+ const handlerName = `get${pascal(operationName)}MockHandler`;
1450
+ const getResponseMockFunctionName = `get${pascal(operationName)}ResponseMock`;
1274
1451
  const splitMockImplementations = [];
1275
1452
  const baseDefinition = generateDefinition("", route, getResponseMockFunctionName, handlerName, generatorVerbOptions, generatorOptions, response.definition.success, response.types.success[0]?.key ?? "200", response.imports, response.types.success, response.contentTypes, splitMockImplementations);
1276
1453
  const mockImplementations = [baseDefinition.implementation.function];
1277
1454
  const handlerImplementations = [baseDefinition.implementation.handler];
1278
1455
  const imports = [...baseDefinition.imports];
1456
+ const strictMockSchemaTypeNames = new Set(baseDefinition.strictMockSchemaTypeNames);
1279
1457
  if (generatorOptions.mock && isObject(generatorOptions.mock) && generatorOptions.mock.generateEachHttpStatus) for (const statusResponse of [...response.types.success, ...response.types.errors]) {
1280
1458
  const definition = generateDefinition(statusResponse.key, route, getResponseMockFunctionName, handlerName, generatorVerbOptions, generatorOptions, statusResponse.value, statusResponse.key, response.imports, [statusResponse], [statusResponse.contentType], splitMockImplementations);
1281
1459
  mockImplementations.push(definition.implementation.function);
1282
1460
  handlerImplementations.push(definition.implementation.handler);
1283
1461
  imports.push(...definition.imports);
1462
+ for (const name of definition.strictMockSchemaTypeNames ?? []) strictMockSchemaTypeNames.add(name);
1284
1463
  }
1464
+ const aggregatedStrictNames = [...strictMockSchemaTypeNames];
1285
1465
  return {
1286
1466
  implementation: {
1287
1467
  function: mockImplementations.join("\n"),
1288
1468
  handlerName,
1289
1469
  handler: handlerImplementations.join("\n")
1290
1470
  },
1291
- imports
1471
+ imports,
1472
+ strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0
1292
1473
  };
1293
1474
  }
1294
1475
  //#endregion
@@ -1325,7 +1506,8 @@ function generateFaker(generatorVerbOptions, generatorOptions) {
1325
1506
  handler: "",
1326
1507
  handlerName: ""
1327
1508
  },
1328
- imports: result.imports
1509
+ imports: result.imports,
1510
+ strictMockSchemaTypeNames: result.strictMockSchemaTypeNames
1329
1511
  };
1330
1512
  }
1331
1513
  /**
@@ -1339,10 +1521,11 @@ function generateFaker(generatorVerbOptions, generatorOptions) {
1339
1521
  */
1340
1522
  function generateFakerForSchemas(schemas, context, options) {
1341
1523
  const factories = [];
1524
+ const strictMockTypeNames = /* @__PURE__ */ new Set();
1342
1525
  const allImports = [];
1343
1526
  const splitMockImplementations = [];
1344
1527
  const localFactoryNames = new Set(schemas.filter((s) => !!s.schema).map((s) => `get${pascal(s.name)}Mock`));
1345
- const mockOptions = context.output.override.mock;
1528
+ const mockOptions = getMockWithoutFunc(context.spec, context.output.override);
1346
1529
  for (const generatorSchema of schemas) {
1347
1530
  const { name, schema } = generatorSchema;
1348
1531
  if (!schema) continue;
@@ -1365,7 +1548,12 @@ function generateFakerForSchemas(schemas, context, options) {
1365
1548
  });
1366
1549
  allImports.push(...result.imports, ...factoryImports);
1367
1550
  const typeName = pascal(name);
1368
- const factory = `export const ${factoryName} = (${result.value.includes("overrideResponse") ? `overrideResponse: Partial<${typeName}> = {}` : ""}): ${typeName} => (${result.value});\n`;
1551
+ const { param, returnType, returnCast } = getMockFactorySignatureParts(typeName, mockOptions, {
1552
+ isOverridable: result.value.includes("overrideResponse"),
1553
+ overrideType: `Partial<${typeName}>`
1554
+ });
1555
+ const factory = formatMockFactoryDeclaration(factoryName, param, returnType, result.value, returnCast);
1556
+ if (isStrictMock(mockOptions)) strictMockTypeNames.add(typeName);
1369
1557
  factories.push(factory);
1370
1558
  allImports.push({
1371
1559
  name: pascal(name),
@@ -1384,9 +1572,12 @@ function generateFakerForSchemas(schemas, context, options) {
1384
1572
  if (!existing.values && imp.values) mergedImports.set(key, imp);
1385
1573
  }
1386
1574
  const uniqueImports = [...mergedImports.values()];
1575
+ const implementation = [...splitMockImplementations, ...factories].filter(Boolean).join("\n\n");
1576
+ const aggregatedStrictNames = [...strictMockTypeNames];
1387
1577
  return {
1388
- implementation: [...splitMockImplementations, ...factories].join("\n"),
1389
- imports: uniqueImports
1578
+ implementation,
1579
+ imports: uniqueImports,
1580
+ strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0
1390
1581
  };
1391
1582
  }
1392
1583
  //#endregion
@@ -1428,12 +1619,19 @@ const generateMockImports = (importOptions) => {
1428
1619
  * `output.mock.generators` is dispatched here individually.
1429
1620
  */
1430
1621
  function generateMock(generatorVerbOptions, generatorOptions) {
1431
- switch (generatorOptions.mock.type) {
1432
- case OutputMockType.FAKER: return generateFaker(generatorVerbOptions, generatorOptions);
1433
- default: return generateMSW(generatorVerbOptions, generatorOptions);
1622
+ const { context } = generatorOptions;
1623
+ const previousActiveMockOutputType = context.activeMockOutputType;
1624
+ context.activeMockOutputType = generatorOptions.mock.type;
1625
+ try {
1626
+ switch (generatorOptions.mock.type) {
1627
+ case OutputMockType.FAKER: return generateFaker(generatorVerbOptions, generatorOptions);
1628
+ default: return generateMSW(generatorVerbOptions, generatorOptions);
1629
+ }
1630
+ } finally {
1631
+ context.activeMockOutputType = previousActiveMockOutputType;
1434
1632
  }
1435
1633
  }
1436
1634
  //#endregion
1437
- export { DEFAULT_FAKER_OPTIONS, DEFAULT_MSW_OPTIONS, generateFaker, generateFakerForSchemas, generateFakerImports, generateMSW, generateMSWImports, generateMock, generateMockImports, getDefaultMockOptionsForType };
1635
+ export { DEFAULT_FAKER_OPTIONS, DEFAULT_MSW_OPTIONS, buildStrictMockTypeFileHeader, dedupeStrictMockTypeDeclarations, generateFaker, generateFakerForSchemas, generateFakerImports, generateMSW, generateMSWImports, generateMock, generateMockImports, getDefaultMockOptionsForType };
1438
1636
 
1439
1637
  //# sourceMappingURL=index.mjs.map