@kubb/plugin-faker 5.2.1 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +171 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -13
- package/dist/index.d.ts +2 -13
- package/dist/index.js +172 -78
- package/dist/index.js.map +1 -1
- package/docs/options.md +2 -0
- package/kubb-extension.json +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Exclude, Group, Include, Output, OutputOptions, Override, PluginType, Resolver, ResolverPatch, ast } from "kubb/kit";
|
|
2
2
|
import { KubbReactNode } from "kubb/jsx";
|
|
3
|
-
//#region src/types.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Resolver for Faker that provides naming methods for mock functions.
|
|
6
5
|
*
|
|
@@ -172,8 +171,6 @@ declare global {
|
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
}
|
|
175
|
-
//#endregion
|
|
176
|
-
//#region src/printers/printerFaker.d.ts
|
|
177
174
|
/**
|
|
178
175
|
* Partial map of node-type overrides for the Faker printer. Each key is a
|
|
179
176
|
* `SchemaType` (`'string'`, `'date'`, ...) and each handler returns the
|
|
@@ -231,8 +228,6 @@ type PrinterFakerFactory = ast.PrinterFactoryOptions<'faker', PrinterFakerOption
|
|
|
231
228
|
* Handles circular references gracefully by emitting memoizing getters for cyclic properties.
|
|
232
229
|
*/
|
|
233
230
|
export declare const printerFaker: (options: PrinterFakerOptions) => ast.Printer<PrinterFakerFactory>;
|
|
234
|
-
//#endregion
|
|
235
|
-
//#region src/components/Faker.d.ts
|
|
236
231
|
type Props = {
|
|
237
232
|
name: string;
|
|
238
233
|
typeName: string;
|
|
@@ -241,10 +236,9 @@ type Props = {
|
|
|
241
236
|
description?: string;
|
|
242
237
|
canOverride: boolean;
|
|
243
238
|
typeMode?: PluginFaker['resolvedOptions']['typeMode'];
|
|
239
|
+
keysToOmit?: Array<string> | null;
|
|
244
240
|
};
|
|
245
|
-
export declare function Faker({ node, description, name, typeName, printer, canOverride, typeMode }: Props): KubbReactNode;
|
|
246
|
-
//#endregion
|
|
247
|
-
//#region src/generators/fakerGenerator.d.ts
|
|
241
|
+
export declare function Faker({ node, description, name, typeName, printer, canOverride, typeMode, keysToOmit }: Props): KubbReactNode;
|
|
248
242
|
/**
|
|
249
243
|
* Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
|
|
250
244
|
* per schema in the spec plus per-operation request/response factories. Each
|
|
@@ -252,8 +246,6 @@ export declare function Faker({ node, description, name, typeName, printer, canO
|
|
|
252
246
|
* `@kubb/plugin-ts`.
|
|
253
247
|
*/
|
|
254
248
|
export declare const fakerGenerator: import("kubb/kit").Generator<PluginFaker, unknown>;
|
|
255
|
-
//#endregion
|
|
256
|
-
//#region src/plugin.d.ts
|
|
257
249
|
/**
|
|
258
250
|
* Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
|
|
259
251
|
* cross-plugin dependency references.
|
|
@@ -284,8 +276,6 @@ export declare const pluginFakerName = "plugin-faker";
|
|
|
284
276
|
* ```
|
|
285
277
|
*/
|
|
286
278
|
export declare const pluginFaker: import("kubb/kit").PluginFactory<PluginFaker>;
|
|
287
|
-
//#endregion
|
|
288
|
-
//#region src/resolvers/resolverFaker.d.ts
|
|
289
279
|
/**
|
|
290
280
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|
|
291
281
|
* paths for every generated mock factory. Functions and files are prefixed
|
|
@@ -299,6 +289,5 @@ export declare const pluginFaker: import("kubb/kit").PluginFactory<PluginFaker>;
|
|
|
299
289
|
* ```
|
|
300
290
|
*/
|
|
301
291
|
export declare const resolverFaker: ResolverFaker;
|
|
302
|
-
//#endregion
|
|
303
292
|
export { type PluginFaker, type PrinterFakerFactory, type PrinterFakerNodes, type PrinterFakerOptions, type ResolverFaker, pluginFaker as default };
|
|
304
293
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Exclude, Group, Include, Output, OutputOptions, Override, PluginType, Resolver, ResolverPatch, ast } from "kubb/kit";
|
|
2
2
|
import { KubbReactNode } from "kubb/jsx";
|
|
3
|
-
//#region src/types.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Resolver for Faker that provides naming methods for mock functions.
|
|
6
5
|
*
|
|
@@ -172,8 +171,6 @@ declare global {
|
|
|
172
171
|
}
|
|
173
172
|
}
|
|
174
173
|
}
|
|
175
|
-
//#endregion
|
|
176
|
-
//#region src/printers/printerFaker.d.ts
|
|
177
174
|
/**
|
|
178
175
|
* Partial map of node-type overrides for the Faker printer. Each key is a
|
|
179
176
|
* `SchemaType` (`'string'`, `'date'`, ...) and each handler returns the
|
|
@@ -231,8 +228,6 @@ type PrinterFakerFactory = ast.PrinterFactoryOptions<'faker', PrinterFakerOption
|
|
|
231
228
|
* Handles circular references gracefully by emitting memoizing getters for cyclic properties.
|
|
232
229
|
*/
|
|
233
230
|
export declare const printerFaker: (options: PrinterFakerOptions) => ast.Printer<PrinterFakerFactory>;
|
|
234
|
-
//#endregion
|
|
235
|
-
//#region src/components/Faker.d.ts
|
|
236
231
|
type Props = {
|
|
237
232
|
name: string;
|
|
238
233
|
typeName: string;
|
|
@@ -241,10 +236,9 @@ type Props = {
|
|
|
241
236
|
description?: string;
|
|
242
237
|
canOverride: boolean;
|
|
243
238
|
typeMode?: PluginFaker['resolvedOptions']['typeMode'];
|
|
239
|
+
keysToOmit?: Array<string> | null;
|
|
244
240
|
};
|
|
245
|
-
export declare function Faker({ node, description, name, typeName, printer, canOverride, typeMode }: Props): KubbReactNode;
|
|
246
|
-
//#endregion
|
|
247
|
-
//#region src/generators/fakerGenerator.d.ts
|
|
241
|
+
export declare function Faker({ node, description, name, typeName, printer, canOverride, typeMode, keysToOmit }: Props): KubbReactNode;
|
|
248
242
|
/**
|
|
249
243
|
* Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
|
|
250
244
|
* per schema in the spec plus per-operation request/response factories. Each
|
|
@@ -252,8 +246,6 @@ export declare function Faker({ node, description, name, typeName, printer, canO
|
|
|
252
246
|
* `@kubb/plugin-ts`.
|
|
253
247
|
*/
|
|
254
248
|
export declare const fakerGenerator: import("kubb/kit").Generator<PluginFaker, unknown>;
|
|
255
|
-
//#endregion
|
|
256
|
-
//#region src/plugin.d.ts
|
|
257
249
|
/**
|
|
258
250
|
* Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
|
|
259
251
|
* cross-plugin dependency references.
|
|
@@ -284,8 +276,6 @@ export declare const pluginFakerName = "plugin-faker";
|
|
|
284
276
|
* ```
|
|
285
277
|
*/
|
|
286
278
|
export declare const pluginFaker: import("kubb/kit").PluginFactory<PluginFaker>;
|
|
287
|
-
//#endregion
|
|
288
|
-
//#region src/resolvers/resolverFaker.d.ts
|
|
289
279
|
/**
|
|
290
280
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|
|
291
281
|
* paths for every generated mock factory. Functions and files are prefixed
|
|
@@ -299,6 +289,5 @@ export declare const pluginFaker: import("kubb/kit").PluginFactory<PluginFaker>;
|
|
|
299
289
|
* ```
|
|
300
290
|
*/
|
|
301
291
|
export declare const resolverFaker: ResolverFaker;
|
|
302
|
-
//#endregion
|
|
303
292
|
export { type PluginFaker, type PrinterFakerFactory, type PrinterFakerNodes, type PrinterFakerOptions, type ResolverFaker, pluginFaker as default };
|
|
304
293
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
|
-
import { Diagnostics, Resolver, addGenerator, ast, containsCircularRef, createResolver, defineExtension, defineGenerator, setMacros, setResolver } from "kubb/kit";
|
|
2
|
+
import { Diagnostics, Resolver, addGenerator, ast, containsCircularRef, createResolver, defineExtension, defineGenerator, setMacros, setResolver, syncSchemaRef } from "kubb/kit";
|
|
3
3
|
import { File, Function, jsxRenderer } from "kubb/jsx";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
5
5
|
import { buildParams, enumTypeName, pluginTsName } from "@kubb/plugin-ts";
|
|
6
|
-
|
|
7
|
-
//#region ../../internals/utils/src/casing.ts
|
|
6
|
+
// ../../internals/utils/src/casing.ts
|
|
8
7
|
/**
|
|
9
8
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
10
9
|
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
@@ -41,8 +40,7 @@ function toCamelOrPascal(text, pascal) {
|
|
|
41
40
|
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
42
41
|
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
43
42
|
}
|
|
44
|
-
|
|
45
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
43
|
+
// ../../internals/utils/src/reserved.ts
|
|
46
44
|
/**
|
|
47
45
|
* JavaScript and Java reserved words.
|
|
48
46
|
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
@@ -50,6 +48,7 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
50
48
|
const reservedWords = /* @__PURE__ */ new Set([
|
|
51
49
|
"abstract",
|
|
52
50
|
"arguments",
|
|
51
|
+
"await",
|
|
53
52
|
"boolean",
|
|
54
53
|
"break",
|
|
55
54
|
"byte",
|
|
@@ -180,8 +179,7 @@ function ensureValidVarName(name) {
|
|
|
180
179
|
function isIdentifier(name) {
|
|
181
180
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
182
181
|
}
|
|
183
|
-
|
|
184
|
-
//#region ../../internals/utils/src/strings.ts
|
|
182
|
+
// ../../internals/utils/src/strings.ts
|
|
185
183
|
/**
|
|
186
184
|
* Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
|
|
187
185
|
* any backslash or single quote in the content.
|
|
@@ -242,6 +240,34 @@ function stringify(value) {
|
|
|
242
240
|
function jsDocEscape(input) {
|
|
243
241
|
return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
|
|
244
242
|
}
|
|
243
|
+
const NEEDS_UNICODE = /(?<!\\)(?:\\\\)*\\[pPu]\{|[\u{10000}-\u{10FFFF}]/u;
|
|
244
|
+
const KEPT_ESCAPE = /[A-Za-z0-9^$\\.*+?()[\]{}|/]/;
|
|
245
|
+
/**
|
|
246
|
+
* Drops the backslash from escapes that the `u` flag rejects: an escaped punctuation character that is
|
|
247
|
+
* not a syntax character, and `\-` outside a class. Both match the same character without the backslash.
|
|
248
|
+
*/
|
|
249
|
+
function dropIdentityEscapes(pattern) {
|
|
250
|
+
let inClass = false;
|
|
251
|
+
return pattern.replace(/\\(.)|[[\]]/gs, (match, escaped) => {
|
|
252
|
+
if (escaped === void 0) {
|
|
253
|
+
inClass = match === "[";
|
|
254
|
+
return match;
|
|
255
|
+
}
|
|
256
|
+
return KEPT_ESCAPE.test(escaped) || escaped === "-" && inClass ? match : escaped;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Builds the `RegExp` for a pattern, adding the `u` flag when it uses `\p{...}`, `\P{...}` or `\u{...}`, or
|
|
261
|
+
* holds a character outside the BMP. A pattern that is not valid under `u` keeps the flags it came with.
|
|
262
|
+
*/
|
|
263
|
+
function toRegExp(pattern, flags) {
|
|
264
|
+
if (flags?.includes("u") || !NEEDS_UNICODE.test(pattern)) return new RegExp(pattern, flags);
|
|
265
|
+
try {
|
|
266
|
+
return new RegExp(dropIdentityEscapes(pattern), `${flags ?? ""}u`);
|
|
267
|
+
} catch {
|
|
268
|
+
return new RegExp(pattern, flags);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
245
271
|
/**
|
|
246
272
|
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
247
273
|
* Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
|
|
@@ -258,13 +284,11 @@ function toRegExpString(text, func = "RegExp") {
|
|
|
258
284
|
const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
|
|
259
285
|
const replacementTarget = match?.[1] ?? "";
|
|
260
286
|
const matchedFlags = match?.[2];
|
|
261
|
-
const
|
|
262
|
-
const { source, flags } = new RegExp(cleaned, matchedFlags);
|
|
287
|
+
const { source, flags } = toRegExp(raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, ""), matchedFlags);
|
|
263
288
|
if (func === null) return `/${source}/${flags}`;
|
|
264
289
|
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
265
290
|
}
|
|
266
|
-
|
|
267
|
-
//#region ../../internals/utils/src/codegen.ts
|
|
291
|
+
// ../../internals/utils/src/codegen.ts
|
|
268
292
|
const INDENT = " ";
|
|
269
293
|
/**
|
|
270
294
|
* Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
|
|
@@ -301,8 +325,7 @@ function buildObject(entries) {
|
|
|
301
325
|
if (entries.length === 0) return "{}";
|
|
302
326
|
return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
|
|
303
327
|
}
|
|
304
|
-
|
|
305
|
-
//#region ../../internals/utils/src/fs.ts
|
|
328
|
+
// ../../internals/utils/src/fs.ts
|
|
306
329
|
function toSlash(p) {
|
|
307
330
|
if (p.startsWith("\\\\?\\")) return p;
|
|
308
331
|
return p.replaceAll("\\", "/");
|
|
@@ -344,8 +367,7 @@ function toFilePath(name, caseLast = camelCase) {
|
|
|
344
367
|
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
345
368
|
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
346
369
|
}
|
|
347
|
-
|
|
348
|
-
//#region src/utils.ts
|
|
370
|
+
// src/utils.ts
|
|
349
371
|
/**
|
|
350
372
|
* Returns the `@faker-js/faker` named export for a locale code.
|
|
351
373
|
*
|
|
@@ -396,6 +418,18 @@ const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
|
396
418
|
function canOverrideSchema(node) {
|
|
397
419
|
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
398
420
|
}
|
|
421
|
+
/**
|
|
422
|
+
* Whether a schema can supply object properties when merging faker values.
|
|
423
|
+
*/
|
|
424
|
+
function isObjectSchema(node, seen = /* @__PURE__ */ new Set()) {
|
|
425
|
+
const resolved = ast.resolveRef(node);
|
|
426
|
+
if (seen.has(resolved)) return false;
|
|
427
|
+
seen.add(resolved);
|
|
428
|
+
if (ast.narrowSchema(resolved, ast.schemaTypes.object) || ast.narrowSchema(resolved, ast.schemaTypes.ref)) return true;
|
|
429
|
+
const composition = ast.narrowSchema(resolved, ast.schemaTypes.intersection) ?? ast.narrowSchema(resolved, ast.schemaTypes.union);
|
|
430
|
+
if (!composition) return false;
|
|
431
|
+
return composition.type === ast.schemaTypes.intersection && !composition.members?.length || (composition.members ?? []).some((member) => isObjectSchema(member, seen));
|
|
432
|
+
}
|
|
399
433
|
function shouldInlineSingleResponseSchema(schema) {
|
|
400
434
|
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
401
435
|
}
|
|
@@ -407,11 +441,16 @@ function buildResponseUnionSchema(node, resolver) {
|
|
|
407
441
|
const responses = node.responses.filter((response) => response.content?.[0]?.schema);
|
|
408
442
|
if (!responses.length) return null;
|
|
409
443
|
if (responses.length === 1) {
|
|
410
|
-
const
|
|
444
|
+
const schemas = responses[0].content?.flatMap((content) => content.schema ? [content.schema] : []) ?? [];
|
|
445
|
+
const schema = schemas.length > 1 ? ast.factory.createSchema({
|
|
446
|
+
type: "union",
|
|
447
|
+
members: schemas
|
|
448
|
+
}) : schemas[0];
|
|
411
449
|
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
412
450
|
return ast.factory.createSchema({
|
|
413
451
|
type: "ref",
|
|
414
|
-
name: resolver.response.status(node, responses[0].statusCode)
|
|
452
|
+
name: resolver.response.status(node, responses[0].statusCode),
|
|
453
|
+
schema: responses[0].content?.length === 1 ? schema : void 0
|
|
415
454
|
});
|
|
416
455
|
}
|
|
417
456
|
return ast.factory.createSchema({
|
|
@@ -480,7 +519,8 @@ function getScalarType(node, typeName) {
|
|
|
480
519
|
* Determines the data type, return type, and whether it uses the type name.
|
|
481
520
|
*/
|
|
482
521
|
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
483
|
-
const
|
|
522
|
+
const resolvedNode = ast.resolveRef(node);
|
|
523
|
+
const scalarType = SCALAR_TYPES.has(resolvedNode.type) ? `${getScalarType(resolvedNode, typeName)}${node.nullable || resolvedNode.nullable ? " | null" : ""}` : void 0;
|
|
484
524
|
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
485
525
|
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
486
526
|
return {
|
|
@@ -489,28 +529,27 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
489
529
|
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
490
530
|
};
|
|
491
531
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
|
|
495
|
-
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred" }) {
|
|
532
|
+
// src/components/Faker.tsx
|
|
533
|
+
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred", keysToOmit }) {
|
|
496
534
|
const fakerText = printer.print(node) ?? "undefined";
|
|
497
535
|
const isArray = node.type === "array";
|
|
498
|
-
const isObject =
|
|
536
|
+
const isObject = !!ast.narrowSchema(node, ast.schemaTypes.object) || node.type === ast.schemaTypes.intersection && isObjectSchema(node);
|
|
537
|
+
const isValueIntersection = node.type === ast.schemaTypes.intersection && !isObject;
|
|
499
538
|
const isTuple = node.type === "tuple";
|
|
500
539
|
const isScalar = SCALAR_TYPES.has(node.type);
|
|
501
540
|
const isUnion = node.type === "union";
|
|
502
|
-
const useObjectOverride = canOverride && isObject;
|
|
541
|
+
const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
|
|
503
542
|
const fakerTextWithOverride = (() => {
|
|
504
543
|
if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
|
|
505
544
|
if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
|
|
506
|
-
if (canOverride && (isScalar || isUnion)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
545
|
+
if (canOverride && (isScalar || isUnion || isValueIntersection)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
507
546
|
return fakerText;
|
|
508
547
|
})();
|
|
509
548
|
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
510
549
|
if (!useObjectOverride) {
|
|
511
550
|
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
512
551
|
const returnType = resolvedReturnType;
|
|
513
|
-
const returnExpression = canOverride && !!returnType && (node.type === "ref" || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
552
|
+
const returnExpression = canOverride && !!returnType && (node.type === "ref" && !SCALAR_TYPES.has(ast.resolveRef(node).type) || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
514
553
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
515
554
|
name,
|
|
516
555
|
isExportable: true,
|
|
@@ -525,18 +564,21 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
|
|
|
525
564
|
})
|
|
526
565
|
});
|
|
527
566
|
}
|
|
528
|
-
const returnType = typeMode === "schema" ? typeName : "Omit<typeof defaultFakeData, keyof NoInfer<TData>> & NoInfer<TData>";
|
|
529
567
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
530
|
-
const
|
|
568
|
+
const isCyclic = !!schemaName && !!cyclicSchemas?.has(schemaName);
|
|
569
|
+
const returnType = typeMode === "schema" ? typeName : `Omit<${isCyclic ? typeName : "typeof defaultFakeData"}, keyof NoInfer<TData>> & NoInfer<TData>`;
|
|
570
|
+
const hasGetters = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => containsCircularRef(p.schema, {
|
|
531
571
|
circularSchemas: cyclicSchemas,
|
|
532
572
|
excludeName: schemaName
|
|
533
|
-
}))
|
|
573
|
+
}));
|
|
574
|
+
const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
|
|
575
|
+
const functionBody = hasGetters ? `${declaration}
|
|
534
576
|
if (data) {
|
|
535
577
|
for (const [key, value] of Object.entries(data)) {
|
|
536
578
|
Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
|
|
537
579
|
}
|
|
538
580
|
}
|
|
539
|
-
return defaultFakeData as ${returnType}` :
|
|
581
|
+
return defaultFakeData as ${returnType}` : `${declaration}
|
|
540
582
|
return {
|
|
541
583
|
...defaultFakeData,
|
|
542
584
|
...(data || {}),
|
|
@@ -551,13 +593,12 @@ return {
|
|
|
551
593
|
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
552
594
|
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
553
595
|
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
554
|
-
returnType: typeMode === "schema" ?
|
|
596
|
+
returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
|
|
555
597
|
children: functionBody
|
|
556
598
|
})
|
|
557
599
|
});
|
|
558
600
|
}
|
|
559
|
-
|
|
560
|
-
//#region ../../internals/shared/src/operation.ts
|
|
601
|
+
// ../../internals/shared/src/operation.ts
|
|
561
602
|
/**
|
|
562
603
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
563
604
|
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
@@ -672,17 +713,24 @@ function getOperationParameters(node) {
|
|
|
672
713
|
operationParameterGroupsByNode.set(node, groups);
|
|
673
714
|
return groups;
|
|
674
715
|
}
|
|
675
|
-
|
|
676
|
-
//#region ../../internals/shared/src/resolver.ts
|
|
716
|
+
// ../../internals/shared/src/resolver.ts
|
|
677
717
|
/**
|
|
678
|
-
*
|
|
679
|
-
*
|
|
718
|
+
* Builds the allocation key for a declaration an operation owns. `scope` names which declaration
|
|
719
|
+
* it is, so two of them never share an allocation even when a custom resolver gives both the same
|
|
720
|
+
* name. Leave `scope` empty for the operation's own declaration.
|
|
680
721
|
*
|
|
681
722
|
* @example
|
|
682
|
-
*
|
|
723
|
+
* ```ts
|
|
724
|
+
* resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
|
|
725
|
+
* ```
|
|
683
726
|
*/
|
|
684
|
-
function
|
|
685
|
-
return
|
|
727
|
+
function operationKey(node, ...scope) {
|
|
728
|
+
return [
|
|
729
|
+
"operation",
|
|
730
|
+
node.method,
|
|
731
|
+
node.path,
|
|
732
|
+
...scope.map(String)
|
|
733
|
+
];
|
|
686
734
|
}
|
|
687
735
|
/**
|
|
688
736
|
* Builds the shared `param` namespace. Spread the result into `createResolver`
|
|
@@ -695,15 +743,33 @@ function operationParamName(node, param) {
|
|
|
695
743
|
*/
|
|
696
744
|
function createOperationParamResolver() {
|
|
697
745
|
return {
|
|
698
|
-
name
|
|
746
|
+
name(node, param) {
|
|
747
|
+
const name = this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
748
|
+
return this.resolveName({
|
|
749
|
+
key: operationKey(node, "param", "name", param.in, param.name),
|
|
750
|
+
name
|
|
751
|
+
});
|
|
752
|
+
},
|
|
699
753
|
path(node) {
|
|
700
|
-
|
|
754
|
+
const name = this.name(`${node.operationId} Path`);
|
|
755
|
+
return this.resolveName({
|
|
756
|
+
key: operationKey(node, "param", "path"),
|
|
757
|
+
name
|
|
758
|
+
});
|
|
701
759
|
},
|
|
702
760
|
query(node) {
|
|
703
|
-
|
|
761
|
+
const name = this.name(`${node.operationId} Query`);
|
|
762
|
+
return this.resolveName({
|
|
763
|
+
key: operationKey(node, "param", "query"),
|
|
764
|
+
name
|
|
765
|
+
});
|
|
704
766
|
},
|
|
705
767
|
headers(node) {
|
|
706
|
-
|
|
768
|
+
const name = this.name(`${node.operationId} Headers`);
|
|
769
|
+
return this.resolveName({
|
|
770
|
+
key: operationKey(node, "param", "headers"),
|
|
771
|
+
name
|
|
772
|
+
});
|
|
707
773
|
}
|
|
708
774
|
};
|
|
709
775
|
}
|
|
@@ -720,16 +786,32 @@ function createOperationParamResolver() {
|
|
|
720
786
|
function createOperationResponseResolver() {
|
|
721
787
|
return {
|
|
722
788
|
status(node, statusCode) {
|
|
723
|
-
|
|
789
|
+
const name = this.name(`${node.operationId} Status ${statusCode}`);
|
|
790
|
+
return this.resolveName({
|
|
791
|
+
key: operationKey(node, "response", "status", statusCode),
|
|
792
|
+
name
|
|
793
|
+
});
|
|
724
794
|
},
|
|
725
795
|
body(node) {
|
|
726
|
-
|
|
796
|
+
const name = this.name(`${node.operationId} Body`);
|
|
797
|
+
return this.resolveName({
|
|
798
|
+
key: operationKey(node, "response", "body"),
|
|
799
|
+
name
|
|
800
|
+
});
|
|
727
801
|
},
|
|
728
802
|
responses(node) {
|
|
729
|
-
|
|
803
|
+
const name = this.name(`${node.operationId} Responses`);
|
|
804
|
+
return this.resolveName({
|
|
805
|
+
key: operationKey(node, "response", "responses"),
|
|
806
|
+
name
|
|
807
|
+
});
|
|
730
808
|
},
|
|
731
809
|
response(node) {
|
|
732
|
-
|
|
810
|
+
const name = this.name(`${node.operationId} Response`);
|
|
811
|
+
return this.resolveName({
|
|
812
|
+
key: operationKey(node, "response", "response"),
|
|
813
|
+
name
|
|
814
|
+
});
|
|
733
815
|
}
|
|
734
816
|
};
|
|
735
817
|
}
|
|
@@ -747,8 +829,7 @@ function createCasedFile(caseLast) {
|
|
|
747
829
|
return `${toFilePath(name, caseLast)}${extname}`;
|
|
748
830
|
} };
|
|
749
831
|
}
|
|
750
|
-
|
|
751
|
-
//#region ../../internals/shared/src/group.ts
|
|
832
|
+
// ../../internals/shared/src/group.ts
|
|
752
833
|
/**
|
|
753
834
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
754
835
|
* shared default naming so every plugin groups output consistently:
|
|
@@ -778,8 +859,7 @@ function createGroupConfig(group) {
|
|
|
778
859
|
name: group.name ? group.name : defaultName
|
|
779
860
|
};
|
|
780
861
|
}
|
|
781
|
-
|
|
782
|
-
//#region ../../internals/shared/src/schemaTraversal.ts
|
|
862
|
+
// ../../internals/shared/src/schemaTraversal.ts
|
|
783
863
|
/**
|
|
784
864
|
* Maps each member of a union or intersection schema to its transformed output, pairing every
|
|
785
865
|
* result with the original member.
|
|
@@ -800,8 +880,7 @@ function mapSchemaItems(node, transform) {
|
|
|
800
880
|
output: transform(schema)
|
|
801
881
|
}));
|
|
802
882
|
}
|
|
803
|
-
|
|
804
|
-
//#region src/utils/imports.ts
|
|
883
|
+
// src/utils/imports.ts
|
|
805
884
|
function escapeRegExp(value) {
|
|
806
885
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
807
886
|
}
|
|
@@ -849,8 +928,7 @@ function aliasConflictingImports(imports, reservedNames) {
|
|
|
849
928
|
function rewriteAliasedImports(text, aliases) {
|
|
850
929
|
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
851
930
|
}
|
|
852
|
-
|
|
853
|
-
//#region src/printers/printerFaker.ts
|
|
931
|
+
// src/printers/printerFaker.ts
|
|
854
932
|
/**
|
|
855
933
|
* Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
|
|
856
934
|
* 64-bit integers, so the mock has to be digits rather than letters.
|
|
@@ -986,7 +1064,9 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
986
1064
|
},
|
|
987
1065
|
enum(node) {
|
|
988
1066
|
const { typeName } = this.options;
|
|
989
|
-
|
|
1067
|
+
const values = ast.getSchemaLiteralValues(node);
|
|
1068
|
+
if (values.length === 1 && values[0] !== null && typeof values[0] === "object") return JSON.stringify(values[0]);
|
|
1069
|
+
return `faker.helpers.arrayElement${typeName ? `<${typeName}>` : ""}([${values.map(parseEnumValue).join(", ")}])`;
|
|
990
1070
|
},
|
|
991
1071
|
union(node) {
|
|
992
1072
|
const { discriminatorPropertyName } = node;
|
|
@@ -1010,9 +1090,14 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1010
1090
|
}).map(({ output }) => output).filter((item) => Boolean(item)).join(", ")}])`;
|
|
1011
1091
|
},
|
|
1012
1092
|
intersection(node) {
|
|
1013
|
-
const
|
|
1093
|
+
const objectMembers = (node.members ?? []).filter((member) => isObjectSchema(member));
|
|
1094
|
+
const members = objectMembers.length ? objectMembers : node.members;
|
|
1095
|
+
const items = mapSchemaMembers({
|
|
1096
|
+
...node,
|
|
1097
|
+
members
|
|
1098
|
+
}, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
|
|
1014
1099
|
if (items.length === 0) return "{}";
|
|
1015
|
-
return items.length === 1 ? items
|
|
1100
|
+
return !objectMembers.length || items.length === 1 ? items.at(-1) : `{...${items.join(", ...")}}`;
|
|
1016
1101
|
},
|
|
1017
1102
|
array(node) {
|
|
1018
1103
|
const items = mapSchemaItems(node, (member) => printNested(member, {
|
|
@@ -1035,7 +1120,13 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1035
1120
|
},
|
|
1036
1121
|
object(node) {
|
|
1037
1122
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
1038
|
-
|
|
1123
|
+
const keySchema = node.propertyNames && syncSchemaRef(node.propertyNames);
|
|
1124
|
+
const valueSchema = node.additionalProperties;
|
|
1125
|
+
const recordProperties = keySchema?.type === "enum" && typeof valueSchema === "object" ? ast.getSchemaLiteralValues(keySchema).filter((key) => typeof key === "string" && !node.properties.some((property) => property.name === key)).map((name) => ast.factory.createProperty({
|
|
1126
|
+
name,
|
|
1127
|
+
schema: valueSchema
|
|
1128
|
+
})) : [];
|
|
1129
|
+
return buildObject([...node.properties, ...recordProperties].map((property) => {
|
|
1039
1130
|
const value = printNested(property.schema, {
|
|
1040
1131
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
1041
1132
|
nestedInObject: true
|
|
@@ -1051,8 +1142,7 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1051
1142
|
overrides: options.nodes
|
|
1052
1143
|
};
|
|
1053
1144
|
});
|
|
1054
|
-
|
|
1055
|
-
//#region src/generators/fakerGenerator.tsx
|
|
1145
|
+
// src/generators/fakerGenerator.tsx
|
|
1056
1146
|
/**
|
|
1057
1147
|
* Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
|
|
1058
1148
|
* per schema in the spec plus per-operation request/response factories. Each
|
|
@@ -1224,7 +1314,7 @@ const fakerGenerator = defineGenerator({
|
|
|
1224
1314
|
name: baseName,
|
|
1225
1315
|
typeName: tsBaseName,
|
|
1226
1316
|
description,
|
|
1227
|
-
|
|
1317
|
+
keysToOmit: primary.keysToOmit
|
|
1228
1318
|
}];
|
|
1229
1319
|
}
|
|
1230
1320
|
const variants = resolveContentTypeVariants(entries, baseName);
|
|
@@ -1241,7 +1331,7 @@ const fakerGenerator = defineGenerator({
|
|
|
1241
1331
|
name: variant.name,
|
|
1242
1332
|
typeName: getPerContentTypeName(tsBaseName, variant.suffix),
|
|
1243
1333
|
description,
|
|
1244
|
-
|
|
1334
|
+
keysToOmit: variant.keysToOmit
|
|
1245
1335
|
})), {
|
|
1246
1336
|
schema: unionSchema,
|
|
1247
1337
|
name: baseName,
|
|
@@ -1291,8 +1381,15 @@ const fakerGenerator = defineGenerator({
|
|
|
1291
1381
|
group: group ?? void 0
|
|
1292
1382
|
}).filter((entry) => entry.path !== meta.file.path);
|
|
1293
1383
|
}
|
|
1294
|
-
function renderEntry({ schema, name, typeName, description, skipImportNames = [] }) {
|
|
1384
|
+
function renderEntry({ schema, name, typeName, description, keysToOmit, skipImportNames = [] }) {
|
|
1295
1385
|
if (!schema) return null;
|
|
1386
|
+
if (schema.type === ast.schemaTypes.object && keysToOmit?.length) {
|
|
1387
|
+
schema = {
|
|
1388
|
+
...schema,
|
|
1389
|
+
properties: schema.properties.filter((property) => !keysToOmit?.includes(property.name))
|
|
1390
|
+
};
|
|
1391
|
+
keysToOmit = void 0;
|
|
1392
|
+
}
|
|
1296
1393
|
const canOverride = canOverrideSchema(schema);
|
|
1297
1394
|
const printerInstance = printerFaker({
|
|
1298
1395
|
resolver,
|
|
@@ -1301,7 +1398,8 @@ const fakerGenerator = defineGenerator({
|
|
|
1301
1398
|
dateParser,
|
|
1302
1399
|
regexGenerator,
|
|
1303
1400
|
nodes: printer?.nodes,
|
|
1304
|
-
cyclicSchemas
|
|
1401
|
+
cyclicSchemas,
|
|
1402
|
+
nestedInObject: !!keysToOmit?.length
|
|
1305
1403
|
});
|
|
1306
1404
|
const fakerText = printerInstance.print(schema) ?? "undefined";
|
|
1307
1405
|
const { imports, aliases } = aliasConflictingImports(filterUsedImports(resolveMockImports(schema), fakerText, skipImportNames), localHelperNames);
|
|
@@ -1340,7 +1438,8 @@ const fakerGenerator = defineGenerator({
|
|
|
1340
1438
|
print: () => rewrittenFakerText
|
|
1341
1439
|
},
|
|
1342
1440
|
canOverride,
|
|
1343
|
-
typeMode
|
|
1441
|
+
typeMode,
|
|
1442
|
+
keysToOmit
|
|
1344
1443
|
})
|
|
1345
1444
|
] });
|
|
1346
1445
|
}
|
|
@@ -1397,17 +1496,14 @@ const fakerGenerator = defineGenerator({
|
|
|
1397
1496
|
});
|
|
1398
1497
|
}
|
|
1399
1498
|
});
|
|
1400
|
-
|
|
1401
|
-
//#region kubb-extension.json
|
|
1499
|
+
// kubb-extension.json
|
|
1402
1500
|
var compatibility = {
|
|
1403
|
-
"kubb": ">=5.
|
|
1501
|
+
"kubb": ">=5.14.6",
|
|
1404
1502
|
"node": ">=22.22"
|
|
1405
1503
|
};
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
//#endregion
|
|
1410
|
-
//#region src/resolvers/resolverFaker.ts
|
|
1504
|
+
// package.json
|
|
1505
|
+
var version = "5.2.2";
|
|
1506
|
+
// src/resolvers/resolverFaker.ts
|
|
1411
1507
|
/**
|
|
1412
1508
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|
|
1413
1509
|
* paths for every generated mock factory. Functions and files are prefixed
|
|
@@ -1429,8 +1525,7 @@ const resolverFaker = createResolver({
|
|
|
1429
1525
|
param: createOperationParamResolver(),
|
|
1430
1526
|
response: createOperationResponseResolver()
|
|
1431
1527
|
});
|
|
1432
|
-
|
|
1433
|
-
//#region src/plugin.ts
|
|
1528
|
+
// src/plugin.ts
|
|
1434
1529
|
/**
|
|
1435
1530
|
* Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
|
|
1436
1531
|
* cross-plugin dependency references.
|
|
@@ -1491,7 +1586,6 @@ const pluginFaker = defineExtension({
|
|
|
1491
1586
|
};
|
|
1492
1587
|
}
|
|
1493
1588
|
});
|
|
1494
|
-
//#endregion
|
|
1495
1589
|
export { Faker, pluginFaker as default, pluginFaker, fakerGenerator, pluginFakerName, printerFaker, resolverFaker };
|
|
1496
1590
|
|
|
1497
1591
|
//# sourceMappingURL=index.js.map
|