@kubb/plugin-faker 5.0.0-beta.84 → 5.0.0-beta.85

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 CHANGED
@@ -2,35 +2,382 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- //#region \0rolldown/runtime.js
6
- var __create = Object.create;
7
- var __defProp = Object.defineProperty;
8
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
- var __getOwnPropNames = Object.getOwnPropertyNames;
10
- var __getProtoOf = Object.getPrototypeOf;
11
- var __hasOwnProp = Object.prototype.hasOwnProperty;
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
14
- key = keys[i];
15
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: ((k) => from[k]).bind(null, key),
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
5
+ //#endregion
6
+ let node_path = require("node:path");
7
+ let kubb_kit = require("kubb/kit");
8
+ let _kubb_plugin_ts = require("@kubb/plugin-ts");
9
+ let kubb_jsx = require("kubb/jsx");
10
+ let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
11
+ //#region ../../internals/utils/src/casing.ts
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 toCamelOrPascal(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
+ /**
26
+ * Converts `text` to camelCase.
27
+ *
28
+ * @example Word boundaries
29
+ * `camelCase('hello-world') // 'helloWorld'`
30
+ *
31
+ * @example With a prefix
32
+ * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
33
+ */
34
+ function camelCase(text, { prefix = "", suffix = "" } = {}) {
35
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
36
+ }
37
+ //#endregion
38
+ //#region ../../internals/utils/src/reserved.ts
39
+ /**
40
+ * JavaScript and Java reserved words.
41
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
42
+ */
43
+ const reservedWords = /* @__PURE__ */ new Set([
44
+ "abstract",
45
+ "arguments",
46
+ "boolean",
47
+ "break",
48
+ "byte",
49
+ "case",
50
+ "catch",
51
+ "char",
52
+ "class",
53
+ "const",
54
+ "continue",
55
+ "debugger",
56
+ "default",
57
+ "delete",
58
+ "do",
59
+ "double",
60
+ "else",
61
+ "enum",
62
+ "eval",
63
+ "export",
64
+ "extends",
65
+ "false",
66
+ "final",
67
+ "finally",
68
+ "float",
69
+ "for",
70
+ "function",
71
+ "goto",
72
+ "if",
73
+ "implements",
74
+ "import",
75
+ "in",
76
+ "instanceof",
77
+ "int",
78
+ "interface",
79
+ "let",
80
+ "long",
81
+ "native",
82
+ "new",
83
+ "null",
84
+ "package",
85
+ "private",
86
+ "protected",
87
+ "public",
88
+ "return",
89
+ "short",
90
+ "static",
91
+ "super",
92
+ "switch",
93
+ "synchronized",
94
+ "this",
95
+ "throw",
96
+ "throws",
97
+ "transient",
98
+ "true",
99
+ "try",
100
+ "typeof",
101
+ "var",
102
+ "void",
103
+ "volatile",
104
+ "while",
105
+ "with",
106
+ "yield",
107
+ "Array",
108
+ "Date",
109
+ "hasOwnProperty",
110
+ "Infinity",
111
+ "isFinite",
112
+ "isNaN",
113
+ "isPrototypeOf",
114
+ "length",
115
+ "Math",
116
+ "name",
117
+ "NaN",
118
+ "Number",
119
+ "Object",
120
+ "prototype",
121
+ "String",
122
+ "toString",
123
+ "undefined",
124
+ "valueOf"
125
+ ]);
126
+ /**
127
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * isValidVarName('status') // true
132
+ * isValidVarName('class') // false (reserved word)
133
+ * isValidVarName('42foo') // false (starts with digit)
134
+ * ```
135
+ */
136
+ function isValidVarName(name) {
137
+ if (!name || reservedWords.has(name)) return false;
138
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
139
+ }
140
+ /**
141
+ * Returns `name` when it's a syntactically valid JavaScript variable name,
142
+ * otherwise prefixes it with `_` so the result is a valid identifier.
143
+ *
144
+ * Useful for sanitizing OpenAPI schema names or operation IDs that start with
145
+ * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
146
+ * variable, type, or function names.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * ensureValidVarName('409') // '_409'
151
+ * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
152
+ * ensureValidVarName('Pet') // 'Pet'
153
+ * ensureValidVarName('class') // '_class'
154
+ * ```
155
+ */
156
+ function ensureValidVarName(name) {
157
+ if (!name || isValidVarName(name)) return name;
158
+ return `_${name}`;
159
+ }
160
+ /**
161
+ * Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
162
+ *
163
+ * Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
164
+ * even though they are not valid variable names, so use this (not {@link isValidVarName}) when
165
+ * deciding whether an object key needs quoting.
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * isIdentifier('name') // true
170
+ * isIdentifier('x-total')// false
171
+ * ```
172
+ */
173
+ function isIdentifier(name) {
174
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
175
+ }
176
+ //#endregion
177
+ //#region ../../internals/utils/src/strings.ts
178
+ /**
179
+ * Wraps a value in single quotes for emitting a single-quoted JavaScript string literal, escaping
180
+ * any backslash or single quote in the content.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * singleQuote('foo') // "'foo'"
185
+ * singleQuote("o'clock") // "'o\\'clock'"
186
+ * ```
187
+ */
188
+ function singleQuote(value) {
189
+ if (value === void 0 || value === null) return "''";
190
+ return `'${String(value).replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
191
+ }
192
+ /**
193
+ * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
194
+ * Returns the string unchanged when no balanced quote pair is found.
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * trimQuotes('"hello"') // 'hello'
199
+ * trimQuotes('hello') // 'hello'
200
+ * ```
201
+ */
202
+ function trimQuotes(text) {
203
+ if (text.length >= 2) {
204
+ const first = text[0];
205
+ const last = text[text.length - 1];
206
+ if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
19
207
  }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
208
+ return text;
209
+ }
210
+ /**
211
+ * Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
212
+ *
213
+ * Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
214
+ * code matches the repo style without a formatter.
215
+ *
216
+ * @example
217
+ * ```ts
218
+ * stringify('hello') // "'hello'"
219
+ * stringify('"hello"') // "'hello'"
220
+ * ```
221
+ */
222
+ function stringify(value) {
223
+ if (value === void 0 || value === null) return "''";
224
+ return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
225
+ }
226
+ /**
227
+ * Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
228
+ * and the Unicode line terminators U+2028 and U+2029.
229
+ *
230
+ * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
231
+ *
232
+ * @example
233
+ * ```ts
234
+ * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
235
+ * ```
236
+ */
237
+ function jsStringEscape(input) {
238
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
239
+ switch (character) {
240
+ case "\"":
241
+ case "'":
242
+ case "\\": return `\\${character}`;
243
+ case "\n": return "\\n";
244
+ case "\r": return "\\r";
245
+ case "\u2028": return "\\u2028";
246
+ case "\u2029": return "\\u2029";
247
+ default: return "";
248
+ }
249
+ });
250
+ }
251
+ /**
252
+ * Converts a pattern string into a `new RegExp(...)` constructor call or a regex literal string.
253
+ * Inline flags expressed as a `^(?im)` prefix are extracted and applied to the resulting expression.
254
+ * Pass `null` as the second argument to emit a `/pattern/flags` literal instead.
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * toRegExpString('^(?im)foo') // 'new RegExp("^foo", "im")'
259
+ * toRegExpString('^(?im)foo', null) // '/^foo/im'
260
+ * ```
261
+ */
262
+ function toRegExpString(text, func = "RegExp") {
263
+ const raw = trimQuotes(text);
264
+ const match = raw.match(/^\^(\(\?([igmsuy]+)\))/i);
265
+ const replacementTarget = match?.[1] ?? "";
266
+ const matchedFlags = match?.[2];
267
+ const cleaned = raw.replace(/^\\?\//, "").replace(/\\?\/$/, "").replace(replacementTarget, "");
268
+ const { source, flags } = new RegExp(cleaned, matchedFlags);
269
+ if (func === null) return `/${source}/${flags}`;
270
+ return `new ${func}(${JSON.stringify(source)}${flags ? `, ${JSON.stringify(flags)}` : ""})`;
271
+ }
272
+ //#endregion
273
+ //#region ../../internals/utils/src/codegen.ts
274
+ const INDENT = " ";
275
+ /**
276
+ * Indents every non-empty line of `text` by one indent level, leaving blank lines empty.
277
+ */
278
+ function indentLines(text) {
279
+ if (!text) return "";
280
+ return text.split("\n").map((line) => line.trim() ? `${INDENT}${line}` : "").join("\n");
281
+ }
282
+ /**
283
+ * Renders an object key, quoting it with single quotes only when it is not a valid identifier.
284
+ * Reserved words and globals (`name`, `class`, …) are valid bare keys and stay unquoted.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * objectKey('name') // 'name'
289
+ * objectKey('x-total') // "'x-total'"
290
+ * ```
291
+ */
292
+ function objectKey(name) {
293
+ return isIdentifier(name) ? name : singleQuote(name);
294
+ }
295
+ /**
296
+ * Assembles a multi-line object literal from already-rendered `entries`, indenting each entry one
297
+ * level and closing the brace at column zero. Entries that are themselves multi-line objects indent
298
+ * cumulatively. Each entry ends with a trailing comma to match the formatter's multi-line style.
299
+ *
300
+ * @example
301
+ * ```ts
302
+ * buildObject(['id: z.number()', 'name: z.string()'])
303
+ * // '{\n id: z.number(),\n name: z.string(),\n}'
304
+ * ```
305
+ */
306
+ function buildObject(entries) {
307
+ if (entries.length === 0) return "{}";
308
+ return `{\n${entries.map((entry) => `${indentLines(entry)},`).join("\n")}\n}`;
309
+ }
310
+ //#endregion
311
+ //#region ../../internals/utils/src/fs.ts
312
+ /**
313
+ * Builds a nested file path from a dotted name. Splits on dots that precede a letter
314
+ * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
315
+ * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
316
+ *
317
+ * Empty segments are dropped before joining. They arise when the name starts with a dot
318
+ * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
319
+ * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
320
+ * absolute path, letting generated files escape the configured output directory.
321
+ *
322
+ * @example Nested path from a dotted name
323
+ * `toFilePath('pet.petId') // 'pet/petId'`
324
+ *
325
+ * @example PascalCase the final segment
326
+ * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
327
+ *
328
+ * @example Suffix applied to the final segment only
329
+ * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
330
+ */
331
+ function toFilePath(name, caseLast = camelCase) {
332
+ const parts = name.split(/\.(?=[a-zA-Z])/);
333
+ return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
334
+ }
335
+ //#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
+ }
26
380
  //#endregion
