@kubb/plugin-faker 5.0.0-beta.4 → 5.0.0-beta.56

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.
Files changed (38) hide show
  1. package/README.md +39 -22
  2. package/dist/{Faker-CdyPfOPg.d.ts → Faker-A5UuxwJj.d.ts} +3 -3
  3. package/dist/{Faker-fcQEB9i5.js → Faker-CHh0JtBG.js} +41 -145
  4. package/dist/Faker-CHh0JtBG.js.map +1 -0
  5. package/dist/{Faker-BgleOzVN.cjs → Faker-CcGjn5ZM.cjs} +40 -174
  6. package/dist/Faker-CcGjn5ZM.cjs.map +1 -0
  7. package/dist/components.cjs +1 -1
  8. package/dist/components.d.ts +1 -1
  9. package/dist/components.js +1 -1
  10. package/dist/{fakerGenerator-D7daHCh6.js → fakerGenerator-DDNsdbH2.js} +237 -94
  11. package/dist/fakerGenerator-DDNsdbH2.js.map +1 -0
  12. package/dist/{fakerGenerator-VJEVzLjc.cjs → fakerGenerator-DrwGWYwv.cjs} +240 -97
  13. package/dist/fakerGenerator-DrwGWYwv.cjs.map +1 -0
  14. package/dist/fakerGenerator-KKVr-CA2.d.ts +14 -0
  15. package/dist/generators.cjs +1 -1
  16. package/dist/generators.d.ts +1 -1
  17. package/dist/generators.js +1 -1
  18. package/dist/index.cjs +240 -69
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +35 -15
  21. package/dist/index.js +241 -70
  22. package/dist/index.js.map +1 -1
  23. package/dist/{printerFaker-CJiwzoto.d.ts → printerFaker-CMCJT3FB.d.ts} +68 -35
  24. package/package.json +12 -22
  25. package/src/components/Faker.tsx +51 -65
  26. package/src/generators/fakerGenerator.tsx +108 -72
  27. package/src/plugin.ts +27 -23
  28. package/src/printers/printerFaker.ts +102 -40
  29. package/src/resolvers/resolverFaker.ts +31 -39
  30. package/src/types.ts +40 -31
  31. package/src/utils.ts +7 -106
  32. package/dist/Faker-BgleOzVN.cjs.map +0 -1
  33. package/dist/Faker-fcQEB9i5.js.map +0 -1
  34. package/dist/fakerGenerator-C3Ho3BaI.d.ts +0 -9
  35. package/dist/fakerGenerator-D7daHCh6.js.map +0 -1
  36. package/dist/fakerGenerator-VJEVzLjc.cjs.map +0 -1
  37. package/extension.yaml +0 -364
  38. /package/dist/{chunk--u3MIqq1.js → chunk-C0LytTxp.js} +0 -0
package/README.md CHANGED
@@ -1,19 +1,16 @@
1
1
  <div align="center">
2
- <h1>Plugin Faker</h1>
3
2
  <a href="https://kubb.dev" target="_blank" rel="noopener noreferrer">
4
- <img width="180" src="https://raw.githubusercontent.com/kubb-labs/kubb/main/assets/logo.png" alt="Kubb logo">
3
+ <img src="https://kubb.dev/og.png" alt="Kubb banner">
5
4
  </a>
6
5
 
7
6
  [![npm version][npm-version-src]][npm-version-href]
8
7
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
9
- [![Coverage][coverage-src]][coverage-href]
8
+ [![Stars][stars-src]][stars-href]
10
9
  [![License][license-src]][license-href]
11
- [![Sponsors][sponsors-src]][sponsors-href]
10
+ [![Node][node-src]][node-href]
12
11
 
13
12
  <h4>
14
- <a href="https://codesandbox.io/s/github/kubb-labs/kubb/tree/main//examples/typescript" target="_blank">View Demo</a>
15
- <span> · </span>
16
- <a href="https://kubb.dev/" target="_blank">Documentation</a>
13
+ <a href="https://kubb.dev/plugins/faker" target="_blank">Documentation</a>
17
14
  <span> · </span>
18
15
  <a href="https://github.com/kubb-labs/kubb/issues/" target="_blank">Report Bug</a>
