@kubb/plugin-faker 5.0.0-alpha.9 → 5.0.0-beta.3

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 (43) hide show
  1. package/LICENSE +17 -10
  2. package/README.md +1 -4
  3. package/dist/Faker-BgleOzVN.cjs +486 -0
  4. package/dist/Faker-BgleOzVN.cjs.map +1 -0
  5. package/dist/Faker-CdyPfOPg.d.ts +27 -0
  6. package/dist/Faker-fcQEB9i5.js +384 -0
  7. package/dist/Faker-fcQEB9i5.js.map +1 -0
  8. package/dist/components.cjs +2 -2
  9. package/dist/components.d.ts +2 -31
  10. package/dist/components.js +1 -1
  11. package/dist/fakerGenerator-C3Ho3BaI.d.ts +9 -0
  12. package/dist/fakerGenerator-D7daHCh6.js +516 -0
  13. package/dist/fakerGenerator-D7daHCh6.js.map +1 -0
  14. package/dist/fakerGenerator-VJEVzLjc.cjs +526 -0
  15. package/dist/fakerGenerator-VJEVzLjc.cjs.map +1 -0
  16. package/dist/generators.cjs +1 -1
  17. package/dist/generators.d.ts +2 -505
  18. package/dist/generators.js +1 -1
  19. package/dist/index.cjs +136 -84
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.ts +28 -4
  22. package/dist/index.js +128 -83
  23. package/dist/index.js.map +1 -1
  24. package/dist/printerFaker-CJiwzoto.d.ts +206 -0
  25. package/package.json +52 -50
  26. package/src/components/Faker.tsx +124 -78
  27. package/src/generators/fakerGenerator.tsx +235 -134
  28. package/src/index.ts +7 -2
  29. package/src/plugin.ts +60 -121
  30. package/src/printers/printerFaker.ts +341 -0
  31. package/src/resolvers/resolverFaker.ts +92 -0
  32. package/src/types.ts +127 -81
  33. package/src/utils.ts +356 -0
  34. package/dist/components-BkBIov4R.js +0 -419
  35. package/dist/components-BkBIov4R.js.map +0 -1
  36. package/dist/components-IdP8GXXX.cjs +0 -461
  37. package/dist/components-IdP8GXXX.cjs.map +0 -1
  38. package/dist/fakerGenerator-CYUCNH3Q.cjs +0 -204
  39. package/dist/fakerGenerator-CYUCNH3Q.cjs.map +0 -1
  40. package/dist/fakerGenerator-M5oCrPmy.js +0 -200
  41. package/dist/fakerGenerator-M5oCrPmy.js.map +0 -1
  42. package/dist/types-r7BubMLO.d.ts +0 -132
  43. package/src/parser.ts +0 -453
