@kubb/plugin-faker 5.1.9 → 5.1.11
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 +39 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +40 -43
- package/dist/index.js.map +1 -1
- package/kubb-extension.json +30 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
|
-
import { Diagnostics, Resolver, addGenerator,
|
|
2
|
+
import { Diagnostics, Resolver, addGenerator, ast, containsCircularRef, createResolver, defineExtension, defineGenerator, setMacros, setResolver } 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";
|
|
@@ -12,12 +12,23 @@ import { buildParams, enumTypeName, pluginTsName } from "@kubb/plugin-ts";
|
|
|
12
12
|
*
|
|
13
13
|
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
14
14
|
*/
|
|
15
|
-
function
|
|
15
|
+
function convert(text, pascal) {
|
|
16
16
|
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) => {
|
|
17
17
|
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
18
18
|
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
19
19
|
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
20
20
|
}
|
|
21
|
+
const cache = /* @__PURE__ */ new Map();
|
|
22
|
+
const cacheLimit = 1e4;
|
|
23
|
+
function toCamelOrPascal(text, pascal) {
|
|
24
|
+
const key = `${pascal ? "P" : "c"}${text}`;
|
|
25
|
+
const cached = cache.get(key);
|
|
26
|
+
if (cached !== void 0) return cached;
|
|
27
|
+
const result = convert(text, pascal);
|
|
28
|
+
if (cache.size >= cacheLimit) cache.clear();
|
|
29
|
+
cache.set(key, result);
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
21
32
|
/**
|
|
22
33
|
* Converts `text` to camelCase.
|
|
23
34
|
*
|
|
@@ -220,29 +231,16 @@ function stringify(value) {
|
|
|
220
231
|
return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
221
232
|
}
|
|
222
233
|
/**
|
|
223
|
-
* Escapes
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
|
|
234
|
+
* Escapes an `@` at the start of a line, so a multi-line description can't start a new JSDoc tag.
|
|
235
|
+
* Editors render `\@` as `@` in hovers.
|
|
227
236
|
*
|
|
228
237
|
* @example
|
|
229
238
|
* ```ts
|
|
230
|
-
*
|
|
239
|
+
* jsDocEscape('intro\n@example value') // 'intro\n\\@example value'
|
|
231
240
|
* ```
|
|
232
241
|
*/
|
|
233
|
-
function
|
|
234
|
-
return `${input}`.replace(
|
|
235
|
-
switch (character) {
|
|
236
|
-
case "\"":
|
|
237
|
-
case "'":
|
|
238
|
-
case "\\": return `\\${character}`;
|
|
239
|
-
case "\n": return "\\n";
|
|
240
|
-
case "\r": return "\\r";
|
|
241
|
-
case "\u2028": return "\\u2028";
|
|
242
|
-
case "\u2029": return "\\u2029";
|
|
243
|
-
default: return "";
|
|
244
|
-
}
|
|
245
|
-
});
|
|
242
|
+
function jsDocEscape(input) {
|
|
243
|
+
return `${input}`.replace(/^(\s*)@/gm, "$1\\@");
|
|
246
244
|
}
|
|
247
245
|
/**
|
|
248
246
|
* Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
|
|
@@ -398,6 +396,12 @@ const NON_INLINABLE_RESPONSE_TYPES = /* @__PURE__ */ new Set([
|
|
|
398
396
|
function canOverrideSchema(node) {
|
|
399
397
|
return !NON_OVERRIDABLE_TYPES.has(node.type);
|
|
400
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Follows a ref, including alias chains, to the schema it resolves to. Unresolved refs are returned as is.
|
|
401
|
+
*/
|
|
402
|
+
function resolveRefTarget(node) {
|
|
403
|
+
return node.type === "ref" && node.schema ? resolveRefTarget(node.schema) : node;
|
|
404
|
+
}
|
|
401
405
|
function shouldInlineSingleResponseSchema(schema) {
|
|
402
406
|
return !NON_INLINABLE_RESPONSE_TYPES.has(schema.type);
|
|
403
407
|
}
|
|
@@ -488,7 +492,7 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
|
|
|
488
492
|
return {
|
|
489
493
|
dataType,
|
|
490
494
|
returnType,
|
|
491
|
-
usesTypeName: dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
495
|
+
usesTypeName: canOverride && dataType.includes(typeName) || Boolean(returnType?.includes(typeName))
|
|
492
496
|
};
|
|
493
497
|
}
|
|
494
498
|
//#endregion
|
|
@@ -520,7 +524,7 @@ function Faker({ node, description, name, typeName, printer, canOverride, typeMo
|
|
|
520
524
|
children: /* @__PURE__ */ jsx(Function, {
|
|
521
525
|
export: true,
|
|
522
526
|
name,
|
|
523
|
-
JSDoc: { comments: description ? [`@description ${
|
|
527
|
+
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
524
528
|
params: canOverride ? paramsSignature : void 0,
|
|
525
529
|
returnType: returnType ?? void 0,
|
|
526
530
|
children: `return ${returnExpression}`
|
|
@@ -550,7 +554,7 @@ return {
|
|
|
550
554
|
children: /* @__PURE__ */ jsx(Function, {
|
|
551
555
|
export: true,
|
|
552
556
|
name,
|
|
553
|
-
JSDoc: { comments: description ? [`@description ${
|
|
557
|
+
JSDoc: { comments: description ? [`@description ${jsDocEscape(description)}`] : [] },
|
|
554
558
|
generics: typeMode === "schema" ? void 0 : `TData extends Partial<${typeName}> = object`,
|
|
555
559
|
params: typeMode === "schema" ? `data?: Partial<${typeName}>` : "data?: TData",
|
|
556
560
|
returnType: typeMode === "schema" ? typeName : void 0,
|
|
@@ -892,18 +896,22 @@ function parseEnumValue(value) {
|
|
|
892
896
|
return value;
|
|
893
897
|
}
|
|
894
898
|
/**
|
|
895
|
-
* Reads the discriminator literal off a variant,
|
|
899
|
+
* Reads the discriminator literal off a variant, with whether its property is required, or
|
|
900
|
+
* `undefined` when it can't be determined.
|
|
896
901
|
*
|
|
897
902
|
* A variant carries exactly one discriminator value, so a property resolving to several literals
|
|
898
903
|
* (a `ref` to the enum shared by every branch, say) identifies no branch and narrows nothing.
|
|
899
904
|
*/
|
|
900
|
-
function
|
|
905
|
+
function getDiscriminator(member, discriminatorPropertyName) {
|
|
901
906
|
for (const property of ast.resolveSchemaProperties({
|
|
902
907
|
node: member,
|
|
903
908
|
propertyName: discriminatorPropertyName
|
|
904
909
|
})) {
|
|
905
910
|
const values = ast.getSchemaLiteralValues(property.schema);
|
|
906
|
-
if (values.length === 1) return
|
|
911
|
+
if (values.length === 1) return {
|
|
912
|
+
value: values[0],
|
|
913
|
+
required: property.required
|
|
914
|
+
};
|
|
907
915
|
}
|
|
908
916
|
}
|
|
909
917
|
/**
|
|
@@ -975,7 +983,7 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
975
983
|
});
|
|
976
984
|
if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
|
|
977
985
|
const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
|
|
978
|
-
if (!this.options.nestedInObject) return `${resolvedName}(data)`;
|
|
986
|
+
if (!this.options.nestedInObject && canOverrideSchema(resolveRefTarget(node))) return `${resolvedName}(data)`;
|
|
979
987
|
return `${resolvedName}()`;
|
|
980
988
|
},
|
|
981
989
|
enum(node) {
|
|
@@ -986,9 +994,10 @@ const printerFaker = ast.createPrinter((options) => {
|
|
|
986
994
|
const { discriminatorPropertyName } = node;
|
|
987
995
|
const baseTypeName = this.options.typeName;
|
|
988
996
|
return `faker.helpers.arrayElement([${mapSchemaMembers(node, (member) => {
|
|
989
|
-
const
|
|
990
|
-
if (baseTypeName &&
|
|
991
|
-
const
|
|
997
|
+
const discriminator = discriminatorPropertyName ? getDiscriminator(member, discriminatorPropertyName) : void 0;
|
|
998
|
+
if (baseTypeName && discriminator) {
|
|
999
|
+
const key = `${JSON.stringify(discriminatorPropertyName)}${discriminator.required ? "" : "?"}`;
|
|
1000
|
+
const typeName = `Extract<NonNullable<${baseTypeName}>, { ${key}: ${parseEnumValue(discriminator.value)} }>`;
|
|
992
1001
|
return printNested(member, {
|
|
993
1002
|
typeName,
|
|
994
1003
|
nestedInObject: true,
|
|
@@ -1398,7 +1407,7 @@ var compatibility = {
|
|
|
1398
1407
|
};
|
|
1399
1408
|
//#endregion
|
|
1400
1409
|
//#region package.json
|
|
1401
|
-
var version = "5.1.
|
|
1410
|
+
var version = "5.1.11";
|
|
1402
1411
|
//#endregion
|
|
1403
1412
|
//#region src/resolvers/resolverFaker.ts
|
|
1404
1413
|
/**
|
|
@@ -1466,18 +1475,6 @@ const pluginFaker = defineExtension({
|
|
|
1466
1475
|
path: "mocks",
|
|
1467
1476
|
barrel: { type: "named" }
|
|
1468
1477
|
}, seed, locale = "en", group, exclude = [], include, override = [], typeMode = "inferred", dateParser = "faker", regexGenerator = "faker", printer, resolver: userResolver, macros: userMacros } = options;
|
|
1469
|
-
assertPluginOption({
|
|
1470
|
-
plugin: pluginFakerName,
|
|
1471
|
-
option: "typeMode",
|
|
1472
|
-
value: typeMode,
|
|
1473
|
-
allowed: ["inferred", "schema"]
|
|
1474
|
-
});
|
|
1475
|
-
assertPluginOption({
|
|
1476
|
-
plugin: pluginFakerName,
|
|
1477
|
-
option: "regexGenerator",
|
|
1478
|
-
value: regexGenerator,
|
|
1479
|
-
allowed: ["faker", "randexp"]
|
|
1480
|
-
});
|
|
1481
1478
|
setResolver(userResolver ? Resolver.merge(resolverFaker, userResolver) : resolverFaker);
|
|
1482
1479
|
if (userMacros?.length) setMacros(userMacros);
|
|
1483
1480
|
addGenerator(fakerGenerator);
|