@kubb/plugin-faker 5.0.0-alpha.8 → 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.
- package/LICENSE +17 -10
- package/README.md +1 -4
- package/dist/Faker-BgleOzVN.cjs +486 -0
- package/dist/Faker-BgleOzVN.cjs.map +1 -0
- package/dist/Faker-CdyPfOPg.d.ts +27 -0
- package/dist/Faker-fcQEB9i5.js +384 -0
- package/dist/Faker-fcQEB9i5.js.map +1 -0
- package/dist/components.cjs +2 -2
- package/dist/components.d.ts +2 -31
- package/dist/components.js +1 -1
- package/dist/fakerGenerator-C3Ho3BaI.d.ts +9 -0
- package/dist/fakerGenerator-D7daHCh6.js +516 -0
- package/dist/fakerGenerator-D7daHCh6.js.map +1 -0
- package/dist/fakerGenerator-VJEVzLjc.cjs +526 -0
- package/dist/fakerGenerator-VJEVzLjc.cjs.map +1 -0
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +2 -476
- package/dist/generators.js +1 -1
- package/dist/index.cjs +136 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -4
- package/dist/index.js +128 -83
- package/dist/index.js.map +1 -1
- package/dist/printerFaker-CJiwzoto.d.ts +206 -0
- package/package.json +52 -50
- package/src/components/Faker.tsx +124 -78
- package/src/generators/fakerGenerator.tsx +235 -134
- package/src/index.ts +7 -2
- package/src/plugin.ts +60 -121
- package/src/printers/printerFaker.ts +341 -0
- package/src/resolvers/resolverFaker.ts +92 -0
- package/src/types.ts +127 -81
- package/src/utils.ts +356 -0
- package/dist/components-BkBIov4R.js +0 -419
- package/dist/components-BkBIov4R.js.map +0 -1
- package/dist/components-IdP8GXXX.cjs +0 -461
- package/dist/components-IdP8GXXX.cjs.map +0 -1
- package/dist/fakerGenerator-CYUCNH3Q.cjs +0 -204
- package/dist/fakerGenerator-CYUCNH3Q.cjs.map +0 -1
- package/dist/fakerGenerator-M5oCrPmy.js +0 -200
- package/dist/fakerGenerator-M5oCrPmy.js.map +0 -1
- package/dist/types-r7BubMLO.d.ts +0 -132
- package/src/parser.ts +0 -453
|
@@ -1,87 +1,223 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type OperationSchema as OperationSchemaType, SchemaGenerator, schemaKeywords } from '@kubb/plugin-oas'
|
|
3
|
-
import { createReactGenerator } from '@kubb/plugin-oas/generators'
|
|
4
|
-
import { useOas, useOperationManager, useSchemaManager } from '@kubb/plugin-oas/hooks'
|
|
5
|
-
import { applyParamsCasing, getBanner, getFooter, getImports, isParameterSchema } from '@kubb/plugin-oas/utils'
|
|
1
|
+
import { ast, defineGenerator } from '@kubb/core'
|
|
6
2
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
7
|
-
import { File } from '@kubb/
|
|
8
|
-
import { Faker } from '../components'
|
|
9
|
-
import
|
|
3
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
4
|
+
import { Faker } from '../components/Faker.tsx'
|
|
5
|
+
import { printerFaker } from '../printers/printerFaker.ts'
|
|
6
|
+
import type { PluginFaker } from '../types.ts'
|
|
7
|
+
import {
|
|
8
|
+
aliasConflictingImports,
|
|
9
|
+
buildResponseUnionSchema,
|
|
10
|
+
canOverrideSchema,
|
|
11
|
+
filterUsedImports,
|
|
12
|
+
localeToFakerImport,
|
|
13
|
+
resolveParamNameByLocation,
|
|
14
|
+
resolveSchemaRef,
|
|
15
|
+
resolveTypeReference,
|
|
16
|
+
rewriteAliasedImports,
|
|
17
|
+
} from '../utils.ts'
|
|
10
18
|
|
|
11
|
-
export const fakerGenerator =
|
|
19
|
+
export const fakerGenerator = defineGenerator<PluginFaker>({
|
|
12
20
|
name: 'faker',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const mode = useMode()
|
|
19
|
-
const driver = usePluginDriver()
|
|
21
|
+
renderer: jsxRenderer,
|
|
22
|
+
schema(node, ctx) {
|
|
23
|
+
const { adapter, config, resolver, root } = ctx
|
|
24
|
+
const { output, group, dateParser, regexGenerator, mapper, seed, locale, printer } = ctx.options
|
|
25
|
+
const pluginTs = ctx.driver.getPlugin(pluginTsName)
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
if (!node.name || !pluginTs || !adapter.inputNode) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const tsResolver = ctx.driver.getResolver(pluginTsName)
|
|
24
32
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const schemaNode = resolveSchemaRef(node, adapter.inputNode.schemas)
|
|
34
|
+
const schemaName = schemaNode.name ?? node.name
|
|
35
|
+
const mode = ctx.getMode(output)
|
|
36
|
+
const meta = {
|
|
37
|
+
name: resolver.resolveName(schemaName),
|
|
38
|
+
file: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }),
|
|
39
|
+
typeName: tsResolver.resolveTypeName(schemaName),
|
|
40
|
+
typeFile: tsResolver.resolveFile(
|
|
41
|
+
{ name: schemaName, extname: '.ts' },
|
|
42
|
+
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
43
|
+
),
|
|
44
|
+
} as const
|
|
45
|
+
const canOverride = canOverrideSchema(schemaNode)
|
|
46
|
+
const cyclicSchemas = adapter.inputNode ? ast.findCircularSchemas(adapter.inputNode.schemas) : undefined
|
|
47
|
+
const printerInstance = printerFaker({
|
|
48
|
+
resolver,
|
|
49
|
+
schemaName,
|
|
50
|
+
typeName: meta.typeName,
|
|
51
|
+
dateParser,
|
|
52
|
+
regexGenerator,
|
|
53
|
+
mapper,
|
|
54
|
+
nodes: printer?.nodes,
|
|
55
|
+
cyclicSchemas,
|
|
56
|
+
})
|
|
57
|
+
const fakerText = printerInstance.print(schemaNode) ?? 'undefined'
|
|
58
|
+
const typeReference = resolveTypeReference({
|
|
59
|
+
node: schemaNode,
|
|
60
|
+
canOverride,
|
|
61
|
+
name: meta.name,
|
|
62
|
+
typeName: meta.typeName,
|
|
63
|
+
filePath: meta.file.path,
|
|
64
|
+
typeFilePath: meta.typeFile.path,
|
|
35
65
|
})
|
|
36
66
|
|
|
37
|
-
const
|
|
38
|
-
.
|
|
39
|
-
|
|
67
|
+
const imports = adapter
|
|
68
|
+
.getImports(schemaNode, (schemaName) => ({
|
|
69
|
+
name: resolver.resolveName(schemaName),
|
|
70
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
71
|
+
}))
|
|
72
|
+
.filter((entry) => entry.path !== meta.file.path)
|
|
73
|
+
const usedImports = filterUsedImports(imports, fakerText)
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
75
|
+
return (
|
|
76
|
+
<File
|
|
77
|
+
baseName={meta.file.baseName}
|
|
78
|
+
path={meta.file.path}
|
|
79
|
+
meta={meta.file.meta}
|
|
80
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
81
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
82
|
+
>
|
|
83
|
+
<File.Import name={locale ? [{ propertyName: localeToFakerImport(locale), name: 'faker' }] : ['faker']} path="@faker-js/faker" />
|
|
84
|
+
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
85
|
+
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
86
|
+
{typeReference.importPath && <File.Import isTypeOnly root={meta.file.path} path={typeReference.importPath} name={[meta.typeName]} />}
|
|
87
|
+
{mode === 'split' &&
|
|
88
|
+
usedImports.map((imp) => <File.Import key={[schemaName, imp.path, imp.name].join('-')} root={meta.file.path} path={imp.path} name={imp.name} />)}
|
|
89
|
+
<Faker
|
|
90
|
+
name={meta.name}
|
|
91
|
+
typeName={typeReference.typeName}
|
|
92
|
+
description={schemaNode.description}
|
|
93
|
+
node={schemaNode}
|
|
94
|
+
printer={printerInstance}
|
|
95
|
+
seed={seed}
|
|
96
|
+
canOverride={canOverride}
|
|
97
|
+
/>
|
|
98
|
+
</File>
|
|
99
|
+
)
|
|
100
|
+
},
|
|
101
|
+
operation(node, ctx) {
|
|
102
|
+
const { adapter, config, resolver, root } = ctx
|
|
103
|
+
const { output, group, paramsCasing, dateParser, regexGenerator, mapper, seed, locale, printer } = ctx.options
|
|
104
|
+
const pluginTs = ctx.driver.getPlugin(pluginTsName)
|
|
105
|
+
|
|
106
|
+
if (!pluginTs) {
|
|
107
|
+
return
|
|
108
|
+
}
|
|
45
109
|
|
|
46
|
-
|
|
47
|
-
const imports = getImports(tree)
|
|
48
|
-
const group = options.operation ? getGroup(options.operation) : undefined
|
|
110
|
+
const tsResolver = ctx.driver.getResolver(pluginTsName)
|
|
49
111
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
112
|
+
const params = ast.caseParams(node.parameters, paramsCasing)
|
|
113
|
+
const paramEntries = params.map((param) => ({
|
|
114
|
+
param,
|
|
115
|
+
name: resolveParamNameByLocation(resolver, node, param),
|
|
116
|
+
typeName: resolveParamNameByLocation(tsResolver, node, param),
|
|
117
|
+
}))
|
|
118
|
+
const responseEntries = node.responses.map((response) => ({
|
|
119
|
+
response,
|
|
120
|
+
name: resolver.resolveResponseStatusName(node, response.statusCode),
|
|
121
|
+
typeName: tsResolver.resolveResponseStatusName(node, response.statusCode),
|
|
122
|
+
}))
|
|
123
|
+
const dataEntry = node.requestBody?.content?.[0]?.schema
|
|
124
|
+
? {
|
|
125
|
+
schema: {
|
|
126
|
+
...node.requestBody.content![0]!.schema!,
|
|
127
|
+
description: node.requestBody.description ?? node.requestBody.content![0]!.schema!.description,
|
|
128
|
+
},
|
|
129
|
+
name: resolver.resolveDataName(node),
|
|
130
|
+
typeName: tsResolver.resolveDataName(node),
|
|
131
|
+
description: node.requestBody.description ?? node.requestBody.content![0]!.schema!.description,
|
|
132
|
+
}
|
|
133
|
+
: null
|
|
134
|
+
const responseName = resolver.resolveResponseName(node)
|
|
135
|
+
const localHelperNames = new Set([
|
|
136
|
+
...paramEntries.map((entry) => entry.name),
|
|
137
|
+
...responseEntries.map((entry) => entry.name),
|
|
138
|
+
...(dataEntry ? [dataEntry.name] : []),
|
|
139
|
+
responseName,
|
|
140
|
+
])
|
|
141
|
+
const meta = {
|
|
142
|
+
file: resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
|
|
143
|
+
typeFile: tsResolver.resolveFile(
|
|
144
|
+
{
|
|
145
|
+
name: node.operationId,
|
|
146
|
+
extname: '.ts',
|
|
147
|
+
tag: node.tags[0] ?? 'default',
|
|
148
|
+
path: node.path,
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
root,
|
|
152
|
+
output: pluginTs.options?.output ?? output,
|
|
153
|
+
group: pluginTs.options?.group,
|
|
154
|
+
},
|
|
155
|
+
),
|
|
156
|
+
} as const
|
|
54
157
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
158
|
+
function resolveMockImports(schema: ast.SchemaNode) {
|
|
159
|
+
return adapter
|
|
160
|
+
.getImports(schema, (schemaName) => ({
|
|
161
|
+
name: resolver.resolveName(schemaName),
|
|
162
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
163
|
+
}))
|
|
164
|
+
.filter((entry) => entry.path !== meta.file.path)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function renderEntry({
|
|
168
|
+
schema,
|
|
169
|
+
name,
|
|
170
|
+
typeName,
|
|
171
|
+
description,
|
|
172
|
+
skipImportNames = [],
|
|
173
|
+
}: {
|
|
174
|
+
schema: ast.SchemaNode | null
|
|
175
|
+
name: string
|
|
176
|
+
typeName: string
|
|
177
|
+
description?: string
|
|
178
|
+
skipImportNames?: Array<string>
|
|
179
|
+
}) {
|
|
180
|
+
if (!schema) {
|
|
181
|
+
return null
|
|
58
182
|
}
|
|
59
183
|
|
|
60
|
-
const canOverride =
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
184
|
+
const canOverride = canOverrideSchema(schema)
|
|
185
|
+
const cyclicSchemas = adapter.inputNode ? ast.findCircularSchemas(adapter.inputNode.schemas) : undefined
|
|
186
|
+
const printerInstance = printerFaker({
|
|
187
|
+
resolver,
|
|
188
|
+
schemaName: name,
|
|
189
|
+
typeName,
|
|
190
|
+
dateParser,
|
|
191
|
+
regexGenerator,
|
|
192
|
+
mapper,
|
|
193
|
+
nodes: printer?.nodes,
|
|
194
|
+
cyclicSchemas,
|
|
195
|
+
})
|
|
196
|
+
const fakerText = printerInstance.print(schema) ?? 'undefined'
|
|
197
|
+
const usedImports = filterUsedImports(resolveMockImports(schema), fakerText, skipImportNames)
|
|
198
|
+
const { imports, aliases } = aliasConflictingImports(usedImports, localHelperNames)
|
|
199
|
+
const rewrittenFakerText = rewriteAliasedImports(fakerText, aliases)
|
|
200
|
+
const typeReference = resolveTypeReference({
|
|
201
|
+
node: schema,
|
|
202
|
+
canOverride,
|
|
203
|
+
name,
|
|
204
|
+
typeName,
|
|
205
|
+
filePath: meta.file.path,
|
|
206
|
+
typeFilePath: meta.typeFile.path,
|
|
207
|
+
})
|
|
70
208
|
|
|
71
209
|
return (
|
|
72
210
|
<>
|
|
73
|
-
{
|
|
211
|
+
{typeReference.importPath && <File.Import isTypeOnly root={meta.file.path} path={typeReference.importPath} name={[typeName]} />}
|
|
74
212
|
{imports.map((imp) => (
|
|
75
|
-
<File.Import key={[imp.path, imp.name
|
|
213
|
+
<File.Import key={[name, imp.path, imp.name].join('-')} root={meta.file.path} path={imp.path} name={imp.name} />
|
|
76
214
|
))}
|
|
77
215
|
<Faker
|
|
78
|
-
name={
|
|
79
|
-
typeName={
|
|
216
|
+
name={name}
|
|
217
|
+
typeName={typeReference.typeName}
|
|
80
218
|
description={description}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
dateParser={dateParser}
|
|
84
|
-
mapper={mapper}
|
|
219
|
+
node={schema}
|
|
220
|
+
printer={{ ...printerInstance, print: () => rewrittenFakerText }}
|
|
85
221
|
seed={seed}
|
|
86
222
|
canOverride={canOverride}
|
|
87
223
|
/>
|
|
@@ -91,79 +227,44 @@ export const fakerGenerator = createReactGenerator<PluginFaker>({
|
|
|
91
227
|
|
|
92
228
|
return (
|
|
93
229
|
<File
|
|
94
|
-
baseName={file.baseName}
|
|
95
|
-
path={file.path}
|
|
96
|
-
meta={file.meta}
|
|
97
|
-
banner={
|
|
98
|
-
footer={
|
|
230
|
+
baseName={meta.file.baseName}
|
|
231
|
+
path={meta.file.path}
|
|
232
|
+
meta={meta.file.meta}
|
|
233
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
234
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
99
235
|
>
|
|
100
|
-
<File.Import name={['faker']} path="@faker-js/faker" />
|
|
236
|
+
<File.Import name={locale ? [{ propertyName: localeToFakerImport(locale), name: 'faker' }] : ['faker']} path="@faker-js/faker" />
|
|
101
237
|
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
102
238
|
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
103
|
-
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
keyword === schemaKeywords.tuple ||
|
|
133
|
-
keyword === schemaKeywords.ref ||
|
|
134
|
-
keyword === schemaKeywords.enum ||
|
|
135
|
-
keyword === schemaKeywords.string ||
|
|
136
|
-
keyword === schemaKeywords.integer ||
|
|
137
|
-
keyword === schemaKeywords.number,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<File
|
|
142
|
-
baseName={faker.file.baseName}
|
|
143
|
-
path={faker.file.path}
|
|
144
|
-
meta={faker.file.meta}
|
|
145
|
-
banner={getBanner({ oas, output, config: driver.config })}
|
|
146
|
-
footer={getFooter({ oas, output })}
|
|
147
|
-
>
|
|
148
|
-
<File.Import name={['faker']} path="@faker-js/faker" />
|
|
149
|
-
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
150
|
-
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
151
|
-
<File.Import isTypeOnly root={faker.file.path} path={type.file.path} name={[type.name]} />
|
|
152
|
-
{imports.map((imp) => (
|
|
153
|
-
<File.Import key={[imp.path, imp.name, imp.isTypeOnly].join('-')} root={faker.file.path} path={imp.path} name={imp.name} />
|
|
154
|
-
))}
|
|
155
|
-
|
|
156
|
-
<Faker
|
|
157
|
-
name={faker.name}
|
|
158
|
-
typeName={type.name}
|
|
159
|
-
description={schema.value.description}
|
|
160
|
-
tree={schema.tree}
|
|
161
|
-
regexGenerator={regexGenerator}
|
|
162
|
-
dateParser={dateParser}
|
|
163
|
-
mapper={mapper}
|
|
164
|
-
seed={seed}
|
|
165
|
-
canOverride={canOverride}
|
|
166
|
-
/>
|
|
239
|
+
{paramEntries.map(({ param, name, typeName }) =>
|
|
240
|
+
renderEntry({
|
|
241
|
+
schema: param.schema,
|
|
242
|
+
name,
|
|
243
|
+
typeName,
|
|
244
|
+
}),
|
|
245
|
+
)}
|
|
246
|
+
{responseEntries.map(({ response, name, typeName }) =>
|
|
247
|
+
renderEntry({
|
|
248
|
+
schema: response.schema,
|
|
249
|
+
name,
|
|
250
|
+
typeName,
|
|
251
|
+
description: response.description,
|
|
252
|
+
}),
|
|
253
|
+
)}
|
|
254
|
+
{dataEntry
|
|
255
|
+
? renderEntry({
|
|
256
|
+
schema: dataEntry.schema,
|
|
257
|
+
name: dataEntry.name,
|
|
258
|
+
typeName: dataEntry.typeName,
|
|
259
|
+
description: dataEntry.description,
|
|
260
|
+
})
|
|
261
|
+
: null}
|
|
262
|
+
{renderEntry({
|
|
263
|
+
schema: buildResponseUnionSchema(node, resolver),
|
|
264
|
+
name: responseName,
|
|
265
|
+
typeName: tsResolver.resolveResponseName(node),
|
|
266
|
+
skipImportNames: responseEntries.map(({ name }) => name),
|
|
267
|
+
})}
|
|
167
268
|
</File>
|
|
168
269
|
)
|
|
169
270
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export
|
|
1
|
+
export { Faker } from './components/Faker.tsx'
|
|
2
|
+
export { fakerGenerator } from './generators/fakerGenerator.tsx'
|
|
3
|
+
export { default, pluginFaker, pluginFakerName } from './plugin.ts'
|
|
4
|
+
export type { PrinterFakerFactory, PrinterFakerNodes, PrinterFakerOptions } from './printers/printerFaker.ts'
|
|
5
|
+
export { printerFaker } from './printers/printerFaker.ts'
|
|
6
|
+
export { resolverFaker } from './resolvers/resolverFaker.ts'
|
|
7
|
+
export type { PluginFaker, ResolverFaker } from './types.ts'
|
package/src/plugin.ts
CHANGED
|
@@ -1,149 +1,88 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
1
|
import { camelCase } from '@internals/utils'
|
|
3
|
-
import {
|
|
4
|
-
import { OperationGenerator, pluginOasName, SchemaGenerator } from '@kubb/plugin-oas'
|
|
2
|
+
import { definePlugin, type Group } from '@kubb/core'
|
|
5
3
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
6
4
|
import { fakerGenerator } from './generators/fakerGenerator.tsx'
|
|
5
|
+
import { resolverFaker } from './resolvers/resolverFaker.ts'
|
|
7
6
|
import type { PluginFaker } from './types.ts'
|
|
8
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Canonical plugin name for `@kubb/plugin-faker`, used in driver lookups and warnings.
|
|
10
|
+
*/
|
|
9
11
|
export const pluginFakerName = 'plugin-faker' satisfies PluginFaker['name']
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Generates Faker mock data factories from OpenAPI/AST specification.
|
|
15
|
+
*
|
|
16
|
+
* Creates randomized test data and mock helpers from schema definitions.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* `import pluginFaker from '@kubb/plugin-faker'; export default defineConfig({ plugins: [pluginFaker({ output: { path: 'mocks' } })], })`
|
|
20
|
+
*/
|
|
21
|
+
export const pluginFaker = definePlugin<PluginFaker>((options) => {
|
|
12
22
|
const {
|
|
13
23
|
output = { path: 'mocks', barrelType: 'named' },
|
|
14
24
|
seed,
|
|
25
|
+
locale,
|
|
15
26
|
group,
|
|
16
27
|
exclude = [],
|
|
17
28
|
include,
|
|
18
29
|
override = [],
|
|
19
|
-
transformers = {},
|
|
20
30
|
mapper = {},
|
|
21
|
-
unknownType = 'any',
|
|
22
|
-
emptySchemaType = unknownType,
|
|
23
|
-
dateType = 'string',
|
|
24
|
-
integerType = 'number',
|
|
25
31
|
dateParser = 'faker',
|
|
26
|
-
generators = [
|
|
32
|
+
generators: userGenerators = [],
|
|
27
33
|
regexGenerator = 'faker',
|
|
28
34
|
paramsCasing,
|
|
29
|
-
|
|
35
|
+
printer,
|
|
36
|
+
resolver: userResolver,
|
|
37
|
+
transformer: userTransformer,
|
|
30
38
|
} = options
|
|
31
39
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
name: pluginFakerName,
|
|
37
|
-
options: {
|
|
38
|
-
output,
|
|
39
|
-
transformers,
|
|
40
|
-
seed,
|
|
41
|
-
dateType,
|
|
42
|
-
integerType,
|
|
43
|
-
unknownType,
|
|
44
|
-
emptySchemaType,
|
|
45
|
-
dateParser,
|
|
46
|
-
mapper,
|
|
47
|
-
override,
|
|
48
|
-
regexGenerator,
|
|
49
|
-
paramsCasing,
|
|
50
|
-
group,
|
|
51
|
-
usedEnumNames,
|
|
52
|
-
},
|
|
53
|
-
pre: [pluginOasName, pluginTsName],
|
|
54
|
-
resolvePath(baseName, pathMode, options) {
|
|
55
|
-
const root = path.resolve(this.config.root, this.config.output.path)
|
|
56
|
-
const mode = pathMode ?? getMode(path.resolve(root, output.path))
|
|
57
|
-
|
|
58
|
-
if (mode === 'single') {
|
|
59
|
-
/**
|
|
60
|
-
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
61
|
-
* Other plugins then need to call addOrAppend instead of just add from the fileManager class
|
|
62
|
-
*/
|
|
63
|
-
return path.resolve(root, output.path)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (group && (options?.group?.path || options?.group?.tag)) {
|
|
67
|
-
const groupName: Group['name'] = group?.name
|
|
40
|
+
const groupConfig = group
|
|
41
|
+
? ({
|
|
42
|
+
...group,
|
|
43
|
+
name: group.name
|
|
68
44
|
? group.name
|
|
69
|
-
: (ctx) => {
|
|
70
|
-
if (group
|
|
45
|
+
: (ctx: { group: string }) => {
|
|
46
|
+
if (group.type === 'path') {
|
|
71
47
|
return `${ctx.group.split('/')[1]}`
|
|
72
48
|
}
|
|
73
|
-
return `${camelCase(ctx.group)}Controller`
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return path.resolve(
|
|
77
|
-
root,
|
|
78
|
-
output.path,
|
|
79
|
-
groupName({
|
|
80
|
-
group: group.type === 'path' ? options.group.path! : options.group.tag!,
|
|
81
|
-
}),
|
|
82
|
-
baseName,
|
|
83
|
-
)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return path.resolve(root, output.path, baseName)
|
|
87
|
-
},
|
|
88
|
-
resolveName(name, type) {
|
|
89
|
-
const resolvedName = camelCase(name, {
|
|
90
|
-
prefix: type ? 'create' : undefined,
|
|
91
|
-
isFile: type === 'file',
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
if (type) {
|
|
95
|
-
return transformers?.name?.(resolvedName, type) || resolvedName
|
|
96
|
-
}
|
|
97
49
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const mode = getMode(path.resolve(root, output.path))
|
|
103
|
-
const oas = await this.getOas()
|
|
104
|
-
|
|
105
|
-
const schemaGenerator = new SchemaGenerator(this.plugin.options, {
|
|
106
|
-
fabric: this.fabric,
|
|
107
|
-
oas,
|
|
108
|
-
driver: this.driver,
|
|
109
|
-
events: this.events,
|
|
110
|
-
plugin: this.plugin,
|
|
111
|
-
contentType,
|
|
112
|
-
include: undefined,
|
|
113
|
-
override,
|
|
114
|
-
mode,
|
|
115
|
-
output: output.path,
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
const schemaFiles = await schemaGenerator.build(...generators)
|
|
119
|
-
await this.upsertFile(...schemaFiles)
|
|
120
|
-
|
|
121
|
-
const operationGenerator = new OperationGenerator(this.plugin.options, {
|
|
122
|
-
fabric: this.fabric,
|
|
123
|
-
oas,
|
|
124
|
-
driver: this.driver,
|
|
125
|
-
events: this.events,
|
|
126
|
-
plugin: this.plugin,
|
|
127
|
-
contentType,
|
|
128
|
-
exclude,
|
|
129
|
-
include,
|
|
130
|
-
override,
|
|
131
|
-
mode,
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
const operationFiles = await operationGenerator.build(...generators)
|
|
135
|
-
await this.upsertFile(...operationFiles)
|
|
136
|
-
|
|
137
|
-
const barrelFiles = await getBarrelFiles(this.fabric.files, {
|
|
138
|
-
type: output.barrelType ?? 'named',
|
|
139
|
-
root,
|
|
140
|
-
output,
|
|
141
|
-
meta: {
|
|
142
|
-
pluginName: this.plugin.name,
|
|
143
|
-
},
|
|
144
|
-
})
|
|
50
|
+
return `${camelCase(ctx.group)}Controller`
|
|
51
|
+
},
|
|
52
|
+
} satisfies Group)
|
|
53
|
+
: undefined
|
|
145
54
|
|
|
146
|
-
|
|
55
|
+
return {
|
|
56
|
+
name: pluginFakerName,
|
|
57
|
+
options,
|
|
58
|
+
dependencies: [pluginTsName],
|
|
59
|
+
hooks: {
|
|
60
|
+
'kubb:plugin:setup'(ctx) {
|
|
61
|
+
ctx.setOptions({
|
|
62
|
+
output,
|
|
63
|
+
seed,
|
|
64
|
+
locale,
|
|
65
|
+
exclude,
|
|
66
|
+
include,
|
|
67
|
+
override,
|
|
68
|
+
group: groupConfig,
|
|
69
|
+
mapper,
|
|
70
|
+
dateParser,
|
|
71
|
+
regexGenerator,
|
|
72
|
+
paramsCasing,
|
|
73
|
+
printer,
|
|
74
|
+
})
|
|
75
|
+
ctx.setResolver(userResolver ? { ...resolverFaker, ...userResolver } : resolverFaker)
|
|
76
|
+
if (userTransformer) {
|
|
77
|
+
ctx.setTransformer(userTransformer)
|
|
78
|
+
}
|
|
79
|
+
ctx.addGenerator(fakerGenerator)
|
|
80
|
+
for (const generator of userGenerators) {
|
|
81
|
+
ctx.addGenerator(generator)
|
|
82
|
+
}
|
|
83
|
+
},
|
|
147
84
|
},
|
|
148
85
|
}
|
|
149
86
|
})
|
|
87
|
+
|
|
88
|
+
export default pluginFaker
|