@@ -0,0 +1,341 @@
1
+ import { stringify, toRegExpString } from '@internals/utils'
2
+ import { ast } from '@kubb/core'
3
+ import type { PluginFaker, ResolverFaker } from '../types.ts'
4
+
5
+ /**
6
+ * Partial printer nodes for Faker generation, mapping schema types to output strings.
7
+ */
8
+ export type PrinterFakerNodes = ast.PrinterPartial<string, PrinterFakerOptions>
9
+
10
+ /**
11
+ * Configuration options for the Faker printer, including resolvers, mappers, and cyclic schema tracking.
12
+ */
13
+ export type PrinterFakerOptions = {
14
+ dateParser?: PluginFaker['resolvedOptions']['dateParser']
15
+ regexGenerator?: PluginFaker['resolvedOptions']['regexGenerator']
16
+ mapper?: PluginFaker['resolvedOptions']['mapper']
17
+ resolver: ResolverFaker
18
+ typeName?: string
19
+ schemaName?: string
20
+ nestedInObject?: boolean
21
+ nodes?: PrinterFakerNodes
22
+ /**
23
+ * Names of schemas that participate in a circular dependency chain.
24
+ * Properties whose schema transitively references one of these are emitted
25
+ * as lazy getters so that user overrides via the `data` parameter prevent
26
+ * the recursive faker call from ever executing (avoiding stack overflow).
27
+ */
28
+ cyclicSchemas?: ReadonlySet<string>
29
+ }
30
+
31
+ /**
32
+ * Factory options for the Faker printer, defining input/output types and configuration.
33
+ */
34
+ export type PrinterFakerFactory = ast.PrinterFactoryOptions<'faker', PrinterFakerOptions, string, string>
35
+
36
+ const fakerKeywordMapper = {
37
+ any: () => 'undefined',
38
+ unknown: () => 'undefined',
39
+ void: () => 'undefined',
40
+ number: (min?: number, max?: number) => {
41
+ if (max !== undefined && min !== undefined) {
42
+ return `faker.number.float({ min: ${min}, max: ${max} })`
43
+ }
44
+
45
+ if (max !== undefined) {
46
+ return `faker.number.float({ max: ${max} })`
47
+ }
48
+
49
+ if (min !== undefined) {
50
+ return `faker.number.float({ min: ${min} })`
51
+ }
52
+
53
+ return 'faker.number.float()'
54
+ },
55
+ integer: (min?: number, max?: number) => {
56
+ if (max !== undefined && min !== undefined) {
57
+ return `faker.number.int({ min: ${min}, max: ${max} })`
58
+ }
59
+
60
+ if (max !== undefined) {
61
+ return `faker.number.int({ max: ${max} })`
62
+ }
63
+
64
+ if (min !== undefined) {
65
+ return `faker.number.int({ min: ${min} })`
66
+ }
67
+
68
+ return 'faker.number.int()'
69
+ },
70
+ bigint: () => 'faker.number.bigInt()',
71
+ string: (min?: number, max?: number) => {
72
+ if (max !== undefined && min !== undefined) {
73
+ return `faker.string.alpha({ length: { min: ${min}, max: ${max} } })`
74
+ }
75
+
76
+ if (max !== undefined) {
77
+ return `faker.string.alpha({ length: ${max} })`
78
+ }
79
+
80
+ if (min !== undefined) {
81
+ return `faker.string.alpha({ length: ${min} })`
82
+ }
83
+
84
+ return 'faker.string.alpha()'
85
+ },
86
+ boolean: () => 'faker.datatype.boolean()',
87
+ null: () => 'null',
88
+ array: (items: string[] = [], min?: number, max?: number) => {
89
+ if (items.length > 1) {
90
+ return `faker.helpers.arrayElements([${items.join(', ')}])`
91
+ }
92
+
93
+ const item = items.at(0)
94
+
95
+ if (min !== undefined && max !== undefined) {
96
+ return `faker.helpers.multiple(() => (${item}), { count: { min: ${min}, max: ${max} }})`
97
+ }
98
+
99
+ if (min !== undefined) {
100
+ return `faker.helpers.multiple(() => (${item}), { count: ${min} })`
101
+ }
102
+
103
+ if (max !== undefined) {
104
+ return `faker.helpers.multiple(() => (${item}), { count: { min: 0, max: ${max} }})`
105
+ }
106
+
107
+ return `faker.helpers.multiple(() => (${item}))`
108
+ },
109
+ tuple: (items: string[] = []) => `[${items.join(', ')}]`,
110
+ enum: (items: Array<string | number | boolean | undefined> = [], type = 'any') => `faker.helpers.arrayElement<${type}>([${items.join(', ')}])`,
111
+ union: (items: string[] = []) => `faker.helpers.arrayElement<any>([${items.join(', ')}])`,
112
+ datetime: () => 'faker.date.anytime().toISOString()',
113
+ date: (representation: 'date' | 'string' = 'string', parser: PluginFaker['resolvedOptions']['dateParser'] = 'faker') => {
114
+ if (representation === 'string') {
115
+ if (parser !== 'faker') {
116
+ return `${parser}(faker.date.anytime()).format("YYYY-MM-DD")`
117
+ }
118
+
119
+ return 'faker.date.anytime().toISOString().substring(0, 10)'
120
+ }
121
+
122
+ if (parser !== 'faker') {
123
+ throw new Error(`type '${representation}' and parser '${parser}' can not work together`)
124
+ }
125
+
126
+ return 'faker.date.anytime()'
127
+ },
128
+ time: (representation: 'date' | 'string' = 'string', parser: PluginFaker['resolvedOptions']['dateParser'] = 'faker') => {
129
+ if (representation === 'string') {
130
+ if (parser !== 'faker') {
131
+ return `${parser}(faker.date.anytime()).format("HH:mm:ss")`
132
+ }
133
+
134
+ return 'faker.date.anytime().toISOString().substring(11, 19)'
135
+ }
136
+
137
+ if (parser !== 'faker') {
138
+ throw new Error(`type '${representation}' and parser '${parser}' can not work together`)
139
+ }
140
+
141
+ return 'faker.date.anytime()'
142
+ },
143
+ uuid: () => 'faker.string.uuid()',
144
+ url: () => 'faker.internet.url()',
145
+ and: (items: string[] = []) => {
146
+ if (items.length === 0) {
147
+ return '{}'
148
+ }
149
+
150
+ if (items.length === 1) {
151
+ return items[0] ?? '{}'
152
+ }
153
+
154
+ return `{...${items.join(', ...')}}`
155
+ },
156
+ matches: (value = '', regexGenerator: 'faker' | 'randexp' = 'faker') => {
157
+ if (regexGenerator === 'randexp') {
158
+ return `${toRegExpString(value, 'RandExp')}.gen()`
159
+ }
160
+
161
+ return `faker.helpers.fromRegExp("${value}")`
162
+ },
163
+ email: () => 'faker.internet.email()',
164
+ blob: () => 'faker.image.url() as unknown as Blob',
165
+ } as const
166
+
167
+ function getEnumValues(node: ast.EnumSchemaNode): Array<string | number | boolean | undefined> {
168
+ if (node.namedEnumValues?.length) {
169
+ return node.namedEnumValues.map((item) => item.value as string | number | boolean | undefined)
170
+ }
171
+
172
+ return (node.enumValues ?? []) as Array<string | number | boolean | undefined>
173
+ }
174
+
175
+ function parseEnumValue(value: string | number | boolean | undefined) {
176
+ if (typeof value === 'string') {
177
+ return stringify(value)
178
+ }
179
+
180
+ return value
181
+ }
182
+
183
+ /**
184
+ * Creates a Faker printer that generates mock data generation code from schema nodes.
185
+ * Handles circular references gracefully by emitting memoizing getters for cyclic properties.
186
+ */
187
+ export const printerFaker: (options: PrinterFakerOptions) => ast.Printer<PrinterFakerFactory> = ast.definePrinter<PrinterFakerFactory>((options) => {
188
+ const printNested = (node: ast.SchemaNode, overrideOptions: Partial<PrinterFakerOptions> = {}): string => {
189
+ return (
190
+ printerFaker({
191
+ ...options,
192
+ ...overrideOptions,
193
+ nodes: options.nodes,
194
+ }).print(node) ?? 'undefined'
195
+ )
196
+ }
197
+
198
+ return {
199
+ name: 'faker',
200
+ options,
201
+ nodes: {
202
+ any: () => fakerKeywordMapper.any(),
203
+ unknown: () => fakerKeywordMapper.unknown(),
204
+ void: () => fakerKeywordMapper.void(),
205
+ boolean: () => fakerKeywordMapper.boolean(),
206
+ null: () => fakerKeywordMapper.null(),
207
+ string(node) {
208
+ if (node.pattern) {
209
+ return fakerKeywordMapper.matches(node.pattern, this.options.regexGenerator)
210
+ }
211
+
212
+ return fakerKeywordMapper.string(node.min, node.max)
213
+ },
214
+ email: () => fakerKeywordMapper.email(),
215
+ url: () => fakerKeywordMapper.url(),
216
+ uuid: () => fakerKeywordMapper.uuid(),
217
+ number(node) {
218
+ return fakerKeywordMapper.number(node.min, node.max)
219
+ },
220
+ integer(node) {
221
+ return fakerKeywordMapper.integer(node.min, node.max)
222
+ },
223
+ bigint: () => fakerKeywordMapper.bigint(),
224
+ blob: () => fakerKeywordMapper.blob(),
225
+ datetime: () => fakerKeywordMapper.datetime(),
226
+ date(node) {
227
+ return fakerKeywordMapper.date(node.representation ?? 'string', this.options.dateParser)
228
+ },
229
+ time(node) {
230
+ return fakerKeywordMapper.time(node.representation ?? 'string', this.options.dateParser)
231
+ },
232
+ ref(node) {
233
+ // Parser-generated refs (with $ref) carry raw schema names that need resolving.
234
+ // Use the canonical name from the $ref path — node.name may have been overridden
235
+ // (e.g. by single-member allOf flatten using the property-derived child name).
236
+ // Inline refs (without $ref) from faker utils already carry resolved helper names.
237
+ const refName = node.ref ? (ast.extractRefName(node.ref) ?? node.name ?? node.schema?.name) : (node.name ?? node.schema?.name)
238
+
239
+ if (!refName) {
240
+ throw new Error('Name not defined for ref node')
241
+ }
242
+
243
+ if (this.options.schemaName && refName === this.options.schemaName) {
244
+ return 'undefined as any'
245
+ }
246
+
247
+ // Internal helper refs (for generated response/data helpers) are already
248
+ // emitted with resolver output and should not be transformed twice.
249
+ const resolvedName = node.ref ? this.options.resolver.resolveName(refName) : refName
250
+
251
+ if (!this.options.nestedInObject) {
252
+ return `${resolvedName}(data)`
253
+ }
254
+
255
+ return `${resolvedName}()`
256
+ },
257
+ enum(node) {
258
+ return fakerKeywordMapper.enum(getEnumValues(node).map(parseEnumValue), this.options.typeName)
259
+ },
260
+ union(node): string {
261
+ const items: string[] = (node.members ?? [])
262
+ .map((member) =>
263
+ printNested(member, {
264
+ nestedInObject: true,
265
+ }),
266
+ )
267
+ .filter((item): item is string => Boolean(item))
268
+
269
+ return fakerKeywordMapper.union(items)
270
+ },
271
+ intersection(node): string {
272
+ const items: string[] = (node.members ?? [])
273
+ .map((member) =>
274
+ printNested(member, {
275
+ nestedInObject: true,
276
+ }),
277
+ )
278
+ .filter((item): item is string => Boolean(item))
279
+
280
+ return fakerKeywordMapper.and(items)
281
+ },
282
+ array(node): string {
283
+ const items: string[] = (node.items ?? [])
284
+ .map((member) =>
285
+ printNested(member, {
286
+ typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[number]` : undefined,
287
+ nestedInObject: true,
288
+ }),
289
+ )
290
+ .filter((item): item is string => Boolean(item))
291
+
292
+ return fakerKeywordMapper.array(items, node.min, node.max)
293
+ },
294
+ tuple(node): string {
295
+ const items: string[] = (node.items ?? [])
296
+ .map((member, index) =>
297
+ printNested(member, {
298
+ typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[${index}]` : undefined,
299
+ nestedInObject: true,
300
+ }),
301
+ )
302
+ .filter((item): item is string => Boolean(item))
303
+
304
+ return fakerKeywordMapper.tuple(items)
305
+ },
306
+ object(node): string {
307
+ const cyclicSchemas = this.options.cyclicSchemas
308
+ const properties = (node.properties ?? [])
309
+ .map((property): string => {
310
+ if (this.options.mapper && Object.hasOwn(this.options.mapper, property.name)) {
311
+ return `"${property.name}": ${this.options.mapper[property.name]}`
312
+ }
313
+
314
+ const value: string =
315
+ printNested(property.schema, {
316
+ typeName: this.options.typeName ? `NonNullable<${this.options.typeName}>[${JSON.stringify(property.name)}]` : undefined,
317
+ nestedInObject: true,
318
+ }) ?? 'undefined'
319
+
320
+ // When the property's schema transitively references a schema that is
321
+ // part of a circular dependency (other than the current schema itself),
322
+ // emit a memoizing lazy getter. On first access it computes the value,
323
+ // replaces itself with a plain data property via Object.defineProperty,
324
+ // and returns the cached value – so every subsequent read is stable.
325
+ if (cyclicSchemas && ast.containsCircularRef(property.schema, { circularSchemas: cyclicSchemas, excludeName: this.options.schemaName })) {
326
+ return `get ${property.name}() { const _value = ${value}; Object.defineProperty(this, ${JSON.stringify(property.name)}, { value: _value, configurable: true, writable: true, enumerable: true }); return _value }`
327
+ }
328
+
329
+ return `"${property.name}": ${value}`
330
+ })
331
+ .join(',')
332
+
333
+ return `{${properties}}`
334
+ },
335
+ ...options.nodes,
336
+ },
337
+ print(node) {
338
+ return this.transform(node) ?? null
339
+ },
340
+ }
341
+ })
@@ -0,0 +1,92 @@
1
+ import { createHash } from 'node:crypto'
2
+ import path from 'node:path'
3
+ import { camelCase } from '@internals/utils'
4
+ import { defineResolver, PluginDriver } from '@kubb/core'
5
+ import type { PluginFaker } from '../types.ts'
6
+
7
+ function isValidStrictIdentifier(name: string): boolean {
8
+ try {
9
+ new Function(`"use strict"; const ${name} = 1;`)
10
+ } catch {
11
+ return false
12
+ }
13
+
14
+ return true
15
+ }
16
+
17
+ /**
18
+ * Naming convention resolver for Faker plugin.
19
+ *
20
+ * Provides default naming helpers using camelCase. Prefixes invalid identifiers with `_`.
21
+ *
22
+ * @example
23
+ * `resolverFaker.default('list pets', 'function') // → 'listPets'`
24
+ */
25
+ export const resolverFaker = defineResolver<PluginFaker>((ctx) => {
26
+ return {
27
+ name: 'default',
28
+ pluginName: 'plugin-faker',
29
+ default(name, type) {
30
+ const resolvedName = camelCase(name, { isFile: type === 'file' })
31
+
32
+ if (type === 'file' || isValidStrictIdentifier(resolvedName)) {
33
+ return resolvedName
34
+ }
35
+
36
+ return `_${resolvedName}`
37
+ },
38
+ resolveName(name, type) {
39
+ return ctx.default(name, type)
40
+ },
41
+ resolvePathName(name, type) {
42
+ return ctx.default(name, type)
43
+ },
44
+ resolveFile({ name, extname, tag, path: groupPath }, context) {
45
+ const pathMode = PluginDriver.getMode(path.resolve(context.root, context.output.path))
46
+ const baseName = `${pathMode === 'single' ? '' : ctx.resolveName(name, 'file')}${extname}` as `${string}.${string}`
47
+ const filePath = ctx.resolvePath(
48
+ {
49
+ baseName,
50
+ pathMode,
51
+ tag,
52
+ path: groupPath,
53
+ },
54
+ context,
55
+ )
56
+
57
+ return {
58
+ kind: 'File',
59
+ id: createHash('sha256').update(filePath).digest('hex'),
60
+ name: path.basename(filePath, extname),
61
+ path: filePath,
62
+ baseName,
63
+ extname,
64
+ meta: { pluginName: ctx.pluginName },
65
+ sources: [],
66
+ imports: [],
67
+ exports: [],
68
+ }
69
+ },
70
+ resolveParamName(node, param) {
71
+ return ctx.resolveName(`${node.operationId} ${param.in} ${param.name}`)
72
+ },
73
+ resolveDataName(node) {
74
+ return ctx.resolveName(`${node.operationId} Data`)
75
+ },
76
+ resolveResponseStatusName(node, statusCode) {
77
+ return ctx.resolveName(`${node.operationId} Status ${statusCode}`)
78
+ },
79
+ resolveResponseName(node) {
80
+ return ctx.resolveName(`${node.operationId} Response`)
81
+ },
82
+ resolvePathParamsName(node, param) {
83
+ return ctx.resolveParamName(node, param)
84
+ },
85
+ resolveQueryParamsName(node, param) {
86
+ return ctx.resolveParamName(node, param)
87
+ },
88
+ resolveHeaderParamsName(node, param) {
89
+ return ctx.resolveParamName(node, param)
90
+ },
91
+ }
92
+ })
package/src/types.ts CHANGED
@@ -1,126 +1,172 @@
1
- import type { Group, Output, PluginFactoryOptions, ResolveNameParams } from '@kubb/core'
1
+ import type { ast, Exclude, Generator, Group, Include, Output, Override, PluginFactoryOptions, Resolver } from '@kubb/core'
2
+ import type { PrinterFakerNodes } from './printers/printerFaker.ts'
2
3
 
