@kubb/plugin-faker 5.1.6 → 5.1.7
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 +204 -294
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +205 -295
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -5,9 +5,9 @@ Object.defineProperties(exports, {
|
|
|
5
5
|
//#endregion
|
|
6
6
|
let node_path = require("node:path");
|
|
7
7
|
let kubb_kit = require("kubb/kit");
|
|
8
|
-
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
9
8
|
let kubb_jsx = require("kubb/jsx");
|
|
10
9
|
let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
|
|
10
|
+
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
11
11
|
//#region ../../internals/utils/src/casing.ts
|
|
12
12
|
/**
|
|
13
13
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -309,6 +309,24 @@ function buildObject(entries) {
|
|
|
309
309
|
}
|
|
310
310
|
//#endregion
|
|
311
311
|
//#region ../../internals/utils/src/fs.ts
|
|
312
|
+
function toSlash(p) {
|
|
313
|
+
if (p.startsWith("\\\\?\\")) return p;
|
|
314
|
+
return p.replaceAll("\\", "/");
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Returns the relative path from `rootDir` to `filePath`, always using forward slashes
|
|
318
|
+
* and prefixed with `./` when not already traversing upward.
|
|
319
|
+
*
|
|
320
|
+
* @example
|
|
321
|
+
* ```ts
|
|
322
|
+
* getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'
|
|
323
|
+
* getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
function getRelativePath(rootDir, filePath) {
|
|
327
|
+
const relativePath = node_path.posix.relative(toSlash(rootDir), toSlash(filePath));
|
|
328
|
+
return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
|
|
329
|
+
}
|
|
312
330
|
/**
|
|
313
331
|
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
314
332
|
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
@@ -333,51 +351,6 @@ function toFilePath(name, caseLast = camelCase) {
|
|
|
333
351
|
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
334
352
|
}
|
|
335
353
|
//#endregion
|
|
336
|
-
//#region ../../internals/utils/src/imports.ts
|
|
337
|
-
function escapeRegExp(value) {
|
|
338
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
339
|
-
}
|
|
340
|
-
function getImportNames(entry) {
|
|
341
|
-
return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
|
|
342
|
-
if (typeof name === "string") return name;
|
|
343
|
-
return name.name ?? name.propertyName;
|
|
344
|
-
}).filter((name) => Boolean(name));
|
|
345
|
-
}
|
|
346
|
-
function filterUsedImports(imports, text, skipImportNames = []) {
|
|
347
|
-
const skip = new Set(skipImportNames);
|
|
348
|
-
return imports.filter((entry) => {
|
|
349
|
-
return getImportNames(entry).some((name) => {
|
|
350
|
-
if (skip.has(name)) return false;
|
|
351
|
-
return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*[<(])`).test(text);
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
function aliasConflictingImports(imports, reservedNames) {
|
|
356
|
-
const reservedNameSet = new Set(reservedNames);
|
|
357
|
-
const aliases = /* @__PURE__ */ new Map();
|
|
358
|
-
return {
|
|
359
|
-
imports: imports.map((entry) => {
|
|
360
|
-
const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
|
|
361
|
-
if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
|
|
362
|
-
const alias = `${item}Schema`;
|
|
363
|
-
aliases.set(item, alias);
|
|
364
|
-
return {
|
|
365
|
-
propertyName: item,
|
|
366
|
-
name: alias
|
|
367
|
-
};
|
|
368
|
-
});
|
|
369
|
-
return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
|
|
370
|
-
...entry,
|
|
371
|
-
name: aliasedNames
|
|
372
|
-
} : entry;
|
|
373
|
-
}),
|
|
374
|
-
aliases
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
function rewriteAliasedImports(text, aliases) {
|
|
378
|
-
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
379
|
-
}
|
|
380
|
-
//#endregion
|
|
381
354
|
//#region src/utils.ts
|
|
382
355
|
/**
|
|
383
356
|
* Returns the `@faker-js/faker` named export for a locale code.
|
|
@@ -401,54 +374,36 @@ function localeToFakerImport(locale) {
|
|
|
401
374
|
return `faker${parts.join("_")}`;
|
|
402
375
|
}
|
|
403
376
|
/**
|
|
377
|
+
* Schema types a factory cannot override with `data`: they print a constant or have no faker value.
|
|
378
|
+
*/
|
|
379
|
+
const NON_OVERRIDABLE_TYPES = /* @__PURE__ */ new Set([
|
|
380
|
+
"any",
|
|
381
|
+
"unknown",
|
|
382
|
+
"void",
|
|
383
|
+
"null",
|
|
384
|
+
"never",
|
|
385
|
+
"ipv4",
|
|
386
|
+
"ipv6"
|
|
387
|
+
]);
|
|
388
|
+
/**
|
|
389
|
+
* Schema types a single response cannot inline: they reference or compose other schemas.
|
|
390
|
+
*/
|
|
391
|
+
const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
392
|
+
"object",
|
|
393
|
+
"intersection",
|
|
394
|
+
"ref",
|
|
395
|
+
"never",
|
|
396
|
+
"ipv4",
|
|
397
|
+
"ipv6"
|
|
398
|
+
]);
|
|
399
|
+
/**
|
|
404
400
|
* Determines if a schema node can be overridden during faker generation.
|
|
405
401
|
*/
|
|
406
402
|
function canOverrideSchema(node) {
|
|
407
|
-
return (
|
|
408
|
-
"array",
|
|
409
|
-
"tuple",
|
|
410
|
-
"object",
|
|
411
|
-
"intersection",
|
|
412
|
-
"union",
|
|
413
|
-
"enum",
|
|
414
|
-
"ref",
|
|
415
|
-
"string",
|
|
416
|
-
"email",
|
|
417
|
-
"url",
|
|
418
|
-
"uuid",
|
|
419
|
-
"number",
|
|
420
|
-
"integer",
|
|
421
|
-
"bigint",
|
|
422
|
-
"boolean",
|
|
423
|
-
"date",
|
|
424
|
-
"time",
|
|
425
|
-
"datetime",
|
|
426
|
-
"blob"
|
|
427
|
-
])).has(node.type);
|
|
403
|
+
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
428
404
|
}
|
|
429
405
|
function shouldInlineSingleResponseSchema(schema) {
|
|
430
|
-
return (
|
|
431
|
-
"any",
|
|
432
|
-
"unknown",
|
|
433
|
-
"void",
|
|
434
|
-
"null",
|
|
435
|
-
"array",
|
|
436
|
-
"tuple",
|
|
437
|
-
"string",
|
|
438
|
-
"email",
|
|
439
|
-
"url",
|
|
440
|
-
"uuid",
|
|
441
|
-
"number",
|
|
442
|
-
"integer",
|
|
443
|
-
"bigint",
|
|
444
|
-
"boolean",
|
|
445
|
-
"date",
|
|
446
|
-
"time",
|
|
447
|
-
"datetime",
|
|
448
|
-
"blob",
|
|
449
|
-
"enum",
|
|
450
|
-
"union"
|
|
451
|
-
])).has(schema.type);
|
|
406
|
+
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
452
407
|
}
|
|
453
408
|
/**
|
|
454
409
|
* Builds a response schema as a union of all response statuses.
|
|
@@ -477,7 +432,7 @@ function buildResponseUnionSchema(node, resolver) {
|
|
|
477
432
|
})
|
|
478
433
|
});
|
|
479
434
|
}
|
|
480
|
-
const SCALAR_TYPES
|
|
435
|
+
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
481
436
|
"string",
|
|
482
437
|
"email",
|
|
483
438
|
"url",
|
|
@@ -492,10 +447,6 @@ const SCALAR_TYPES$1 = /* @__PURE__ */ new Set([
|
|
|
492
447
|
"blob",
|
|
493
448
|
"enum"
|
|
494
449
|
]);
|
|
495
|
-
function toRelativeImportPath(from, to) {
|
|
496
|
-
const relativePath = node_path.posix.relative(node_path.posix.dirname(from), to);
|
|
497
|
-
return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
|
|
498
|
-
}
|
|
499
450
|
/**
|
|
500
451
|
* Resolves a type reference, determining if it needs an import statement or inline type reference.
|
|
501
452
|
* Takes into account whether the type can be overridden and the file paths.
|
|
@@ -503,7 +454,7 @@ function toRelativeImportPath(from, to) {
|
|
|
503
454
|
function resolveTypeReference({ node, canOverride, name, typeName, filePath, typeFilePath }) {
|
|
504
455
|
const { usesTypeName } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
505
456
|
if (!usesTypeName) return { typeName };
|
|
506
|
-
if (name === typeName) return { typeName: `import('${
|
|
457
|
+
if (name === typeName) return { typeName: `import('${getRelativePath(node_path.posix.dirname(filePath), typeFilePath)}').${typeName}` };
|
|
507
458
|
return {
|
|
508
459
|
importPath: typeFilePath,
|
|
509
460
|
typeName
|
|
@@ -527,28 +478,17 @@ function getScalarType(node, typeName) {
|
|
|
527
478
|
case "time": return node.representation === "date" ? "Date" : "string";
|
|
528
479
|
case "datetime": return "string";
|
|
529
480
|
case "blob": return "Blob";
|
|
530
|
-
case "enum": return typeName;
|
|
531
481
|
default: return typeName;
|
|
532
482
|
}
|
|
533
483
|
}
|
|
534
484
|
/**
|
|
535
|
-
* A nullable scalar inlines its primitive instead of naming the generated type, so the
|
|
536
|
-
* nullability the type plugin emitted has to be reapplied here. Non-scalars keep `typeName`,
|
|
537
|
-
* which already carries it.
|
|
538
|
-
*/
|
|
539
|
-
function withNullability(type, node) {
|
|
540
|
-
return node.nullable ? `${type} | null` : type;
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
485
|
* Resolves faker type usage information for a schema.
|
|
544
486
|
* Determines the data type, return type, and whether it uses the type name.
|
|
545
487
|
*/
|
|
546
488
|
function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
let returnType = canOverride ? typeName : null;
|
|
551
|
-
if (isScalar) returnType = withNullability(getScalarType(node, typeName), node);
|
|
489
|
+
const scalarType = SCALAR_TYPES.has(node.type) ? `${getScalarType(node, typeName)}${node.nullable ? " | null" : ""}` : void 0;
|
|
490
|
+
const dataType = scalarType ?? `Partial<${typeName}>`;
|
|
491
|
+
const returnType = scalarType ?? (canOverride ? typeName : null);
|
|
552
492
|
return {
|
|
553
493
|
dataType,
|
|
554
494
|
returnType,
|
|
@@ -558,22 +498,6 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
558
498
|
//#endregion
|
|
559
499
|
//#region src/components/Faker.tsx
|
|
560
500
|
const OBJECT_TYPES = /* @__PURE__ */ new Set(["object", "intersection"]);
|
|
561
|
-
const SCALAR_TYPES = /* @__PURE__ */ new Set([
|
|
562
|
-
"string",
|
|
563
|
-
"email",
|
|
564
|
-
"url",
|
|
565
|
-
"uuid",
|
|
566
|
-
"number",
|
|
567
|
-
"integer",
|
|
568
|
-
"bigint",
|
|
569
|
-
"boolean",
|
|
570
|
-
"date",
|
|
571
|
-
"time",
|
|
572
|
-
"datetime",
|
|
573
|
-
"blob",
|
|
574
|
-
"enum"
|
|
575
|
-
]);
|
|
576
|
-
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
577
501
|
function Faker({ node, description, name, typeName, printer, canOverride, typeMode = "inferred" }) {
|
|
578
502
|
const fakerText = printer.print(node) ?? "undefined";
|
|
579
503
|
const isArray = node.type === "array";
|
|
@@ -590,13 +514,7 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
|
|
|
590
514
|
})();
|
|
591
515
|
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
592
516
|
if (!useObjectOverride) {
|
|
593
|
-
const
|
|
594
|
-
const params = (0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
|
|
595
|
-
name: dataParamName,
|
|
596
|
-
type: dataType,
|
|
597
|
-
optional: true
|
|
598
|
-
})] });
|
|
599
|
-
const paramsSignature = declarationPrinter.print(params) ?? "";
|
|
517
|
+
const paramsSignature = `${/\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data"}?: ${dataType}`;
|
|
600
518
|
const returnType = resolvedReturnType;
|
|
601
519
|
const returnExpression = canOverride && !!returnType && (node.type === "ref" || isArray || isTuple || isUnion) ? `${isTuple || isUnion ? `(${fakerTextWithOverride})` : fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
|
|
602
520
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
@@ -645,24 +563,6 @@ return {
|
|
|
645
563
|
});
|
|
646
564
|
}
|
|
647
565
|
//#endregion
|
|
648
|
-
//#region ../../internals/shared/src/params.ts
|
|
649
|
-
/**
|
|
650
|
-
* Drops parameters that share the same name, keeping the first.
|
|
651
|
-
*
|
|
652
|
-
* A malformed spec can declare the same parameter name twice within one `in` location. Both would
|
|
653
|
-
* resolve to the same output property, so emitting both would yield an object type with a duplicate
|
|
654
|
-
* member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
|
|
655
|
-
* parameter names flow through unchanged, so no two distinct names ever collide here anymore.
|
|
656
|
-
*/
|
|
657
|
-
function dedupeParams(params) {
|
|
658
|
-
const seen = /* @__PURE__ */ new Set();
|
|
659
|
-
return params.filter((param) => {
|
|
660
|
-
if (seen.has(param.name)) return false;
|
|
661
|
-
seen.add(param.name);
|
|
662
|
-
return true;
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
//#endregion
|
|
666
566
|
//#region ../../internals/shared/src/operation.ts
|
|
667
567
|
/**
|
|
668
568
|
* Builds the `ResolverFileParams` every operation generator passes to
|
|
@@ -761,11 +661,19 @@ const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
|
761
661
|
function getOperationParameters(node) {
|
|
762
662
|
const cached = operationParameterGroupsByNode.get(node);
|
|
763
663
|
if (cached) return cached;
|
|
664
|
+
const group = (location) => {
|
|
665
|
+
const seen = /* @__PURE__ */ new Set();
|
|
666
|
+
return node.parameters.filter((param) => {
|
|
667
|
+
if (param.in !== location || seen.has(param.name)) return false;
|
|
668
|
+
seen.add(param.name);
|
|
669
|
+
return true;
|
|
670
|
+
});
|
|
671
|
+
};
|
|
764
672
|
const groups = {
|
|
765
|
-
path:
|
|
766
|
-
query:
|
|
767
|
-
header:
|
|
768
|
-
cookie:
|
|
673
|
+
path: group("path"),
|
|
674
|
+
query: group("query"),
|
|
675
|
+
header: group("header"),
|
|
676
|
+
cookie: group("cookie")
|
|
769
677
|
};
|
|
770
678
|
operationParameterGroupsByNode.set(node, groups);
|
|
771
679
|
return groups;
|
|
@@ -846,20 +754,6 @@ function createCasedFile(caseLast) {
|
|
|
846
754
|
} };
|
|
847
755
|
}
|
|
848
756
|
//#endregion
|
|
849
|
-
//#region ../../internals/shared/src/refs.ts
|
|
850
|
-
/**
|
|
851
|
-
* Collects the resolved target name of every pointer-carrying ref in a schema tree, in
|
|
852
|
-
* first-occurrence order. Use this for name-only checks (e.g. redeclaration detection) where
|
|
853
|
-
* `resolver.imports` would resolve file paths that are then discarded.
|
|
854
|
-
*/
|
|
855
|
-
function collectRefNames(schema) {
|
|
856
|
-
return kubb_kit.ast.collectSync(schema, { schema: (node) => {
|
|
857
|
-
const refNode = kubb_kit.ast.narrowSchema(node, "ref");
|
|
858
|
-
if (!refNode?.ref) return null;
|
|
859
|
-
return kubb_kit.ast.resolveRefName(refNode);
|
|
860
|
-
} });
|
|
861
|
-
}
|
|
862
|
-
//#endregion
|
|
863
757
|
//#region ../../internals/shared/src/group.ts
|
|
864
758
|
/**
|
|
865
759
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -913,6 +807,51 @@ function mapSchemaItems(node, transform) {
|
|
|
913
807
|
}));
|
|
914
808
|
}
|
|
915
809
|
//#endregion
|
|
810
|
+
//#region src/utils/imports.ts
|
|
811
|
+
function escapeRegExp(value) {
|
|
812
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
813
|
+
}
|
|
814
|
+
function getImportNames(entry) {
|
|
815
|
+
return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
|
|
816
|
+
if (typeof name === "string") return name;
|
|
817
|
+
return name.name ?? name.propertyName;
|
|
818
|
+
}).filter((name) => Boolean(name));
|
|
819
|
+
}
|
|
820
|
+
function filterUsedImports(imports, text, skipImportNames = []) {
|
|
821
|
+
const skip = new Set(skipImportNames);
|
|
822
|
+
return imports.filter((entry) => {
|
|
823
|
+
return getImportNames(entry).some((name) => {
|
|
824
|
+
if (skip.has(name)) return false;
|
|
825
|
+
return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*[<(])`).test(text);
|
|
826
|
+
});
|
|
827
|
+
});
|
|
828
|
+
}
|
|
829
|
+
function aliasConflictingImports(imports, reservedNames) {
|
|
830
|
+
const reservedNameSet = new Set(reservedNames);
|
|
831
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
832
|
+
return {
|
|
833
|
+
imports: imports.map((entry) => {
|
|
834
|
+
const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
|
|
835
|
+
if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
|
|
836
|
+
const alias = `${item}Schema`;
|
|
837
|
+
aliases.set(item, alias);
|
|
838
|
+
return {
|
|
839
|
+
propertyName: item,
|
|
840
|
+
name: alias
|
|
841
|
+
};
|
|
842
|
+
});
|
|
843
|
+
return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
|
|
844
|
+
...entry,
|
|
845
|
+
name: aliasedNames
|
|
846
|
+
} : entry;
|
|
847
|
+
}),
|
|
848
|
+
aliases
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
function rewriteAliasedImports(text, aliases) {
|
|
852
|
+
return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
|
|
853
|
+
}
|
|
854
|
+
//#endregion
|
|
916
855
|
//#region src/printers/printerFaker.ts
|
|
917
856
|
/**
|
|
918
857
|
* Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
|
|
@@ -926,77 +865,32 @@ const integerFormats = /* @__PURE__ */ new Set([
|
|
|
926
865
|
"uint64"
|
|
927
866
|
]);
|
|
928
867
|
const maxInt32 = 2147483647;
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
},
|
|
956
|
-
boolean: () => "faker.datatype.boolean()",
|
|
957
|
-
null: () => "null",
|
|
958
|
-
array: (items = [], min, max) => {
|
|
959
|
-
if (items.length > 1) return `faker.helpers.arrayElements([${items.join(", ")}])`;
|
|
960
|
-
const item = items.at(0);
|
|
961
|
-
if (min !== void 0 && max !== void 0) return `faker.helpers.multiple(() => (${item}), { count: { min: ${min}, max: ${max} }})`;
|
|
962
|
-
if (min !== void 0) return `faker.helpers.multiple(() => (${item}), { count: ${min} })`;
|
|
963
|
-
if (max !== void 0) return `faker.helpers.multiple(() => (${item}), { count: { min: 0, max: ${max} }})`;
|
|
964
|
-
return `faker.helpers.multiple(() => (${item}))`;
|
|
965
|
-
},
|
|
966
|
-
tuple: (items = []) => `[${items.join(", ")}]`,
|
|
967
|
-
enum: (items = [], type) => `faker.helpers.arrayElement${type ? `<${type}>` : ""}([${items.join(", ")}])`,
|
|
968
|
-
union: (items = []) => `faker.helpers.arrayElement([${items.join(", ")}])`,
|
|
969
|
-
datetime: () => "faker.date.anytime().toISOString()",
|
|
970
|
-
date: (representation = "string", parser = "faker") => {
|
|
971
|
-
if (representation === "string") {
|
|
972
|
-
if (parser !== "faker") return `${parser}(faker.date.anytime()).format("YYYY-MM-DD")`;
|
|
973
|
-
return "faker.date.anytime().toISOString().substring(0, 10)";
|
|
974
|
-
}
|
|
975
|
-
if (parser !== "faker") throw new Error(`type '${representation}' and parser '${parser}' can not work together`);
|
|
976
|
-
return "faker.date.anytime()";
|
|
977
|
-
},
|
|
978
|
-
time: (representation = "string", parser = "faker") => {
|
|
979
|
-
if (representation === "string") {
|
|
980
|
-
if (parser !== "faker") return `${parser}(faker.date.anytime()).format("HH:mm:ss")`;
|
|
981
|
-
return "faker.date.anytime().toISOString().substring(11, 19)";
|
|
982
|
-
}
|
|
983
|
-
if (parser !== "faker") throw new Error(`type '${representation}' and parser '${parser}' can not work together`);
|
|
984
|
-
return "faker.date.anytime()";
|
|
985
|
-
},
|
|
986
|
-
uuid: () => "faker.string.uuid()",
|
|
987
|
-
url: () => "faker.internet.url()",
|
|
988
|
-
and: (items = []) => {
|
|
989
|
-
if (items.length === 0) return "{}";
|
|
990
|
-
if (items.length === 1) return items[0] ?? "{}";
|
|
991
|
-
return `{...${items.join(", ...")}}`;
|
|
992
|
-
},
|
|
993
|
-
matches: (value = "", regexGenerator = "faker") => {
|
|
994
|
-
if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
|
|
995
|
-
return `faker.helpers.fromRegExp(${toRegExpString(value, null)})`;
|
|
996
|
-
},
|
|
997
|
-
email: () => "faker.internet.email()",
|
|
998
|
-
blob: () => "faker.image.url() as unknown as Blob"
|
|
999
|
-
};
|
|
868
|
+
/**
|
|
869
|
+
* `faker.number.float()` or `faker.number.int()`, with `min` and `max` passed only when set.
|
|
870
|
+
*/
|
|
871
|
+
function numberCall(kind, min, max) {
|
|
872
|
+
const args = [min !== void 0 && `min: ${min}`, max !== void 0 && `max: ${max}`].filter(Boolean).join(", ");
|
|
873
|
+
return `faker.number.${kind}(${args ? `{ ${args} }` : ""})`;
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* A `date` or `time` value: an ISO substring, a `dateParser` call, or a `Date` when `representation` is `'date'`.
|
|
877
|
+
*/
|
|
878
|
+
function dateTimeCall(representation, { format, substring }, parser = "faker", schemaName) {
|
|
879
|
+
if (representation === "string") return parser !== "faker" ? `${parser}(faker.date.anytime()).format("${format}")` : `faker.date.anytime().toISOString().substring(${substring})`;
|
|
880
|
+
if (parser !== "faker") throw new kubb_kit.Diagnostics.Error({
|
|
881
|
+
code: kubb_kit.Diagnostics.code.invalidPluginOptions,
|
|
882
|
+
severity: "error",
|
|
883
|
+
message: `Option \`dateParser: '${parser}'\` cannot format the adapter's \`dateType: 'date'\` values${schemaName ? ` in schema "${schemaName}"` : ""}.`,
|
|
884
|
+
help: "Set adapterOas({ dateType: 'string' }) or remove `dateParser`.",
|
|
885
|
+
location: { kind: "config" },
|
|
886
|
+
plugin: "plugin-faker"
|
|
887
|
+
});
|
|
888
|
+
return "faker.date.anytime()";
|
|
889
|
+
}
|
|
890
|
+
function matches(value, regexGenerator = "faker") {
|
|
891
|
+
if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
|
|
892
|
+
return `faker.helpers.fromRegExp(${toRegExpString(value, null)})`;
|
|
893
|
+
}
|
|
1000
894
|
function parseEnumValue(value) {
|
|
1001
895
|
if (typeof value === "string") return stringify(value);
|
|
1002
896
|
return value;
|
|
@@ -1042,49 +936,60 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1042
936
|
name: "faker",
|
|
1043
937
|
options,
|
|
1044
938
|
nodes: {
|
|
1045
|
-
any: () =>
|
|
1046
|
-
unknown: () =>
|
|
1047
|
-
void: () =>
|
|
1048
|
-
boolean: () =>
|
|
1049
|
-
null: () =>
|
|
939
|
+
any: () => "undefined",
|
|
940
|
+
unknown: () => "undefined",
|
|
941
|
+
void: () => "undefined",
|
|
942
|
+
boolean: () => "faker.datatype.boolean()",
|
|
943
|
+
null: () => "null",
|
|
1050
944
|
string(node) {
|
|
1051
|
-
if (node.pattern) return
|
|
1052
|
-
if (node.format && integerFormats.has(node.format)) return
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
uuid: () => fakerKeywordMapper.uuid(),
|
|
1058
|
-
number(node) {
|
|
1059
|
-
return fakerKeywordMapper.number(node.min, node.max);
|
|
945
|
+
if (node.pattern) return matches(node.pattern, this.options.regexGenerator);
|
|
946
|
+
if (node.format && integerFormats.has(node.format)) return node.format === "int32" ? `faker.number.int({ max: ${maxInt32} }).toString()` : "faker.number.bigInt().toString()";
|
|
947
|
+
const { min, max } = node;
|
|
948
|
+
if (min !== void 0 && max !== void 0) return `faker.string.alpha({ length: { min: ${min}, max: ${max} } })`;
|
|
949
|
+
if (max !== void 0 || min !== void 0) return `faker.string.alpha({ length: ${max ?? min} })`;
|
|
950
|
+
return "faker.string.alpha()";
|
|
1060
951
|
},
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
952
|
+
email: () => "faker.internet.email()",
|
|
953
|
+
url: () => "faker.internet.url()",
|
|
954
|
+
uuid: () => "faker.string.uuid()",
|
|
955
|
+
number: (node) => numberCall("float", node.min, node.max),
|
|
956
|
+
integer: (node) => numberCall("int", node.min, node.max),
|
|
957
|
+
bigint: () => "faker.number.bigInt()",
|
|
958
|
+
blob: () => "faker.image.url() as unknown as Blob",
|
|
959
|
+
datetime: () => "faker.date.anytime().toISOString()",
|
|
1067
960
|
date(node) {
|
|
1068
|
-
return
|
|
961
|
+
return dateTimeCall(node.representation ?? "string", {
|
|
962
|
+
format: "YYYY-MM-DD",
|
|
963
|
+
substring: "0, 10"
|
|
964
|
+
}, this.options.dateParser, this.options.schemaName);
|
|
1069
965
|
},
|
|
1070
966
|
time(node) {
|
|
1071
|
-
return
|
|
967
|
+
return dateTimeCall(node.representation ?? "string", {
|
|
968
|
+
format: "HH:mm:ss",
|
|
969
|
+
substring: "11, 19"
|
|
970
|
+
}, this.options.dateParser, this.options.schemaName);
|
|
1072
971
|
},
|
|
1073
972
|
ref(node) {
|
|
1074
973
|
const refName = kubb_kit.ast.resolveRefName(node);
|
|
1075
|
-
if (!refName) throw new Error(
|
|
974
|
+
if (!refName) throw new kubb_kit.Diagnostics.Error({
|
|
975
|
+
code: kubb_kit.Diagnostics.code.pluginFailed,
|
|
976
|
+
severity: "error",
|
|
977
|
+
message: `Ref node "${node.ref ?? node.name ?? "unknown"}"${this.options.schemaName ? ` in schema "${this.options.schemaName}"` : ""} has no name.`,
|
|
978
|
+
plugin: "plugin-faker"
|
|
979
|
+
});
|
|
1076
980
|
if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
|
|
1077
981
|
const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
|
|
1078
982
|
if (!this.options.nestedInObject) return `${resolvedName}(data)`;
|
|
1079
983
|
return `${resolvedName}()`;
|
|
1080
984
|
},
|
|
1081
985
|
enum(node) {
|
|
1082
|
-
|
|
986
|
+
const { typeName } = this.options;
|
|
987
|
+
return `faker.helpers.arrayElement${typeName ? `<${typeName}>` : ""}([${kubb_kit.ast.getSchemaLiteralValues(node).map(parseEnumValue).join(", ")}])`;
|
|
1083
988
|
},
|
|
1084
989
|
union(node) {
|
|
1085
990
|
const { discriminatorPropertyName } = node;
|
|
1086
991
|
const baseTypeName = this.options.typeName;
|
|
1087
|
-
|
|
992
|
+
return `faker.helpers.arrayElement([${mapSchemaMembers(node, (member) => {
|
|
1088
993
|
const value = discriminatorPropertyName ? getDiscriminatorValue(member, discriminatorPropertyName) : void 0;
|
|
1089
994
|
if (baseTypeName && value !== void 0) {
|
|
1090
995
|
const typeName = `Extract<NonNullable<${baseTypeName}>, { ${JSON.stringify(discriminatorPropertyName)}: ${parseEnumValue(value)} }>`;
|
|
@@ -1099,26 +1004,31 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1099
1004
|
nestedInObject: true,
|
|
1100
1005
|
nestedInUnion: true
|
|
1101
1006
|
});
|
|
1102
|
-
}).map(({ output }) => output).filter((item) => Boolean(item))
|
|
1103
|
-
return fakerKeywordMapper.union(items);
|
|
1007
|
+
}).map(({ output }) => output).filter((item) => Boolean(item)).join(", ")}])`;
|
|
1104
1008
|
},
|
|
1105
1009
|
intersection(node) {
|
|
1106
1010
|
const items = mapSchemaMembers(node, (member) => printNested(member, { nestedInObject: true })).map(({ output }) => output).filter((item) => Boolean(item) && item !== "undefined");
|
|
1107
|
-
|
|
1011
|
+
if (items.length === 0) return "{}";
|
|
1012
|
+
return items.length === 1 ? items[0] : `{...${items.join(", ...")}}`;
|
|
1108
1013
|
},
|
|
1109
1014
|
array(node) {
|
|
1110
1015
|
const items = mapSchemaItems(node, (member) => printNested(member, {
|
|
1111
1016
|
typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[number]` : void 0,
|
|
1112
1017
|
nestedInObject: true
|
|
1113
1018
|
})).map(({ output }) => output).filter((item) => Boolean(item));
|
|
1114
|
-
return
|
|
1019
|
+
if (items.length > 1) return `faker.helpers.arrayElements([${items.join(", ")}])`;
|
|
1020
|
+
const { min, max } = node;
|
|
1021
|
+
const item = items[0];
|
|
1022
|
+
if (min !== void 0 && max !== void 0) return `faker.helpers.multiple(() => (${item}), { count: { min: ${min}, max: ${max} }})`;
|
|
1023
|
+
if (min !== void 0) return `faker.helpers.multiple(() => (${item}), { count: ${min} })`;
|
|
1024
|
+
if (max !== void 0) return `faker.helpers.multiple(() => (${item}), { count: { min: 0, max: ${max} }})`;
|
|
1025
|
+
return `faker.helpers.multiple(() => (${item}))`;
|
|
1115
1026
|
},
|
|
1116
1027
|
tuple(node) {
|
|
1117
|
-
|
|
1028
|
+
return `[${(node.items ?? []).map((member, index) => printNested(member, {
|
|
1118
1029
|
typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[${index}]` : void 0,
|
|
1119
1030
|
nestedInObject: true
|
|
1120
|
-
})).filter((item) => Boolean(item))
|
|
1121
|
-
return fakerKeywordMapper.tuple(items);
|
|
1031
|
+
})).filter((item) => Boolean(item)).join(", ")}]`;
|
|
1122
1032
|
},
|
|
1123
1033
|
object(node) {
|
|
1124
1034
|
const cyclicSchemas = this.options.cyclicSchemas;
|
|
@@ -1135,10 +1045,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
|
|
|
1135
1045
|
}));
|
|
1136
1046
|
}
|
|
1137
1047
|
},
|
|
1138
|
-
overrides: options.nodes
|
|
1139
|
-
print(node) {
|
|
1140
|
-
return this.transform(node) ?? null;
|
|
1141
|
-
}
|
|
1048
|
+
overrides: options.nodes
|
|
1142
1049
|
};
|
|
1143
1050
|
});
|
|
1144
1051
|
//#endregion
|
|
@@ -1160,9 +1067,12 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1160
1067
|
const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
|
|
1161
1068
|
const schemaName = node.name;
|
|
1162
1069
|
const isEnumSchema = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
|
|
1163
|
-
const
|
|
1164
|
-
|
|
1165
|
-
|
|
1070
|
+
const schemaTypeName = (0, _kubb_plugin_ts.enumTypeName)({
|
|
1071
|
+
resolver: tsResolver,
|
|
1072
|
+
name: schemaName,
|
|
1073
|
+
enumOptions: pluginTs.options?.enum,
|
|
1074
|
+
isEnum: isEnumSchema
|
|
1075
|
+
});
|
|
1166
1076
|
const meta = {
|
|
1167
1077
|
name: resolver.name(schemaName),
|
|
1168
1078
|
file: resolver.file({
|
|
@@ -1343,7 +1253,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1343
1253
|
description: node.requestBody?.description ?? schema.description
|
|
1344
1254
|
}));
|
|
1345
1255
|
const responseName = resolver.response.response(node);
|
|
1346
|
-
const hasResponseNameCollision = new Set(node.responses.flatMap((response) => (response.content ?? []).flatMap((entry) => entry.schema ?
|
|
1256
|
+
const hasResponseNameCollision = new Set(node.responses.flatMap((response) => (response.content ?? []).flatMap((entry) => entry.schema ? kubb_kit.ast.collectImportedRefNames(entry.schema).map((name) => resolver.name(name)) : []))).has(responseName);
|
|
1347
1257
|
const localHelperNames = /* @__PURE__ */ new Set([
|
|
1348
1258
|
...paramGroups.map((group) => group.name),
|
|
1349
1259
|
...responseUnits.map((unit) => unit.name),
|
|
@@ -1472,20 +1382,8 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1472
1382
|
children: `faker.seed(${JSON.stringify(seed)})`
|
|
1473
1383
|
}) : void 0,
|
|
1474
1384
|
paramGroups.map((group) => renderEntry(group)),
|
|
1475
|
-
responseUnits.map((unit) => renderEntry(
|
|
1476
|
-
|
|
1477
|
-
name: unit.name,
|
|
1478
|
-
typeName: unit.typeName,
|
|
1479
|
-
description: unit.description,
|
|
1480
|
-
skipImportNames: unit.skipImportNames
|
|
1481
|
-
})),
|
|
1482
|
-
dataUnits.map((unit) => renderEntry({
|
|
1483
|
-
schema: unit.schema,
|
|
1484
|
-
name: unit.name,
|
|
1485
|
-
typeName: unit.typeName,
|
|
1486
|
-
description: unit.description,
|
|
1487
|
-
skipImportNames: unit.skipImportNames
|
|
1488
|
-
})),
|
|
1385
|
+
responseUnits.map((unit) => renderEntry(unit)),
|
|
1386
|
+
dataUnits.map((unit) => renderEntry(unit)),
|
|
1489
1387
|
!hasResponseNameCollision && renderEntry({
|
|
1490
1388
|
schema: buildResponseUnionSchema(node, resolver),
|
|
1491
1389
|
name: responseName,
|
|
@@ -1504,7 +1402,7 @@ var compatibility = {
|
|
|
1504
1402
|
};
|
|
1505
1403
|
//#endregion
|
|
1506
1404
|
//#region package.json
|
|
1507
|
-
var version = "5.1.
|
|
1405
|
+
var version = "5.1.7";
|
|
1508
1406
|
//#endregion
|
|
1509
1407
|
//#region src/resolvers/resolverFaker.ts
|
|
1510
1408
|
/**
|
|
@@ -1572,6 +1470,18 @@ const pluginFaker = (0, kubb_kit.defineExtension)({
|
|
|
1572
1470
|
path: "mocks",
|
|
1573
1471
|
barrel: { type: "named" }
|
|
1574
1472
|
}, seed, locale = "en", group, exclude = [], include, override = [], typeMode = "inferred", dateParser = "faker", regexGenerator = "faker", printer, resolver: userResolver, macros: userMacros } = options;
|
|
1473
|
+
(0, kubb_kit.assertPluginOption)({
|
|
1474
|
+
plugin: pluginFakerName,
|
|
1475
|
+
option: "typeMode",
|
|
1476
|
+
value: typeMode,
|
|
1477
|
+
allowed: ["inferred", "schema"]
|
|
1478
|
+
});
|
|
1479
|
+
(0, kubb_kit.assertPluginOption)({
|
|
1480
|
+
plugin: pluginFakerName,
|
|
1481
|
+
option: "regexGenerator",
|
|
1482
|
+
value: regexGenerator,
|
|
1483
|
+
allowed: ["faker", "randexp"]
|
|
1484
|
+
});
|
|
1575
1485
|
(0, kubb_kit.setResolver)(userResolver ? kubb_kit.Resolver.merge(resolverFaker, userResolver) : resolverFaker);
|
|
1576
1486
|
if (userMacros?.length) (0, kubb_kit.setMacros)(userMacros);
|
|
1577
1487
|
(0, kubb_kit.addGenerator)(fakerGenerator);
|