19
16
  <span> · </span>
@@ -21,11 +18,31 @@
21
18
  </h4>
22
19
  </div>
23
20
 
24
- Swagger integration to create mock data based on Faker.js
21
+ <br />
22
+
23
+ # @kubb/plugin-faker
24
+
25
+ ### Generate Faker mock data from OpenAPI
26
+
27
+ `@kubb/plugin-faker` generates Faker.js factory functions from your OpenAPI schemas. Each schema produces a function that returns realistic mock data matching the schema's structure.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ bun add @kubb/plugin-faker
33
+ # or
34
+ pnpm add @kubb/plugin-faker
35
+ # or
36
+ npm install @kubb/plugin-faker
37
+ ```
38
+
39
+ ## Documentation
40
+
41
+ See the [full documentation](https://kubb.dev/plugins/faker) for configuration options and examples.
25
42
 
26
43
  ## Supporting Kubb
27
44
 
28
- Kubb uses an MIT-licensed open source project with its ongoing development made possible entirely by the support of Sponsors. If you would like to become a sponsor, please consider:
45
+ Kubb is an open source project, and its development is funded entirely by sponsors. If you would like to become a sponsor, please consider:
29
46
 
30
47
  - [Become a Sponsor on GitHub](https://github.com/sponsors/stijnvanhulle)
31
48
 
@@ -35,19 +52,19 @@ Kubb uses an MIT-licensed open source project with its ongoing development made
35
52
  </a>
36
53
  </p>
37
54
 
55
+ ## License
56
+
57
+ [MIT](https://github.com/kubb-labs/plugins/blob/main/LICENSE)
58
+
38
59
  <!-- Badges -->
39
60
 
40
- [npm-version-src]: https://img.shields.io/npm/v/@kubb/plugin-faker?flat&colorA=18181B&colorB=f58517
41
- [npm-version-href]: https://npmjs.com/package/@kubb/plugin-faker
42
- [npm-downloads-src]: https://img.shields.io/npm/dm/@kubb/plugin-faker?flat&colorA=18181B&colorB=f58517
43
- [npm-downloads-href]: https://npmjs.com/package/@kubb/plugin-faker
44
- [license-src]: https://img.shields.io/github/license/kubb-labs/kubb.svg?flat&colorA=18181B&colorB=f58517
61
+ [npm-version-src]: https://shieldcn.dev/npm/v/@kubb/plugin-faker.svg?variant=secondary&size=xs&theme=zinc&mode=dark
62
+ [npm-version-href]: https://npmx.dev/package/@kubb/plugin-faker
63
+ [npm-downloads-src]: https://shieldcn.dev/npm/dm/@kubb/plugin-faker.svg?variant=secondary&size=xs&theme=zinc&mode=dark
64
+ [npm-downloads-href]: https://npmx.dev/package/@kubb/plugin-faker
65
+ [stars-src]: https://shieldcn.dev/github/stars/kubb-labs/kubb.svg?variant=secondary&size=xs&theme=zinc&mode=dark
66
+ [stars-href]: https://github.com/kubb-labs/kubb
67
+ [license-src]: https://shieldcn.dev/npm/license/@kubb/plugin-faker.svg?variant=secondary&size=xs&theme=zinc
45
68
  [license-href]: https://github.com/kubb-labs/kubb/blob/main/LICENSE
46
- [build-src]: https://img.shields.io/github/actions/workflow/status/kubb-labs/kubb/ci.yaml?style=flat&colorA=18181B&colorB=f58517
47
- [build-href]: https://www.npmjs.com/package/@kubb/plugin-faker
48
- [minified-src]: https://img.shields.io/bundlephobia/min/@kubb/plugin-faker?style=flat&colorA=18181B&colorB=f58517
49
- [minified-href]: https://www.npmjs.com/package/@kubb/plugin-faker
50
- [coverage-src]: https://img.shields.io/codecov/c/github/kubb-labs/kubb?style=flat&colorA=18181B&colorB=f58517
51
- [coverage-href]: https://www.npmjs.com/package/@kubb/plugin-faker
52
- [sponsors-src]: https://img.shields.io/github/sponsors/stijnvanhulle?style=flat&colorA=18181B&colorB=f58517
53
- [sponsors-href]: https://github.com/sponsors/stijnvanhulle/
69
+ [node-src]: https://shieldcn.dev/npm/node/@kubb/plugin-faker.svg?variant=secondary&size=xs&theme=zinc&mode=dark
70
+ [node-href]: https://npmx.dev/package/@kubb/plugin-faker
@@ -1,5 +1,5 @@
1
- import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { o as PluginFaker, t as PrinterFakerFactory } from "./printerFaker-CJiwzoto.js";
1
+ import { t as __name } from "./chunk-C0LytTxp.js";
2
+ import { o as PluginFaker, t as PrinterFakerFactory } from "./printerFaker-CMCJT3FB.js";
3
3
  import { ast } from "@kubb/core";
4
4
  import { KubbReactNode } from "@kubb/renderer-jsx/types";
5
5
 
@@ -24,4 +24,4 @@ declare function Faker({
24
24
  }: Props): KubbReactNode;
25
25
  //#endregion
26
26
  export { Faker as t };
27
- //# sourceMappingURL=Faker-CdyPfOPg.d.ts.map
27
+ //# sourceMappingURL=Faker-A5UuxwJj.d.ts.map
@@ -1,52 +1,10 @@
1
- import "./chunk--u3MIqq1.js";
2
- import { posix } from "node:path";
1
+ import "./chunk-C0LytTxp.js";
2
+ import { jsStringEscape } from "@kubb/ast/utils";
3
3
  import { ast } from "@kubb/core";
4
4
  import { functionPrinter } from "@kubb/plugin-ts";
5
5
  import { File, Function } from "@kubb/renderer-jsx";
6
+ import { posix } from "node:path";
6
7
  import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
7
- //#region ../../internals/utils/src/string.ts
8
- /**
9
- * Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
10
- * Returns the string unchanged when no balanced quote pair is found.
11
- *
12
- * @example
13
- * trimQuotes('"hello"') // 'hello'
14
- * trimQuotes('hello') // 'hello'
15
- */
16
- function trimQuotes(text) {
17
- if (text.length >= 2) {
18
- const first = text[0];
19
- const last = text[text.length - 1];
20
- if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
21
- }
22
- return text;
23
- }
24
- /**
25
- * Escapes characters that are not allowed inside JS string literals.
26
- * Handles quotes, backslashes, and Unicode line terminators (U+2028 / U+2029).
27
- *
28
- * @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
29
- *
30
- * @example
31
- * ```ts
32
- * jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
33
- * ```
34
- */
35
- function jsStringEscape(input) {
36
- return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
37
- switch (character) {
38
- case "\"":
39
- case "'":
40
- case "\\": return `\\${character}`;
41
- case "\n": return "\\n";
42
- case "\r": return "\\r";
43
- case "\u2028": return "\\u2028";
44
- case "\u2029": return "\\u2029";
45
- default: return "";
46
- }
47
- });
48
- }
49
- //#endregion
50
8
  //#region src/utils.ts
51
9
  /**
52
10
  * Returns the `@faker-js/faker` named export for a locale code.
@@ -96,14 +54,6 @@ function canOverrideSchema(node) {
96
54
  ]).has(node.type);
97
55
  }
98
56
  /**
99
- * Resolves a schema reference by looking up the referenced schema in the provided array.
100
- * Returns the original node if it's not a reference.
101
- */
102
- function resolveSchemaRef(node, schemas) {
103
- if (node.type !== "ref") return node;
104
- return schemas.find((schema) => schema.name === node.name && schema.type !== "ref") ?? node;
105
- }
106
- /**
107
57
  * Resolves a parameter name based on its location (path, query, header, etc.) using the provided resolver.
108
58
  */
109
59
  function resolveParamNameByLocation(resolver, node, param) {
@@ -143,10 +93,11 @@ function shouldInlineSingleResponseSchema(schema) {
143
93
  * Returns null if no responses are provided, or embeds single simple responses inline.
144
94
  */
145
95
  function buildResponseUnionSchema(node, resolver) {
146
- const responses = node.responses.filter((response) => response.schema);
96
+ const responses = node.responses.filter((response) => response.content?.[0]?.schema);
147
97
  if (!responses.length) return null;
148
98
  if (responses.length === 1) {
149
- if (shouldInlineSingleResponseSchema(responses[0].schema)) return responses[0].schema;
99
+ const schema = responses[0].content?.[0]?.schema;
100
+ if (schema && shouldInlineSingleResponseSchema(schema)) return schema;
150
101
  return ast.createSchema({
151
102
  type: "ref",
152
103
  name: resolver.resolveResponseStatusName(node, responses[0].statusCode)
@@ -180,56 +131,6 @@ function toRelativeImportPath(from, to) {
180
131
  const relativePath = posix.relative(posix.dirname(from), to);
181
132
  return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
182
133
  }
183
- function escapeRegExp(value) {
184
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
185
- }
186
- /**
187
- * Filters imports to only those that are actually used in the generated code.
188
- * Checks for function calls matching the imported names.
189
- */
190
- function filterUsedImports(imports, text, skipImportNames = []) {
191
- return imports.filter((entry) => {
192
- return (Array.isArray(entry.name) ? entry.name : [entry.name]).map((name) => {
193
- if (typeof name === "string") return name;
194
- return name?.name ?? name?.propertyName;
195
- }).filter((name) => Boolean(name)).some((name) => {
196
- if (skipImportNames.includes(name)) return false;
197
- return new RegExp(`\\b${escapeRegExp(name)}\\b(?=\\s*\\()`).test(text);
198
- });
199
- });
200
- }
201
- /**
202
- * Detects and resolves import name conflicts by adding aliases to conflicting names.
203
- * Returns updated imports with a mapping of original names to their aliases.
204
- */
205
- function aliasConflictingImports(imports, reservedNames) {
206
- const reservedNameSet = new Set(reservedNames);
207
- const aliases = /* @__PURE__ */ new Map();
208
- return {
209
- imports: imports.map((entry) => {
210
- const aliasedNames = (Array.isArray(entry.name) ? entry.name : [entry.name]).map((item) => {
211
- if (typeof item !== "string" || !reservedNameSet.has(item)) return item;
212
- const alias = `${item}Schema`;
213
- aliases.set(item, alias);
214
- return {
215
- propertyName: item,
216
- name: alias
217
- };
218
- });
219
- return aliasedNames.some((item) => typeof item === "object" && item.name) ? {
220
- ...entry,
221
- name: aliasedNames
222
- } : entry;
223
- }),
224
- aliases
225
- };
226
- }
227
- /**
228
- * Replaces all occurrences of original names with their aliased versions in the given text.
229
- */
230
- function rewriteAliasedImports(text, aliases) {
231
- return Array.from(aliases).reduce((acc, [name, alias]) => acc.replace(new RegExp(`\\b${escapeRegExp(name)}\\b`, "g"), alias), text);
232
- }
233
134
  /**
234
135
  * Resolves a type reference, determining if it needs an import statement or inline type reference.
235
136
  * Takes into account whether the type can be overridden and the file paths.
@@ -276,7 +177,7 @@ function resolveFakerTypeUsage(node, typeName, canOverride) {
276
177
  let dataType = `Partial<${typeName}>`;
277
178
  if (isArray || isTuple || node.type === "union" || node.type === "enum") dataType = typeName;
278
179
  if (isScalar) dataType = getScalarType(node, typeName);
279
- let returnType = canOverride ? typeName : void 0;
180
+ let returnType = canOverride ? typeName : null;
280
181
  if (isScalar) returnType = getScalarType(node, typeName);
281
182
  return {
282
183
  dataType,
@@ -310,42 +211,15 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
310
211
  const isObject = OBJECT_TYPES.has(node.type);
311
212
  const isTuple = node.type === "tuple";
312
213
  const isScalar = SCALAR_TYPES.has(node.type);
313
- let fakerTextWithOverride = fakerText;
314
- let useGenericOverride = false;
315
- if (canOverride && isObject) useGenericOverride = true;
316
- if (canOverride && isTuple) fakerTextWithOverride = `data || ${fakerText}`;
317
- if (canOverride && isArray) fakerTextWithOverride = `[
318
- ...${fakerText},
319
- ...(data || [])
320
- ]`;
321
- if (canOverride && isScalar) fakerTextWithOverride = `data ?? ${fakerText}`;
214
+ const useGenericOverride = canOverride && isObject;
215
+ const fakerTextWithOverride = (() => {
216
+ if (canOverride && isTuple) return `data || ${fakerText}`;
217
+ if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || [])\n]`;
218
+ if (canOverride && isScalar) return `data ?? ${fakerText}`;
219
+ return fakerText;
220
+ })();
322
221
  const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride);