3
- import type { contentType, Oas, SchemaObject } from '@kubb/oas'
4
- import type { Exclude, Include, Override, ResolvePathOptions, Schema } from '@kubb/plugin-oas'
5
- import type { Generator } from '@kubb/plugin-oas/generators'
4
+ /**
5
+ * Resolver for Faker that provides naming methods for mock functions.
6
+ */
7
+ export type ResolverFaker = Resolver &
8
+ ast.OperationParamsResolver & {
9
+ /**
10
+ * Resolves the faker function name for a schema.
11
+ *
12
+ * @example Resolving faker function names
13
+ * `resolver.resolveName('show pet by id') // -> 'showPetById'`
14
+ */
15
+ resolveName(this: ResolverFaker, name: string, type?: 'file' | 'function' | 'type' | 'const'): string
16
+ /**
17
+ * Resolves the output file name for a faker module.
18
+ *
19
+ * @example Resolving faker file names
20
+ * `resolver.resolvePathName('show pet by id', 'file') // -> 'showPetById'`
21
+ */
22
+ resolvePathName(this: ResolverFaker, name: string, type?: 'file' | 'function' | 'type' | 'const'): string
23
+ /**
24
+ * Resolves the faker function name for a request body.
25
+ *
26
+ * @example Resolving data function names
27
+ * `resolver.resolveDataName(node) // -> 'createPetsData'`
28
+ */
29
+ resolveDataName(this: ResolverFaker, node: ast.OperationNode): string
30
+ /**
31
+ * Resolves the faker function name for a response by status code.
32
+ *
33
+ * @example Response status names
34
+ * `resolver.resolveResponseStatusName(node, 200) // -> 'listPetsStatus200'`
35
+ */
36
+ resolveResponseStatusName(this: ResolverFaker, node: ast.OperationNode, statusCode: ast.StatusCode): string
37
+ /**
38
+ * Resolves the faker function name for the response union.
39
+ *
40
+ * @example Response union names
41
+ * `resolver.resolveResponseName(node) // -> 'listPetsResponse'`
42
+ */
43
+ resolveResponseName(this: ResolverFaker, node: ast.OperationNode): string
44
+ /**
45
+ * Resolves the faker function name for path parameters.
46
+ *
47
+ * @example Path parameters names
48
+ * `resolver.resolvePathParamsName(node, param) // -> 'showPetByIdPathPetId'`
49
+ */
50
+ resolvePathParamsName(this: ResolverFaker, node: ast.OperationNode, param: ast.ParameterNode): string
51
+ /**
52
+ * Resolves the faker function name for query parameters.
53
+ *
54
+ * @example Query parameters names
55
+ * `resolver.resolveQueryParamsName(node, param) // -> 'listPetsQueryLimit'`
56
+ */
57
+ resolveQueryParamsName(this: ResolverFaker, node: ast.OperationNode, param: ast.ParameterNode): string
58
+ /**
59
+ * Resolves the faker function name for header parameters.
60
+ *
61
+ * @example Header parameters names
62
+ * `resolver.resolveHeaderParamsName(node, param) // -> 'deletePetHeaderApiKey'`
63
+ */
64
+ resolveHeaderParamsName(this: ResolverFaker, node: ast.OperationNode, param: ast.ParameterNode): string
65
+ }
6
66
 
