@kubb/plugin-faker 5.2.1 → 5.2.3
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 +176 -119
- 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 +173 -116
- 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.cjs
CHANGED
|
@@ -2,51 +2,12 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
//#endregion
|
|
6
5
|
let node_path = require("node:path");
|
|
7
6
|
let kubb_kit = require("kubb/kit");
|
|
8
7
|
let kubb_jsx = require("kubb/jsx");
|
|
9
8
|
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
10
9
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
14
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
15
|
-
* and capitalizes each word according to `pascal`.
|
|
16
|
-
*
|
|
17
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
18
|
-
*/
|
|
19
|
-
function convert(text, pascal) {
|
|
20
|
-
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
21
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
22
|
-
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
23
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
24
|
-
}
|
|
25
|
-
const cache = /* @__PURE__ */ new Map();
|
|
26
|
-
const cacheLimit = 1e4;
|
|
27
|
-
function toCamelOrPascal(text, pascal) {
|
|
28
|
-
const key = `${pascal ? "P" : "c"}${text}`;
|
|
29
|
-
const cached = cache.get(key);
|
|
30
|
-
if (cached !== void 0) return cached;
|
|
31
|
-
const result = convert(text, pascal);
|
|
32
|
-
if (cache.size >= cacheLimit) cache.clear();
|
|
33
|
-
cache.set(key, result);
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Converts `text` to camelCase.
|
|
38
|
-
*
|
|
39
|
-
* @example Word boundaries
|
|
40
|
-
* `camelCase('hello-world') // 'helloWorld'`
|
|
41
|
-
*
|
|
42
|
-
* @example With a prefix
|
|
43
|
-
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
44
|
-
*/
|
|
45
|
-
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
46
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region ../../internals/utils/src/reserved.ts
|
|
10
|
+
// ../../internals/utils/src/reserved.ts
|
|
50
11
|
/**
|
|
51
12
|
* JavaScript and Java reserved words.
|
|
52
13
|
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
@@ -54,6 +15,7 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
|
54
15
|
const reservedWords = /* @__PURE__ */ new Set([
|
|
55
16
|
"abstract",
|
|
56
17
|
"arguments",
|
|
18
|
+
"await",
|
|
57
19
|
"boolean",
|
|
58
20
|
"break",
|
|
59
21
|
"byte",
|
|
@@ -184,8 +146,7 @@ function ensureValidVarName(name) {
|
|
|
184
146
|
function isIdentifier(name) {
|
|
185
147
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
186
148
|
}
|
|
187
|
-
|
|
188
|
-
//#region ../../internals/utils/src/strings.ts
|
|
149
|
+
// ../../internals/utils/src/strings.ts
|
|
189
150
|
/**
|
|
190
151
|
* Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
|
|
191
152
|
* any backslash or single quote in the content.
|
|
@@ -246,6 +207,34 @@ function stringify(value) {
|
|
|
246
207
|
function jsDocEscape(input) {
|
|
247
208
|
return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
|
|
248
209
|
}
|
|
210
|
+
const NEEDS_UNICODE = /(?<!\\)(?:\\\\)*\\[pPu]\{|[\u{10000}-\u{10FFFF}]/u;
|
|
211
|
+
const KEPT_ESCAPE = /[A-Za-z0-9^$\\.*+?()[\]{}|/]/;
|
|
212
|
+
/**
|
|
213
|
+
* Drops the backslash from escapes that the `u` flag rejects: an escaped punctuation character that is
|
|
214
|
+
* not a syntax character, and `\-` outside a class. Both match the same character without the backslash.
|
|
215
|
+
*/
|
|
216
|
+
function dropIdentityEscapes(pattern) {
|
|
217
|
+
let inClass = false;
|
|
218
|
+
return pattern.replace(/\\(.)|[[\]]/gs, (match, escaped) => {
|
|
219
|
+
if (escaped === void 0) {
|
|
220
|
+
inClass = match === "[";
|
|
221
|
+
return match;
|
|
222
|
+
}
|
|
223
|
+
return KEPT_ESCAPE.test(escaped) || escaped === "-" && inClass ? match : escaped;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Builds the `RegExp` for a pattern, adding the `u` flag when it uses `\p{...}`, `\P{...}` or `\u{...}`, or
|
|
228
|
+
* holds a character outside the BMP. A pattern that is not valid under `u` keeps the flags it came with.
|
|
229
|
+
*/
|
|
230
|
+
function toRegExp(pattern, flags) {
|
|
231
|
+
if (flags?.includes("u") || !NEEDS_UNICODE.test(pattern)) return new RegExp(pattern, flags);
|
|
232
|
+
try {
|
|
233
|
+
return new RegExp(dropIdentityEscapes(pattern), `${flags ?? ""}u`);
|
|
234
|
+
} catch {
|
|
235
|
+
return new RegExp(pattern, flags);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
249
238
|
/**
|
|
250
239
|
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
251
240
|
* Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
|
|
@@ -262,13 +251,11 @@ function toRegExpString(text, func = "RegExp") {
|
|
|
262
251
|
const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
|
|
263
252
|
const replacementTarget = match?.[1] ?? "";
|
|
264
253
|
const matchedFlags = match?.[2];
|
|
265
|
-
const
|
|
266
|
-
const { source, flags } = new RegExp(cleaned, matchedFlags);
|
|
254
|
+
const { source, flags } = toRegExp(raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, ""), matchedFlags);
|
|
267
255
|
if (func === null) return `/${source}/${flags}`;
|
|
268
256
|
return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
|
|
269
257
|
}
|
|
270
|
-
|
|
271
|
-
//#region ../../internals/utils/src/codegen.ts
|
|
258
|
+
// ../../internals/utils/src/codegen.ts
|
|
272
259
|
const INDENT = " ";
|
|
273
260
|
/**
|
|
274
261
|
* Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
|
|
@@ -305,8 +292,7 @@ function buildObject(entries) {
|
|
|
305
292
|
if (entries.length === 0) return "{}";
|
|
306
293
|
return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
|
|
307
294
|
}
|
|
308
|
-
|
|
309
|
-
//#region ../../internals/utils/src/fs.ts
|
|
295
|
+
// ../../internals/utils/src/fs.ts
|
|
310
296
|
function toSlash(p) {
|
|
311
297
|
if (p.startsWith("\\\\?\\")) return p;
|
|
312
298
|
return p.replaceAll("\\", "/");
|
|
@@ -344,12 +330,11 @@ function getRelativePath(rootDir, filePath) {
|
|
|
344
330
|
* @example Suffix applied to the final segment only
|
|
345
331
|
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
346
332
|
*/
|
|
347
|
-
function toFilePath(name, caseLast = camelCase) {
|
|
333
|
+
function toFilePath(name, caseLast = kubb_kit.camelCase) {
|
|
348
334
|
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
349
|
-
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
335
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : (0, kubb_kit.camelCase)(part)).filter(Boolean).join("/");
|
|
350
336
|
}
|
|
351
|
-
|
|
352
|
-
//#region src/utils.ts
|
|
337
|
+
// src/utils.ts
|
|
353
338
|
/**
|
|
354
339
|
* Returns the `@faker-js/faker` named export for a locale code.
|
|
355
340
|
*
|
|
@@ -400,6 +385,18 @@ const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
|
400
385
|
function canOverrideSchema(node) {
|
|
401
386
|
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
402
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* Whether a schema can supply object properties when merging faker values.
|
|
390
|
+
*/
|
|
391
|
+
function isObjectSchema(node, seen = /* @__PURE__ */ new Set()) {
|
|
392
|
+
const resolved = kubb_kit.ast.resolveRef(node);
|
|
393
|
+
if (seen.has(resolved)) return false;
|
|
394
|
+
seen.add(resolved);
|
|
395
|
+
if (kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.object) || kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.ref)) return true;
|
|
396
|
+
const composition = kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.intersection) ?? kubb_kit.ast.narrowSchema(resolved, kubb_kit.ast.schemaTypes.union);
|
|
397
|
+
if (!composition) return false;
|
|
398
|
+
return composition.type === kubb_kit.ast.schemaTypes.intersection && !composition.members?.length || (composition.members ?? []).some((member) => isObjectSchema(member, seen));
|
|
399
|
+
}
|
|
403
400
|
function shouldInlineSingleResponseSchema(schema) {
|
|
404
401
|
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
405
402
|
}
|
|
@@ -411,11 +408,16 @@ function buildResponseUnionSchema(node, resolver) {
|
|
|
411
408
|
const responses = node.responses.filter((response) => response.content?.[0]?.schema);
|
|
412
409
|
if (!responses.length) return null;
|
|
413
410
|
if (responses.length === 1) {
|
|
414
|
-
const
|
|
411
|
+
const schemas = responses[0].content?.flatMap((content) => content.schema ? [content.schema] : []) ?? [];
|
|
412
|
+
const schema = schemas.length > 1 ? kubb_kit.ast.factory.createSchema({
|
|
413
|
+
type: "union",
|
|
414
|
+
members: schemas
|
|
415
|
+
}) : schemas[0];
|
|
415
416
|
if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
|
|
416
417
|
return kubb_kit.ast.factory.createSchema({
|
|
417
418
|
type: "ref",
|
|
418
|
-
name: resolver.response.status(node, responses[0].statusCode)
|
|
419
|
+
name: resolver.response.status(node, responses[0].statusCode),
|
|
420
|
+
schema: responses[0].content?.length === 1 ? schema : void 0
|
|
419
421
|
});
|
|
420
422
|
}
|
|
421
423
|
return kubb_kit.ast.factory.createSchema({
|
|
@@ -484,7 +486,8 @@ function getScalarType(node, typeName) {
|
|
|
484
486
|
* Determines the data type, return type, and whether it uses the type name.
|
|
485
487
|
*/
|
|
486
488
|
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
487
|
-
const
|
|
489
|
+
const resolvedNode = kubb_kit.ast.resolveRef(node);
|
|
490
|
+
const scalarType = SCALAR_TYPES.has(resolvedNode.type) ? `${getScalarType(resolvedNode, typeName)}${node.nullable || resolvedNode.nullable ? " | null" : ""}` : void 0;
|
|
488
491
|
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
489
492
|
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
490
493
|
return {
|
|
@@ -493,28 +496,27 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
493
496
|
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
494
497
|
};
|
|
495
498
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
|
|
499
|
-
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred" }) {
|
|
499
|
+
// src/components/Faker.tsx
|
|
500
|
+
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred", keysToOmit }) {
|
|
500
501
|
const fakerText = printer.print(node) ?? "undefined";
|
|
501
502
|
const isArray = node.type === "array";
|
|
502
|
-
const isObject =
|
|
503
|
+
const isObject = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.object) || node.type === kubb_kit.ast.schemaTypes.intersection && isObjectSchema(node);
|
|
504
|
+
const isValueIntersection = node.type === kubb_kit.ast.schemaTypes.intersection && !isObject;
|
|
503
505
|
const isTuple = node.type === "tuple";
|
|
504
506
|
const isScalar = SCALAR_TYPES.has(node.type);
|
|
505
507
|
const isUnion = node.type === "union";
|
|
506
|
-
const useObjectOverride = canOverride && isObject;
|
|
508
|
+
const useObjectOverride = canOverride && (isObject || !!keysToOmit?.length);
|
|
507
509
|
const fakerTextWithOverride = (() => {
|
|
508
510
|
if (canOverride && node.type === "tuple") return `data && data.length === ${node.items?.length ?? 0} && !data.includes(undefined) ? data : ${fakerText}`;
|
|
509
511
|
if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || []).filter((item) => item !== undefined),\n]`;
|
|
510
|
-
if (canOverride && (isScalar || isUnion)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
512
|
+
if (canOverride && (isScalar || isUnion || isValueIntersection)) return node.nullable ? `data !== undefined ? data : ${fakerText}` : `data ?? ${fakerText}`;
|
|
511
513
|
return fakerText;
|
|
512
514
|
})();
|
|
513
515
|
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
514
516
|
if (!useObjectOverride) {
|
|
515
517
|
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
516
518
|
const returnType = resolvedReturnType;
|
|
517
|
-
const returnExpression = canOverride && !!returnType && (node.type === "ref" || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
519
|
+
const returnExpression = canOverride && !!returnType && (node.type === "ref" && !SCALAR_TYPES.has(kubb_kit.ast.resolveRef(node).type) || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
518
520
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
519
521
|
name,
|
|
520
522
|
isExportable: true,
|
|
@@ -529,18 +531,21 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
|
|
|
529
531
|
})
|
|
530
532
|
});
|
|
531
533
|
}
|
|
532
|
-
const returnType = typeMode === "schema" ? typeName : "Omit<typeof defaultFakeData, keyof NoInfer<TData>> & NoInfer<TData>";
|
|
533
534
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
534
|
-
const
|
|
535
|
+
const isCyclic = !!schemaName && !!cyclicSchemas?.has(schemaName);
|
|
536
|
+
const returnType = typeMode === "schema" ? typeName : `Omit<${isCyclic ? typeName : "typeof defaultFakeData"}, keyof NoInfer<TData>> & NoInfer<TData>`;
|
|
537
|
+
const hasGetters = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => (0, kubb_kit.containsCircularRef)(p.schema, {
|
|
535
538
|
circularSchemas: cyclicSchemas,
|
|
536
539
|
excludeName: schemaName
|
|
537
|
-
}))
|
|
540
|
+
}));
|
|
541
|
+
const declaration = `const ${keysToOmit?.length ? `{ ${keysToOmit.map((key, index) => `${objectKey(key)}: _omit${index}`).join(", ")}, ...defaultFakeData }` : "defaultFakeData"} = ${fakerText}`;
|
|
542
|
+
const functionBody = hasGetters ? `${declaration}
|
|
538
543
|
if (data) {
|
|
539
544
|
for (const [key, value] of Object.entries(data)) {
|
|
540
545
|
Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
|
|
541
546
|
}
|
|
542
547
|
}
|
|
543
|
-
return defaultFakeData as ${returnType}` :
|
|
548
|
+
return defaultFakeData as ${returnType}` : `${declaration}
|
|
544
549
|
return {
|
|
545
550
|
...defaultFakeData,
|
|
546
551
|
...(data || {}),
|
|
@@ -555,13 +560,12 @@ return {
|
|
|
555
560
|
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
556
561
|
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
557
562
|
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
558
|
-
returnType: typeMode === "schema" ?
|
|
563
|
+
returnType: typeMode === "schema" || isCyclic ? returnType : void 0,
|
|
559
564
|
children: functionBody
|
|
560
565
|
})
|
|
561
566
|
});
|
|
562
567
|
}
|
|
563
|
-
|
|
564
|
-
//#region ../../internals/shared/src/operation.ts
|
|
568
|
+
// ../../internals/shared/src/operation.ts
|
|
565
569
|
/**
|
|
566
570
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
567
571
|
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
@@ -676,17 +680,24 @@ function getOperationParameters(node) {
|
|
|
676
680
|
operationParameterGroupsByNode.set(node, groups);
|
|
677
681
|
return groups;
|
|
678
682
|
}
|
|
679
|
-
|
|
680
|
-
//#region ../../internals/shared/src/resolver.ts
|
|
683
|
+
// ../../internals/shared/src/resolver.ts
|
|
681
684
|
/**
|
|
682
|
-
*
|
|
683
|
-
*
|
|
685
|
+
* Builds the allocation key for a declaration an operation owns. `scope` names which declaration
|
|
686
|
+
* it is, so two of them never share an allocation even when a custom resolver gives both the same
|
|
687
|
+
* name. Leave `scope` empty for the operation's own declaration.
|
|
684
688
|
*
|
|
685
689
|
* @example
|
|
686
|
-
*
|
|
690
|
+
* ```ts
|
|
691
|
+
* resolver.resolveName({ key: operationKey(node, 'response', 'status', 404), name })
|
|
692
|
+
* ```
|
|
687
693
|
*/
|
|
688
|
-
function
|
|
689
|
-
return
|
|
694
|
+
function operationKey(node, ...scope) {
|
|
695
|
+
return [
|
|
696
|
+
"operation",
|
|
697
|
+
node.method,
|
|
698
|
+
node.path,
|
|
699
|
+
...scope.map(String)
|
|
700
|
+
];
|
|
690
701
|
}
|
|
691
702
|
/**
|
|
692
703
|
* Builds the shared `param` namespace. Spread the result into `createResolver`
|
|
@@ -699,15 +710,33 @@ function operationParamName(node, param) {
|
|
|
699
710
|
*/
|
|
700
711
|
function createOperationParamResolver() {
|
|
701
712
|
return {
|
|
702
|
-
name
|
|
713
|
+
name(node, param) {
|
|
714
|
+
const name = this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
715
|
+
return this.resolveName({
|
|
716
|
+
key: operationKey(node, "param", "name", param.in, param.name),
|
|
717
|
+
name
|
|
718
|
+
});
|
|
719
|
+
},
|
|
703
720
|
path(node) {
|
|
704
|
-
|
|
721
|
+
const name = this.name(`${node.operationId} Path`);
|
|
722
|
+
return this.resolveName({
|
|
723
|
+
key: operationKey(node, "param", "path"),
|
|
724
|
+
name
|
|
725
|
+
});
|
|
705
726
|
},
|
|
706
727
|
query(node) {
|
|
707
|
-
|
|
728
|
+
const name = this.name(`${node.operationId} Query`);
|
|
729
|
+
return this.resolveName({
|
|
730
|
+
key: operationKey(node, "param", "query"),
|
|
731
|
+
name
|
|
732
|
+
});
|
|
708
733
|
},
|
|
709
734
|
headers(node) {
|
|
710
|
-
|
|
735
|
+
const name = this.name(`${node.operationId} Headers`);
|
|
736
|
+
return this.resolveName({
|
|
737
|
+
key: operationKey(node, "param", "headers"),
|
|
738
|
+
name
|
|
739
|
+
});
|
|
711
740
|
}
|
|
712
741
|
};
|
|
713
742
|
}
|
|
@@ -724,16 +753,32 @@ function createOperationParamResolver() {
|
|
|
724
753
|
function createOperationResponseResolver() {
|
|
725
754
|
return {
|
|
726
755
|
status(node, statusCode) {
|
|
727
|
-
|
|
756
|
+
const name = this.name(`${node.operationId} Status ${statusCode}`);
|
|
757
|
+
return this.resolveName({
|
|
758
|
+
key: operationKey(node, "response", "status", statusCode),
|
|
759
|
+
name
|
|
760
|
+
});
|
|
728
761
|
},
|
|
729
762
|
body(node) {
|
|
730
|
-
|
|
763
|
+
const name = this.name(`${node.operationId} Body`);
|
|
764
|
+
return this.resolveName({
|
|
765
|
+
key: operationKey(node, "response", "body"),
|
|
766
|
+
name
|
|
767
|
+
});
|
|
731
768
|
},
|
|
732
769
|
responses(node) {
|
|
733
|
-
|
|
770
|
+
const name = this.name(`${node.operationId} Responses`);
|
|
771
|
+
return this.resolveName({
|
|
772
|
+
key: operationKey(node, "response", "responses"),
|
|
773
|
+
name
|
|
774
|
+
});
|
|
734
775
|
},
|
|
735
776
|
response(node) {
|
|
736
|
-
|
|
777
|
+
const name = this.name(`${node.operationId} Response`);
|
|
778
|
+
return this.resolveName({
|
|
779
|
+
key: operationKey(node, "response", "response"),
|
|
780
|
+
name
|
|
781
|
+
});
|
|
737
782
|
}
|
|
738
783
|
};
|
|
739
784
|
}
|
|
@@ -748,11 +793,10 @@ function createOperationResponseResolver() {
|
|
|
748
793
|
*/
|
|
749
794
|
function createCasedFile(caseLast) {
|
|
750
795
|
return { baseName({ name, extname }) {
|
|
751
|
-
return `${toFilePath(name, caseLast)}${extname}
|
|
796
|
+
return this.memo(`file:${name}\0${extname}`, () => `${toFilePath(name, caseLast)}${extname}`);
|
|
752
797
|
} };
|
|
753
798
|
}
|
|
754
|
-
|
|
755
|
-
//#region ../../internals/shared/src/group.ts
|
|
799
|
+
// ../../internals/shared/src/group.ts
|
|
756
800
|
/**
|
|
757
801
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
758
802
|
* shared default naming so every plugin groups output consistently:
|
|
@@ -775,15 +819,14 @@ function createGroupConfig(group) {
|
|
|
775
819
|
if (!group) return null;
|
|
776
820
|
const defaultName = (ctx) => {
|
|
777
821
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
778
|
-
return camelCase(ctx.group);
|
|
822
|
+
return (0, kubb_kit.camelCase)(ctx.group);
|
|
779
823
|
};
|
|
780
824
|
return {
|
|
781
825
|
...group,
|
|
782
826
|
name: group.name ? group.name : defaultName
|
|
783
827
|
};
|
|
784
828
|
}
|
|
785
|
-
|
|
786
|
-
//#region ../../internals/shared/src/schemaTraversal.ts
|
|
829
|
+
// ../../internals/shared/src/schemaTraversal.ts
|
|
787
830
|
/**
|
|
788
831
|
* Maps each member of a union or intersection schema to its transformed output, pairing every
|
|
789
832
|
* result with the original member.
|
|
@@ -804,8 +847,7 @@ function mapSchemaItems(node, transform) {
|
|
|
804
847
|
output: transform(schema)
|
|
805
848
|
}));
|
|
806
849
|
}
|
|
807
|
-
|
|
808
|
-
//#region src/utils/imports.ts
|
|
850
|
+
// src/utils/imports.ts
|
|
809
851
|
function escapeRegExp(value) {
|
|
810
852
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
811
853
|
}
|
|
@@ -853,8 +895,7 @@ function aliasConflictingImports(imports, reservedNames) {
|
|
|
853
895
|
function rewriteAliasedImports(text, aliases) {
|
|
854
896
|
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
855
897
|
}
|
|
856
|
-
|
|
857
|
-
//#region src/printers/printerFaker.ts
|
|
898
|
+
// src/printers/printerFaker.ts
|
|
858
899
|
/**
|
|
859
900
|
* Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
|
|
860
901
|
* 64-bit integers, so the mock has to be digits rather than letters.
|
|
@@ -990,7 +1031,9 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
990
1031
|
},
|
|
991
1032
|
enum(node) {
|
|
992
1033
|
const { typeName } = this.options;
|
|
993
|
-
|
|
1034
|
+
const values = kubb_kit.ast.getSchemaLiteralValues(node);
|
|
1035
|
+
if (values.length === 1 && values[0] !== null && typeof values[0] === "object") return JSON.stringify(values[0]);
|
|
1036
|
+
return `faker.helpers.arrayElement${typeName ? `<${typeName}>` : ""}([${values.map(parseEnumValue).join(", ")}])`;
|
|
994
1037
|
},
|
|
995
1038
|
union(node) {
|
|
996
1039
|
const { discriminatorPropertyName } = node;
|
|
@@ -1014,9 +1057,14 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1014
1057
|
}).map(({ output }) => output).filter((item) => Boolean(item)).join(", ")}])`;
|
|
1015
1058
|
},
|
|
1016
1059
|
intersection(node) {
|
|
1017
|
-
const
|
|
1060
|
+
const objectMembers = (node.members ?? []).filter((member) => isObjectSchema(member));
|
|
1061
|
+
const members = objectMembers.length ? objectMembers : node.members;
|
|
1062
|
+
const items = mapSchemaMembers({
|
|
1063
|
+
...node,
|
|
1064
|
+
members
|
|
1065
|
+
}, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
|
|
1018
1066
|
if (items.length === 0) return "{}";
|
|
1019
|
-
return items.length === 1 ? items
|
|
1067
|
+
return !objectMembers.length || items.length === 1 ? items.at(-1) : `{...${items.join(", ...")}}`;
|
|
1020
1068
|
},
|
|
1021
1069
|
array(node) {
|
|
1022
1070
|
const items = mapSchemaItems(node, (member) => printNested(member, {
|
|
@@ -1039,7 +1087,13 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1039
1087
|
},
|
|
1040
1088
|
object(node) {
|
|
1041
1089
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
1042
|
-
|
|
1090
|
+
const keySchema = node.propertyNames && (0, kubb_kit.syncSchemaRef)(node.propertyNames);
|
|
1091
|
+
const valueSchema = node.additionalProperties;
|
|
1092
|
+
const recordProperties = keySchema?.type === "enum" && typeof valueSchema === "object" ? kubb_kit.ast.getSchemaLiteralValues(keySchema).filter((key) => typeof key === "string" && !node.properties.some((property) => property.name === key)).map((name) => kubb_kit.ast.factory.createProperty({
|
|
1093
|
+
name,
|
|
1094
|
+
schema: valueSchema
|
|
1095
|
+
})) : [];
|
|
1096
|
+
return buildObject([...node.properties, ...recordProperties].map((property) => {
|
|
1043
1097
|
const value = printNested(property.schema, {
|
|
1044
1098
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
1045
1099
|
nestedInObject: true
|
|
@@ -1055,8 +1109,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1055
1109
|
overrides: options.nodes
|
|
1056
1110
|
};
|
|
1057
1111
|
});
|
|
1058
|
-
|
|
1059
|
-
//#region src/generators/fakerGenerator.tsx
|
|
1112
|
+
// src/generators/fakerGenerator.tsx
|
|
1060
1113
|
/**
|
|
1061
1114
|
* Built-in generator for `@kubb/plugin-faker`. Emits one `createX` factory
|
|
1062
1115
|
* per schema in the spec plus per-operation request/response factories. Each
|
|
@@ -1228,7 +1281,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1228
1281
|
name: baseName,
|
|
1229
1282
|
typeName: tsBaseName,
|
|
1230
1283
|
description,
|
|
1231
|
-
|
|
1284
|
+
keysToOmit: primary.keysToOmit
|
|
1232
1285
|
}];
|
|
1233
1286
|
}
|
|
1234
1287
|
const variants = resolveContentTypeVariants(entries, baseName);
|
|
@@ -1245,7 +1298,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1245
1298
|
name: variant.name,
|
|
1246
1299
|
typeName: getPerContentTypeName(tsBaseName, variant.suffix),
|
|
1247
1300
|
description,
|
|
1248
|
-
|
|
1301
|
+
keysToOmit: variant.keysToOmit
|
|
1249
1302
|
})), {
|
|
1250
1303
|
schema: unionSchema,
|
|
1251
1304
|
name: baseName,
|
|
@@ -1295,8 +1348,15 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1295
1348
|
group: group ?? void 0
|
|
1296
1349
|
}).filter((entry) => entry.path !== meta.file.path);
|
|
1297
1350
|
}
|
|
1298
|
-
function renderEntry({ schema, name, typeName, description, skipImportNames = [] }) {
|
|
1351
|
+
function renderEntry({ schema, name, typeName, description, keysToOmit, skipImportNames = [] }) {
|
|
1299
1352
|
if (!schema) return null;
|
|
1353
|
+
if (schema.type === kubb_kit.ast.schemaTypes.object && keysToOmit?.length) {
|
|
1354
|
+
schema = {
|
|
1355
|
+
...schema,
|
|
1356
|
+
properties: schema.properties.filter((property) => !keysToOmit?.includes(property.name))
|
|
1357
|
+
};
|
|
1358
|
+
keysToOmit = void 0;
|
|
1359
|
+
}
|
|
1300
1360
|
const canOverride = canOverrideSchema(schema);
|
|
1301
1361
|
const printerInstance = printerFaker({
|
|
1302
1362
|
resolver,
|
|
@@ -1305,7 +1365,8 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1305
1365
|
dateParser,
|
|
1306
1366
|
regexGenerator,
|
|
1307
1367
|
nodes: printer?.nodes,
|
|
1308
|
-
cyclicSchemas
|
|
1368
|
+
cyclicSchemas,
|
|
1369
|
+
nestedInObject: !!keysToOmit?.length
|
|
1309
1370
|
});
|
|
1310
1371
|
const fakerText = printerInstance.print(schema) ?? "undefined";
|
|
1311
1372
|
const { imports, aliases } = aliasConflictingImports(filterUsedImports(resolveMockImports(schema), fakerText, skipImportNames), localHelperNames);
|
|
@@ -1344,7 +1405,8 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1344
1405
|
print: () => rewrittenFakerText
|
|
1345
1406
|
},
|
|
1346
1407
|
canOverride,
|
|
1347
|
-
typeMode
|
|
1408
|
+
typeMode,
|
|
1409
|
+
keysToOmit
|
|
1348
1410
|
})
|
|
1349
1411
|
] });
|
|
1350
1412
|
}
|
|
@@ -1401,17 +1463,14 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1401
1463
|
});
|
|
1402
1464
|
}
|
|
1403
1465
|
});
|
|
1404
|
-
|
|
1405
|
-
//#region kubb-extension.json
|
|
1466
|
+
// kubb-extension.json
|
|
1406
1467
|
var compatibility = {
|
|
1407
|
-
"kubb": ">=5.
|
|
1468
|
+
"kubb": ">=5.14.6",
|
|
1408
1469
|
"node": ">=22.22"
|
|
1409
1470
|
};
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
//#endregion
|
|
1414
|
-
//#region src/resolvers/resolverFaker.ts
|
|
1471
|
+
// package.json
|
|
1472
|
+
var version = "5.2.3";
|
|
1473
|
+
// src/resolvers/resolverFaker.ts
|
|
1415
1474
|
/**
|
|
1416
1475
|
* Default resolver used by `@kubb/plugin-faker`. Decides the names and file
|
|
1417
1476
|
* paths for every generated mock factory. Functions and files are prefixed
|
|
@@ -1427,14 +1486,13 @@ var version = "5.2.1";
|
|
|
1427
1486
|
const resolverFaker = (0, kubb_kit.createResolver)({
|
|
1428
1487
|
pluginName: "plugin-faker",
|
|
1429
1488
|
name(name) {
|
|
1430
|
-
return ensureValidVarName(camelCase(name, { prefix: "create" }));
|
|
1489
|
+
return this.memo(`name:${name}`, () => ensureValidVarName((0, kubb_kit.camelCase)(name, { prefix: "create" })));
|
|
1431
1490
|
},
|
|
1432
|
-
file: createCasedFile((part) => camelCase(part, { prefix: "create" })),
|
|
1491
|
+
file: createCasedFile((part) => (0, kubb_kit.camelCase)(part, { prefix: "create" })),
|
|
1433
1492
|
param: createOperationParamResolver(),
|
|
1434
1493
|
response: createOperationResponseResolver()
|
|
1435
1494
|
});
|
|
1436
|
-
|
|
1437
|
-
//#region src/plugin.ts
|
|
1495
|
+
// src/plugin.ts
|
|
1438
1496
|
/**
|
|
1439
1497
|
* Canonical plugin name for `@kubb/plugin-faker`. Used for driver lookups and
|
|
1440
1498
|
* cross-plugin dependency references.
|
|
@@ -1495,7 +1553,6 @@ const pluginFaker = (0, kubb_kit.defineExtension)({
|
|
|
1495
1553
|
};
|
|
1496
1554
|
}
|
|
1497
1555
|
});
|
|
1498
|
-
//#endregion
|
|
1499
1556
|
exports.Faker = Faker;
|
|
1500
1557
|
exports.default = pluginFaker;
|
|
1501
1558
|
exports.fakerGenerator = fakerGenerator;
|