323
- let functionSignature = "";
324
- let functionBody = "";
325
- if (useGenericOverride) {
326
- functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}(data?: Partial<${typeName}>): Required<${typeName}>`;
327
- const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
328
- const { cyclicSchemas, schemaName } = printer.options;
329
- if (node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => ast.containsCircularRef(p.schema, {
330
- circularSchemas: cyclicSchemas,
331
- excludeName: schemaName
332
- }))) functionBody = `{
333
- ${seedCode}const defaultFakeData = ${fakerText}
334
- if (data) {
335
- for (const [key, value] of Object.entries(data)) {
336
- Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
337
- }
338
- }
339
- return defaultFakeData as Required<${typeName}>
340
- }`;
341
- else functionBody = `{
342
- ${seedCode}const defaultFakeData = ${fakerText}
343
- return {
344
- ...defaultFakeData,
345
- ...(data || {}),
346
- } as Required<${typeName}>
347
- }`;
348
- } else {
222
+ if (!useGenericOverride) {
349
223
  const dataParamName = /\bdata\b/.test(fakerTextWithOverride) ? "data" : "_data";
350
224
  const params = ast.createFunctionParameters({ params: [ast.createFunctionParameter({
351
225
  name: dataParamName,
@@ -357,6 +231,7 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
357
231
  })] });
358
232
  const paramsSignature = declarationPrinter.print(params) ?? "";
359
233
  const returnType = resolvedReturnType;
234
+ const returnExpression = node.type === "ref" && canOverride && returnType ? `${fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride;
360
235
  return /* @__PURE__ */ jsx(File.Source, {
361
236
  name,
362
237
  isExportable: true,
@@ -366,11 +241,32 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
366
241
  name,
367
242
  JSDoc: { comments: description ? [`@description ${jsStringEscape(description)}`] : [] },
368
243
  params: canOverride ? paramsSignature : void 0,
369
- returnType,
370
- children: [seed ? /* @__PURE__ */ jsxs(Fragment, { children: [`faker.seed(${JSON.stringify(seed)})`, /* @__PURE__ */ jsx("br", {})] }) : void 0, `return ${fakerTextWithOverride}`]
244
+ returnType: returnType ?? void 0,
245
+ children: [seed ? /* @__PURE__ */ jsxs(Fragment, { children: [`faker.seed(${JSON.stringify(seed)})`, /* @__PURE__ */ jsx("br", {})] }) : void 0, `return ${returnExpression}`]
371
246
  })
372
247
  });