7
67
  export type Options = {
8
68
  /**
9
- * Specify the export location for the files and define the behavior of the output
10
- * @default { path: 'handlers', barrelType: 'named' }
11
- */
12
- output?: Output<Oas>
13
- /**
14
- * Define which contentType should be used.
15
- * By default, the first JSON valid mediaType is used
69
+ * Specify the export location for the files and define the behavior of the output.
70
+ * @default { path: 'mocks', barrelType: 'named' }
16
71
  */
17
- contentType?: contentType
72
+ output?: Output
18
73
  /**
19
74
  * Group the Faker mocks based on the provided name.
20
75
  */
21
76
  group?: Group
22
77
  /**
23
- * Array containing exclude parameters to exclude/skip tags/operations/methods/paths.
78
+ * Tags, operations, or paths to exclude from generation.
24
79
  */
25
80
  exclude?: Array<Exclude>
26
81
  /**
27
- * Array containing include parameters to include tags/operations/methods/paths.
82
+ * Tags, operations, or paths to include in generation.
28
83
  */
29
84
  include?: Array<Include>
30
85
  /**
31
- * Array containing override parameters to override `options` based on tags/operations/methods/paths.
86
+ * Override options for specific tags, operations, or paths.
32
87
  */
33
88
  override?: Array<Override<ResolvedOptions>>
34
89
  /**
35
- * Choose to use date or datetime as JavaScript Date instead of string.
36
- * - 'string' represents dates as string values.
37
- * - 'date' represents dates as JavaScript Date objects.
38
- * @default 'string'
39
- */
40
- dateType?: 'string' | 'date'
41
- /**
42
- * Choose to use `number` or `bigint` for integer fields with `int64` format.
43
- * - 'number' uses the JavaScript `number` type (matches JSON.parse() runtime behavior).
44
- * - 'bigint' uses the JavaScript `bigint` type (accurate for values exceeding Number.MAX_SAFE_INTEGER).
45
- * @note in v5 of Kubb 'bigint' will become the default to better align with OpenAPI's int64 specification.
46
- * @default 'number'
47
- */
48
- integerType?: 'number' | 'bigint'
49
- /**
50
- * Which parser should be used when dateType is set to string.
51
- * - 'faker' uses faker's built-in date formatting methods.
52
- * - 'dayjs' uses dayjs for date formatting with custom patterns.
53
- * - 'moment' uses moment for date formatting with custom patterns.
90
+ * Parser to use when formatting date/time values as strings.
91
+ *
54
92
  * @default 'faker'
55
93
  */
56
94
  dateParser?: 'faker' | 'dayjs' | 'moment' | (string & {})
57
95
  /**
58
- * Which type to use when the Swagger/OpenAPI file is not providing more information.
59
- * - 'any' allows any value.
60
- * - 'unknown' requires type narrowing before use.
61
- * - 'void' represents no value.
62
- * @default 'any'
96
+ * Generator to use for RegExp patterns.
97
+ *
98
+ * @default 'faker'
63
99
  */
64
- unknownType?: 'any' | 'unknown' | 'void'
100
+ regexGenerator?: 'faker' | 'randexp'
65
101
  /**
66
- * Which type to use for empty schema values.
67
- * - 'any' allows any value.
68
- * - 'unknown' requires type narrowing before use.
69
- * - 'void' represents no value.
70
- * @default `unknownType`
102
+ * Provide per-property faker expressions keyed by property name.
71
103
  */
72
- emptySchemaType?: 'any' | 'unknown' | 'void'
104
+ mapper?: Record<string, string>
73
105
  /**
74
- * Choose which generator to use when using Regexp.
75
- * - 'faker' uses faker.helpers.fromRegExp for generating values from regex patterns.
76
- * - 'randexp' uses RandExp library for generating values from regex patterns.
77
- * @default 'faker'
106
+ * Locale for generating mock data.
107
+ * Imports the matching localized `@faker-js/faker` instance so names, addresses,
108
+ * and phone numbers reflect the target region.
109
+ *
110
+ * @default 'en'
111
+ *
112
+ * @example German
113
+ * `locale: 'de'`
114
+ *
115
+ * @example Austrian German
116
+ * `locale: 'de_AT'`
117
+ *
118
+ * @see https://fakerjs.dev/api/localization.html
78
119
  */
79
- regexGenerator?: 'faker' | 'randexp'
80
-
81
- mapper?: Record<string, string>
120
+ locale?: string
82
121
  /**
83
- * The use of Seed is intended to allow for consistent values in a test.
122
+ * Seed faker for deterministic output.
84
123
  */
85
124
  seed?: number | number[]
86
125
  /**
87
- * Transform parameter names to a specific casing format.
88
- * When set to 'camelcase', parameter names in path, query, and header params will be transformed to camelCase.
89
- * This should match the paramsCasing setting used in @kubb/plugin-ts.
90
- * @default undefined
126
+ * Apply casing to parameter names to match your configuration.
91
127
  */
92
128
  paramsCasing?: 'camelcase'
93
- transformers?: {
94
- /**
95
- * Customize the names based on the type that is provided by the plugin.
96
- */
97
- name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
98
- /**
99
- * Receive schema and baseName(propertyName) and return FakerMeta array
100
- * TODO TODO add docs
101
- * @beta
102
- */
103
- schema?: (props: { schema: SchemaObject | null; name: string | null; parentName: string | null }, defaultSchemas: Schema[]) => Schema[] | undefined
104
- }
105
129
  /**
106
- * Define some generators next to the faker generators
130
+ * Additional generators alongside the default generators.
107
131
  */
108
132
  generators?: Array<Generator<PluginFaker>>
133
+ /**
134
+ * Override naming conventions for function names and types.
135
+ */
136
+ resolver?: Partial<ResolverFaker> & ThisType<ResolverFaker>
137
+ /**
138
+ * AST visitor to transform generated nodes.
139
+ */
140
+ transformer?: ast.Visitor
141
+ /**
142
+ * Override individual faker printer node handlers.
143
+ */
144
+ printer?: {
145
+ nodes?: PrinterFakerNodes
146
+ }
109
147
  }
