@kubb/plugin-faker 5.2.0 → 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 +169 -81
- 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 +170 -82
- 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
|
*
|
|
@@ -397,10 +419,16 @@ function canOverrideSchema(node) {
|
|
|
397
419
|
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
398
420
|
}
|
|
399
421
|
/**
|
|
400
|
-
*
|
|
422
|
+
* Whether a schema can supply object properties when merging faker values.
|
|
401
423
|
*/
|
|
402
|
-
function
|
|
403
|
-
|
|
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));
|
|
404
432
|
}
|
|
405
433
|
function shouldInlineSingleResponseSchema(schema) {
|
|
406
434
|
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
@@ -413,11 +441,16 @@ function buildResponseUnionSchema(node, resolver) {
|
|
|
413
441
|
const responses = node.responses.filter((response) => response.content?.[0]?.schema);
|
|
414
442
|
if (!responses.length) return null;
|
|
415
443
|
if (responses.length === 1) {
|
|
416
|
-
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];
|
|
417
449
|
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
418
450
|
return ast.factory.createSchema({
|
|
419
451
|
type: "ref",
|
|
420
|
-
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
|
|
421
454
|
});
|
|
422
455
|
}
|
|
423
456
|
return ast.factory.createSchema({
|
|
@@ -486,7 +519,8 @@ function getScalarType(node, typeName) {
|
|
|
486
519
|
* Determines the data type, return type, and whether it uses the type name.
|
|
487
520
|
*/
|
|
488
521
|
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
489
|
-
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;
|
|
490
524
|
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
491
525
|
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
492
526
|
return {
|
|
@@ -495,28 +529,27 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
495
529
|
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
496
530
|
};
|
|
497
531
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
|
|
501
|
-
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 }) {
|
|
502
534
|
const fakerText = printer.print(node) ?? "undefined";
|
|
503
535
|
const isArray = node.type === "array";
|
|
504
|
-
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;
|
|
505
538
|
const isTuple = node.type === "tuple";
|
|
506
539
|
const isScalar = SCALAR_TYPES.has(node.type);
|
|
507
540
|
const isUnion = node.type === "union";
|
|
508
|
-
const useObjectOverride = canOverride && isObject;
|
|
541
|
+
const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
|
|
509
542
|
const fakerTextWithOverride = (() => {
|
|
510
543
|
if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
|
|
511
544
|
if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
|
|
512
|
-
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}`;
|
|
513
546
|
return fakerText;
|
|
514
547
|
})();
|
|
515
548
|
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
516
549
|
if (!useObjectOverride) {
|
|
517
550
|
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
518
551
|
const returnType = resolvedReturnType;
|
|
519
|
-
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;
|
|
520
553
|
return /* @__PURE__ */ jsx(File.Source, {
|
|
521
554
|
name,
|
|
522
555
|
isExportable: true,
|
|
@@ -531,18 +564,21 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
|
|
|
531
564
|
})
|
|
532
565
|
});
|
|
533
566
|
}
|
|
534
|
-
const returnType = typeMode === "schema" ? typeName : "Omit<typeof defaultFakeData, keyof NoInfer<TData>> & NoInfer<TData>";
|
|
535
567
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
536
|
-
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, {
|
|
537
571
|
circularSchemas: cyclicSchemas,
|
|
538
572
|
excludeName: schemaName
|
|
539
|
-
}))
|
|
573
|
+
}));
|
|
574
|
+
const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
|
|
575
|
+
const functionBody = hasGetters ? `${declaration}
|
|
540
576
|
if (data) {
|
|
541
577
|
for (const [key, value] of Object.entries(data)) {
|
|
542
578
|
Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
|
|
543
579
|
}
|
|
544
580
|
}
|
|
545
|
-
return defaultFakeData as ${returnType}` :
|
|
581
|
+
return defaultFakeData as ${returnType}` : `${declaration}
|
|
546
582
|
return {
|
|
547
583
|
...defaultFakeData,
|
|
548
584
|
...(data || {}),
|
|
@@ -557,13 +593,12 @@ return {
|
|
|
557
593
|
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
558
594
|
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
559
595
|
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
560
|
-
returnType: typeMode === "schema" ?
|
|
596
|
+
returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
|
|
561
597
|
children: functionBody
|
|
562
598
|
})
|
|
563
599
|
});
|
|
564
600
|
}
|
|
565
|
-
|
|
566
|
-
//#region ../../internals/shared/src/operation.ts
|
|
601
|
+
// ../../internals/shared/src/operation.ts
|
|
567
602
|
/**
|
|
568
603
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
569
604
|
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
@@ -678,17 +713,24 @@ function getOperationParameters(node) {
|
|
|
678
713
|
operationParameterGroupsByNode.set(node, groups);
|
|
679
714
|
return groups;
|
|
680
715
|
}
|
|
681
|
-
|
|
682
|
-
//#region ../../internals/shared/src/resolver.ts
|
|
716
|
+
// ../../internals/shared/src/resolver.ts
|
|
683
717
|
/**
|
|
684
|
-
*
|
|
685
|
-
*
|
|
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.
|
|
686
721
|
*
|
|
687
722
|
* @example
|
|
688
|
-
*
|
|
723
|
+
* ```ts
|
|
724
|
+
* resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
|
|
725
|
+
* ```
|
|
689
726
|
*/
|
|
690
|
-
function
|
|
691
|
-
return
|
|
727
|
+
function operationKey(node, ...scope) {
|
|
728
|
+
return [
|
|
729
|
+
"operation",
|
|
730
|
+
node.method,
|
|
731
|
+
node.path,
|
|
732
|
+
...scope.map(String)
|
|
733
|
+
];
|
|
692
734
|
}
|
|
693
735
|
/**
|
|
694
736
|
* Builds the shared `param` namespace. Spread the result into `createResolver`
|
|
@@ -701,15 +743,33 @@ function operationParamName(node, param) {
|
|
|
701
743
|
*/
|
|
702
744
|
function createOperationParamResolver() {
|
|
703
745
|
return {
|
|
704
|
-
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
|
+
},
|
|
705
753
|
path(node) {
|
|
706
|
-
|
|
754
|
+
const name = this.name(`${node.operationId} Path`);
|
|
755
|
+
return this.resolveName({
|
|
756
|
+
key: operationKey(node, "param", "path"),
|
|
757
|
+
name
|
|
758
|
+
});
|
|
707
759
|
},
|
|
708
760
|
query(node) {
|
|
709
|
-
|
|
761
|
+
const name = this.name(`${node.operationId} Query`);
|
|
762
|
+
return this.resolveName({
|
|
763
|
+
key: operationKey(node, "param", "query"),
|
|
764
|
+
name
|
|
765
|
+
});
|
|
710
766
|
},
|
|
711
767
|
headers(node) {
|
|
712
|
-
|
|
768
|
+
const name = this.name(`${node.operationId} Headers`);
|
|
769
|
+
return this.resolveName({
|
|
770
|
+
key: operationKey(node, "param", "headers"),
|
|
771
|
+
name
|
|
772
|
+
});
|
|
713
773
|
}
|
|
714
774
|
};
|
|
715
775
|
}
|
|
@@ -726,16 +786,32 @@ function createOperationParamResolver() {
|
|
|
726
786
|
function createOperationResponseResolver() {
|
|
727
787
|
return {
|
|
728
788
|
status(node, statusCode) {
|
|
729
|
-
|
|
789
|
+
const name = this.name(`${node.operationId} Status ${statusCode}`);
|
|
790
|
+
return this.resolveName({
|
|
791
|
+
key: operationKey(node, "response", "status", statusCode),
|
|
792
|
+
name
|
|
793
|
+
});
|
|
730
794
|
},
|
|
731
795
|
body(node) {
|
|
732
|
-
|
|
796
|
+
const name = this.name(`${node.operationId} Body`);
|
|
797
|
+
return this.resolveName({
|
|
798
|
+
key: operationKey(node, "response", "body"),
|
|
799
|
+
name
|
|
800
|
+
});
|
|
733
801
|
},
|
|
734
802
|
responses(node) {
|
|
735
|
-
|
|
803
|
+
const name = this.name(`${node.operationId} Responses`);
|
|
804
|
+
return this.resolveName({
|
|
805
|
+
key: operationKey(node, "response", "responses"),
|
|
806
|
+
name
|
|
807
|
+
});
|
|
736
808
|
},
|
|
737
809
|
response(node) {
|
|
738
|
-
|
|
810
|
+
const name = this.name(`${node.operationId} Response`);
|
|
811
|
+
return this.resolveName({
|
|
812
|
+
key: operationKey(node, "response", "response"),
|
|
813
|
+
name
|
|
814
|
+
});
|
|
739
815
|
}
|
|
740
816
|
};
|
|
741
817
|
}
|
|
@@ -753,8 +829,7 @@ function createCasedFile(caseLast) {
|
|
|
753
829
|
return `${toFilePath(name, caseLast)}${extname}`;
|
|
754
830
|
} };
|
|
755
831
|
}
|
|
756
|
-
|
|
757
|
-
//#region ../../internals/shared/src/group.ts
|
|
832
|
+
// ../../internals/shared/src/group.ts
|
|
758
833
|
/**
|
|
759
834
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
760
835
|
* shared default naming so every plugin groups output consistently:
|
|
@@ -784,8 +859,7 @@ function createGroupConfig(group) {
|
|
|
784
859
|
name: group.name ? group.name : defaultName
|
|
785
860
|
};
|
|
786
861
|
}
|
|
787
|
-
|
|
788
|
-
//#region ../../internals/shared/src/schemaTraversal.ts
|
|
862
|
+
// ../../internals/shared/src/schemaTraversal.ts
|
|
789
863
|
/**
|
|
790
864
|
* Maps each member of a union or intersection schema to its transformed output, pairing every
|
|
791
865
|
* result with the original member.
|
|
@@ -806,8 +880,7 @@ function mapSchemaItems(node, transform) {
|
|
|
806
880
|
output: transform(schema)
|
|
807
881
|
}));
|
|
808
882
|
}
|
|
809
|
-
|
|
810
|
-
//#region src/utils/imports.ts
|
|
883
|
+
// src/utils/imports.ts
|
|
811
884
|
function escapeRegExp(value) {
|
|
812
885
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
813
886
|
}
|
|
@@ -855,8 +928,7 @@ function aliasConflictingImports(imports, reservedNames) {
|
|
|
855
928
|
function rewriteAliasedImports(text, aliases) {
|
|
856
929
|
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
857
930
|
}
|
|
858
|
-
|
|
859
|
-
//#region src/printers/printerFaker.ts
|
|
931
|
+
// src/printers/printerFaker.ts
|
|
860
932
|
/**
|
|
861
933
|
* Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
|
|
862
934
|
* 64-bit integers, so the mock has to be digits rather than letters.
|
|
@@ -987,12 +1059,14 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
987
1059
|
});
|
|
988
1060
|
if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
|
|
989
1061
|
const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
|
|
990
|
-
if (!this.options.nestedInObject && canOverrideSchema(
|
|
1062
|
+
if (!this.options.nestedInObject && canOverrideSchema(ast.resolveRef(node))) return `${resolvedName}(data)`;
|
|
991
1063
|
return `${resolvedName}()`;
|
|
992
1064
|
},
|
|
993
1065
|
enum(node) {
|
|
994
1066
|
const { typeName } = this.options;
|
|
995
|
-
|
|
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(", ")}])`;
|
|
996
1070
|
},
|
|
997
1071
|
union(node) {
|
|
998
1072
|
const { discriminatorPropertyName } = node;
|
|
@@ -1016,9 +1090,14 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1016
1090
|
}).map(({ output }) => output).filter((item) => Boolean(item)).join(", ")}])`;
|
|
1017
1091
|
},
|
|
1018
1092
|
intersection(node) {
|
|
1019
|
-
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");
|
|
1020
1099
|
if (items.length === 0) return "{}";
|
|
1021
|
-
return items.length === 1 ? items
|
|
1100
|
+
return !objectMembers.length || items.length === 1 ? items.at(-1) : `{...${items.join(", ...")}}`;
|
|
1022
1101
|
},
|
|
1023
1102
|
array(node) {
|
|
1024
1103
|
const items = mapSchemaItems(node, (member) => printNested(member, {
|
|
@@ -1041,7 +1120,13 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1041
1120
|
},
|
|
1042
1121
|
object(node) {
|
|
1043
1122
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
1044
|
-
|
|
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) => {
|
|
1045
1130
|
const value = printNested(property.schema, {
|
|
1046
1131
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
1047
1132
|
nestedInObject: true
|
|
@@ -1057,8 +1142,7 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1057
1142
|
overrides: options.nodes
|
|
1058
1143
|
};
|
|
1059
1144
|
});
|
|
1060
|
-
|
|
1061
|
-
//#region src/generators/fakerGenerator.tsx
|
|
1145
|
+
// src/generators/fakerGenerator.tsx
|
|
1062
1146
|
/**
|
|
1063
1147
|
* Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
|
|
1064
1148
|
* per schema in the spec plus per-operation request/response factories. Each
|
|
@@ -1230,7 +1314,7 @@ const fakerGenerator = defineGenerator({
|
|
|
1230
1314
|
name: baseName,
|
|
1231
1315
|
typeName: tsBaseName,
|
|
1232
1316
|
description,
|
|
1233
|
-
|
|
1317
|
+
keysToOmit: primary.keysToOmit
|
|
1234
1318
|
}];
|
|
1235
1319
|
}
|
|
1236
1320
|
const variants = resolveContentTypeVariants(entries, baseName);
|
|
@@ -1247,7 +1331,7 @@ const fakerGenerator = defineGenerator({
|
|
|
1247
1331
|
name: variant.name,
|
|
1248
1332
|
typeName: getPerContentTypeName(tsBaseName, variant.suffix),
|
|
1249
1333
|
description,
|
|
1250
|
-
|
|
1334
|
+
keysToOmit: variant.keysToOmit
|
|
1251
1335
|
})), {
|
|
1252
1336
|
schema: unionSchema,
|
|
1253
1337
|
name: baseName,
|
|
@@ -1297,8 +1381,15 @@ const fakerGenerator = defineGenerator({
|
|
|
1297
1381
|
group: group ?? void 0
|
|
1298
1382
|
}).filter((entry) => entry.path !== meta.file.path);
|
|
1299
1383
|
}
|
|
1300
|
-
function renderEntry({ schema, name, typeName, description, skipImportNames = [] }) {
|
|
1384
|
+
function renderEntry({ schema, name, typeName, description, keysToOmit, skipImportNames = [] }) {
|
|
1301
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
|
+
}
|
|
1302
1393
|
const canOverride = canOverrideSchema(schema);
|
|
1303
1394
|
const printerInstance = printerFaker({
|
|
1304
1395
|
resolver,
|
|
@@ -1307,7 +1398,8 @@ const fakerGenerator = defineGenerator({
|
|
|
1307
1398
|
dateParser,
|
|
1308
1399
|
regexGenerator,
|
|
1309
1400
|
nodes: printer?.nodes,
|
|
1310
|
-
cyclicSchemas
|
|
1401
|
+
cyclicSchemas,
|
|
1402
|
+
nestedInObject: !!keysToOmit?.length
|
|
1311
1403
|
});
|
|
1312
1404
|
const fakerText = printerInstance.print(schema) ?? "undefined";
|
|
1313
1405
|
const { imports, aliases } = aliasConflictingImports(filterUsedImports(resolveMockImports(schema), fakerText, skipImportNames), localHelperNames);
|
|
@@ -1346,7 +1438,8 @@ const fakerGenerator = defineGenerator({
|
|
|
1346
1438
|
print: () => rewrittenFakerText
|
|
1347
1439
|
},
|
|
1348
1440
|
canOverride,
|
|
1349
|
-
typeMode
|
|
1441
|
+
typeMode,
|
|
1442
|
+
keysToOmit
|
|
1350
1443
|
})
|
|
1351
1444
|
] });
|
|
1352
1445
|
}
|
|
@@ -1403,17 +1496,14 @@ const fakerGenerator = defineGenerator({
|
|
|
1403
1496
|
});
|
|
1404
1497
|
}
|
|
1405
1498
|
});
|
|
1406
|
-
|
|
1407
|
-
//#region kubb-extension.json
|
|
1499
|
+
// kubb-extension.json
|
|
1408
1500
|
var compatibility = {
|
|
1409
|
-
"kubb": ">=5.
|
|
1501
|
+
"kubb": ">=5.14.6",
|
|
1410
1502
|
"node": ">=22.22"
|
|
1411
1503
|
};
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
//#endregion
|
|
1416
|
-
//#region src/resolvers/resolverFaker.ts
|
|
1504
|
+
// package.json
|
|
1505
|
+
var version = "5.2.2";
|
|
1506
|
+
// src/resolvers/resolverFaker.ts
|
|
1417
1507
|
/**
|
|
1418
1508
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|
|
1419
1509
|
* paths for every generated mock factory. Functions and files are prefixed
|
|
@@ -1435,8 +1525,7 @@ const resolverFaker = createResolver({
|
|
|
1435
1525
|
param: createOperationParamResolver(),
|
|
1436
1526
|
response: createOperationResponseResolver()
|
|
1437
1527
|
});
|
|
1438
|
-
|
|
1439
|
-
//#region src/plugin.ts
|
|
1528
|
+
// src/plugin.ts
|
|
1440
1529
|
/**
|
|
1441
1530
|
* Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
|
|
1442
1531
|
* cross-plugin dependency references.
|
|
@@ -1497,7 +1586,6 @@ const pluginFaker = defineExtension({
|
|
|
1497
1586
|
};
|
|
1498
1587
|
}
|
|
1499
1588
|
});
|
|
1500
|
-
//#endregion
|
|
1501
1589
|
export { Faker, pluginFaker as default, pluginFaker, fakerGenerator, pluginFakerName, printerFaker, resolverFaker };
|
|
1502
1590
|
|
|
1503
1591
|
//# sourceMappingURL=index.js.map
|