@orval/mock 8.17.0 → 8.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +409 -59
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camel, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getOperationTagKey, getRefInfo, isBoolean, isFunction, isMswMock, isNumber, isObject, isReference, isSchema, isString, jsStringLiteralEscape, mergeDeep, pascal, resolveRef, sanitize, stringify } from "@orval/core";
|
|
2
2
|
import { prop } from "remeda";
|
|
3
3
|
//#region src/mock-types.ts
|
|
4
4
|
function isStrictMock(mockOptions) {
|
|
@@ -20,13 +20,65 @@ export type MockWithNullableOverrides<
|
|
|
20
20
|
[K in Extract<KeysWithNull<O>, keyof T>]: M[K] | null;
|
|
21
21
|
};`;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
23
|
+
function classifyStrictMockSchemaType(schema, context) {
|
|
24
|
+
if (!schema) return "object";
|
|
25
|
+
if (schema.format === "binary" || schema.contentMediaType === "application/octet-stream" && !schema.contentEncoding) return "binary";
|
|
26
|
+
if (typeof schema.$ref === "string") {
|
|
27
|
+
if (context) {
|
|
28
|
+
const { schema: resolved } = resolveRef(schema, context);
|
|
29
|
+
return classifyStrictMockSchemaType(resolved, context);
|
|
30
|
+
}
|
|
31
|
+
return "object";
|
|
32
|
+
}
|
|
33
|
+
if (schema.type === "object" || schema.properties || isComposedObjectSchema(schema)) return "object";
|
|
34
|
+
return "alias";
|
|
35
|
+
}
|
|
36
|
+
function isComposedObjectSchema(schema) {
|
|
37
|
+
const branches = schema.oneOf ?? schema.anyOf ?? schema.allOf;
|
|
38
|
+
if (!branches?.length) return false;
|
|
39
|
+
return branches.some((branch) => {
|
|
40
|
+
const item = branch;
|
|
41
|
+
if (typeof item.$ref === "string" || item.type === "object" || item.properties) return true;
|
|
42
|
+
return isComposedObjectSchema(item);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function getStrictMockTypeDeclaration(typeName, kind = "object", options) {
|
|
46
|
+
const mockTypeName = getStrictMockTypeName(typeName);
|
|
47
|
+
if (kind === "alias") return `export type ${mockTypeName} = ${typeName};`;
|
|
48
|
+
if (kind === "binary") return `export type ${mockTypeName} = ArrayBuffer;`;
|
|
49
|
+
const mappedType = `{\n [K in keyof Required<NonNullable<${typeName}>>]: NonNullable<Required<NonNullable<${typeName}>>[K]>;\n}`;
|
|
50
|
+
return `export type ${mockTypeName} = ${options?.schemaNullableAtRoot ? `${mappedType} | null` : mappedType};`;
|
|
25
51
|
}
|
|
26
|
-
function getStrictMockTypeDeclarations(typeNames) {
|
|
52
|
+
function getStrictMockTypeDeclarations(typeNames, kinds, nullableAtRoot) {
|
|
27
53
|
const unique = [...new Set(typeNames)];
|
|
28
54
|
if (unique.length === 0) return "";
|
|
29
|
-
return unique.map((typeName) => getStrictMockTypeDeclaration(typeName)).join("\n\n");
|
|
55
|
+
return unique.map((typeName) => getStrictMockTypeDeclaration(typeName, kinds?.[typeName] ?? "object", { schemaNullableAtRoot: nullableAtRoot?.[typeName] })).join("\n\n");
|
|
56
|
+
}
|
|
57
|
+
function strictMockResolvedImportMatches(typeName, resolvedImport, importBareName) {
|
|
58
|
+
const resolvedName = resolvedImport?.name;
|
|
59
|
+
if (!resolvedName) return false;
|
|
60
|
+
if (typeName === resolvedName) return true;
|
|
61
|
+
if (resolvedImport.alias && typeName === resolvedImport.alias) return true;
|
|
62
|
+
return importBareName !== void 0 && importBareName === resolvedName;
|
|
63
|
+
}
|
|
64
|
+
function resolveStrictMockSchemaForTypeName(typeName, originalSchema, context, importBareName) {
|
|
65
|
+
if (!originalSchema) return;
|
|
66
|
+
if (!context) return originalSchema;
|
|
67
|
+
const branches = originalSchema.oneOf ?? originalSchema.anyOf ?? originalSchema.allOf;
|
|
68
|
+
if (branches?.length) {
|
|
69
|
+
for (const branch of branches) {
|
|
70
|
+
if (typeof branch.$ref !== "string") continue;
|
|
71
|
+
const resolved = resolveRef(branch, context);
|
|
72
|
+
if (strictMockResolvedImportMatches(typeName, resolved.imports[0], importBareName)) return resolved.schema;
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (typeof originalSchema.$ref === "string") {
|
|
77
|
+
const resolved = resolveRef(originalSchema, context);
|
|
78
|
+
if (strictMockResolvedImportMatches(typeName, resolved.imports[0], importBareName)) return resolved.schema;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
return originalSchema;
|
|
30
82
|
}
|
|
31
83
|
function getMockFactoryReturnType(typeName, mockOptions) {
|
|
32
84
|
return isStrictMock(mockOptions) ? getStrictMockTypeName(typeName) : typeName;
|
|
@@ -73,8 +125,33 @@ function getSchemaTypeNamesFromResponses(responses) {
|
|
|
73
125
|
}
|
|
74
126
|
return [...names];
|
|
75
127
|
}
|
|
76
|
-
function
|
|
77
|
-
const
|
|
128
|
+
function getStrictMockSchemaKindsFromResponses(responses, context) {
|
|
129
|
+
const kinds = {};
|
|
130
|
+
for (const response of responses) {
|
|
131
|
+
for (const imp of response.imports) {
|
|
132
|
+
if (imp.values || imp.schemaFactory) continue;
|
|
133
|
+
const importName = imp.alias ?? imp.name;
|
|
134
|
+
if (!/^[A-Z]\w*$/.test(importName)) continue;
|
|
135
|
+
const schemaForImport = resolveStrictMockSchemaForTypeName(importName, response.originalSchema, context, imp.name);
|
|
136
|
+
if (!schemaForImport) continue;
|
|
137
|
+
kinds[importName] = classifyStrictMockSchemaType(schemaForImport, context);
|
|
138
|
+
}
|
|
139
|
+
const { value } = response;
|
|
140
|
+
if (!value || !response.originalSchema) continue;
|
|
141
|
+
const baseType = value.endsWith("[]") ? value.slice(0, -2) : value;
|
|
142
|
+
if (!/^[A-Z]\w*$/.test(baseType)) continue;
|
|
143
|
+
const schema = response.originalSchema;
|
|
144
|
+
if (value.endsWith("[]") && schema.type === "array" && schema.items) {
|
|
145
|
+
const items = schema.items;
|
|
146
|
+
kinds[baseType] = classifyStrictMockSchemaType(items, context);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
kinds[baseType] = classifyStrictMockSchemaType(resolveStrictMockSchemaForTypeName(baseType, response.originalSchema, context) ?? response.originalSchema, context);
|
|
150
|
+
}
|
|
151
|
+
return kinds;
|
|
152
|
+
}
|
|
153
|
+
function buildStrictMockTypeFileHeader(schemaTypeNames, kinds) {
|
|
154
|
+
const schemaBlock = getStrictMockTypeDeclarations([...new Set(schemaTypeNames)], kinds);
|
|
78
155
|
return [getStrictMockHelperTypeDeclarations(), schemaBlock].filter(Boolean).join("\n\n");
|
|
79
156
|
}
|
|
80
157
|
/**
|
|
@@ -88,7 +165,7 @@ function dedupeStrictMockTypeDeclarations(implementation, options = {}) {
|
|
|
88
165
|
if (!isStrictMock(options.mockOptions)) return implementation;
|
|
89
166
|
const schemaTypeNames = options.strictSchemaTypeNames ? [...new Set(options.strictSchemaTypeNames)] : [];
|
|
90
167
|
if (schemaTypeNames.length === 0) return implementation;
|
|
91
|
-
return `${buildStrictMockTypeFileHeader(schemaTypeNames)}\n\n${implementation.trimStart()}`;
|
|
168
|
+
return `${buildStrictMockTypeFileHeader(schemaTypeNames, options.strictMockSchemaKinds)}\n\n${implementation.trimStart()}`;
|
|
92
169
|
}
|
|
93
170
|
function applyStrictMockReturnType(returnType, schemaTypeNames) {
|
|
94
171
|
if (schemaTypeNames.length === 0) return returnType;
|
|
@@ -128,6 +205,54 @@ function mergeStrictMockSchemaTypeNames(...groups) {
|
|
|
128
205
|
}
|
|
129
206
|
return names.size > 0 ? [...names] : void 0;
|
|
130
207
|
}
|
|
208
|
+
function mergeStrictMockSchemaKinds(...groups) {
|
|
209
|
+
const merged = {};
|
|
210
|
+
for (const group of groups) {
|
|
211
|
+
if (!group) continue;
|
|
212
|
+
for (const [name, kind] of Object.entries(group)) merged[name] ??= kind;
|
|
213
|
+
}
|
|
214
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
215
|
+
}
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/faker/imports.ts
|
|
218
|
+
/**
|
|
219
|
+
* Appends entries added to `source` since `sinceIndex`. Uses indexed push
|
|
220
|
+
* instead of spread so large import batches (common with `schemas: true`
|
|
221
|
+
* delegation on wide objects) do not overflow the call stack.
|
|
222
|
+
*/
|
|
223
|
+
function appendImportsDelta(target, source, sinceIndex) {
|
|
224
|
+
for (let i = sinceIndex; i < source.length; i++) target.push(source[i]);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Merge imports returned from mock resolution when the shared imports array
|
|
228
|
+
* was not mutated in place. Enum mocks and nested object factories return
|
|
229
|
+
* their imports separately; schema-factory delegation mutates `sharedImports`
|
|
230
|
+
* directly and must not be merged again from `resolvedImports`.
|
|
231
|
+
*/
|
|
232
|
+
function mergeReturnedMockImports(sharedImports, sharedBefore, resolvedImports) {
|
|
233
|
+
if (sharedImports.length === sharedBefore) appendImportsDelta(sharedImports, resolvedImports, 0);
|
|
234
|
+
}
|
|
235
|
+
/** Recover type imports referenced by nested oneOf split mock helpers. */
|
|
236
|
+
function collectSplitMockTypeImports(implementations) {
|
|
237
|
+
const seen = /* @__PURE__ */ new Set();
|
|
238
|
+
const imports = [];
|
|
239
|
+
const addType = (name) => {
|
|
240
|
+
if (!name || seen.has(name)) return;
|
|
241
|
+
seen.add(name);
|
|
242
|
+
imports.push({
|
|
243
|
+
name,
|
|
244
|
+
values: false
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
for (const impl of implementations) {
|
|
248
|
+
for (const match of impl.matchAll(/export const get\w+Mock = \(\s*overrideResponse: Partial<(\w+)[^)]*\):\s*(\w+)\s*=>/g)) {
|
|
249
|
+
addType(match[1]);
|
|
250
|
+
addType(match[2]);
|
|
251
|
+
}
|
|
252
|
+
for (const match of impl.matchAll(/export const get\w+Mock[\s\S]*?MockWithNullableOverrides<(?:Extract<(\w+),[^>]+>|(\w+)),/g)) addType(match[1] ?? match[2]);
|
|
253
|
+
}
|
|
254
|
+
return imports;
|
|
255
|
+
}
|
|
131
256
|
//#endregion
|
|
132
257
|
//#region src/delay.ts
|
|
133
258
|
const getDelay = (override, options) => {
|
|
@@ -180,6 +305,13 @@ const DEFAULT_OBJECT_KEY_MOCK = "faker.string.alphanumeric(5)";
|
|
|
180
305
|
//#endregion
|
|
181
306
|
//#region src/faker/getters/object.ts
|
|
182
307
|
const overrideVarName = "overrideResponse";
|
|
308
|
+
function wrapRootNullableObjectValue(value, schemaItem, mockOptions, combine) {
|
|
309
|
+
const nullableAtRoot = !combine && isNullableSchema(schemaItem) && !mockOptions?.nonNullable;
|
|
310
|
+
return {
|
|
311
|
+
value: nullableAtRoot ? getNullable(value, true) : value,
|
|
312
|
+
nullWrapped: nullableAtRoot
|
|
313
|
+
};
|
|
314
|
+
}
|
|
183
315
|
function getReferenceName$1(ref, context) {
|
|
184
316
|
if (!ref) return "";
|
|
185
317
|
return getRefInfo(ref, context).name;
|
|
@@ -222,10 +354,44 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
222
354
|
splitMockImplementations
|
|
223
355
|
});
|
|
224
356
|
if (Array.isArray(itemType)) {
|
|
357
|
+
const nonNullTypes = mockOptions?.nonNullable ? itemType.filter((type) => type !== "null") : itemType;
|
|
358
|
+
if (nonNullTypes.length === 0) return {
|
|
359
|
+
value: "null",
|
|
360
|
+
imports: [],
|
|
361
|
+
name: schemaItem.name
|
|
362
|
+
};
|
|
363
|
+
if (nonNullTypes.length === 1) return getMockObject({
|
|
364
|
+
item: {
|
|
365
|
+
...schemaItem,
|
|
366
|
+
type: nonNullTypes[0]
|
|
367
|
+
},
|
|
368
|
+
mockOptions,
|
|
369
|
+
operationId,
|
|
370
|
+
tags,
|
|
371
|
+
combine,
|
|
372
|
+
context,
|
|
373
|
+
imports,
|
|
374
|
+
existingReferencedProperties,
|
|
375
|
+
existingReferencedAllOfRefs,
|
|
376
|
+
splitMockImplementations,
|
|
377
|
+
allowOverride
|
|
378
|
+
});
|
|
379
|
+
if (!itemProperties && (!itemRequired || itemRequired.length === 0) && !itemAdditionalProperties && nonNullTypes.includes("object") && nonNullTypes.includes("null") && nonNullTypes.every((type) => type === "object" || type === "null")) {
|
|
380
|
+
if (mockOptions?.nonNullable) return {
|
|
381
|
+
value: "{}",
|
|
382
|
+
imports: [],
|
|
383
|
+
name: schemaItem.name
|
|
384
|
+
};
|
|
385
|
+
return {
|
|
386
|
+
value: "faker.helpers.arrayElement([{}, null])",
|
|
387
|
+
imports: [],
|
|
388
|
+
name: schemaItem.name
|
|
389
|
+
};
|
|
390
|
+
}
|
|
225
391
|
const baseItem = schemaItem;
|
|
226
392
|
return combineSchemasMock({
|
|
227
393
|
item: {
|
|
228
|
-
anyOf:
|
|
394
|
+
anyOf: nonNullTypes.map((type) => ({
|
|
229
395
|
...baseItem,
|
|
230
396
|
type
|
|
231
397
|
})),
|
|
@@ -259,6 +425,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
259
425
|
if (isRequired) return `${getKey(key)}: null`;
|
|
260
426
|
return;
|
|
261
427
|
}
|
|
428
|
+
const importsBefore = imports.length;
|
|
262
429
|
const resolvedValue = resolveMockValue({
|
|
263
430
|
schema: {
|
|
264
431
|
...prop,
|
|
@@ -275,7 +442,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
275
442
|
existingReferencedAllOfRefs: [],
|
|
276
443
|
splitMockImplementations
|
|
277
444
|
});
|
|
278
|
-
imports
|
|
445
|
+
mergeReturnedMockImports(imports, importsBefore, resolvedValue.imports);
|
|
279
446
|
includedProperties.push(key);
|
|
280
447
|
const keyDefinition = getKey(key);
|
|
281
448
|
const hasDefault = "default" in prop && prop.default !== void 0;
|
|
@@ -289,25 +456,35 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
289
456
|
if (allowOverride) propertyScalars.push(`...${overrideVarName}`);
|
|
290
457
|
value += propertyScalars.join(", ");
|
|
291
458
|
value += !combine || combine.separator === "oneOf" || combine.separator === "anyOf" ? "}" : "";
|
|
459
|
+
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue(value, schemaItem, mockOptions, combine);
|
|
292
460
|
return {
|
|
293
|
-
value,
|
|
461
|
+
value: finalValue,
|
|
462
|
+
nullWrapped,
|
|
294
463
|
imports,
|
|
295
464
|
name: schemaItem.name,
|
|
296
465
|
includedProperties
|
|
297
466
|
};
|
|
298
467
|
}
|
|
299
468
|
if (itemAdditionalProperties) {
|
|
300
|
-
if (itemAdditionalProperties === true)
|
|
301
|
-
value: `{}`,
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
469
|
+
if (itemAdditionalProperties === true) {
|
|
470
|
+
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue(`{}`, schemaItem, mockOptions, combine);
|
|
471
|
+
return {
|
|
472
|
+
value: finalValue,
|
|
473
|
+
nullWrapped,
|
|
474
|
+
imports: [],
|
|
475
|
+
name: schemaItem.name
|
|
476
|
+
};
|
|
477
|
+
}
|
|
305
478
|
const additionalProperties = itemAdditionalProperties;
|
|
306
|
-
if (isReference(additionalProperties) && existingReferencedProperties.includes(getReferenceName$1(additionalProperties.$ref, context)))
|
|
307
|
-
value: `{}`,
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
479
|
+
if (isReference(additionalProperties) && existingReferencedProperties.includes(getReferenceName$1(additionalProperties.$ref, context))) {
|
|
480
|
+
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue(`{}`, schemaItem, mockOptions, combine);
|
|
481
|
+
return {
|
|
482
|
+
value: finalValue,
|
|
483
|
+
nullWrapped,
|
|
484
|
+
imports: [],
|
|
485
|
+
name: schemaItem.name
|
|
486
|
+
};
|
|
487
|
+
}
|
|
311
488
|
const resolvedValue = resolveMockValue({
|
|
312
489
|
schema: {
|
|
313
490
|
...additionalProperties,
|
|
@@ -323,15 +500,19 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
323
500
|
existingReferencedAllOfRefs: [],
|
|
324
501
|
splitMockImplementations
|
|
325
502
|
});
|
|
503
|
+
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue(`{
|
|
504
|
+
[${DEFAULT_OBJECT_KEY_MOCK}]: ${resolvedValue.value}
|
|
505
|
+
}`, schemaItem, mockOptions, combine);
|
|
326
506
|
return {
|
|
327
507
|
...resolvedValue,
|
|
328
|
-
value:
|
|
329
|
-
|
|
330
|
-
}`
|
|
508
|
+
value: finalValue,
|
|
509
|
+
nullWrapped
|
|
331
510
|
};
|
|
332
511
|
}
|
|
512
|
+
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue("{}", schemaItem, mockOptions, combine);
|
|
333
513
|
return {
|
|
334
|
-
value:
|
|
514
|
+
value: finalValue,
|
|
515
|
+
nullWrapped,
|
|
335
516
|
imports: [],
|
|
336
517
|
name: schemaItem.name
|
|
337
518
|
};
|
|
@@ -347,7 +528,7 @@ function getArrayItemMockFileScope(context, tags) {
|
|
|
347
528
|
const mode = context.output.mode;
|
|
348
529
|
const mockType = context.activeMockOutputType ?? OutputMockType.MSW;
|
|
349
530
|
let base;
|
|
350
|
-
if (mode === OutputMode.TAGS || mode === OutputMode.TAGS_SPLIT) base = `tag:${
|
|
531
|
+
if (mode === OutputMode.TAGS || mode === OutputMode.TAGS_SPLIT) base = `tag:${getOperationTagKey({ tags })}`;
|
|
351
532
|
else if (mode === OutputMode.SPLIT) base = "split";
|
|
352
533
|
else base = "single";
|
|
353
534
|
return `${base}:${mockType}`;
|
|
@@ -463,8 +644,8 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
|
|
|
463
644
|
if (!names) return;
|
|
464
645
|
const { factoryName, typeName } = names;
|
|
465
646
|
const fileLevelFactories = getFileLevelExtractedFactories(context, getArrayItemMockFileScope(context, tags));
|
|
647
|
+
const mockOptions = context.output.override.mock;
|
|
466
648
|
if (!(fileLevelFactories.has(factoryName) || splitMockImplementations.some((f) => f.includes(`export const ${factoryName}`)))) {
|
|
467
|
-
const mockOptions = context.output.override.mock;
|
|
468
649
|
const { param, returnType, returnCast } = getMockFactorySignatureParts(typeName, mockOptions, {
|
|
469
650
|
isOverridable: true,
|
|
470
651
|
overrideType: `Partial<${typeName}>`
|
|
@@ -474,7 +655,116 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
|
|
|
474
655
|
fileLevelFactories.add(factoryName);
|
|
475
656
|
}
|
|
476
657
|
imports.push({ name: typeName });
|
|
477
|
-
return `{...${factoryName}()}`;
|
|
658
|
+
return `{...${factoryName}()${isStrictMock(mockOptions) ? ` as ${getStrictMockTypeName(typeName)}` : ""}}`;
|
|
659
|
+
}
|
|
660
|
+
//#endregion
|
|
661
|
+
//#region src/faker/format-example-value.ts
|
|
662
|
+
const DATE_FORMATS = new Set(["date", "date-time"]);
|
|
663
|
+
function isDateFormat(format) {
|
|
664
|
+
return format !== void 0 && DATE_FORMATS.has(format);
|
|
665
|
+
}
|
|
666
|
+
function isSchemaObject(schema) {
|
|
667
|
+
return typeof schema === "object" && schema !== null && !Array.isArray(schema);
|
|
668
|
+
}
|
|
669
|
+
function resolveSchema(schema, context) {
|
|
670
|
+
if (!schema) return;
|
|
671
|
+
if (isReference(schema)) return resolveRef(schema, context).schema;
|
|
672
|
+
return schema;
|
|
673
|
+
}
|
|
674
|
+
function mergePropertySchemas(...schemas) {
|
|
675
|
+
const merged = {};
|
|
676
|
+
for (const schema of schemas) {
|
|
677
|
+
if (!schema?.properties) continue;
|
|
678
|
+
for (const [key, prop] of Object.entries(schema.properties)) if (isSchemaObject(prop)) merged[key] = prop;
|
|
679
|
+
}
|
|
680
|
+
return merged;
|
|
681
|
+
}
|
|
682
|
+
function getEffectiveScalarFormat(resolved, context) {
|
|
683
|
+
if (!resolved) return;
|
|
684
|
+
if (isDateFormat(resolved.format)) return resolved.format;
|
|
685
|
+
const oneOf = resolved.oneOf;
|
|
686
|
+
const anyOf = resolved.anyOf;
|
|
687
|
+
for (const variant of [...oneOf ?? [], ...anyOf ?? []]) {
|
|
688
|
+
const resolvedVariant = resolveSchema(isReference(variant) || isSchemaObject(variant) ? variant : void 0, context);
|
|
689
|
+
if (isDateFormat(resolvedVariant?.format)) return resolvedVariant.format;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Resolves compositional schemas (allOf / oneOf / anyOf) so example formatting
|
|
694
|
+
* can see property formats on nested and referenced types.
|
|
695
|
+
*/
|
|
696
|
+
function resolveExampleSchema(schema, context, seenRefs = /* @__PURE__ */ new Set()) {
|
|
697
|
+
if (!schema) return;
|
|
698
|
+
if (isReference(schema)) {
|
|
699
|
+
const ref = schema.$ref;
|
|
700
|
+
if (ref && seenRefs.has(ref)) return resolveRef(schema, context).schema;
|
|
701
|
+
if (ref) seenRefs = new Set(seenRefs).add(ref);
|
|
702
|
+
}
|
|
703
|
+
const resolved = resolveSchema(schema, context);
|
|
704
|
+
if (!resolved) return;
|
|
705
|
+
const allOf = resolved.allOf;
|
|
706
|
+
const oneOf = resolved.oneOf;
|
|
707
|
+
const anyOf = resolved.anyOf;
|
|
708
|
+
const compositors = [
|
|
709
|
+
...allOf ?? [],
|
|
710
|
+
...oneOf ?? [],
|
|
711
|
+
...anyOf ?? []
|
|
712
|
+
];
|
|
713
|
+
const properties = mergePropertySchemas(resolved, ...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
714
|
+
const baseResolved = resolved;
|
|
715
|
+
if (resolved.type === "array" && isSchemaObject(resolved.items)) {
|
|
716
|
+
const items = resolveExampleSchema(resolved.items, context, seenRefs);
|
|
717
|
+
const itemProperties = items?.properties;
|
|
718
|
+
const normalizedItems = itemProperties && Object.keys(itemProperties).length > 0 ? {
|
|
719
|
+
type: "object",
|
|
720
|
+
properties: itemProperties
|
|
721
|
+
} : items;
|
|
722
|
+
return {
|
|
723
|
+
...baseResolved,
|
|
724
|
+
...Object.keys(properties).length > 0 ? { properties } : {},
|
|
725
|
+
items: normalizedItems ?? resolved.items
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (Object.keys(properties).length > 0) return {
|
|
729
|
+
...baseResolved,
|
|
730
|
+
properties
|
|
731
|
+
};
|
|
732
|
+
if (compositors.length > 0 && (oneOf ?? anyOf)) {
|
|
733
|
+
const variantProperties = mergePropertySchemas(...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
734
|
+
if (Object.keys(variantProperties).length > 0) return {
|
|
735
|
+
type: "object",
|
|
736
|
+
properties: variantProperties
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
const scalarFormat = getEffectiveScalarFormat(resolved, context);
|
|
740
|
+
if (scalarFormat) return {
|
|
741
|
+
...baseResolved,
|
|
742
|
+
format: scalarFormat
|
|
743
|
+
};
|
|
744
|
+
return resolved;
|
|
745
|
+
}
|
|
746
|
+
function formatLiteralValue(example, schema, context) {
|
|
747
|
+
if (example === null) return "null";
|
|
748
|
+
if (example === void 0) return "undefined";
|
|
749
|
+
const resolved = resolveExampleSchema(schema, context);
|
|
750
|
+
if (Array.isArray(example)) {
|
|
751
|
+
const itemsSchema = resolved?.type === "array" && isSchemaObject(resolved.items) ? resolveExampleSchema(resolved.items, context) : resolved;
|
|
752
|
+
return `[${example.map((item) => formatLiteralValue(item, itemsSchema, context)).join(", ")}]`;
|
|
753
|
+
}
|
|
754
|
+
if (typeof example === "object") {
|
|
755
|
+
const properties = resolved?.properties ?? {};
|
|
756
|
+
return `{ ${Object.entries(example).map(([key, value]) => {
|
|
757
|
+
const propSchema = properties[key];
|
|
758
|
+
const resolvedProp = isSchemaObject(propSchema) ? resolveExampleSchema(propSchema, context) : void 0;
|
|
759
|
+
return `${/^[a-zA-Z_$][\w$]*$/.test(key) ? key : JSON.stringify(key)}: ${formatLiteralValue(value, resolvedProp, context)}`;
|
|
760
|
+
}).join(", ")} }`;
|
|
761
|
+
}
|
|
762
|
+
if (context.output.override.useDates && typeof example === "string" && isDateFormat(getEffectiveScalarFormat(resolved, context))) return `new Date(${JSON.stringify(example)})`;
|
|
763
|
+
return JSON.stringify(example);
|
|
764
|
+
}
|
|
765
|
+
function formatSchemaExampleValue(example, schema, context) {
|
|
766
|
+
if (!context.output.override.useDates || schema === void 0) return JSON.stringify(example);
|
|
767
|
+
return formatLiteralValue(example, schema, context);
|
|
478
768
|
}
|
|
479
769
|
//#endregion
|
|
480
770
|
//#region src/faker/getters/scalar.ts
|
|
@@ -492,12 +782,15 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
492
782
|
}
|
|
493
783
|
const tagProperty = resolveMockOverride(overrideTag.properties, item, nonNullableOption);
|
|
494
784
|
if (tagProperty) return tagProperty;
|
|
785
|
+
const schemaName = item.parentName;
|
|
786
|
+
const schemaProperty = schemaName ? resolveMockOverride(safeMockOptions.schemas?.[schemaName]?.properties, item, nonNullableOption) : void 0;
|
|
787
|
+
if (schemaProperty) return schemaProperty;
|
|
495
788
|
const property = resolveMockOverride(safeMockOptions.properties, item, nonNullableOption);
|
|
496
789
|
if (property) return property;
|
|
497
790
|
if (context.output.override.mock?.useExamples || safeMockOptions.useExamples) {
|
|
498
791
|
const propertyExample = item.example === void 0 ? Array.isArray(item.examples) && item.examples.length > 0 ? item.examples[0] : void 0 : item.example;
|
|
499
792
|
if (propertyExample !== void 0) return {
|
|
500
|
-
value:
|
|
793
|
+
value: formatSchemaExampleValue(propertyExample, item, context),
|
|
501
794
|
imports: [],
|
|
502
795
|
name: item.name,
|
|
503
796
|
overrided: true
|
|
@@ -820,6 +1113,11 @@ function isComponentsSchemaRef(refPaths) {
|
|
|
820
1113
|
* the schema body so the override actually applies; the shared
|
|
821
1114
|
* `get<X>Mock` factory has no knowledge of operation-scoped overrides.
|
|
822
1115
|
*
|
|
1116
|
+
* Schema-scoped overrides (`override.mock.schemas`) need no special handling
|
|
1117
|
+
* here: they target a schema's *own* properties, so the schema's `get<X>Mock`
|
|
1118
|
+
* factory — built with the same mock options — already bakes them in, and
|
|
1119
|
+
* delegating to it preserves the override.
|
|
1120
|
+
*
|
|
823
1121
|
* Reuses `resolveMockOverride` so the same matching rules apply as for
|
|
824
1122
|
* regular property mocks — bare name, regex (`/.../`), and exact-path
|
|
825
1123
|
* (`#.foo.bar`). The parent's `path` (where the `$ref` appears in the
|
|
@@ -878,19 +1176,28 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
|
|
|
878
1176
|
const newSeparator = newSchema.allOf ? "allOf" : newSchema.oneOf ? "oneOf" : "anyOf";
|
|
879
1177
|
if (shouldDelegateToSchemaFactories(context) && isComponentsSchemaRef(refPaths) && !hasOverrideTouchingSchema(schemaRef?.properties, mockOptions, operationId, tags, schemaReference.path)) {
|
|
880
1178
|
const factoryName = `get${pascal(name)}Mock`;
|
|
881
|
-
|
|
1179
|
+
const factoryImport = {
|
|
882
1180
|
name: factoryName,
|
|
883
1181
|
values: true,
|
|
884
1182
|
schemaFactory: true
|
|
885
|
-
}
|
|
1183
|
+
};
|
|
1184
|
+
const isObjectLike = newSchema.type === "object" || !!newSchema.allOf || resolvesToObjectLike(newSchema, context);
|
|
1185
|
+
const mockTypeName = getStrictMockTypeName(pascal(name));
|
|
1186
|
+
const strictMockTypeImport = isStrictMock(mockOptions) && isObjectLike ? {
|
|
1187
|
+
name: mockTypeName,
|
|
1188
|
+
values: false,
|
|
1189
|
+
schemaFactory: true
|
|
1190
|
+
} : void 0;
|
|
1191
|
+
const strictObjectCast = isStrictMock(mockOptions) && isObjectLike ? ` as ${mockTypeName}` : "";
|
|
886
1192
|
return {
|
|
887
|
-
value: getNullable(
|
|
888
|
-
imports,
|
|
1193
|
+
value: getNullable(isObjectLike ? `{ ...${factoryName}()${strictObjectCast} }` : `${factoryName}()`, Boolean(newSchema.nullable), mockOptions?.nonNullable),
|
|
1194
|
+
imports: strictMockTypeImport ? [factoryImport, strictMockTypeImport] : [factoryImport],
|
|
889
1195
|
name: newSchema.name,
|
|
890
1196
|
type: getType(newSchema),
|
|
891
1197
|
nullWrapped: Boolean(newSchema.nullable) && !mockOptions?.nonNullable
|
|
892
1198
|
};
|
|
893
1199
|
}
|
|
1200
|
+
const importsBefore = imports.length;
|
|
894
1201
|
const scalar = getMockScalar({
|
|
895
1202
|
item: newSchema,
|
|
896
1203
|
mockOptions,
|
|
@@ -921,27 +1228,36 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
|
|
|
921
1228
|
splitMockImplementations.push(func);
|
|
922
1229
|
}
|
|
923
1230
|
scalar.value = newSchema.nullable ? `${funcName}()` : `{...${funcName}()}`;
|
|
924
|
-
|
|
1231
|
+
const typeImport = {
|
|
1232
|
+
name: newSchema.name,
|
|
1233
|
+
values: false
|
|
1234
|
+
};
|
|
1235
|
+
scalar.imports.push(typeImport);
|
|
1236
|
+
if (scalar.imports !== imports) imports.push(typeImport);
|
|
925
1237
|
}
|
|
1238
|
+
mergeReturnedMockImports(imports, importsBefore, scalar.imports);
|
|
926
1239
|
return {
|
|
927
1240
|
...scalar,
|
|
928
1241
|
type: getType(newSchema)
|
|
929
1242
|
};
|
|
930
1243
|
}
|
|
1244
|
+
const importsBefore = imports.length;
|
|
1245
|
+
const scalar = getMockScalar({
|
|
1246
|
+
item: schema,
|
|
1247
|
+
mockOptions,
|
|
1248
|
+
operationId,
|
|
1249
|
+
tags,
|
|
1250
|
+
combine,
|
|
1251
|
+
context,
|
|
1252
|
+
imports,
|
|
1253
|
+
existingReferencedProperties,
|
|
1254
|
+
existingReferencedAllOfRefs,
|
|
1255
|
+
splitMockImplementations,
|
|
1256
|
+
allowOverride
|
|
1257
|
+
});
|
|
1258
|
+
mergeReturnedMockImports(imports, importsBefore, scalar.imports);
|
|
931
1259
|
return {
|
|
932
|
-
...
|
|
933
|
-
item: schema,
|
|
934
|
-
mockOptions,
|
|
935
|
-
operationId,
|
|
936
|
-
tags,
|
|
937
|
-
combine,
|
|
938
|
-
context,
|
|
939
|
-
imports,
|
|
940
|
-
existingReferencedProperties,
|
|
941
|
-
existingReferencedAllOfRefs,
|
|
942
|
-
splitMockImplementations,
|
|
943
|
-
allowOverride
|
|
944
|
-
}),
|
|
1260
|
+
...scalar,
|
|
945
1261
|
type: getType(schema)
|
|
946
1262
|
};
|
|
947
1263
|
}
|
|
@@ -1138,6 +1454,14 @@ function getMockWithoutFunc(spec, override) {
|
|
|
1138
1454
|
}
|
|
1139
1455
|
return tagMocks;
|
|
1140
1456
|
})() : void 0;
|
|
1457
|
+
const schemas = override?.mock?.schemas ? (() => {
|
|
1458
|
+
const schemaMocks = {};
|
|
1459
|
+
for (const [key, value] of Object.entries(override.mock.schemas)) {
|
|
1460
|
+
if (!value?.properties) continue;
|
|
1461
|
+
schemaMocks[key] = { properties: getMockPropertiesWithoutFunc(value.properties, spec) };
|
|
1462
|
+
}
|
|
1463
|
+
return schemaMocks;
|
|
1464
|
+
})() : void 0;
|
|
1141
1465
|
return {
|
|
1142
1466
|
arrayMin: override?.mock?.arrayMin,
|
|
1143
1467
|
arrayMax: override?.mock?.arrayMax,
|
|
@@ -1151,7 +1475,8 @@ function getMockWithoutFunc(spec, override) {
|
|
|
1151
1475
|
...override?.mock?.properties ? { properties: getMockPropertiesWithoutFunc(override.mock.properties, spec) } : {},
|
|
1152
1476
|
...override?.mock?.format ? { format: getMockPropertiesWithoutFunc(override.mock.format, spec) } : {},
|
|
1153
1477
|
...operations ? { operations } : {},
|
|
1154
|
-
...tags ? { tags } : {}
|
|
1478
|
+
...tags ? { tags } : {},
|
|
1479
|
+
...schemas ? { schemas } : {}
|
|
1155
1480
|
};
|
|
1156
1481
|
}
|
|
1157
1482
|
function getMockNumberOption(mockOptionsWithoutFunc, key) {
|
|
@@ -1201,7 +1526,8 @@ function getResponsesMockDefinition({ operationId, tags, returnType, responses,
|
|
|
1201
1526
|
if (context.output.override.mock?.useExamples || mockOptions?.useExamples) {
|
|
1202
1527
|
const exampleValue = unwrapExampleValue(example ?? originalSchema?.example ?? getExampleEntries(examples)[0] ?? getExampleEntries(originalSchema?.examples)[0]);
|
|
1203
1528
|
if (exampleValue !== void 0) {
|
|
1204
|
-
|
|
1529
|
+
const formatted = formatSchemaExampleValue(exampleValue, originalSchema, context);
|
|
1530
|
+
result.definitions.push(transformer ? transformer(formatted, returnType) : formatted);
|
|
1205
1531
|
continue;
|
|
1206
1532
|
}
|
|
1207
1533
|
}
|
|
@@ -1216,13 +1542,15 @@ function getResponsesMockDefinition({ operationId, tags, returnType, responses,
|
|
|
1216
1542
|
};
|
|
1217
1543
|
else if (!originalSchema) continue;
|
|
1218
1544
|
const resolvedSchema = resolveRef(originalSchema, context).schema;
|
|
1545
|
+
const responseImports = imports ?? [];
|
|
1546
|
+
const importsBefore = responseImports.length;
|
|
1219
1547
|
const scalar = getMockScalar({
|
|
1220
1548
|
item: {
|
|
1221
1549
|
...resolvedSchema,
|
|
1222
1550
|
name: definition,
|
|
1223
1551
|
...context.output.override.enumGenerationType === "enum" && isRef ? { isRef: true } : {}
|
|
1224
1552
|
},
|
|
1225
|
-
imports,
|
|
1553
|
+
imports: responseImports,
|
|
1226
1554
|
mockOptions: mockOptionsWithoutFunc,
|
|
1227
1555
|
operationId,
|
|
1228
1556
|
tags,
|
|
@@ -1231,9 +1559,11 @@ function getResponsesMockDefinition({ operationId, tags, returnType, responses,
|
|
|
1231
1559
|
splitMockImplementations,
|
|
1232
1560
|
allowOverride: true
|
|
1233
1561
|
});
|
|
1234
|
-
result.imports
|
|
1562
|
+
appendImportsDelta(result.imports, responseImports, importsBefore);
|
|
1563
|
+
if (scalar.imports !== responseImports) appendImportsDelta(result.imports, scalar.imports, 0);
|
|
1235
1564
|
result.definitions.push(transformer ? transformer(scalar.value, returnType) : scalar.value);
|
|
1236
1565
|
}
|
|
1566
|
+
appendImportsDelta(result.imports, collectSplitMockTypeImports(splitMockImplementations), 0);
|
|
1237
1567
|
return result;
|
|
1238
1568
|
}
|
|
1239
1569
|
function getMockDefinition({ operationId, tags, returnType, responses, override, transformer, context, mockOptions, splitMockImplementations }) {
|
|
@@ -1437,7 +1767,8 @@ export const ${handlerName} = (overrideResponse?: ${mockReturnType} | ((${infoPa
|
|
|
1437
1767
|
handler: handlerImplementation
|
|
1438
1768
|
},
|
|
1439
1769
|
imports: includeResponseImports,
|
|
1440
|
-
strictMockSchemaTypeNames: strictMock ? mergeStrictMockSchemaTypeNames(schemaTypeNames, collectStrictMockSchemaTypeNamesFromImplementation(mockImplementation)) : void 0
|
|
1770
|
+
strictMockSchemaTypeNames: strictMock ? mergeStrictMockSchemaTypeNames(schemaTypeNames, collectStrictMockSchemaTypeNamesFromImplementation(mockImplementation)) : void 0,
|
|
1771
|
+
strictMockSchemaKinds: strictMock ? mergeStrictMockSchemaKinds(getStrictMockSchemaKindsFromResponses(responses, context), Object.fromEntries((collectStrictMockSchemaTypeNamesFromImplementation(mockImplementation) ?? []).map((name) => [name, "object"]))) : void 0
|
|
1441
1772
|
};
|
|
1442
1773
|
}
|
|
1443
1774
|
function generateMSW(generatorVerbOptions, generatorOptions) {
|
|
@@ -1454,12 +1785,14 @@ function generateMSW(generatorVerbOptions, generatorOptions) {
|
|
|
1454
1785
|
const handlerImplementations = [baseDefinition.implementation.handler];
|
|
1455
1786
|
const imports = [...baseDefinition.imports];
|
|
1456
1787
|
const strictMockSchemaTypeNames = new Set(baseDefinition.strictMockSchemaTypeNames);
|
|
1788
|
+
const strictMockSchemaKinds = { ...baseDefinition.strictMockSchemaKinds };
|
|
1457
1789
|
if (generatorOptions.mock && isObject(generatorOptions.mock) && generatorOptions.mock.generateEachHttpStatus) for (const statusResponse of [...response.types.success, ...response.types.errors]) {
|
|
1458
1790
|
const definition = generateDefinition(statusResponse.key, route, getResponseMockFunctionName, handlerName, generatorVerbOptions, generatorOptions, statusResponse.value, statusResponse.key, response.imports, [statusResponse], [statusResponse.contentType], splitMockImplementations);
|
|
1459
1791
|
mockImplementations.push(definition.implementation.function);
|
|
1460
1792
|
handlerImplementations.push(definition.implementation.handler);
|
|
1461
1793
|
imports.push(...definition.imports);
|
|
1462
1794
|
for (const name of definition.strictMockSchemaTypeNames ?? []) strictMockSchemaTypeNames.add(name);
|
|
1795
|
+
if (definition.strictMockSchemaKinds) for (const [name, kind] of Object.entries(definition.strictMockSchemaKinds)) strictMockSchemaKinds[name] ??= kind;
|
|
1463
1796
|
}
|
|
1464
1797
|
const aggregatedStrictNames = [...strictMockSchemaTypeNames];
|
|
1465
1798
|
return {
|
|
@@ -1469,7 +1802,8 @@ function generateMSW(generatorVerbOptions, generatorOptions) {
|
|
|
1469
1802
|
handler: handlerImplementations.join("\n")
|
|
1470
1803
|
},
|
|
1471
1804
|
imports,
|
|
1472
|
-
strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0
|
|
1805
|
+
strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0,
|
|
1806
|
+
strictMockSchemaKinds: mergeStrictMockSchemaKinds(strictMockSchemaKinds)
|
|
1473
1807
|
};
|
|
1474
1808
|
}
|
|
1475
1809
|
//#endregion
|
|
@@ -1507,7 +1841,8 @@ function generateFaker(generatorVerbOptions, generatorOptions) {
|
|
|
1507
1841
|
handlerName: ""
|
|
1508
1842
|
},
|
|
1509
1843
|
imports: result.imports,
|
|
1510
|
-
strictMockSchemaTypeNames: result.strictMockSchemaTypeNames
|
|
1844
|
+
strictMockSchemaTypeNames: result.strictMockSchemaTypeNames,
|
|
1845
|
+
strictMockSchemaKinds: result.strictMockSchemaKinds
|
|
1511
1846
|
};
|
|
1512
1847
|
}
|
|
1513
1848
|
/**
|
|
@@ -1522,38 +1857,47 @@ function generateFaker(generatorVerbOptions, generatorOptions) {
|
|
|
1522
1857
|
function generateFakerForSchemas(schemas, context, options) {
|
|
1523
1858
|
const factories = [];
|
|
1524
1859
|
const strictMockTypeNames = /* @__PURE__ */ new Set();
|
|
1860
|
+
const strictMockSchemaKinds = {};
|
|
1525
1861
|
const allImports = [];
|
|
1526
1862
|
const splitMockImplementations = [];
|
|
1527
1863
|
const localFactoryNames = new Set(schemas.filter((s) => !!s.schema).map((s) => `get${pascal(s.name)}Mock`));
|
|
1864
|
+
const localMockTypeNames = new Set(schemas.filter((s) => !!s.schema).map((s) => getStrictMockTypeName(pascal(s.name))));
|
|
1528
1865
|
const mockOptions = getMockWithoutFunc(context.spec, context.output.override);
|
|
1529
1866
|
for (const generatorSchema of schemas) {
|
|
1530
1867
|
const { name, schema } = generatorSchema;
|
|
1531
1868
|
if (!schema) continue;
|
|
1532
1869
|
const factoryName = `get${pascal(name)}Mock`;
|
|
1533
1870
|
const factoryImports = [];
|
|
1871
|
+
const factoryImportsBefore = factoryImports.length;
|
|
1872
|
+
const schemaName = pascal(name);
|
|
1534
1873
|
const result = getMockScalar({
|
|
1535
1874
|
item: {
|
|
1536
1875
|
...schema,
|
|
1537
|
-
name
|
|
1876
|
+
name: schemaName
|
|
1538
1877
|
},
|
|
1539
1878
|
imports: factoryImports,
|
|
1540
1879
|
mockOptions,
|
|
1541
1880
|
operationId: name,
|
|
1542
1881
|
tags: [],
|
|
1543
1882
|
context,
|
|
1544
|
-
existingReferencedProperties: [],
|
|
1883
|
+
existingReferencedProperties: [schemaName],
|
|
1884
|
+
existingReferencedAllOfRefs: [schemaName],
|
|
1545
1885
|
splitMockImplementations,
|
|
1546
1886
|
allowOverride: true,
|
|
1547
1887
|
isRef: false
|
|
1548
1888
|
});
|
|
1549
|
-
allImports
|
|
1889
|
+
appendImportsDelta(allImports, factoryImports, factoryImportsBefore);
|
|
1890
|
+
if (result.imports !== factoryImports) appendImportsDelta(allImports, result.imports, 0);
|
|
1550
1891
|
const typeName = pascal(name);
|
|
1551
1892
|
const { param, returnType, returnCast } = getMockFactorySignatureParts(typeName, mockOptions, {
|
|
1552
1893
|
isOverridable: result.value.includes("overrideResponse"),
|
|
1553
1894
|
overrideType: `Partial<${typeName}>`
|
|
1554
1895
|
});
|
|
1555
1896
|
const factory = formatMockFactoryDeclaration(factoryName, param, returnType, result.value, returnCast);
|
|
1556
|
-
if (isStrictMock(mockOptions))
|
|
1897
|
+
if (isStrictMock(mockOptions)) {
|
|
1898
|
+
strictMockTypeNames.add(typeName);
|
|
1899
|
+
strictMockSchemaKinds[typeName] = classifyStrictMockSchemaType(schema);
|
|
1900
|
+
}
|
|
1557
1901
|
factories.push(factory);
|
|
1558
1902
|
allImports.push({
|
|
1559
1903
|
name: pascal(name),
|
|
@@ -1563,6 +1907,7 @@ function generateFakerForSchemas(schemas, context, options) {
|
|
|
1563
1907
|
const mergedImports = /* @__PURE__ */ new Map();
|
|
1564
1908
|
for (const imp of allImports) {
|
|
1565
1909
|
if (imp.schemaFactory && localFactoryNames.has(imp.name)) continue;
|
|
1910
|
+
if (imp.schemaFactory && !imp.values && localMockTypeNames.has(imp.name)) continue;
|
|
1566
1911
|
const key = `${imp.name}::${imp.alias ?? ""}`;
|
|
1567
1912
|
const existing = mergedImports.get(key);
|
|
1568
1913
|
if (!existing) {
|
|
@@ -1573,11 +1918,16 @@ function generateFakerForSchemas(schemas, context, options) {
|
|
|
1573
1918
|
}
|
|
1574
1919
|
const uniqueImports = [...mergedImports.values()];
|
|
1575
1920
|
const implementation = [...splitMockImplementations, ...factories].filter(Boolean).join("\n\n");
|
|
1921
|
+
for (const name of collectStrictMockSchemaTypeNamesFromImplementation(implementation)) {
|
|
1922
|
+
strictMockTypeNames.add(name);
|
|
1923
|
+
strictMockSchemaKinds[name] ??= "object";
|
|
1924
|
+
}
|
|
1576
1925
|
const aggregatedStrictNames = [...strictMockTypeNames];
|
|
1577
1926
|
return {
|
|
1578
1927
|
implementation,
|
|
1579
1928
|
imports: uniqueImports,
|
|
1580
|
-
strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0
|
|
1929
|
+
strictMockSchemaTypeNames: aggregatedStrictNames.length > 0 ? aggregatedStrictNames : void 0,
|
|
1930
|
+
strictMockSchemaKinds: mergeStrictMockSchemaKinds(strictMockSchemaKinds)
|
|
1581
1931
|
};
|
|
1582
1932
|
}
|
|
1583
1933
|
//#endregion
|