@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
@@ -1,5 +1,5 @@
1
- import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { Exclude, Generator, Group, Include, Output, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
1
+ import { t as __name } from "./chunk-C0LytTxp.js";
2
+ import { Exclude, Generator, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
3
3
 
4
4
  //#region src/types.d.ts
5
5
  /**
@@ -41,6 +41,13 @@ type ResolverFaker = Resolver & ast.OperationParamsResolver & {
41
41
  * `resolver.resolveResponseName(node) // -> 'listPetsResponse'`
42
42
  */
43
43
  resolveResponseName(this: ResolverFaker, node: ast.OperationNode): string;
44
+ /**
45
+ * Resolves the faker function name for the response collection.
46
+ *
47
+ * @example Responses collection names
48
+ * `resolver.resolveResponsesName(node) // -> 'listPetsResponses'`
49
+ */
50
+ resolveResponsesName(this: ResolverFaker, node: ast.OperationNode): string;
44
51
  /**
45
52
  * Resolves the faker function name for path parameters.
46
53
  *
@@ -63,82 +70,84 @@ type ResolverFaker = Resolver & ast.OperationParamsResolver & {
63
70
  */
64
71
  resolveHeaderParamsName(this: ResolverFaker, node: ast.OperationNode, param: ast.ParameterNode): string;
65
72
  };
66
- type Options = {
67
- /**
68
- * Specify the export location for the files and define the behavior of the output.
69
- * @default { path: 'mocks', barrelType: 'named' }
70
- */
71
- output?: Output;
72
- /**
73
- * Group the Faker mocks based on the provided name.
74
- */
75
- group?: Group;
73
+ /**
74
+ * Where the generated mock factories are written and how they are exported, plus the optional
75
+ * `group` strategy. The `group` option organizes `output.mode: 'directory'` output into per-tag or per-path subdirectories.
76
+ *
77
+ * @default { path: 'mocks', barrel: { type: 'named' } }
78
+ */
79
+ type Options = OutputOptions & {
76
80
  /**
77
- * Tags, operations, or paths to exclude from generation.
81
+ * Skip operations matching at least one entry in the list.
78
82
  */
79
83
  exclude?: Array<Exclude>;
80
84
  /**
81
- * Tags, operations, or paths to include in generation.
85
+ * Restrict generation to operations matching at least one entry in the list.
82
86
  */
83
87
  include?: Array<Include>;
84
88
  /**
85
- * Override options for specific tags, operations, or paths.
89
+ * Apply a different options object to operations matching a pattern.
86
90
  */
87
91
  override?: Array<Override<ResolvedOptions>>;
88
92
  /**
89
- * Parser to use when formatting date/time values as strings.
93
+ * Library used to format string-represented date, time, and datetime fields.
94
+ * Any library exporting a default function works; Kubb adds the import for you.
90
95
  *
91
96
  * @default 'faker'
92
97
  */
93
98
  dateParser?: 'faker' | 'dayjs' | 'moment' | (string & {});
94
99
  /**
95
- * Generator to use for RegExp patterns.
100
+ * Library used to generate strings that satisfy a regex `pattern` keyword.
101
+ * - `'faker'` uses `faker.helpers.fromRegExp`. No extra dependency.
102
+ * - `'randexp'` uses the `randexp` package. Supports a wider regex grammar.
96
103
  *
97
104
  * @default 'faker'
98
105
  */
99
106
  regexGenerator?: 'faker' | 'randexp';
100
107
  /**
101
- * Provide per-property faker expressions keyed by property name.
108
+ * Map a schema name to a custom Faker expression. Use this when the schema name
109
+ * does not give Faker enough context (`'email'`, `'avatarUrl'`, `'phoneNumber'`).
102
110
  */
103
111
  mapper?: Record<string, string>;
104
112
  /**
105
- * Locale for generating mock data.
106
- * Imports the matching localized `@faker-js/faker` instance so names, addresses,
107
- * and phone numbers reflect the target region.
113
+ * Faker locale code. Switches the named import to `fakerXX` from `@faker-js/faker`
114
+ * so names, addresses, and phone numbers reflect the target region.
108
115
  *
109
116
  * @default 'en'
110
- *
111
117
  * @example German
112
118
  * `locale: 'de'`
113
- *
114
119
  * @example Austrian German
115
120
  * `locale: 'de_AT'`
116
- *
117
121
  * @see https://fakerjs.dev/api/localization.html
118
122
  */
119
123
  locale?: string;
120
124
  /**
121
- * Seed faker for deterministic output.
125
+ * Value passed to `faker.seed(...)`. Set this for deterministic mock output,
126
+ * which is useful for snapshot tests.
122
127
  */
123
- seed?: number | number[];
128
+ seed?: number | Array<number>;
124
129
  /**
125
- * Apply casing to parameter names to match your configuration.
130
+ * Rename properties inside path/query/header mocks. Body mocks are unaffected.
131
+ *
132
+ * @note Must match the value of `paramsCasing` on `@kubb/plugin-ts`.
126
133
  */
127
134
  paramsCasing?: 'camelcase';
128
135
  /**
129
- * Additional generators alongside the default generators.
136
+ * Custom generators that run alongside the built-in Faker generators.
130
137
  */
131
138
  generators?: Array<Generator<PluginFaker>>;
132
139
  /**
133
- * Override naming conventions for function names and types.
140
+ * Override the naming of generated factory helpers. Common use: append `Mock` or
141
+ * `Factory` so helpers do not clash with imported types.
134
142
  */
135
143
  resolver?: Partial<ResolverFaker> & ThisType<ResolverFaker>;
136
144
  /**
137
- * AST visitor to transform generated nodes.
145
+ * AST visitor applied to schema and operation nodes before printing.
138
146
  */
139
147
  transformer?: ast.Visitor;
140
148
  /**
141
- * Override individual faker printer node handlers.
149
+ * Replace the Faker handler for a specific schema type (`'integer'`, `'date'`, ...).
150
+ * Each handler returns the Faker expression as a string.
142
151
  */
143
152
  printer?: {
144
153
  nodes?: PrinterFakerNodes;
@@ -146,7 +155,7 @@ type Options = {
146
155
  };
147
156
  type ResolvedOptions = {
148
157
  output: Output;
149
- group: Group | undefined;
158
+ group: Group | null;
150
159
  exclude: NonNullable<Options['exclude']>;
151
160
  include: Options['include'];
152
161
  override: NonNullable<Options['override']>;
@@ -169,11 +178,29 @@ declare global {
169
178
  //#endregion
170
179
  //#region src/printers/printerFaker.d.ts
171
180
  /**
172
- * Partial printer nodes for Faker generation, mapping schema types to output strings.
181
+ * Partial map of node-type overrides for the Faker printer. Each key is a
182
+ * `SchemaType` (`'string'`, `'date'`, ...) and each handler returns the
183
+ * Faker expression for that schema as a string. Use `this.transform` to
184
+ * recurse into nested schema nodes and `this.options` to read printer options.
185
+ *
186
+ * @example Override the integer handler
187
+ * ```ts
188
+ * pluginFaker({
189
+ * printer: {
190
+ * nodes: {
191
+ * integer() {
192
+ * return 'faker.number.float()'
193
+ * },
194
+ * },
195
+ * },
196
+ * })
197
+ * ```
173
198
  */
174
199
  type PrinterFakerNodes = ast.PrinterPartial<string, PrinterFakerOptions>;
175
200
  /**
176
- * Configuration options for the Faker printer, including resolvers, mappers, and cyclic schema tracking.
201
+ * Options passed to the Faker printer at instantiation: the parser library
202
+ * for date strings, the regex generator, the user-supplied schema-name
203
+ * mapper, and the resolver used to compute identifiers.
177
204
  */
178
205
  type PrinterFakerOptions = {
179
206
  dateParser?: PluginFaker['resolvedOptions']['dateParser'];
@@ -183,6 +210,12 @@ type PrinterFakerOptions = {
183
210
  typeName?: string;
184
211
  schemaName?: string;
185
212
  nestedInObject?: boolean;
213
+ /**
214
+ * Set while printing the members of a union (`oneOf`). Object properties then index their
215
+ * type as `(NonNullable<T> & Record<K, unknown>)[K]` instead of `NonNullable<T>[K]`, so a key
216
+ * carried by only some branches stays valid (a plain index would be a TS2339).
217
+ */
218
+ nestedInUnion?: boolean;
186
219
  nodes?: PrinterFakerNodes;
187
220
  /**
188
221
  * Names of schemas that participate in a circular dependency chain.
@@ -203,4 +236,4 @@ type PrinterFakerFactory = ast.PrinterFactoryOptions<'faker', PrinterFakerOption
203
236
  declare const printerFaker: (options: PrinterFakerOptions) => ast.Printer<PrinterFakerFactory>;
204
237
  //#endregion
205
238
  export { Options as a, printerFaker as i, PrinterFakerNodes as n, PluginFaker as o, PrinterFakerOptions as r, ResolverFaker as s, PrinterFakerFactory as t };
206
- //# sourceMappingURL=printerFaker-CJiwzoto.d.ts.map
239
+ //# sourceMappingURL=printerFaker-CMCJT3FB.d.ts.map
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "@kubb/plugin-faker",
3
- "version": "5.0.0-beta.4",
4
- "description": "Faker.js data generator plugin for Kubb, creating realistic mock data from OpenAPI specifications for development and testing.",
3
+ "version": "5.0.0-beta.56",
4
+ "description": "Generate Faker.js mock data factories from your OpenAPI schemas. Produces realistic seed data, test fixtures, and datasets for development and testing.",
5
5
  "keywords": [
6
- "code-generator",
6
+ "code-generation",
7
7
  "codegen",
8
- "data-generation",
9
- "development",
10
8
  "faker",
11
9
  "faker.js",
12
10
  "fakerjs",
@@ -14,11 +12,8 @@
14
12
  "kubb",
15
13
  "mock-data",
16
14
  "mocks",
17
- "oas",
18
15
  "openapi",
19
- "plugins",
20
16
  "swagger",
21
- "testing",
22
17
  "typescript"
23
18
  ],
24
19
  "license": "MIT",
@@ -31,7 +26,6 @@
31
26
  "files": [
32
27
  "src",
33
28
  "dist",
34
- "extension.yaml",
35
29
  "!/**/**.test.**",
36
30
  "!/**/__tests__/**",
37
31
  "!/**/__snapshots__/**"
@@ -71,33 +65,29 @@
71
65
  "registry": "https://registry.npmjs.org/"
72
66
  },
73
67
  "dependencies": {
74
- "@kubb/core": "5.0.0-beta.4",
75
- "@kubb/renderer-jsx": "5.0.0-beta.4",
76
- "@kubb/plugin-ts": "5.0.0-beta.4"
68
+ "@kubb/ast": "5.0.0-beta.55",
69
+ "@kubb/core": "5.0.0-beta.55",
70
+ "@kubb/renderer-jsx": "5.0.0-beta.55",
71
+ "@kubb/plugin-ts": "5.0.0-beta.56"
77
72
  },
78
73
  "devDependencies": {
74
+ "@internals/shared": "0.0.0",
79
75
  "@internals/utils": "0.0.0"
80
76
  },
81
77
  "peerDependencies": {
82
- "@kubb/renderer-jsx": "5.0.0-beta.4"
78
+ "@kubb/renderer-jsx": "5.0.0-beta.55"
83
79
  },
84
- "size-limit": [
85
- {
86
- "path": "./dist/*.js",
87
- "limit": "510 KiB",
88
- "gzip": true
89
- }
90
- ],
91
80
  "engines": {
92
81
  "node": ">=22"
93
82
  },
94
83
  "scripts": {
95
- "build": "tsdown && size-limit",
96
- "clean": "npx rimraf ./dist",
84
+ "build": "tsdown",
85
+ "clean": "node -e \"require('node:fs').rmSync('./dist', {recursive:true,force:true})\"",
97
86
  "lint": "oxlint .",
98
87
  "lint:fix": "oxlint --fix .",
99
88
  "release": "pnpm publish --no-git-check",
100
89
  "release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
90
+ "release:stage": "pnpm stage publish --no-git-check",
101
91
  "start": "tsdown --watch",
102
92
  "test": "vitest --passWithNoTests",
103
93
  "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
@@ -1,4 +1,4 @@
1
- import { jsStringEscape } from '@internals/utils'
1
+ import { jsStringEscape } from '@kubb/ast/utils'
2
2
  import { ast } from '@kubb/core'
3
3
  import { functionPrinter } from '@kubb/plugin-ts'
4
4
  import { File, Function } from '@kubb/renderer-jsx'
@@ -44,71 +44,17 @@ export function Faker({ node, description, name, typeName, printer, seed, canOve
44
44
  const isTuple = node.type === 'tuple'
45
45
  const isScalar = SCALAR_TYPES.has(node.type)
46
46
 
47
- let fakerTextWithOverride = fakerText
48
- let useGenericOverride = false
49
-
50
- if (canOverride && isObject) {
51
- useGenericOverride = true
52
- }
53
-
54
- if (canOverride && isTuple) {
55
- fakerTextWithOverride = `data || ${fakerText}`
56
- }
57
-
58
- if (canOverride && isArray) {
59
- fakerTextWithOverride = `[
60
- ...${fakerText},
61
- ...(data || [])
62
- ]`
63
- }
64
-
65
- if (canOverride && isScalar) {
66
- fakerTextWithOverride = `data ?? ${fakerText}`
67
- }
47
+ const useGenericOverride = canOverride && isObject
48
+ const fakerTextWithOverride = (() => {
49
+ if (canOverride && isTuple) return `data || ${fakerText}`
50
+ if (canOverride && isArray) return `[\n ...${fakerText},\n ...(data || [])\n]`
51
+ if (canOverride && isScalar) return `data ?? ${fakerText}`
52
+ return fakerText
53
+ })()
68
54
 
69
55
  const { dataType, returnType: resolvedReturnType } = resolveFakerTypeUsage(node, typeName, canOverride)
70
56
 
71
- let functionSignature = ''
72
- let functionBody = ''
73
-
74
- if (useGenericOverride) {
75
- // Generate function with defaultFakeData structure
76
- const jsdoc = description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ''
77
- functionSignature = `${jsdoc}export function ${name}(data?: Partial<${typeName}>): Required<${typeName}>`
78
-
79
- const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : ''
80
-
81
- // When the object node has properties that transitively reference a cyclic schema,
82
- // the printer emits memoizing getters for those properties. Spreading the object
83
- // literal would immediately invoke those getters, triggering recursive faker calls
84
- // and causing a stack overflow. Detect this upfront via ast helpers so we can
85
- // use Object.defineProperty-based merging instead of spread.
86
- const { cyclicSchemas, schemaName } = printer.options
87
- const hasGetters =
88
- node.type === 'object' &&
89
- !!cyclicSchemas &&
90
- (node.properties ?? []).some((p) => ast.containsCircularRef(p.schema, { circularSchemas: cyclicSchemas, excludeName: schemaName }))
91
-
92
- if (hasGetters) {
93
- functionBody = `{
94
- ${seedCode}const defaultFakeData = ${fakerText}
95
- if (data) {
96
- for (const [key, value] of Object.entries(data)) {
97
- Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
98
- }
99
- }
100
- return defaultFakeData as Required<${typeName}>
101
- }`
102
- } else {
103
- functionBody = `{
104
- ${seedCode}const defaultFakeData = ${fakerText}
105
- return {
106
- ...defaultFakeData,
107
- ...(data || {}),
108
- } as Required<${typeName}>
109
- }`
110
- }
111
- } else {
57
+ if (!useGenericOverride) {
112
58
  const usesData = /\bdata\b/.test(fakerTextWithOverride)
113
59
  const dataParamName = usesData ? 'data' : '_data'
114
60
  const params = ast.createFunctionParameters({
@@ -123,6 +69,11 @@ export function Faker({ node, description, name, typeName, printer, seed, canOve
123
69
  const paramsSignature = declarationPrinter.print(params) ?? ''
124
70
  const returnType = resolvedReturnType
125
71
 
72
+ // A `ref` wrapper delegates to another faker. Object fakers are now generic and
73
+ // widen to `Partial<T>` when called with a `Partial<T>`-typed argument, so cast
74
+ // back to the wrapper's declared return type to keep it assignable.
75
+ const returnExpression = node.type === 'ref' && canOverride && returnType ? `${fakerTextWithOverride} as ${returnType}` : fakerTextWithOverride
76
+
126
77
  return (
127
78
  <File.Source name={name} isExportable isIndexable>
128
79
  <Function
@@ -130,7 +81,7 @@ export function Faker({ node, description, name, typeName, printer, seed, canOve
130
81
  name={name}
131
82
  JSDoc={{ comments: description ? [`@description ${jsStringEscape(description)}`] : [] }}
132
83
  params={canOverride ? paramsSignature : undefined}
133
- returnType={returnType}
84
+ returnType={returnType ?? undefined}
134
85
  >
135
86
  {seed ? (
136
87
  <>
@@ -138,12 +89,47 @@ export function Faker({ node, description, name, typeName, printer, seed, canOve
138
89
  <br />
139
90
  </>
140
91
  ) : undefined}
141
- {`return ${fakerTextWithOverride}`}
92
+ {`return ${returnExpression}`}
142
93
  </Function>
143
94
  </File.Source>
144
95
  )
145
96
  }
146
97
 
98
+ // Generate function with defaultFakeData structure
99
+ const jsdoc = description ? `/**\n * @description ${jsStringEscape(description)}\n */\n ` : ''
100
+ const functionSignature = `${jsdoc}export function ${name}<TData extends Partial<${typeName}> = object>(data?: TData)`
101
+
102
+ const seedCode = seed ? `faker.seed(${JSON.stringify(seed)})\n ` : ''
103
+
104
+ // When the object node has properties that transitively reference a cyclic schema,
105
+ // the printer emits memoizing getters for those properties. Spreading the object
106
+ // literal would immediately invoke those getters, triggering recursive faker calls
107
+ // and causing a stack overflow. Detect this upfront via ast helpers so we can
108
+ // use Object.defineProperty-based merging instead of spread.
109
+ const { cyclicSchemas, schemaName } = printer.options
110
+ const hasGetters =
111
+ node.type === 'object' &&
112
+ !!cyclicSchemas &&
113
+ (node.properties ?? []).some((p) => ast.containsCircularRef(p.schema, { circularSchemas: cyclicSchemas, excludeName: schemaName }))
114
+
115
+ const functionBody = hasGetters
116
+ ? `{
117
+ ${seedCode}const defaultFakeData = ${fakerText}
118
+ if (data) {
119
+ for (const [key, value] of Object.entries(data)) {
120
+ Object.defineProperty(defaultFakeData, key, { value, configurable: true, writable: true, enumerable: true })
121
+ }
122
+ }
123
+ return defaultFakeData as Omit<typeof defaultFakeData, keyof TData> & TData
124
+ }`
125
+ : `{
126
+ ${seedCode}const defaultFakeData = ${fakerText}
127
+ return {
128
+ ...defaultFakeData,
129
+ ...(data || {}),
130
+ } as Omit<typeof defaultFakeData, keyof TData> & TData
131
+ }`
132
+
147
133
  return (
148
134
  <File.Source name={name} isExportable isIndexable>
149
135
  {functionSignature}