110
148
 
111
149
  type ResolvedOptions = {
112
- output: Output<Oas>
113
- group: Options['group']
150
+ output: Output
151
+ group: Group | undefined
152
+ exclude: NonNullable<Options['exclude']>
153
+ include: Options['include']
114
154
  override: NonNullable<Options['override']>
115
- dateType: NonNullable<Options['dateType']>
116
- integerType: NonNullable<Options['integerType']>
117
155
  dateParser: NonNullable<Options['dateParser']>
118
- unknownType: NonNullable<Options['unknownType']>
119
- emptySchemaType: NonNullable<Options['emptySchemaType']>
120
- transformers: NonNullable<Options['transformers']>
121
- seed: NonNullable<Options['seed']> | undefined
122
- mapper: NonNullable<Options['mapper']>
123
156
  regexGenerator: NonNullable<Options['regexGenerator']>
157
+ mapper: NonNullable<Options['mapper']>
158
+ seed: NonNullable<Options['seed']> | undefined
159
+ locale: Options['locale']
124
160
  paramsCasing: Options['paramsCasing']
161
+ printer: Options['printer']
162
+ }
163
+
164
+ export type PluginFaker = PluginFactoryOptions<'plugin-faker', Options, ResolvedOptions, ResolverFaker>
165
+
166
+ declare global {
167
+ namespace Kubb {
168
+ interface PluginRegistry {
169
+ 'plugin-faker': PluginFaker
170
+ }
171
+ }
125
172
  }
126
- export type PluginFaker = PluginFactoryOptions<'plugin-faker', Options, ResolvedOptions, never, ResolvePathOptions>