@kubb/plugin-faker 5.0.0-beta.99 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +78 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +79 -15
- package/dist/index.js.map +1 -1
- package/package.json +6 -9
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
2
|
import { posix } from "node:path";
|
|
3
|
-
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
3
|
+
import { Resolver, ast, containsCircularRef, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
4
4
|
import { buildParams, createFunctionParameter, createFunctionParameters, functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
5
5
|
import { File, Function, jsxRenderer } from "kubb/jsx";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
@@ -576,8 +576,9 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
576
576
|
})();
|
|
577
577
|
const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
|
|
578
578
|
if (!useGenericOverride) {
|
|
579
|
+
const dataParamName = /\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data";
|
|
579
580
|
const params = createFunctionParameters({ params: [createFunctionParameter({
|
|
580
|
-
name:
|
|
581
|
+
name: dataParamName,
|
|
581
582
|
type: dataType,
|
|
582
583
|
optional: true
|
|
583
584
|
})] });
|
|
@@ -601,7 +602,7 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
|
|
|
601
602
|
const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
|
|
602
603
|
const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
|
|
603
604
|
const { cyclicSchemas, schemaName } = printer.options;
|
|
604
|
-
const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) =>
|
|
605
|
+
const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => containsCircularRef(p.schema, {
|
|
605
606
|
circularSchemas: cyclicSchemas,
|
|
606
607
|
excludeName: schemaName
|
|
607
608
|
})) ? `{
|
|
@@ -647,6 +648,45 @@ function dedupeParams(params) {
|
|
|
647
648
|
//#endregion
|
|
648
649
|
//#region ../../internals/shared/src/operation.ts
|
|
649
650
|
/**
|
|
651
|
+
* Builds the `ResolverFileParams` every operation generator passes to
|
|
652
|
+
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
653
|
+
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
654
|
+
* that was repeated at dozens of call sites across the client and query plugins.
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```ts
|
|
658
|
+
* resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
function operationFileEntry(node, name, extname = ".ts") {
|
|
662
|
+
return {
|
|
663
|
+
name,
|
|
664
|
+
extname,
|
|
665
|
+
tag: node.tags[0] ?? "default",
|
|
666
|
+
path: node.path
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
|
|
671
|
+
* current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
|
|
672
|
+
* same dependency for the same operation in one pass (a query plugin's several hook generators, the
|
|
673
|
+
* MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
|
|
674
|
+
*
|
|
675
|
+
* @example Cache `plugin-ts`'s file for the current operation
|
|
676
|
+
* ```ts
|
|
677
|
+
* const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
|
|
678
|
+
* ```
|
|
679
|
+
*/
|
|
680
|
+
function resolveDependencyOperationFile(options) {
|
|
681
|
+
const { cache, node, resolver, root, output, group } = options;
|
|
682
|
+
return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
|
|
683
|
+
...operationFileEntry(node, node.operationId),
|
|
684
|
+
root,
|
|
685
|
+
output,
|
|
686
|
+
group: group ?? void 0
|
|
687
|
+
}));
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
650
690
|
* Maps a content type to the PascalCase suffix used to name per-content-type variants
|
|
651
691
|
* (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).
|
|
652
692
|
*/
|
|
@@ -694,16 +734,24 @@ function resolveContentTypeVariants(entries, baseName) {
|
|
|
694
734
|
};
|
|
695
735
|
});
|
|
696
736
|
}
|
|
737
|
+
const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
738
|
+
/**
|
|
739
|
+
* Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
|
|
740
|
+
* group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
|
|
741
|
+
* (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
|
|
742
|
+
* same parameters once per plugin.
|
|
743
|
+
*/
|
|
697
744
|
function getOperationParameters(node) {
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
})),
|
|
745
|
+
const cached = operationParameterGroupsByNode.get(node);
|
|
746
|
+
if (cached) return cached;
|
|
747
|
+
const groups = {
|
|
748
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
703
749
|
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
704
750
|
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
705
751
|
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
706
752
|
};
|
|
753
|
+
operationParameterGroupsByNode.set(node, groups);
|
|
754
|
+
return groups;
|
|
707
755
|
}
|
|
708
756
|
//#endregion
|
|
709
757
|
//#region ../../internals/shared/src/resolver.ts
|
|
@@ -835,6 +883,18 @@ function mapSchemaItems(node, transform) {
|
|
|
835
883
|
}
|
|
836
884
|
//#endregion
|
|
837
885
|
//#region src/printers/printerFaker.ts
|
|
886
|
+
/**
|
|
887
|
+
* Formats that put a whole number inside a `type: 'string'` schema, the way ProtoJSON encodes
|
|
888
|
+
* 64-bit integers, so the mock has to be digits rather than letters.
|
|
889
|
+
*
|
|
890
|
+
* @see https://protobuf.dev/programming-guides/json/#int64-strings
|
|
891
|
+
*/
|
|
892
|
+
const integerFormats = /* @__PURE__ */ new Set([
|
|
893
|
+
"int32",
|
|
894
|
+
"int64",
|
|
895
|
+
"uint64"
|
|
896
|
+
]);
|
|
897
|
+
const maxInt32 = 2147483647;
|
|
838
898
|
const fakerKeywordMapper = {
|
|
839
899
|
any: () => "undefined",
|
|
840
900
|
unknown: () => "undefined",
|
|
@@ -852,6 +912,10 @@ const fakerKeywordMapper = {
|
|
|
852
912
|
return "faker.number.int()";
|
|
853
913
|
},
|
|
854
914
|
bigint: () => "faker.number.bigInt()",
|
|
915
|
+
integerString: (format) => {
|
|
916
|
+
if (format === "int32") return `faker.number.int({ max: ${maxInt32} }).toString()`;
|
|
917
|
+
return "faker.number.bigInt().toString()";
|
|
918
|
+
},
|
|
855
919
|
string: (min, max) => {
|
|
856
920
|
if (max !== void 0 && min !== void 0) return `faker.string.alpha({ length: { min: ${min}, max: ${max} } })`;
|
|
857
921
|
if (max !== void 0) return `faker.string.alpha({ length: ${max} })`;
|
|
@@ -951,6 +1015,7 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
951
1015
|
null: () => fakerKeywordMapper.null(),
|
|
952
1016
|
string(node) {
|
|
953
1017
|
if (node.pattern) return fakerKeywordMapper.matches(node.pattern, this.options.regexGenerator);
|
|
1018
|
+
if (node.format && integerFormats.has(node.format)) return fakerKeywordMapper.integerString(node.format);
|
|
954
1019
|
return fakerKeywordMapper.string(node.min, node.max);
|
|
955
1020
|
},
|
|
956
1021
|
email: () => fakerKeywordMapper.email(),
|
|
@@ -1027,7 +1092,7 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
1027
1092
|
typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
|
|
1028
1093
|
nestedInObject: true
|
|
1029
1094
|
}) ?? "undefined";
|
|
1030
|
-
if (cyclicSchemas &&
|
|
1095
|
+
if (cyclicSchemas && containsCircularRef(property.schema, {
|
|
1031
1096
|
circularSchemas: cyclicSchemas,
|
|
1032
1097
|
excludeName: this.options.schemaName
|
|
1033
1098
|
})) return `get ${objectKey(property.name)}() { const _value = ${value}; Object.defineProperty(this, ${JSON.stringify(property.name)}, { value: _value, configurable: true, writable: true, enumerable: true }); return _value }`;
|
|
@@ -1256,14 +1321,13 @@ const fakerGenerator = defineGenerator({
|
|
|
1256
1321
|
output,
|
|
1257
1322
|
group: group ?? void 0
|
|
1258
1323
|
}),
|
|
1259
|
-
typeFile:
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
path: node.path,
|
|
1324
|
+
typeFile: resolveDependencyOperationFile({
|
|
1325
|
+
cache: ctx.cache,
|
|
1326
|
+
node,
|
|
1327
|
+
resolver: tsResolver,
|
|
1264
1328
|
root,
|
|
1265
1329
|
output: pluginTs.options?.output ?? output,
|
|
1266
|
-
group: pluginTs.options?.group
|
|
1330
|
+
group: pluginTs.options?.group
|
|
1267
1331
|
})
|
|
1268
1332
|
};
|
|
1269
1333
|
function resolveMockImports(schema) {
|