27
- let kubb_kit = require("kubb/kit");
28
- let _kubb_plugin_ts = require("@kubb/plugin-ts");
29
- let kubb_jsx = require("kubb/jsx");
30
- let node_path = require("node:path");
31
- node_path = __toESM(node_path, 1);
32
- let kubb_jsx_jsx_runtime = require("kubb/jsx/jsx-runtime");
33
- let node_crypto = require("node:crypto");
34
381
  //#region src/utils.ts
35
382
  /**
36
383
  * Returns the `@faker-js/faker` named export for a locale code.
@@ -79,17 +426,6 @@ function canOverrideSchema(node) {
79
426
  "blob"
80
427
  ])).has(node.type);
81
428
  }
82
- /**
83
- * Resolves a parameter name based on its location (path, query, header, etc.) using the provided resolver.
84
- */
85
- function resolveParamNameByLocation(resolver, node, param) {
86
- switch (param.in) {
87
- case "path": return resolver.resolvePathParamsName(node, param);
88
- case "query": return resolver.resolveQueryParamsName(node, param);
89
- case "header": return resolver.resolveHeaderParamsName(node, param);
90
- default: return resolver.resolveParamName(node, param);
91
- }
92
- }
93
429
  function shouldInlineSingleResponseSchema(schema) {
94
430
  return (/* @__PURE__ */ new Set([
95
431
  "any",
@@ -126,14 +462,14 @@ function buildResponseUnionSchema(node, resolver) {
126
462
  if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
127
463
  return kubb_kit.ast.factory.createSchema({
128
464
  type: "ref",
129
- name: resolver.resolveResponseStatusName(node, responses[0].statusCode)
465
+ name: resolver.response.status(node, responses[0].statusCode)
130
466
  });
131
467
  }
132
468
  return kubb_kit.ast.factory.createSchema({
133
469
  type: "union",
134
470
  members: responses.map((response) => kubb_kit.ast.factory.createSchema({
135
471
  type: "ref",
136
- name: resolver.resolveResponseStatusName(node, response.statusCode)
472
+ name: resolver.response.status(node, response.statusCode)
137
473
  }))
138
474
  });
139
475
  }
@@ -261,14 +597,14 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
261
597
  children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.Function, {
262
598
  export: true,
263
599
  name,
264
- JSDoc: { comments: description ? [`@description ${kubb_kit.ast.jsStringEscape(description)}`] : [] },
600
+ JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
265
601
  params: canOverride ? paramsSignature : void 0,
266
602
  returnType: returnType ?? void 0,
267
603
  children: [seed ? /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [`faker.seed(${JSON.stringify(seed)})`, /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)("br", {})] }) : void 0, `return ${returnExpression}`]
268
604
  })