373
248
  }
249
+ const functionSignature = `${description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ""}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`;
250
+ const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : "";
251
+ const { cyclicSchemas, schemaName } = printer.options;
252
+ const functionBody = node.type === "object" && !!cyclicSchemas && (node.properties ?? []).some((p) => ast.containsCircularRef(p.schema, {
253
+ circularSchemas: cyclicSchemas,
254
+ excludeName: schemaName
255
+ })) ? `{
256
+ ${seedCode}const defaultFakeData = ${fakerText}
257
+ if (data) {
258
+ for (const [key, value] of Object.entries(data)) {
259
+ Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
260
+ }
261
+ }
262
+ return defaultFakeData as Omit<typeof defaultFakeData, keyof TData> & TData
263
+ }` : `{
264
+ ${seedCode}const defaultFakeData = ${fakerText}
265
+ return {
266
+ ...defaultFakeData,
267
+ ...(data || {}),
268
+ } as Omit<typeof defaultFakeData, keyof TData> & TData
269
+ }`;
374
270
  return /* @__PURE__ */ jsxs(File.Source, {
375
271
  name,
376
272
  isExportable: true,
@@ -379,6 +275,6 @@ function Faker({ node, description, name, typeName, printer, seed, canOverride }
379
275
  });
380
276
  }
381
277
  //#endregion
