@orval/mock 8.36.0 → 8.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +249 -202
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camelPathParamName, compareNatural, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getKey, getOperationTagKey, getRefInfo, getRequiredKeys, getStringLiteralType, isBoolean, isFunction, isMswMock, isNumber, isObject,
|
|
2
|
-
import { prop } from "remeda";
|
|
1
|
+
import { EnumGeneration, OutputMockType, OutputMode, PropertySortOrder, camelPathParamName, compareNatural, compareVersions, escapeRegExp, generalJSTypesWithArray, generateDependencyImports, getAtPath, getKey, getOperationTagKey, getRefInfo, getRequiredKeys, getStringLiteralType, isBoolean, isFunction, isInlineSchema, isMswMock, isNullOnlyEnum, isNumber, isObject, isSchemaNullable, isString, jsStringLiteralEscape, mergeDeep, pascal, resolveRef, safeNumericConstraint, stringify, toColonRoutePath, toJsLiteral, toObjectSchema } from "@orval/core";
|
|
3
2
|
//#region src/mock-types.ts
|
|
3
|
+
function asObjectSchema(schema) {
|
|
4
|
+
if (!schema || typeof schema !== "object") return;
|
|
5
|
+
return schema;
|
|
6
|
+
}
|
|
4
7
|
function isStrictMock(mockOptions) {
|
|
5
8
|
return Boolean(mockOptions && mockOptions.required && mockOptions.nonNullable);
|
|
6
9
|
}
|
|
@@ -21,23 +24,25 @@ export type MockWithNullableOverrides<
|
|
|
21
24
|
};`;
|
|
22
25
|
}
|
|
23
26
|
function classifyStrictMockSchemaType(schema, context) {
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
+
const objectSchema = asObjectSchema(schema);
|
|
28
|
+
if (!objectSchema) return "object";
|
|
29
|
+
if (objectSchema.format === "binary" || objectSchema.contentMediaType === "application/octet-stream" && !objectSchema.contentEncoding) return "binary";
|
|
30
|
+
if (typeof objectSchema.$ref === "string") {
|
|
27
31
|
if (context) {
|
|
28
|
-
const { schema: resolved } = resolveRef(
|
|
32
|
+
const { schema: resolved } = resolveRef(objectSchema, context);
|
|
29
33
|
return classifyStrictMockSchemaType(resolved, context);
|
|
30
34
|
}
|
|
31
35
|
return "object";
|
|
32
36
|
}
|
|
33
|
-
if (
|
|
37
|
+
if (objectSchema.type === "object" || objectSchema.properties || isComposedObjectSchema(objectSchema)) return "object";
|
|
34
38
|
return "alias";
|
|
35
39
|
}
|
|
36
40
|
function isComposedObjectSchema(schema) {
|
|
37
41
|
const branches = schema.oneOf ?? schema.anyOf ?? schema.allOf;
|
|
38
42
|
if (!branches?.length) return false;
|
|
39
43
|
return branches.some((branch) => {
|
|
40
|
-
const item = branch;
|
|
44
|
+
const item = asObjectSchema(branch);
|
|
45
|
+
if (!item) return false;
|
|
41
46
|
if (typeof item.$ref === "string" || item.type === "object" || item.properties) return true;
|
|
42
47
|
return isComposedObjectSchema(item);
|
|
43
48
|
});
|
|
@@ -62,23 +67,24 @@ function strictMockResolvedImportMatches(typeName, resolvedImport, importBareNam
|
|
|
62
67
|
return importBareName !== void 0 && importBareName === resolvedName;
|
|
63
68
|
}
|
|
64
69
|
function resolveStrictMockSchemaForTypeName(typeName, originalSchema, context, importBareName) {
|
|
65
|
-
|
|
66
|
-
if (!
|
|
67
|
-
|
|
70
|
+
const objectSchema = asObjectSchema(originalSchema);
|
|
71
|
+
if (!objectSchema) return;
|
|
72
|
+
if (!context) return objectSchema;
|
|
73
|
+
const branches = objectSchema.oneOf ?? objectSchema.anyOf ?? objectSchema.allOf;
|
|
68
74
|
if (branches?.length) {
|
|
69
75
|
for (const branch of branches) {
|
|
70
|
-
if (typeof branch.$ref !== "string") continue;
|
|
76
|
+
if (typeof branch !== "object" || branch === null || !("$ref" in branch) || typeof branch.$ref !== "string") continue;
|
|
71
77
|
const resolved = resolveRef(branch, context);
|
|
72
78
|
if (strictMockResolvedImportMatches(typeName, resolved.imports[0], importBareName)) return resolved.schema;
|
|
73
79
|
}
|
|
74
80
|
return;
|
|
75
81
|
}
|
|
76
|
-
if (typeof
|
|
77
|
-
const resolved = resolveRef(
|
|
82
|
+
if (typeof objectSchema.$ref === "string") {
|
|
83
|
+
const resolved = resolveRef(objectSchema, context);
|
|
78
84
|
if (strictMockResolvedImportMatches(typeName, resolved.imports[0], importBareName)) return resolved.schema;
|
|
79
85
|
return;
|
|
80
86
|
}
|
|
81
|
-
return
|
|
87
|
+
return objectSchema;
|
|
82
88
|
}
|
|
83
89
|
function getMockFactoryReturnType(typeName, mockOptions) {
|
|
84
90
|
return isStrictMock(mockOptions) ? getStrictMockTypeName(typeName) : typeName;
|
|
@@ -140,10 +146,9 @@ function getStrictMockSchemaKindsFromResponses(responses, context) {
|
|
|
140
146
|
if (!value || !response.originalSchema) continue;
|
|
141
147
|
const baseType = value.endsWith("[]") ? value.slice(0, -2) : value;
|
|
142
148
|
if (!/^[A-Z]\w*$/.test(baseType)) continue;
|
|
143
|
-
const schema = response.originalSchema;
|
|
144
|
-
if (value.endsWith("[]") && schema
|
|
145
|
-
|
|
146
|
-
kinds[baseType] = classifyStrictMockSchemaType(items, context);
|
|
149
|
+
const schema = asObjectSchema(response.originalSchema);
|
|
150
|
+
if (value.endsWith("[]") && schema?.type === "array" && schema.items && typeof schema.items === "object") {
|
|
151
|
+
kinds[baseType] = classifyStrictMockSchemaType(schema.items, context);
|
|
147
152
|
continue;
|
|
148
153
|
}
|
|
149
154
|
kinds[baseType] = classifyStrictMockSchemaType(resolveStrictMockSchemaForTypeName(baseType, response.originalSchema, context) ?? response.originalSchema, context);
|
|
@@ -214,46 +219,6 @@ function mergeStrictMockSchemaKinds(...groups) {
|
|
|
214
219
|
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
215
220
|
}
|
|
216
221
|
//#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
|
-
}
|
|
256
|
-
//#endregion
|
|
257
222
|
//#region src/delay.ts
|
|
258
223
|
const getDelay = (override, options) => {
|
|
259
224
|
const mswOptions = options && isMswMock(options) ? options : void 0;
|
|
@@ -268,12 +233,12 @@ const getDelay = (override, options) => {
|
|
|
268
233
|
//#region src/faker/getters/all-of-required.ts
|
|
269
234
|
function derefAllOfMember(member, context, seen) {
|
|
270
235
|
let current = member;
|
|
271
|
-
while (current && typeof current === "object" &&
|
|
236
|
+
while (current && typeof current === "object" && "$ref" in current && typeof current.$ref === "string") {
|
|
272
237
|
const ref = current.$ref;
|
|
273
|
-
if (
|
|
238
|
+
if (seen.has(ref)) return;
|
|
274
239
|
seen.add(ref);
|
|
275
240
|
const { refPaths } = getRefInfo(ref, context);
|
|
276
|
-
current = Array.isArray(refPaths) ?
|
|
241
|
+
current = Array.isArray(refPaths) ? getAtPath(context.spec, refPaths) : void 0;
|
|
277
242
|
}
|
|
278
243
|
return current && typeof current === "object" ? current : void 0;
|
|
279
244
|
}
|
|
@@ -340,6 +305,161 @@ const DEFAULT_FORMAT_MOCK = {
|
|
|
340
305
|
};
|
|
341
306
|
const DEFAULT_OBJECT_KEY_MOCK = "faker.string.alphanumeric(5)";
|
|
342
307
|
//#endregion
|
|
308
|
+
//#region src/faker/format-example-value.ts
|
|
309
|
+
const DATE_FORMATS = /* @__PURE__ */ new Set(["date", "date-time"]);
|
|
310
|
+
function isDateFormat(format) {
|
|
311
|
+
return format !== void 0 && DATE_FORMATS.has(format);
|
|
312
|
+
}
|
|
313
|
+
function isSchemaObject(schema) {
|
|
314
|
+
return typeof schema === "object" && schema !== null && !Array.isArray(schema);
|
|
315
|
+
}
|
|
316
|
+
function resolveSchema(schema, context) {
|
|
317
|
+
if (!schema || typeof schema !== "object") return;
|
|
318
|
+
if (typeof schema.$ref === "string") {
|
|
319
|
+
const resolved = resolveRef(schema, context).schema;
|
|
320
|
+
return resolved && typeof resolved === "object" ? resolved : void 0;
|
|
321
|
+
}
|
|
322
|
+
return schema;
|
|
323
|
+
}
|
|
324
|
+
function mergePropertySchemas(...schemas) {
|
|
325
|
+
const merged = {};
|
|
326
|
+
for (const schema of schemas) {
|
|
327
|
+
if (!schema?.properties) continue;
|
|
328
|
+
for (const [key, prop] of Object.entries(schema.properties)) if (isSchemaObject(prop)) merged[key] = prop;
|
|
329
|
+
}
|
|
330
|
+
return merged;
|
|
331
|
+
}
|
|
332
|
+
function getEffectiveScalarFormat(resolved, context) {
|
|
333
|
+
if (!resolved) return;
|
|
334
|
+
if (isDateFormat(resolved.format)) return resolved.format;
|
|
335
|
+
const oneOf = resolved.oneOf;
|
|
336
|
+
const anyOf = resolved.anyOf;
|
|
337
|
+
for (const variant of [...oneOf ?? [], ...anyOf ?? []]) {
|
|
338
|
+
const resolvedVariant = resolveSchema(isSchemaObject(variant) ? variant : void 0, context);
|
|
339
|
+
if (isDateFormat(resolvedVariant?.format)) return resolvedVariant.format;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Resolves compositional schemas (allOf / oneOf / anyOf) so example formatting
|
|
344
|
+
* can see property formats on nested and referenced types.
|
|
345
|
+
*/
|
|
346
|
+
function resolveExampleSchema(schema, context, seenRefs = /* @__PURE__ */ new Set()) {
|
|
347
|
+
if (!schema || typeof schema !== "object") return;
|
|
348
|
+
if (typeof schema.$ref === "string") {
|
|
349
|
+
const ref = schema.$ref;
|
|
350
|
+
if (seenRefs.has(ref)) {
|
|
351
|
+
const resolved = resolveRef(schema, context).schema;
|
|
352
|
+
return resolved && typeof resolved === "object" ? resolved : void 0;
|
|
353
|
+
}
|
|
354
|
+
seenRefs = new Set(seenRefs).add(ref);
|
|
355
|
+
}
|
|
356
|
+
const resolved = resolveSchema(schema, context);
|
|
357
|
+
if (!resolved) return;
|
|
358
|
+
const allOf = resolved.allOf;
|
|
359
|
+
const oneOf = resolved.oneOf;
|
|
360
|
+
const anyOf = resolved.anyOf;
|
|
361
|
+
const compositors = [
|
|
362
|
+
...allOf ?? [],
|
|
363
|
+
...oneOf ?? [],
|
|
364
|
+
...anyOf ?? []
|
|
365
|
+
];
|
|
366
|
+
const properties = mergePropertySchemas(resolved, ...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
367
|
+
const baseResolved = resolved;
|
|
368
|
+
if (resolved.type === "array" && isSchemaObject(resolved.items)) {
|
|
369
|
+
const items = resolveExampleSchema(resolved.items, context, seenRefs);
|
|
370
|
+
const itemProperties = items?.properties;
|
|
371
|
+
const normalizedItems = itemProperties && Object.keys(itemProperties).length > 0 ? {
|
|
372
|
+
type: "object",
|
|
373
|
+
properties: itemProperties
|
|
374
|
+
} : items;
|
|
375
|
+
return {
|
|
376
|
+
...baseResolved,
|
|
377
|
+
...Object.keys(properties).length > 0 ? { properties } : {},
|
|
378
|
+
items: normalizedItems ?? resolved.items
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
if (Object.keys(properties).length > 0) return {
|
|
382
|
+
...baseResolved,
|
|
383
|
+
properties
|
|
384
|
+
};
|
|
385
|
+
if (compositors.length > 0 && (oneOf ?? anyOf)) {
|
|
386
|
+
const variantProperties = mergePropertySchemas(...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
387
|
+
if (Object.keys(variantProperties).length > 0) return {
|
|
388
|
+
type: "object",
|
|
389
|
+
properties: variantProperties
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
const scalarFormat = getEffectiveScalarFormat(resolved, context);
|
|
393
|
+
if (scalarFormat) return {
|
|
394
|
+
...baseResolved,
|
|
395
|
+
format: scalarFormat
|
|
396
|
+
};
|
|
397
|
+
return resolved;
|
|
398
|
+
}
|
|
399
|
+
function formatLiteralValue(example, schema, context) {
|
|
400
|
+
if (example === null) return "null";
|
|
401
|
+
if (example === void 0) return "undefined";
|
|
402
|
+
const resolved = resolveExampleSchema(schema, context);
|
|
403
|
+
if (Array.isArray(example)) {
|
|
404
|
+
const itemsSchema = resolved?.type === "array" && isSchemaObject(resolved.items) ? resolveExampleSchema(resolved.items, context) : resolved;
|
|
405
|
+
return `[${example.map((item) => formatLiteralValue(item, itemsSchema, context)).join(", ")}]`;
|
|
406
|
+
}
|
|
407
|
+
if (typeof example === "object") {
|
|
408
|
+
const properties = resolved?.properties ?? {};
|
|
409
|
+
return `{ ${Object.entries(example).map(([key, value]) => {
|
|
410
|
+
const propSchema = properties[key];
|
|
411
|
+
const resolvedProp = isSchemaObject(propSchema) ? resolveExampleSchema(propSchema, context) : void 0;
|
|
412
|
+
return `${/^[a-zA-Z_$][\w$]*$/.test(key) ? key : JSON.stringify(key)}: ${formatLiteralValue(value, resolvedProp, context)}`;
|
|
413
|
+
}).join(", ")} }`;
|
|
414
|
+
}
|
|
415
|
+
if (context.output.override.useDates && typeof example === "string" && isDateFormat(getEffectiveScalarFormat(resolved, context))) return `new Date(${JSON.stringify(example)})`;
|
|
416
|
+
return JSON.stringify(example);
|
|
417
|
+
}
|
|
418
|
+
function formatSchemaExampleValue(example, schema, context) {
|
|
419
|
+
if (!context.output.override.useDates || schema === void 0) return JSON.stringify(example);
|
|
420
|
+
return formatLiteralValue(example, schema, context);
|
|
421
|
+
}
|
|
422
|
+
//#endregion
|
|
423
|
+
//#region src/faker/imports.ts
|
|
424
|
+
/**
|
|
425
|
+
* Appends entries added to `source` since `sinceIndex`. Uses indexed push
|
|
426
|
+
* instead of spread so large import batches (common with `schemas: true`
|
|
427
|
+
* delegation on wide objects) do not overflow the call stack.
|
|
428
|
+
*/
|
|
429
|
+
function appendImportsDelta(target, source, sinceIndex) {
|
|
430
|
+
for (let i = sinceIndex; i < source.length; i++) target.push(source[i]);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Merge imports returned from mock resolution when the shared imports array
|
|
434
|
+
* was not mutated in place. Enum mocks and nested object factories return
|
|
435
|
+
* their imports separately; schema-factory delegation mutates `sharedImports`
|
|
436
|
+
* directly and must not be merged again from `resolvedImports`.
|
|
437
|
+
*/
|
|
438
|
+
function mergeReturnedMockImports(sharedImports, sharedBefore, resolvedImports) {
|
|
439
|
+
if (sharedImports.length === sharedBefore) appendImportsDelta(sharedImports, resolvedImports, 0);
|
|
440
|
+
}
|
|
441
|
+
/** Recover type imports referenced by nested oneOf split mock helpers. */
|
|
442
|
+
function collectSplitMockTypeImports(implementations) {
|
|
443
|
+
const seen = /* @__PURE__ */ new Set();
|
|
444
|
+
const imports = [];
|
|
445
|
+
const addType = (name) => {
|
|
446
|
+
if (!name || seen.has(name)) return;
|
|
447
|
+
seen.add(name);
|
|
448
|
+
imports.push({
|
|
449
|
+
name,
|
|
450
|
+
values: false
|
|
451
|
+
});
|
|
452
|
+
};
|
|
453
|
+
for (const impl of implementations) {
|
|
454
|
+
for (const match of impl.matchAll(/export const get\w+Mock = \(\s*overrideResponse: Partial<(\w+)[^)]*\):\s*(\w+)\s*=>/g)) {
|
|
455
|
+
addType(match[1]);
|
|
456
|
+
addType(match[2]);
|
|
457
|
+
}
|
|
458
|
+
for (const match of impl.matchAll(/export const get\w+Mock[\s\S]*?MockWithNullableOverrides<(?:Extract<(\w+),[^>]+>|(\w+)),/g)) addType(match[1] ?? match[2]);
|
|
459
|
+
}
|
|
460
|
+
return imports;
|
|
461
|
+
}
|
|
462
|
+
//#endregion
|
|
343
463
|
//#region src/faker/getters/object.ts
|
|
344
464
|
const overrideVarName = "overrideResponse";
|
|
345
465
|
function wrapRootNullableObjectValue(value, schemaItem, mockOptions, combine) {
|
|
@@ -362,13 +482,13 @@ function reExpansionWouldCollapse(ref, context, existingReferencedProperties, no
|
|
|
362
482
|
const targetRequired = target?.required;
|
|
363
483
|
if (!targetProperties || !Array.isArray(targetRequired)) return false;
|
|
364
484
|
return Object.entries(targetProperties).some(([key, property]) => {
|
|
365
|
-
if (!targetRequired.includes(key) ||
|
|
485
|
+
if (!targetRequired.includes(key) || isInlineSchema(property)) return false;
|
|
366
486
|
if (!existingReferencedProperties.includes(getReferenceName$1(property.$ref, context))) return false;
|
|
367
487
|
return nonNullable || !isNullableRefTarget(property.$ref, context);
|
|
368
488
|
});
|
|
369
489
|
}
|
|
370
490
|
function getMockObject({ item, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride = false }) {
|
|
371
|
-
if (
|
|
491
|
+
if (typeof item.$ref === "string") return resolveMockValue({
|
|
372
492
|
schema: {
|
|
373
493
|
...item,
|
|
374
494
|
name: item.name,
|
|
@@ -476,14 +596,14 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
476
596
|
const propertyScalars = entries.map(([key, prop]) => {
|
|
477
597
|
if (combine?.includedProperties.includes(key)) return;
|
|
478
598
|
const isRequired = mockOptions?.required ?? (Array.isArray(itemRequired) ? itemRequired : []).includes(key);
|
|
479
|
-
const hasNullable =
|
|
480
|
-
const refName =
|
|
599
|
+
const hasNullable = isInlineSchema(prop) && isSchemaNullable(prop);
|
|
600
|
+
const refName = !isInlineSchema(prop) ? getReferenceName$1(prop.$ref, context) : "";
|
|
481
601
|
const isRecursiveRef = !!refName && existingReferencedProperties.includes(refName);
|
|
482
602
|
if (isRecursiveRef) {
|
|
483
603
|
if (!isRequired) return;
|
|
484
604
|
const keyDefinition = getKey(key);
|
|
485
|
-
if (!mockOptions?.nonNullable && (hasNullable ||
|
|
486
|
-
if (new Set(existingReferencedProperties).size !== existingReferencedProperties.length ||
|
|
605
|
+
if (!mockOptions?.nonNullable && (hasNullable || !isInlineSchema(prop) && isNullableRefTarget(prop.$ref, context))) return `${keyDefinition}: null`;
|
|
606
|
+
if (new Set(existingReferencedProperties).size !== existingReferencedProperties.length || !isInlineSchema(prop) && reExpansionWouldCollapse(prop.$ref, context, existingReferencedProperties, mockOptions?.nonNullable)) {
|
|
487
607
|
imports.push({ name: refName });
|
|
488
608
|
return `${keyDefinition}: {} as unknown as ${refName}`;
|
|
489
609
|
}
|
|
@@ -516,13 +636,14 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
516
636
|
imports.push({ name: refName });
|
|
517
637
|
return `${keyDefinition}: {} as unknown as ${refName}`;
|
|
518
638
|
}
|
|
519
|
-
const hasDefault = "default" in prop && prop.default !== void 0;
|
|
639
|
+
const hasDefault = typeof prop === "object" && prop !== null && "default" in prop && prop.default !== void 0;
|
|
520
640
|
if (!isRequired && !resolvedValue.overrided && !hasDefault) {
|
|
521
641
|
if (resolvedValue.nullWrapped) return `${keyDefinition}: ${resolvedValue.value}`;
|
|
522
642
|
const omitValue = mockOptions?.nonNullable || !hasNullable ? "undefined" : "null";
|
|
643
|
+
if (omitValue === "undefined" && mockOptions?.exactOptional) return `...(faker.datatype.boolean() ? {${keyDefinition}: ${resolvedValue.value}} : {})`;
|
|
523
644
|
return `${keyDefinition}: faker.helpers.arrayElement([${resolvedValue.value}, ${omitValue}])`;
|
|
524
645
|
}
|
|
525
|
-
if (Array.isArray(prop.type) && prop.type.includes("null") && !resolvedValue.nullWrapped && !resolvedValue.overrided && !mockOptions?.nonNullable) return `${keyDefinition}: faker.helpers.arrayElement([${resolvedValue.value}, null])`;
|
|
646
|
+
if (typeof prop === "object" && prop !== null && "type" in prop && Array.isArray(prop.type) && prop.type.includes("null") && !resolvedValue.nullWrapped && !resolvedValue.overrided && !mockOptions?.nonNullable) return `${keyDefinition}: faker.helpers.arrayElement([${resolvedValue.value}, null])`;
|
|
526
647
|
return `${keyDefinition}: ${resolvedValue.value}`;
|
|
527
648
|
}).filter(Boolean);
|
|
528
649
|
if (allowOverride) propertyScalars.push(`...${overrideVarName}`);
|
|
@@ -548,7 +669,7 @@ function getMockObject({ item, mockOptions, operationId, tags, combine, context,
|
|
|
548
669
|
};
|
|
549
670
|
}
|
|
550
671
|
const additionalProperties = itemAdditionalProperties;
|
|
551
|
-
if (
|
|
672
|
+
if (!isInlineSchema(additionalProperties) && existingReferencedProperties.includes(getReferenceName$1(additionalProperties.$ref, context))) {
|
|
552
673
|
const { value: finalValue, nullWrapped } = wrapRootNullableObjectValue(`{}`, schemaItem, mockOptions, combine);
|
|
553
674
|
return {
|
|
554
675
|
value: finalValue,
|
|
@@ -661,11 +782,12 @@ function shouldExtractArrayItem(items, context, operationId, parentName) {
|
|
|
661
782
|
const itemsRef = extractItemsRef(items);
|
|
662
783
|
if (itemsRef) try {
|
|
663
784
|
const { schema } = resolveRef({ $ref: itemsRef }, context);
|
|
785
|
+
if (typeof schema !== "object" || schema === null) return false;
|
|
664
786
|
return isResolvedSchemaObjectLike(schema);
|
|
665
787
|
} catch {
|
|
666
788
|
return false;
|
|
667
789
|
}
|
|
668
|
-
if (
|
|
790
|
+
if (!isInlineSchema(items)) return false;
|
|
669
791
|
const schema = items;
|
|
670
792
|
if (isNullableArrayItem(schema)) return false;
|
|
671
793
|
if (schema.oneOf || schema.anyOf) return false;
|
|
@@ -746,115 +868,6 @@ function extractArrayItemMock({ items, propertyName, parentName, operationId, ta
|
|
|
746
868
|
return `{...${factoryName}()${isStrictMock(mockOptions) ? ` as ${getStrictMockTypeName(typeName)}` : ""}}`;
|
|
747
869
|
}
|
|
748
870
|
//#endregion
|
|
749
|
-
//#region src/faker/format-example-value.ts
|
|
750
|
-
const DATE_FORMATS = /* @__PURE__ */ new Set(["date", "date-time"]);
|
|
751
|
-
function isDateFormat(format) {
|
|
752
|
-
return format !== void 0 && DATE_FORMATS.has(format);
|
|
753
|
-
}
|
|
754
|
-
function isSchemaObject(schema) {
|
|
755
|
-
return typeof schema === "object" && schema !== null && !Array.isArray(schema);
|
|
756
|
-
}
|
|
757
|
-
function resolveSchema(schema, context) {
|
|
758
|
-
if (!schema) return;
|
|
759
|
-
if (isReference(schema)) return resolveRef(schema, context).schema;
|
|
760
|
-
return schema;
|
|
761
|
-
}
|
|
762
|
-
function mergePropertySchemas(...schemas) {
|
|
763
|
-
const merged = {};
|
|
764
|
-
for (const schema of schemas) {
|
|
765
|
-
if (!schema?.properties) continue;
|
|
766
|
-
for (const [key, prop] of Object.entries(schema.properties)) if (isSchemaObject(prop)) merged[key] = prop;
|
|
767
|
-
}
|
|
768
|
-
return merged;
|
|
769
|
-
}
|
|
770
|
-
function getEffectiveScalarFormat(resolved, context) {
|
|
771
|
-
if (!resolved) return;
|
|
772
|
-
if (isDateFormat(resolved.format)) return resolved.format;
|
|
773
|
-
const oneOf = resolved.oneOf;
|
|
774
|
-
const anyOf = resolved.anyOf;
|
|
775
|
-
for (const variant of [...oneOf ?? [], ...anyOf ?? []]) {
|
|
776
|
-
const resolvedVariant = resolveSchema(isReference(variant) || isSchemaObject(variant) ? variant : void 0, context);
|
|
777
|
-
if (isDateFormat(resolvedVariant?.format)) return resolvedVariant.format;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
/**
|
|
781
|
-
* Resolves compositional schemas (allOf / oneOf / anyOf) so example formatting
|
|
782
|
-
* can see property formats on nested and referenced types.
|
|
783
|
-
*/
|
|
784
|
-
function resolveExampleSchema(schema, context, seenRefs = /* @__PURE__ */ new Set()) {
|
|
785
|
-
if (!schema) return;
|
|
786
|
-
if (isReference(schema)) {
|
|
787
|
-
const ref = schema.$ref;
|
|
788
|
-
if (ref && seenRefs.has(ref)) return resolveRef(schema, context).schema;
|
|
789
|
-
if (ref) seenRefs = new Set(seenRefs).add(ref);
|
|
790
|
-
}
|
|
791
|
-
const resolved = resolveSchema(schema, context);
|
|
792
|
-
if (!resolved) return;
|
|
793
|
-
const allOf = resolved.allOf;
|
|
794
|
-
const oneOf = resolved.oneOf;
|
|
795
|
-
const anyOf = resolved.anyOf;
|
|
796
|
-
const compositors = [
|
|
797
|
-
...allOf ?? [],
|
|
798
|
-
...oneOf ?? [],
|
|
799
|
-
...anyOf ?? []
|
|
800
|
-
];
|
|
801
|
-
const properties = mergePropertySchemas(resolved, ...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
802
|
-
const baseResolved = resolved;
|
|
803
|
-
if (resolved.type === "array" && isSchemaObject(resolved.items)) {
|
|
804
|
-
const items = resolveExampleSchema(resolved.items, context, seenRefs);
|
|
805
|
-
const itemProperties = items?.properties;
|
|
806
|
-
const normalizedItems = itemProperties && Object.keys(itemProperties).length > 0 ? {
|
|
807
|
-
type: "object",
|
|
808
|
-
properties: itemProperties
|
|
809
|
-
} : items;
|
|
810
|
-
return {
|
|
811
|
-
...baseResolved,
|
|
812
|
-
...Object.keys(properties).length > 0 ? { properties } : {},
|
|
813
|
-
items: normalizedItems ?? resolved.items
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
if (Object.keys(properties).length > 0) return {
|
|
817
|
-
...baseResolved,
|
|
818
|
-
properties
|
|
819
|
-
};
|
|
820
|
-
if (compositors.length > 0 && (oneOf ?? anyOf)) {
|
|
821
|
-
const variantProperties = mergePropertySchemas(...compositors.map((sub) => resolveExampleSchema(sub, context, seenRefs)));
|
|
822
|
-
if (Object.keys(variantProperties).length > 0) return {
|
|
823
|
-
type: "object",
|
|
824
|
-
properties: variantProperties
|
|
825
|
-
};
|
|
826
|
-
}
|
|
827
|
-
const scalarFormat = getEffectiveScalarFormat(resolved, context);
|
|
828
|
-
if (scalarFormat) return {
|
|
829
|
-
...baseResolved,
|
|
830
|
-
format: scalarFormat
|
|
831
|
-
};
|
|
832
|
-
return resolved;
|
|
833
|
-
}
|
|
834
|
-
function formatLiteralValue(example, schema, context) {
|
|
835
|
-
if (example === null) return "null";
|
|
836
|
-
if (example === void 0) return "undefined";
|
|
837
|
-
const resolved = resolveExampleSchema(schema, context);
|
|
838
|
-
if (Array.isArray(example)) {
|
|
839
|
-
const itemsSchema = resolved?.type === "array" && isSchemaObject(resolved.items) ? resolveExampleSchema(resolved.items, context) : resolved;
|
|
840
|
-
return `[${example.map((item) => formatLiteralValue(item, itemsSchema, context)).join(", ")}]`;
|
|
841
|
-
}
|
|
842
|
-
if (typeof example === "object") {
|
|
843
|
-
const properties = resolved?.properties ?? {};
|
|
844
|
-
return `{ ${Object.entries(example).map(([key, value]) => {
|
|
845
|
-
const propSchema = properties[key];
|
|
846
|
-
const resolvedProp = isSchemaObject(propSchema) ? resolveExampleSchema(propSchema, context) : void 0;
|
|
847
|
-
return `${/^[a-zA-Z_$][\w$]*$/.test(key) ? key : JSON.stringify(key)}: ${formatLiteralValue(value, resolvedProp, context)}`;
|
|
848
|
-
}).join(", ")} }`;
|
|
849
|
-
}
|
|
850
|
-
if (context.output.override.useDates && typeof example === "string" && isDateFormat(getEffectiveScalarFormat(resolved, context))) return `new Date(${JSON.stringify(example)})`;
|
|
851
|
-
return JSON.stringify(example);
|
|
852
|
-
}
|
|
853
|
-
function formatSchemaExampleValue(example, schema, context) {
|
|
854
|
-
if (!context.output.override.useDates || schema === void 0) return JSON.stringify(example);
|
|
855
|
-
return formatLiteralValue(example, schema, context);
|
|
856
|
-
}
|
|
857
|
-
//#endregion
|
|
858
871
|
//#region src/faker/getters/scalar.ts
|
|
859
872
|
function getMockScalar({ item, imports, mockOptions, operationId, tags, combine, context, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride = false }) {
|
|
860
873
|
const safeMockOptions = mockOptions ?? {};
|
|
@@ -884,6 +897,18 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
884
897
|
overrided: true
|
|
885
898
|
};
|
|
886
899
|
}
|
|
900
|
+
if (isNullOnlyEnum(item)) return {
|
|
901
|
+
value: "null",
|
|
902
|
+
imports: [],
|
|
903
|
+
name: item.name,
|
|
904
|
+
nullWrapped: true
|
|
905
|
+
};
|
|
906
|
+
if ("const" in item && item.type === void 0) return {
|
|
907
|
+
value: toJsLiteral(item.const),
|
|
908
|
+
imports: [],
|
|
909
|
+
name: item.name,
|
|
910
|
+
nullWrapped: item.const === null
|
|
911
|
+
};
|
|
887
912
|
const formatOverrides = safeMockOptions.format ?? {};
|
|
888
913
|
const ALL_FORMAT = {
|
|
889
914
|
...DEFAULT_FORMAT_MOCK,
|
|
@@ -934,7 +959,10 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
934
959
|
value = getNullable(`faker.number.float(${floatParts.length > 0 ? `{${floatParts.join(", ")}}` : ""})`, isNullable, nonNullableOption);
|
|
935
960
|
}
|
|
936
961
|
const numberImports = [];
|
|
937
|
-
if (item.enum) value = getEnum(item, numberImports, context, existingReferencedProperties,
|
|
962
|
+
if (item.enum) value = getEnum(item, numberImports, context, existingReferencedProperties, {
|
|
963
|
+
type: "number",
|
|
964
|
+
exactOptional: safeMockOptions.exactOptional
|
|
965
|
+
});
|
|
938
966
|
else if ("const" in item) value = JSON.stringify(item.const);
|
|
939
967
|
return {
|
|
940
968
|
value,
|
|
@@ -947,7 +975,10 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
947
975
|
case "boolean": {
|
|
948
976
|
let value = "faker.datatype.boolean()";
|
|
949
977
|
const booleanImports = [];
|
|
950
|
-
if (item.enum) value = getEnum(item, booleanImports, context, existingReferencedProperties,
|
|
978
|
+
if (item.enum) value = getEnum(item, booleanImports, context, existingReferencedProperties, {
|
|
979
|
+
type: "boolean",
|
|
980
|
+
exactOptional: safeMockOptions.exactOptional
|
|
981
|
+
});
|
|
951
982
|
else if ("const" in item) value = JSON.stringify(item.const);
|
|
952
983
|
return {
|
|
953
984
|
value,
|
|
@@ -986,18 +1017,19 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
986
1017
|
name: item.name
|
|
987
1018
|
};
|
|
988
1019
|
}
|
|
989
|
-
if (!item.items) return {
|
|
1020
|
+
if (!item.items || typeof item.items !== "object") return {
|
|
990
1021
|
value: "[]",
|
|
991
1022
|
imports: [],
|
|
992
1023
|
name: item.name
|
|
993
1024
|
};
|
|
994
|
-
const
|
|
1025
|
+
const itemsSchema = item.items;
|
|
1026
|
+
const itemsRef = extractItemsRef(itemsSchema);
|
|
995
1027
|
if (itemsRef && existingReferencedProperties.includes(getRefInfo(itemsRef, context).name)) return {
|
|
996
1028
|
value: "[]",
|
|
997
1029
|
imports: [],
|
|
998
1030
|
name: item.name
|
|
999
1031
|
};
|
|
1000
|
-
const resolvedItems = itemsRef && !("$ref" in
|
|
1032
|
+
const resolvedItems = itemsRef && !("$ref" in itemsSchema) ? { $ref: itemsRef } : itemsSchema;
|
|
1001
1033
|
const { value, enums, imports: resolvedImports } = resolveMockValue({
|
|
1002
1034
|
schema: {
|
|
1003
1035
|
...resolvedItems,
|
|
@@ -1076,7 +1108,10 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
1076
1108
|
if (strMin !== void 0 && strMax !== void 0) strLenParts.push(`min: ${strMin}`, `max: ${strMax}`);
|
|
1077
1109
|
let value = `faker.string.alpha(${strLenParts.length > 0 ? `{length: {${strLenParts.join(", ")}}}` : ""})`;
|
|
1078
1110
|
const stringImports = [];
|
|
1079
|
-
if (item.enum) value = getEnum(item, stringImports, context, existingReferencedProperties,
|
|
1111
|
+
if (item.enum) value = getEnum(item, stringImports, context, existingReferencedProperties, {
|
|
1112
|
+
type: "string",
|
|
1113
|
+
exactOptional: safeMockOptions.exactOptional
|
|
1114
|
+
});
|
|
1080
1115
|
else if (item.pattern) value = `faker.helpers.fromRegExp(${JSON.stringify(item.pattern)})`;
|
|
1081
1116
|
else if ("const" in item) value = JSON.stringify(item.const);
|
|
1082
1117
|
return {
|
|
@@ -1097,7 +1132,7 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
1097
1132
|
if (item.enum) {
|
|
1098
1133
|
const enumImports = [];
|
|
1099
1134
|
return {
|
|
1100
|
-
value: getEnum(item, enumImports, context, existingReferencedProperties),
|
|
1135
|
+
value: getEnum(item, enumImports, context, existingReferencedProperties, { exactOptional: safeMockOptions.exactOptional }),
|
|
1101
1136
|
enums: item.enum,
|
|
1102
1137
|
imports: enumImports,
|
|
1103
1138
|
name: item.name
|
|
@@ -1122,14 +1157,14 @@ function getMockScalar({ item, imports, mockOptions, operationId, tags, combine,
|
|
|
1122
1157
|
}
|
|
1123
1158
|
}
|
|
1124
1159
|
function extractItemsRef(items) {
|
|
1125
|
-
if (
|
|
1160
|
+
if (!isInlineSchema(items)) return items.$ref;
|
|
1126
1161
|
for (const key of [
|
|
1127
1162
|
"allOf",
|
|
1128
1163
|
"oneOf",
|
|
1129
1164
|
"anyOf"
|
|
1130
1165
|
]) {
|
|
1131
1166
|
const composed = items[key];
|
|
1132
|
-
if (Array.isArray(composed) && composed.length === 1 &&
|
|
1167
|
+
if (Array.isArray(composed) && composed.length === 1 && !isInlineSchema(composed[0])) return composed[0].$ref;
|
|
1133
1168
|
}
|
|
1134
1169
|
}
|
|
1135
1170
|
function getItemType(item) {
|
|
@@ -1180,7 +1215,7 @@ function safeTypeIdentifier(name) {
|
|
|
1180
1215
|
const identifier = name.endsWith("[]") ? name.slice(0, -2) : name;
|
|
1181
1216
|
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(identifier) ? identifier : void 0;
|
|
1182
1217
|
}
|
|
1183
|
-
function getEnum(item, imports, context, existingReferencedProperties, type) {
|
|
1218
|
+
function getEnum(item, imports, context, existingReferencedProperties, { type, exactOptional } = {}) {
|
|
1184
1219
|
if (!item.enum) return "";
|
|
1185
1220
|
let enumValue = `[${item.enum.filter((e) => e !== null).map((e) => formatEnumMember(e)).join(",")}]`;
|
|
1186
1221
|
if (context.output.override.enumGenerationType === EnumGeneration.ENUM) {
|
|
@@ -1196,7 +1231,8 @@ function getEnum(item, imports, context, existingReferencedProperties, type) {
|
|
|
1196
1231
|
if (!parentReference) return "";
|
|
1197
1232
|
const parentIdentifier = safeTypeIdentifier(parentReference);
|
|
1198
1233
|
if (parentIdentifier) {
|
|
1199
|
-
|
|
1234
|
+
const indexedType = `${parentIdentifier}[${getStringLiteralType(item.name)}]`;
|
|
1235
|
+
enumValue += exactOptional ? ` as Exclude<${indexedType}, undefined>` : ` as ${indexedType}`;
|
|
1200
1236
|
if (!item.path?.endsWith("[]")) enumValue += "[]";
|
|
1201
1237
|
imports.push({ name: parentIdentifier });
|
|
1202
1238
|
} else enumValue += " as const";
|
|
@@ -1247,7 +1283,7 @@ function resolveRefTarget(ref, context) {
|
|
|
1247
1283
|
if (!fragment) return void 0;
|
|
1248
1284
|
const { refPaths } = getRefInfo(ref, context);
|
|
1249
1285
|
if (!Array.isArray(refPaths)) return void 0;
|
|
1250
|
-
return
|
|
1286
|
+
return getAtPath(context.spec, refPaths);
|
|
1251
1287
|
}
|
|
1252
1288
|
/**
|
|
1253
1289
|
* Whether a schema accepts `null`, in any of the spellings orval sees.
|
|
@@ -1323,7 +1359,7 @@ function hasOverrideTouchingSchema(schemaProperties, mockOptions, operationId, t
|
|
|
1323
1359
|
});
|
|
1324
1360
|
}
|
|
1325
1361
|
function resolveMockValue({ schema, mockOptions, operationId, tags, combine, context, imports, existingReferencedProperties, existingReferencedAllOfRefs = [], splitMockImplementations, allowOverride }) {
|
|
1326
|
-
if (
|
|
1362
|
+
if (!isInlineSchema(schema)) {
|
|
1327
1363
|
const schemaReference = schema;
|
|
1328
1364
|
const schemaRefPath = typeof schema.$ref === "string" ? schema.$ref : "";
|
|
1329
1365
|
const { name, refPaths } = getRefInfo(schemaRefPath, context);
|
|
@@ -1334,7 +1370,7 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
|
|
|
1334
1370
|
path: schemaReference.path,
|
|
1335
1371
|
isRef: true,
|
|
1336
1372
|
required: [...schemaRef?.required ?? [], ...getRequiredKeys(schemaReference, name)],
|
|
1337
|
-
...Array.isArray(schemaReference.type) ? { type: schemaReference.type } : {}
|
|
1373
|
+
..."type" in schemaReference && Array.isArray(schemaReference.type) ? { type: schemaReference.type } : {}
|
|
1338
1374
|
};
|
|
1339
1375
|
if (combine?.separator === "allOf" && newSchema.discriminator && newSchema.oneOf) {
|
|
1340
1376
|
const parentDiscriminator = newSchema.discriminator;
|
|
@@ -1451,12 +1487,12 @@ function resolveMockValue({ schema, mockOptions, operationId, tags, combine, con
|
|
|
1451
1487
|
};
|
|
1452
1488
|
}
|
|
1453
1489
|
function getType(schema) {
|
|
1454
|
-
if (
|
|
1490
|
+
if (!isInlineSchema(schema)) return;
|
|
1455
1491
|
return schema.type ?? (schema.properties ? "object" : schema.items ? "array" : void 0);
|
|
1456
1492
|
}
|
|
1457
1493
|
function resolvesToObjectLike(schema, context, seen = /* @__PURE__ */ new Set()) {
|
|
1458
1494
|
let resolved;
|
|
1459
|
-
if (
|
|
1495
|
+
if (!isInlineSchema(schema)) {
|
|
1460
1496
|
if (typeof schema.$ref !== "string" || seen.has(schema.$ref)) return false;
|
|
1461
1497
|
seen = new Set(seen).add(schema.$ref);
|
|
1462
1498
|
resolved = resolveRefTarget(schema.$ref, context);
|
|
@@ -1478,7 +1514,7 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
|
|
|
1478
1514
|
const includedProperties = [...combine?.includedProperties ?? []];
|
|
1479
1515
|
const separatorItems = item[separator] ?? [];
|
|
1480
1516
|
const itemRequired = item.required;
|
|
1481
|
-
const isRefAndNotExisting =
|
|
1517
|
+
const isRefAndNotExisting = typeof item.$ref === "string" && !existingReferencedProperties.includes(item.name);
|
|
1482
1518
|
const discriminator = item.discriminator;
|
|
1483
1519
|
const itemProperties = item.properties;
|
|
1484
1520
|
const discriminatorPropertyName = separator === "oneOf" && discriminator?.mapping && discriminator.propertyName && itemProperties && discriminator.propertyName in itemProperties ? discriminator.propertyName : void 0;
|
|
@@ -1526,9 +1562,10 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
|
|
|
1526
1562
|
includedProperties.push(...itemResolvedValue?.includedProperties ?? []);
|
|
1527
1563
|
combineImports.push(...itemResolvedValue?.imports ?? []);
|
|
1528
1564
|
let containsOnlyPrimitiveValues = true;
|
|
1565
|
+
let hasNullMember = false;
|
|
1529
1566
|
let value = separator === "allOf" ? "" : "faker.helpers.arrayElement([";
|
|
1530
1567
|
for (const val of separatorItems) {
|
|
1531
|
-
const refName =
|
|
1568
|
+
const refName = isInlineSchema(val) ? "" : getReferenceName(val.$ref, context);
|
|
1532
1569
|
if (separator === "allOf" ? refName && (refName === item.name || existingReferencedProperties.includes(refName) && !item.isRef || existingReferencedAllOfRefs.includes(refName)) : refName && existingReferencedProperties.includes(refName)) {
|
|
1533
1570
|
if (separatorItems.length === 1) value = "undefined";
|
|
1534
1571
|
continue;
|
|
@@ -1580,6 +1617,10 @@ function combineSchemasMock({ item, separator, mockOptions, operationId, tags, c
|
|
|
1580
1617
|
continue;
|
|
1581
1618
|
}
|
|
1582
1619
|
}
|
|
1620
|
+
if (separator !== "allOf" && resolvedValue.value === "null") {
|
|
1621
|
+
if (hasNullMember) continue;
|
|
1622
|
+
hasNullMember = true;
|
|
1623
|
+
}
|
|
1583
1624
|
value += `${resolvedValue.value},`;
|
|
1584
1625
|
}
|
|
1585
1626
|
let finalValue = value === "undefined" || separator !== "allOf" && value === "faker.helpers.arrayElement([" ? "undefined" : `${separator === "allOf" && !containsOnlyPrimitiveValues ? "{" : ""}${value}${separator === "allOf" ? containsOnlyPrimitiveValues ? "" : "}" : "])"}`;
|
|
@@ -1638,6 +1679,7 @@ function getMockWithoutFunc(spec, override) {
|
|
|
1638
1679
|
numberMax: override?.mock?.numberMax,
|
|
1639
1680
|
required: override?.mock?.required,
|
|
1640
1681
|
nonNullable: override?.mock?.nonNullable,
|
|
1682
|
+
exactOptional: override?.mock?.exactOptional,
|
|
1641
1683
|
fractionDigits: override?.mock?.fractionDigits,
|
|
1642
1684
|
...override?.mock?.properties ? { properties: getMockPropertiesWithoutFunc(override.mock.properties, spec) } : {},
|
|
1643
1685
|
...override?.mock?.format ? { format: getMockPropertiesWithoutFunc(override.mock.format, spec) } : {},
|
|
@@ -1694,8 +1736,9 @@ function getResponsesMockDefinition({ operationId, tags, returnType, responses,
|
|
|
1694
1736
|
for (const response of responses) {
|
|
1695
1737
|
const { value: definition, example, examples, imports, isRef } = response;
|
|
1696
1738
|
let { originalSchema } = response;
|
|
1739
|
+
const schemaObject = originalSchema && typeof originalSchema === "object" ? originalSchema : void 0;
|
|
1697
1740
|
if (context.output.override.mock?.useExamples || mockOptions?.useExamples) {
|
|
1698
|
-
const exampleValue = unwrapExampleValue(example ??
|
|
1741
|
+
const exampleValue = unwrapExampleValue(example ?? schemaObject?.example ?? getExampleEntries(examples)[0] ?? getExampleEntries(schemaObject?.examples)[0]);
|
|
1699
1742
|
if (exampleValue !== void 0) {
|
|
1700
1743
|
const formatted = formatSchemaExampleValue(exampleValue, originalSchema, context);
|
|
1701
1744
|
result.definitions.push(transformer ? transformer(formatted, returnType) : formatted);
|
|
@@ -1712,7 +1755,7 @@ function getResponsesMockDefinition({ operationId, tags, returnType, responses,
|
|
|
1712
1755
|
format: "binary"
|
|
1713
1756
|
};
|
|
1714
1757
|
else if (!originalSchema) continue;
|
|
1715
|
-
const resolvedSchema = resolveRef(originalSchema, context).schema;
|
|
1758
|
+
const resolvedSchema = toObjectSchema(resolveRef(originalSchema, context).schema);
|
|
1716
1759
|
const responseImports = imports ? [...imports] : [];
|
|
1717
1760
|
const importsBefore = responseImports.length;
|
|
1718
1761
|
const scalar = getMockScalar({
|
|
@@ -1845,7 +1888,11 @@ function generateDefinition(name, route, getResponseMockFunctionNameBase, handle
|
|
|
1845
1888
|
const hasTextLikeContentType = contentTypes.some((ct) => isTextLikeContentType(ct));
|
|
1846
1889
|
const isExactlyStringReturnType = isTypeExactlyString(returnType);
|
|
1847
1890
|
const isTextResponse = isExactlyStringReturnType && hasTextLikeContentType || contentTypesByPreference.some((ct) => isTextLikeContentType(ct));
|
|
1848
|
-
const isSchemaBinary = (r) =>
|
|
1891
|
+
const isSchemaBinary = (r) => {
|
|
1892
|
+
const schema = r.originalSchema;
|
|
1893
|
+
if (!schema || typeof schema !== "object") return false;
|
|
1894
|
+
return schema.format === "binary" || schema.contentMediaType === "application/octet-stream" && !schema.contentEncoding;
|
|
1895
|
+
};
|
|
1849
1896
|
const isBinaryResponse = preferredContentTypeMatch ? responsesByPreference.some((r) => isSchemaBinary(r)) : contentTypesByPreference.some((ct) => isBinaryLikeContentType(ct)) || responsesByPreference.some((r) => isSchemaBinary(r));
|
|
1850
1897
|
const isReturnHttpResponse = value && value !== "undefined";
|
|
1851
1898
|
const getResponseMockFunctionName = `${getResponseMockFunctionNameBase}${pascal(name)}`;
|