269
605
  });
270
606
  }
271
- const functionSignature = `${description ? `/**\n * @description ${kubb_kit.ast.jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
607
+ const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
272
608
  const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
273
609
  const { cyclicSchemas, schemaName } = printer.options;
274
610
  const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => kubb_kit.ast.containsCircularRef(p.schema, {
@@ -297,226 +633,6 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
297
633
  });
298
634
  }
299
635
  //#endregion
300
- //#region ../../internals/utils/src/casing.ts
301
- /**
302
- * Shared implementation for camelCase and PascalCase conversion.
303
- * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
304
- * and capitalizes each word according to `pascal`.
305
- *
306
- * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
307
- */
308
- function toCamelOrPascal(text, pascal) {
309
- 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) => {
310
- if (word.length > 1 && word === word.toUpperCase()) return word;
311
- return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
312
- }).join("").replace(/[^a-zA-Z0-9]/g, "");
313
- }
314
- /**
315
- * Converts `text` to camelCase.
316
- *
317
- * @example Word boundaries
318
- * `camelCase('hello-world') // 'helloWorld'`
319
- *
320
- * @example With a prefix
321
- * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
322
- */
323
- function camelCase(text, { prefix = "", suffix = "" } = {}) {
324
- return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
325
- }
326
- //#endregion
327
- //#region ../../internals/utils/src/fs.ts
328
- /**
329
- * Builds a nested file path from a dotted name. Splits on dots that precede a letter
330
- * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
331
- * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
332
- *
333
- * Empty segments are dropped before joining. They arise when the name starts with a dot
334
- * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
335
- * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
336
- * absolute path, letting generated files escape the configured output directory.
337
- *
338
- * @example Nested path from a dotted name
339
- * `toFilePath('pet.petId') // 'pet/petId'`
340
- *
341
- * @example PascalCase the final segment
342
- * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
343
- *
344
- * @example Suffix applied to the final segment only
345
- * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
346
- */
347
- function toFilePath(name, caseLast = camelCase) {
348
- const parts = name.split(/\.(?=[a-zA-Z])/);
349
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
350
- }
351
- //#endregion
352
- //#region ../../internals/utils/src/imports.ts
353
- function escapeRegExp(value) {
354
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
355
- }
356
- function getImportNames(entry) {
357
- return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
358
- if (typeof name === "string") return name;
359
- return name.name ?? name.propertyName;
360
- }).filter((name) => Boolean(name));
361
- }
362
- function filterUsedImports(imports, text, skipImportNames = []) {
363
- const skip = new Set(skipImportNames);
364
- return imports.filter((entry) => {
365
- return getImportNames(entry).some((name) => {
366
- if (skip.has(name)) return false;
367
- return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*\\()`).test(text);
368
- });
369
- });
370
- }
371
- function aliasConflictingImports(imports, reservedNames) {
372
- const reservedNameSet = new Set(reservedNames);
373
- const aliases = /* @__PURE__ */ new Map();
374
- return {
375
- imports: imports.map((entry) => {
376
- const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
377
- if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
378
- const alias = `${item}Schema`;
379
- aliases.set(item, alias);
380
- return {
381
- propertyName: item,
382
- name: alias
383
- };
384
- });
385
- return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
386
- ...entry,
387
- name: aliasedNames
388
- } : entry;
389
- }),
390
- aliases
391
- };
392
- }
393
- function rewriteAliasedImports(text, aliases) {
394
- return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
395
- }
396
- //#endregion
397
- //#region ../../internals/utils/src/reserved.ts
398
- /**
399
- * JavaScript and Java reserved words.
400
- * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
401
- */
402
- const reservedWords = /* @__PURE__ */ new Set([
403
- "abstract",
404
- "arguments",
405
- "boolean",
406
- "break",
407
- "byte",
408
- "case",
409
- "catch",
410
- "char",
411
- "class",
412
- "const",
413
- "continue",
414
- "debugger",
415
- "default",
416
- "delete",
417
- "do",
418
- "double",
419
- "else",
420
- "enum",
421
- "eval",
422
- "export",
423
- "extends",
424
- "false",
425
- "final",
426
- "finally",
427
- "float",
428
- "for",
429
- "function",
430
- "goto",
431
- "if",
432
- "implements",
433
- "import",
434
- "in",
435
- "instanceof",
436
- "int",
437
- "interface",
438
- "let",
439
- "long",
440
- "native",
441
- "new",
442
- "null",
443
- "package",
444
- "private",
445
- "protected",
446
- "public",
447
- "return",
448
- "short",
449
- "static",
450
- "super",
451
- "switch",
452
- "synchronized",
453
- "this",
454
- "throw",
455
- "throws",
456
- "transient",
457
- "true",
458
- "try",
459
- "typeof",
460
- "var",
461
- "void",
462
- "volatile",
463
- "while",
464
- "with",
465
- "yield",
466
- "Array",
467
- "Date",
468
- "hasOwnProperty",
469
- "Infinity",
470
- "isFinite",
471
- "isNaN",
472
- "isPrototypeOf",
473
- "length",
474
- "Math",
475
- "name",
476
- "NaN",
477
- "Number",
478
- "Object",
479
- "prototype",
480
- "String",
481
- "toString",
482
- "undefined",
483
- "valueOf"
484
- ]);
485
- /**
486
- * Returns `true` when `name` is a syntactically valid JavaScript variable name.
487
- *
488
- * @example
489
- * ```ts
490
- * isValidVarName('status') // true
491
- * isValidVarName('class') // false (reserved word)
492
- * isValidVarName('42foo') // false (starts with digit)
493
- * ```
494
- */
495
- function isValidVarName(name) {
496
- if (!name || reservedWords.has(name)) return false;
497
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
498
- }
499
- /**
500
- * Returns `name` when it's a syntactically valid JavaScript variable name,
501
- * otherwise prefixes it with `_` so the result is a valid identifier.
502
- *
503
- * Useful for sanitizing OpenAPI schema names or operation IDs that start with
504
- * a digit (e.g. `409`, `504AccountCancel`) before using them as exported
505
- * variable, type, or function names.
506
- *
507
- * @example
508
- * ```ts
509
- * ensureValidVarName('409') // '_409'
510
- * ensureValidVarName('504AccountCancel') // '_504AccountCancel'
511
- * ensureValidVarName('Pet') // 'Pet'
512
- * ensureValidVarName('class') // '_class'
513
- * ```
514
- */
515
- function ensureValidVarName(name) {
516
- if (!name || isValidVarName(name)) return name;
517
- return `_${name}`;
518
- }
519
- //#endregion
520
636
  //#region ../../internals/shared/src/params.ts
521
637
  const caseParamsCache = /* @__PURE__ */ new WeakMap();
522
638
  /**
@@ -537,6 +653,23 @@ function caseParams(params, casing) {
537
653
  caseParamsCache.set(params, result);
538
654
  return result;
539
655
  }
656
+ /**
657
+ * Drops parameters that collapse to the same property identity once camelCased, keeping the first.
658
+ *
659
+ * Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
660
+ * `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
661
+ * an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
662
+ * identity so the resulting group is collision-free regardless of the names each caller carries.
663
+ */
664
+ function dedupeByCasedName(params) {
665
+ const seen = /* @__PURE__ */ new Set();
666
+ return params.filter((param) => {
667
+ const key = camelCase(param.name);
668
+ if (seen.has(key)) return false;
669
+ seen.add(key);
670
+ return true;
671
+ });
672
+ }
540
673
  //#endregion
541
674
  //#region ../../internals/shared/src/operation.ts
542
675
  /**
@@ -587,6 +720,15 @@ function resolveContentTypeVariants(entries, baseName) {
587
720
  };
588
721
  });
589
722
  }
723
+ function getOperationParameters(node, options = {}) {
724
+ const params = caseParams(node.parameters, options.paramsCasing === "original" ? void 0 : "camelcase");
725
+ return {
726
+ path: dedupeByCasedName(params.filter((param) => param.in === "path")),
727
+ query: dedupeByCasedName(params.filter((param) => param.in === "query")),
728
+ header: dedupeByCasedName(params.filter((param) => param.in === "header")),
729
+ cookie: dedupeByCasedName(params.filter((param) => param.in === "cookie"))
730
+ };
731
+ }
590
732
  //#endregion
591
733
  //#region ../../internals/shared/src/group.ts
592
734
  /**
@@ -681,7 +823,7 @@ const fakerKeywordMapper = {
681
823
  return `{...${items.join(", ...")}}`;
682
824
  },
683
825
  matches: (value = "", regexGenerator = "faker") => {
684
- if (regexGenerator === "randexp") return `${kubb_kit.ast.toRegExpString(value, "RandExp")}.gen()`;
826
+ if (regexGenerator === "randexp") return `${toRegExpString(value, "RandExp")}.gen()`;
685
827
  return `faker.helpers.fromRegExp("${value}")`;
686
828
  },
687
829
  email: () => "faker.internet.email()",
@@ -692,7 +834,7 @@ function getEnumValues(node) {
692
834
  return node.enumValues ?? [];
693
835
  }
694
836
  function parseEnumValue(value) {
695
- if (typeof value === "string") return kubb_kit.ast.stringify(value);
837
+ if (typeof value === "string") return stringify(value);
696
838
  return value;
697
839
  }
698
840
  /**
@@ -760,7 +902,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
760
902
  const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? kubb_kit.ast.extractRefName(node.ref) ?? node.name ?? node.schema?.name : node.name ?? node.schema?.name;
761
903
  if (!refName) throw new Error("Name not defined for ref node");
762
904
  if (this.options.schemaName && refName === this.options.schemaName) return this.options.typeName ? `undefined as unknown as ${this.options.typeName}` : "undefined as unknown";
763
- const resolvedName = node.ref ? this.options.resolver.resolveName(refName) : refName;
905
+ const resolvedName = node.ref ? this.options.resolver.name(refName) : refName;
764
906
  if (!this.options.nestedInObject) return `${resolvedName}(data)`;
765
907
  return `${resolvedName}()`;
766
908
  },
@@ -804,7 +946,7 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
804
946
  },
805
947
  object(node) {
806
948
  const cyclicSchemas = this.options.cyclicSchemas;
807
- const entries = (node.properties ?? []).map((property) => {
949
+ return buildObject((node.properties ?? []).map((property) => {
808
950
  const value = printNested(property.schema, {
809
951
  typeName: this.options.typeName ? indexedTypeName(this.options.typeName, property.name, this.options.nestedInUnion) : void 0,
810
952
  nestedInObject: true
@@ -812,10 +954,9 @@ const printerFaker = kubb_kit.ast.createPrinter((options) => {
812
954
  if (cyclicSchemas && kubb_kit.ast.containsCircularRef(property.schema, {
813
955
  circularSchemas: cyclicSchemas,
814
956
  excludeName: this.options.schemaName
815
- })) return `get ${kubb_kit.ast.objectKey(property.name)}() { const _value = ${value}; Object.defineProperty(this, ${JSON.stringify(property.name)}, { value: _value, configurable: true, writable: true, enumerable: true }); return _value }`;
816
- return `${kubb_kit.ast.objectKey(property.name)}: ${value}`;
817
- });
818
- return kubb_kit.ast.buildObject(entries);
957
+ })) 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 }`;
958
+ return `${objectKey(property.name)}: ${value}`;
959
+ }));
819
960
  },
820
961
  ...options.nodes
821
962
  },
@@ -845,22 +986,20 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
845
986
  const isEnumSchema = !!kubb_kit.ast.narrowSchema(node, kubb_kit.ast.schemaTypes.enum);
846
987
  const tsEnumType = pluginTs.options?.enum?.type;
847
988
  const tsEnumTypeSuffix = pluginTs.options?.enum?.typeSuffix ?? "Key";
848
- const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.resolveEnumKeyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.resolveTypeName(schemaName);
989
+ const schemaTypeName = isEnumSchema && tsEnumType === "asConst" ? tsResolver.enum.keyName({ name: schemaName }, tsEnumTypeSuffix) : tsResolver.name(schemaName);
849
990
  const meta = {
850
- name: resolver.resolveName(schemaName),
851
- file: resolver.resolveFile({
991
+ name: resolver.name(schemaName),
992
+ file: resolver.file({
852
993
  name: schemaName,
853
- extname: ".ts"
854
- }, {
994
+ extname: ".ts",
855
995
  root,
856
996
  output,
857
997
  group: group ?? void 0
858
998
  }),
859
999
  typeName: schemaTypeName,
860
- typeFile: tsResolver.resolveFile({
1000
+ typeFile: tsResolver.file({
861
1001
  name: schemaName,
862
- extname: ".ts"
863
- }, {
1002
+ extname: ".ts",
864
1003
  root,
865
1004
  output: pluginTs.options?.output ?? output,
866
1005
  group: pluginTs.options?.group ?? void 0
@@ -888,11 +1027,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
888
1027
  typeFilePath: meta.typeFile.path
889
1028
  });
890
1029
  const usedImports = filterUsedImports(adapter.getImports(node, (schemaName) => ({
891
- name: resolver.resolveName(schemaName),
892
- path: resolver.resolveFile({
1030
+ name: resolver.name(schemaName),
1031
+ path: resolver.file({
893
1032
  name: schemaName,
894
- extname: ".ts"
895
- }, {
1033
+ extname: ".ts",
896
1034
  root,
897
1035
  output,
898
1036
  group: group ?? void 0
@@ -902,7 +1040,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
902
1040
  baseName: meta.file.baseName,
903
1041
  path: meta.file.path,
904
1042
  meta: meta.file.meta,
905
- banner: resolver.resolveBanner(ctx.meta, {
1043
+ banner: resolver.default.banner(ctx.meta, {
906
1044
  output,
907
1045
  config,
908
1046
  file: {
@@ -910,7 +1048,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
910
1048
  baseName: meta.file.baseName
911
1049
  }
912
1050
  }),
913
- footer: resolver.resolveFooter(ctx.meta, {
1051
+ footer: resolver.default.footer(ctx.meta, {
914
1052
  output,
915
1053
  config,
916
1054
  file: {
@@ -967,10 +1105,31 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
967
1105
  const pluginTs = ctx.driver.getPlugin(_kubb_plugin_ts.pluginTsName);
968
1106
  if (!pluginTs) return;
969
1107
  const tsResolver = ctx.driver.getResolver(_kubb_plugin_ts.pluginTsName);
970
- const paramEntries = caseParams(node.parameters, "camelcase").map((param) => ({
971
- param,
972
- name: resolveParamNameByLocation(resolver, node, param),
973
- typeName: resolveParamNameByLocation(tsResolver, node, param)
1108
+ const params = caseParams(node.parameters, "camelcase");
1109
+ const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
1110
+ ...node,
1111
+ parameters: params
1112
+ }, { paramsCasing: "original" });
1113
+ const paramGroups = [
1114
+ {
1115
+ params: pathParams,
1116
+ name: resolver.param.path,
1117
+ typeName: tsResolver.param.path
1118
+ },
1119
+ {
1120
+ params: queryParams,
1121
+ name: resolver.param.query,
1122
+ typeName: tsResolver.param.query
1123
+ },
1124
+ {
1125
+ params: headerParams,
1126
+ name: resolver.param.headers,
1127
+ typeName: tsResolver.param.headers
1128
+ }
1129
+ ].filter((group) => group.params.length > 0).map((group) => ({
1130
+ schema: (0, _kubb_plugin_ts.buildParams)({ params: group.params }),
1131
+ name: group.name(node, group.params[0]),
1132
+ typeName: group.typeName(node, group.params[0])
974
1133
  }));
975
1134
  function expandContentUnits(entries, baseName, tsBaseName, description, decorate) {
976
1135
  const withSchema = entries.filter((entry) => entry.schema);
@@ -1007,36 +1166,34 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1007
1166
  skipImportNames: variants.map((variant) => variant.name)
1008
1167
  }];
1009
1168
  }
1010
- const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.resolveResponseStatusName(node, response.statusCode), tsResolver.resolveResponseStatusName(node, response.statusCode), response.description));
1011
- const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.resolveDataName(node), tsResolver.resolveDataName(node), node.requestBody?.description, (schema) => ({
1169
+ const responseUnits = node.responses.flatMap((response) => expandContentUnits(response.content ?? [], resolver.response.status(node, response.statusCode), tsResolver.response.status(node, response.statusCode), response.description));
1170
+ const dataUnits = expandContentUnits(node.requestBody?.content ?? [], resolver.response.body(node), tsResolver.response.body(node), node.requestBody?.description, (schema) => ({
1012
1171
  ...schema,
1013
1172
  description: node.requestBody?.description ?? schema.description
1014
1173
  }));
1015
- const responseName = resolver.resolveResponseName(node);
1174
+ const responseName = resolver.response.response(node);
1016
1175
  const localHelperNames = /* @__PURE__ */ new Set([
1017
- ...paramEntries.map((entry) => entry.name),
1176
+ ...paramGroups.map((group) => group.name),
1018
1177
  ...responseUnits.map((unit) => unit.name),
1019
1178
  ...dataUnits.map((unit) => unit.name),
1020
1179
  responseName
1021
1180
  ]);
1022
1181
  const cyclicSchemas = new Set(ctx.meta.circularNames);
1023
1182
  const meta = {
1024
- file: resolver.resolveFile({
1183
+ file: resolver.file({
1025
1184
  name: node.operationId,
1026
1185
  extname: ".ts",
1027
1186
  tag: node.tags[0] ?? "default",
1028
- path: node.path
1029
- }, {
1187
+ path: node.path,
1030
1188
  root,
1031
1189
  output,
1032
1190
  group: group ?? void 0
1033
1191
  }),
1034
- typeFile: tsResolver.resolveFile({
1192
+ typeFile: tsResolver.file({
1035
1193
  name: node.operationId,
1036
1194
  extname: ".ts",
1037
1195
  tag: node.tags[0] ?? "default",
1038
- path: node.path
1039
- }, {
1196
+ path: node.path,
1040
1197
  root,
1041
1198
  output: pluginTs.options?.output ?? output,
1042
1199
  group: pluginTs.options?.group ?? void 0
@@ -1044,11 +1201,10 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1044
1201
  };
1045
1202
  function resolveMockImports(schema) {
1046
1203
  return adapter.getImports(schema, (schemaName) => ({
1047
- name: resolver.resolveName(schemaName),
1048
- path: resolver.resolveFile({
1204
+ name: resolver.name(schemaName),
1205
+ path: resolver.file({
1049
1206
  name: schemaName,
1050
- extname: ".ts"
1051
- }, {
1207
+ extname: ".ts",
1052
1208
  root,
1053
1209
  output,
1054
1210
  group: group ?? void 0
@@ -1113,7 +1269,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1113
1269
  baseName: meta.file.baseName,
1114
1270
  path: meta.file.path,
1115
1271
  meta: meta.file.meta,
1116
- banner: resolver.resolveBanner(ctx.meta, {
1272
+ banner: resolver.default.banner(ctx.meta, {
1117
1273
  output,
1118
1274
  config,
1119
1275
  file: {
@@ -1121,7 +1277,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1121
1277
  baseName: meta.file.baseName
1122
1278
  }
1123
1279
  }),
1124
- footer: resolver.resolveFooter(ctx.meta, {
1280
+ footer: resolver.default.footer(ctx.meta, {
1125
1281
  output,
1126
1282
  config,
1127
1283
  file: {
@@ -1145,11 +1301,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1145
1301
  path: dateParser,
1146
1302
  name: dateParser
1147
1303
  }),
1148
- paramEntries.map(({ param, name, typeName }) => renderEntry({
1149
- schema: param.schema,
1150
- name,
1151
- typeName
1152
- })),
1304
+ paramGroups.map((group) => renderEntry(group)),
1153
1305
  responseUnits.map((unit) => renderEntry({
1154
1306
  schema: unit.schema,
1155
1307
  name: unit.name,
@@ -1167,7 +1319,7 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1167
1319
  renderEntry({
1168
1320
  schema: buildResponseUnionSchema(node, resolver),
1169
1321
  name: responseName,
1170
- typeName: tsResolver.resolveResponseName(node),
1322
+ typeName: tsResolver.response.response(node),
1171
1323
  skipImportNames: responseUnits.map((unit) => unit.name)
1172
1324
  })
1173
1325
  ]
@@ -1185,69 +1337,45 @@ const fakerGenerator = (0, kubb_kit.defineGenerator)({
1185
1337
  * ```ts
1186
1338
  * import { resolverFaker } from '@kubb/plugin-faker'
1187
1339
  *
1188
- * resolverFaker.default('list pets', 'function') // 'createListPets'
1340
+ * resolverFaker.name('list pets') // 'createListPets'
1189
1341
  * ```
1190
1342
  */
1191
- const resolverFaker = (0, kubb_kit.defineResolver)(() => {
1192
- return {
1193
- name: "default",
1194
- pluginName: "plugin-faker",
1195
- default(name, type) {
1196
- if (type === "file") return toFilePath(name, (part) => camelCase(part, { prefix: "create" }));
1197
- return ensureValidVarName(camelCase(name, { prefix: "create" }));
1198
- },
1199
- resolveName(name, type) {
1200
- return this.default(name, type);
1201
- },
1202
- resolvePathName(name, type) {
1203
- return this.default(name, type);
1204
- },
1205
- resolveFile({ name, extname, tag, path: groupPath }, context) {
1206
- const inputBaseName = `${context.output.mode === "file" ? "" : this.resolveName(name, "file")}${extname}`;
1207
- const filePath = this.resolvePath({
1208
- baseName: inputBaseName,
1209
- tag,
1210
- path: groupPath
1211
- }, context);
1212
- const baseName = node_path.default.basename(filePath);
1213
- return {
1214
- kind: "File",
1215
- id: (0, node_crypto.createHash)("sha256").update(filePath).digest("hex"),
1216
- name: node_path.default.basename(filePath, extname),
1217
- path: filePath,
1218
- baseName,
1219
- extname,
1220
- meta: { pluginName: this.pluginName },
1221
- sources: [],
1222
- imports: [],
1223
- exports: []
1224
- };
1225
- },
1226
- resolveParamName(node, param) {
1227
- return this.resolveName(`${node.operationId} ${param.in} ${param.name}`);
1228
- },
1229
- resolveDataName(node) {
1230
- return this.resolveName(`${node.operationId} Data`);
1343
+ const resolverFaker = (0, kubb_kit.createResolver)({
1344
+ pluginName: "plugin-faker",
1345
+ name(name) {
1346
+ return ensureValidVarName(camelCase(name, { prefix: "create" }));
1347
+ },
1348
+ file: { baseName({ name, extname }) {
1349
+ return `${toFilePath(name, (part) => camelCase(part, { prefix: "create" }))}${extname}`;
1350
+ } },
1351
+ param: {
1352
+ name(node, param) {
1353
+ return this.name(`${node.operationId} ${param.in} ${param.name}`);
1231
1354
  },
1232
- resolveResponseStatusName(node, statusCode) {
1233
- return this.resolveName(`${node.operationId} Status ${statusCode}`);
1355
+ path(node) {
1356
+ return this.name(`${node.operationId} Path`);
1234
1357
  },
1235
- resolveResponseName(node) {
1236
- return this.resolveName(`${node.operationId} Response`);
1358
+ query(node) {
1359
+ return this.name(`${node.operationId} Query`);
1237
1360
  },
1238
- resolveResponsesName(node) {
1239
- return this.resolveName(`${node.operationId} Responses`);
1361
+ headers(node) {
1362
+ return this.name(`${node.operationId} Headers`);
1363
+ }
1364
+ },
1365
+ response: {
1366
+ status(node, statusCode) {
1367
+ return this.name(`${node.operationId} Status ${statusCode}`);
1240
1368
  },
1241
- resolvePathParamsName(node, param) {
1242
- return this.resolveParamName(node, param);
1369
+ body(node) {
1370
+ return this.name(`${node.operationId} Body`);
1243
1371
  },
1244
- resolveQueryParamsName(node, param) {
1245
- return this.resolveParamName(node, param);
1372
+ response(node) {
1373
+ return this.name(`${node.operationId} Response`);
1246
1374
  },
1247
- resolveHeaderParamsName(node, param) {
1248
- return this.resolveParamName(node, param);
1375
+ responses(node) {
1376
+ return this.name(`${node.operationId} Responses`);
1249
1377
  }
1250
- };
1378
+ }
1251
1379
  });
1252
1380
  //#endregion
1253
1381
  //#region src/plugin.ts
@@ -1303,10 +1431,7 @@ const pluginFaker = (0, kubb_kit.definePlugin)((options) => {
1303
1431
  regexGenerator,
1304
1432
  printer
1305
1433
  });
1306
- ctx.setResolver(userResolver ? {
1307
- ...resolverFaker,
1308
- ...userResolver
1309
- } : resolverFaker);
1434
+ ctx.setResolver(userResolver ? kubb_kit.Resolver.merge(resolverFaker, userResolver) : resolverFaker);
1310
1435
  if (userMacros?.length) ctx.setMacros(userMacros);
1311
1436
  ctx.addGenerator(fakerGenerator);
1312
1437
  } }