382
- export { filterUsedImports as a, resolveSchemaRef as c, trimQuotes as d, canOverrideSchema as i, resolveTypeReference as l, aliasConflictingImports as n, localeToFakerImport as o, buildResponseUnionSchema as r, resolveParamNameByLocation as s, Faker as t, rewriteAliasedImports as u };
278
+ export { resolveParamNameByLocation as a, localeToFakerImport as i, buildResponseUnionSchema as n, resolveTypeReference as o, canOverrideSchema as r, Faker as t };
383
279
 
384
- //# sourceMappingURL=Faker-fcQEB9i5.js.map
280
+ //# sourceMappingURL=Faker-CHh0JtBG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Faker-CHh0JtBG.js","names":["SCALAR_TYPES","ARRAY_TYPES"],"sources":["../src/utils.ts","../src/components/Faker.tsx"],"sourcesContent":["import { posix } from 'node:path'\nimport { ast } from '@kubb/core'\nimport type { ResolverFaker } from './types.ts'\n\n/**\n * Returns the `@faker-js/faker` named export for a locale code.\n *\n * Without a locale, returns `'faker'` for the default English instance.\n * With a locale, the language code is converted to upper case and joined with any region suffix.\n *\n * @example Default\n * `localeToFakerImport() // 'faker'`\n *\n * @example Simple locale\n * `localeToFakerImport('de') // 'fakerDE'`\n *\n * @example Compound locale\n * `localeToFakerImport('de_AT') // 'fakerDE_AT'`\n */\nexport function localeToFakerImport(locale?: string): string {\n if (!locale) {\n return 'faker'\n }\n\n const parts = locale.split('_')\n parts[0] = parts[0]!.toUpperCase()\n return `faker${parts.join('_')}`\n}\n\n/**\n * Determines if a schema node can be overridden during faker generation.\n */\nexport function canOverrideSchema(node: ast.SchemaNode): boolean {\n return new Set<ast.SchemaNode['type']>([\n 'array',\n 'tuple',\n 'object',\n 'intersection',\n 'union',\n 'enum',\n 'ref',\n 'string',\n 'email',\n 'url',\n 'uuid',\n 'number',\n 'integer',\n 'bigint',\n 'boolean',\n 'date',\n 'time',\n 'datetime',\n 'blob',\n ]).has(node.type)\n}\n\n/**\n * Resolves a parameter name based on its location (path, query, header, etc.) using the provided resolver.\n */\nexport function resolveParamNameByLocation(\n resolver: Pick<ResolverFaker, 'resolvePathParamsName' | 'resolveQueryParamsName' | 'resolveHeaderParamsName' | 'resolveParamName'>,\n node: ast.OperationNode,\n param: ast.ParameterNode,\n): string {\n switch (param.in) {\n case 'path':\n return resolver.resolvePathParamsName(node, param)\n case 'query':\n return resolver.resolveQueryParamsName(node, param)\n case 'header':\n return resolver.resolveHeaderParamsName(node, param)\n default:\n return resolver.resolveParamName(node, param)\n }\n}\n\nfunction shouldInlineSingleResponseSchema(schema: ast.SchemaNode): boolean {\n return new Set<ast.SchemaNode['type']>([\n 'any',\n 'unknown',\n 'void',\n 'null',\n 'array',\n 'tuple',\n 'string',\n 'email',\n 'url',\n 'uuid',\n 'number',\n 'integer',\n 'bigint',\n 'boolean',\n 'date',\n 'time',\n 'datetime',\n 'blob',\n 'enum',\n 'union',\n ]).has(schema.type)\n}\n\n/**\n * Builds a response schema as a union of all response statuses.\n * Returns null if no responses are provided, or embeds single simple responses inline.\n */\nexport function buildResponseUnionSchema(node: ast.OperationNode, resolver: ResolverFaker): ast.SchemaNode | null {\n const responses = node.responses.filter((response) => response.content?.[0]?.schema)\n\n if (!responses.length) {\n return null\n }\n\n if (responses.length === 1) {\n const schema = responses[0]!.content?.[0]?.schema\n if (schema && shouldInlineSingleResponseSchema(schema)) {\n return schema\n }\n\n return ast.createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, responses[0]!.statusCode) })\n }\n\n return ast.createSchema({\n type: 'union',\n members: responses.map((response) => ast.createSchema({ type: 'ref', name: resolver.resolveResponseStatusName(node, response.statusCode) })),\n })\n}\n\nconst SCALAR_TYPES = new Set<ast.SchemaNode['type']>([\n 'string',\n 'email',\n 'url',\n 'uuid',\n 'number',\n 'integer',\n 'bigint',\n 'boolean',\n 'date',\n 'time',\n 'datetime',\n 'blob',\n 'enum',\n])\nconst ARRAY_TYPES = new Set<ast.SchemaNode['type']>(['array'])\n\nfunction toRelativeImportPath(from: string, to: string): string {\n const relativePath = posix.relative(posix.dirname(from), to)\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Resolves a type reference, determining if it needs an import statement or inline type reference.\n * Takes into account whether the type can be overridden and the file paths.\n */\nexport function resolveTypeReference({\n node,\n canOverride,\n name,\n typeName,\n filePath,\n typeFilePath,\n}: {\n node: ast.SchemaNode\n canOverride: boolean\n name: string\n typeName: string\n filePath: string\n typeFilePath: string\n}): { importPath?: string; typeName: string } {\n const { usesTypeName } = resolveFakerTypeUsage(node, typeName, canOverride)\n\n if (!usesTypeName) {\n return { typeName }\n }\n\n if (name === typeName) {\n return {\n typeName: `import('${toRelativeImportPath(filePath, typeFilePath)}').${typeName}`,\n }\n }\n\n return {\n importPath: typeFilePath,\n typeName,\n }\n}\n\n/**\n * Maps a schema node type to its corresponding scalar type representation.\n * Returns the type name for enums or the base type (string, number, etc.) for primitives.\n */\nfunction getScalarType(node: ast.SchemaNode, typeName: string): string {\n switch (node.type) {\n case 'string':\n case 'email':\n case 'url':\n case 'uuid':\n return 'string'\n case 'number':\n case 'integer':\n return 'number'\n case 'bigint':\n return 'bigint'\n case 'boolean':\n return 'boolean'\n case 'date':\n case 'time':\n return node.representation === 'date' ? 'Date' : 'string'\n case 'datetime':\n return 'string'\n case 'blob':\n return 'Blob'\n case 'enum':\n return typeName\n default:\n return typeName\n }\n}\n\n/**\n * Resolves faker type usage information for a schema.\n * Determines the data type, return type, and whether it uses the type name.\n */\nexport function resolveFakerTypeUsage(\n node: ast.SchemaNode,\n typeName: string,\n canOverride: boolean,\n): {\n dataType: string\n returnType: string | null\n usesTypeName: boolean\n} {\n const isArray = ARRAY_TYPES.has(node.type)\n const isTuple = node.type === 'tuple'\n const isScalar = SCALAR_TYPES.has(node.type)\n\n let dataType = `Partial<${typeName}>`\n\n if (isArray || isTuple || node.type === 'union' || node.type === 'enum') {\n dataType = typeName\n }\n\n if (isScalar) {\n dataType = getScalarType(node, typeName)\n }\n\n let returnType = canOverride ? typeName : null\n\n if (isScalar) {\n returnType = getScalarType(node, typeName)\n }\n\n return {\n dataType,\n returnType,\n usesTypeName: dataType.includes(typeName) || Boolean(returnType?.includes(typeName)),\n }\n}\n","import { jsStringEscape } from '@kubb/ast/utils'\nimport { ast } from '@kubb/core'\nimport { functionPrinter } from '@kubb/plugin-ts'\nimport { File, Function } from '@kubb/renderer-jsx'\nimport type { KubbReactNode } from '@kubb/renderer-jsx/types'\nimport type { PrinterFakerFactory } from '../printers/printerFaker.ts'\nimport type { PluginFaker } from '../types.ts'\nimport { resolveFakerTypeUsage } from '../utils.ts'\n\ntype Props = {\n name: string\n typeName: string\n node: ast.SchemaNode\n printer: ast.Printer<PrinterFakerFactory>\n seed?: PluginFaker['options']['seed']\n description?: string\n canOverride: boolean\n}\n\nconst OBJECT_TYPES = new Set<ast.SchemaNode['type']>(['object', 'intersection'])\nconst ARRAY_TYPES = new Set<ast.SchemaNode['type']>(['array'])\nconst SCALAR_TYPES = new Set<ast.SchemaNode['type']>([\n 'string',\n 'email',\n 'url',\n 'uuid',\n 'number',\n 'integer',\n 'bigint',\n 'boolean',\n 'date',\n 'time',\n 'datetime',\n 'blob',\n 'enum',\n])\nconst declarationPrinter = functionPrinter({ mode: 'declaration' })\n\nexport function Faker({ node, description, name, typeName, printer, seed, canOverride }: Props): KubbReactNode {\n const fakerText = printer.print(node) ?? 'undefined'\n\n const isArray = ARRAY_TYPES.has(node.type)\n const isObject = OBJECT_TYPES.has(node.type)\n const isTuple = node.type === 'tuple'\n const isScalar = SCALAR_TYPES.has(node.type)\n\n const useGenericOverride = canOverride && isObject\n const fakerTextWithOverride = (() => {\n if (canOverride && isTuple) return `data || ${fakerText}`\n if (canOverride && isArray) return `[\\n ...${fakerText},\\n ...(data || [])\\n]`\n if (canOverride && isScalar) return `data ?? ${fakerText}`\n return fakerText\n })()\n\n const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride)\n\n if (!useGenericOverride) {\n const usesData = /\\bdata\\b/.test(fakerTextWithOverride)\n const dataParamName = usesData ? 'data' : '_data'\n const params = ast.createFunctionParameters({\n params: [\n ast.createFunctionParameter({\n name: dataParamName,\n type: ast.createParamsType({ variant: 'reference', name: dataType }),\n optional: true,\n }),\n ],\n })\n const paramsSignature = declarationPrinter.print(params) ?? ''\n const returnType = resolvedReturnType\n\n // A `ref` wrapper delegates to another faker. Object fakers are now generic and\n // widen to `Partial<T>` when called with a `Partial<T>`-typed argument, so cast\n // back to the wrapper's declared return type to keep it assignable.\n const returnExpression = node.type === 'ref' && canOverride && returnType ? `${fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function\n export\n name={name}\n JSDoc={{ comments: description ? [`@description ${jsStringEscape(description)}`] : [] }}\n params={canOverride ? paramsSignature : undefined}\n returnType={returnType ?? undefined}\n >\n {seed ? (\n <>\n {`faker.seed(${JSON.stringify(seed)})`}\n <br />\n </>\n ) : undefined}\n {`return ${returnExpression}`}\n </Function>\n </File.Source>\n )\n }\n\n // Generate function with defaultFakeData structure\n const jsdoc = description ? `/**\\n * @description ${jsStringEscape(description)}\\n */\\n ` : ''\n const functionSignature = `${jsdoc}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`\n\n const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\\n ` : ''\n\n // When the object node has properties that transitively reference a cyclic schema,\n // the printer emits memoizing getters for those properties. Spreading the object\n // literal would immediately invoke those getters, triggering recursive faker calls\n // and causing a stack overflow. Detect this upfront via ast helpers so we can\n // use Object.defineProperty-based merging instead of spread.\n const { cyclicSchemas, schemaName } = printer.options\n const hasGetters =\n node.type === 'object' &&\n !!cyclicSchemas &&\n (node.properties ?? []).some((p) => ast.containsCircularRef(p.schema, { circularSchemas: cyclicSchemas, excludeName: schemaName }))\n\n const functionBody = hasGetters\n ? `{\n ${seedCode}const defaultFakeData = ${fakerText}\n if (data) {\n for (const [key, value] of Object.entries(data)) {\n Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })\n }\n }\n return defaultFakeData as Omit<typeof defaultFakeData, keyof TData> & TData\n}`\n : `{\n ${seedCode}const defaultFakeData = ${fakerText}\n return {\n ...defaultFakeData,\n ...(data || {}),\n } as Omit<typeof defaultFakeData, keyof TData> & TData\n}`\n\n return (\n <File.Source name={name} isExportable isIndexable>\n {functionSignature}\n {functionBody}\n </File.Source>\n )\n}\n"],"mappings":"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"}