@kubb/plugin-faker 3.0.0-alpha.9 → 3.0.0-beta.10
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/README.md +14 -5
- package/dist/chunk-FCIZHQ4X.cjs +339 -0
- package/dist/chunk-FCIZHQ4X.cjs.map +1 -0
- package/dist/chunk-OOL6ZKDZ.cjs +115 -0
- package/dist/chunk-OOL6ZKDZ.cjs.map +1 -0
- package/dist/chunk-PLVSF3YP.js +333 -0
- package/dist/chunk-PLVSF3YP.js.map +1 -0
- package/dist/chunk-ZOJMDISS.js +113 -0
- package/dist/chunk-ZOJMDISS.js.map +1 -0
- package/dist/components.cjs +6 -556
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +15 -18
- package/dist/components.d.ts +15 -18
- package/dist/components.js +2 -561
- package/dist/components.js.map +1 -1
- package/dist/generators.cjs +13 -0
- package/dist/generators.cjs.map +1 -0
- package/dist/generators.d.cts +8 -0
- package/dist/generators.d.ts +8 -0
- package/dist/generators.js +4 -0
- package/dist/generators.js.map +1 -0
- package/dist/index.cjs +51 -500
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -125
- package/dist/index.d.ts +4 -125
- package/dist/index.js +38 -494
- package/dist/index.js.map +1 -1
- package/dist/types-Cq8z4Gto.d.cts +95 -0
- package/dist/types-Cq8z4Gto.d.ts +95 -0
- package/package.json +20 -16
- package/src/components/Faker.tsx +82 -0
- package/src/components/index.ts +1 -2
- package/src/generators/__snapshots__/createPet.ts +26 -0
- package/src/generators/__snapshots__/createPetSeed.ts +30 -0
- package/src/generators/__snapshots__/createPetUnknownTypeAny.ts +26 -0
- package/src/generators/__snapshots__/deletePet.ts +3 -0
- package/src/generators/__snapshots__/enumNames.ts +5 -0
- package/src/generators/__snapshots__/enumVarNames.ts +5 -0
- package/src/generators/__snapshots__/getPets.ts +26 -0
- package/src/generators/__snapshots__/pet.ts +8 -0
- package/src/generators/__snapshots__/petWithDateString.ts +8 -0
- package/src/generators/__snapshots__/petWithDayjs.ts +9 -0
- package/src/generators/__snapshots__/petWithMapper.ts +8 -0
- package/src/generators/__snapshots__/petWithRandExp.ts +9 -0
- package/src/generators/__snapshots__/pets.ts +8 -0
- package/src/generators/__snapshots__/showPetById.ts +26 -0
- package/src/generators/fakerGenerator.tsx +140 -0
- package/src/generators/index.ts +1 -0
- package/src/parser/index.ts +55 -17
- package/src/plugin.ts +29 -37
- package/src/types.ts +29 -67
- package/src/OperationGenerator.tsx +0 -31
- package/src/SchemaGenerator.tsx +0 -31
- package/src/components/OperationSchema.tsx +0 -82
- package/src/components/Schema.tsx +0 -144
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { faker } from "@faker-js/faker";
|
|
2
|
+
|
|
3
|
+
export function showPetByIdPathParams(data?: Partial<ShowPetByIdPathParams>) {
|
|
4
|
+
return {
|
|
5
|
+
...{ "petId": faker.string.alpha(), "testId": faker.string.alpha() },
|
|
6
|
+
...data || {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description Expected response to a valid request
|
|
12
|
+
*/
|
|
13
|
+
export function showPetById200() {
|
|
14
|
+
return pet();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @description unexpected error
|
|
19
|
+
*/
|
|
20
|
+
export function showPetByIdError() {
|
|
21
|
+
return error();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function showPetByIdQueryResponse(data?: Partial<ShowPetByIdQueryResponse>) {
|
|
25
|
+
return faker.helpers.arrayElement<any>([showPetById200()]) || data;
|
|
26
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type OperationSchema as OperationSchemaType, SchemaGenerator, createReactGenerator, schemaKeywords } from '@kubb/plugin-oas'
|
|
2
|
+
import { Oas } from '@kubb/plugin-oas/components'
|
|
3
|
+
import { useOas, useOperationManager, useSchemaManager } from '@kubb/plugin-oas/hooks'
|
|
4
|
+
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
|
+
import { File, useApp } from '@kubb/react'
|
|
6
|
+
import { Faker } from '../components'
|
|
7
|
+
import type { PluginFaker } from '../types'
|
|
8
|
+
|
|
9
|
+
export const fakerGenerator = createReactGenerator<PluginFaker>({
|
|
10
|
+
name: 'faker',
|
|
11
|
+
Operation({ operation, options }) {
|
|
12
|
+
const { dateParser, regexGenerator, seed, mapper } = options
|
|
13
|
+
|
|
14
|
+
const { plugin, pluginManager, mode } = useApp<PluginFaker>()
|
|
15
|
+
const oas = useOas()
|
|
16
|
+
const { getSchemas, getFile } = useOperationManager()
|
|
17
|
+
const schemaManager = useSchemaManager()
|
|
18
|
+
|
|
19
|
+
const file = getFile(operation)
|
|
20
|
+
const schemas = getSchemas(operation)
|
|
21
|
+
const schemaGenerator = new SchemaGenerator(options, {
|
|
22
|
+
oas,
|
|
23
|
+
plugin,
|
|
24
|
+
pluginManager,
|
|
25
|
+
mode,
|
|
26
|
+
override: options.override,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const operationSchemas = [schemas.pathParams, schemas.queryParams, schemas.headerParams, schemas.statusCodes, schemas.request, schemas.response]
|
|
30
|
+
.flat()
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
|
|
33
|
+
const mapOperationSchema = ({ name, schema, description, ...options }: OperationSchemaType, i: number) => {
|
|
34
|
+
const tree = schemaGenerator.parse({ schema, name })
|
|
35
|
+
const imports = schemaManager.getImports(tree)
|
|
36
|
+
|
|
37
|
+
const faker = {
|
|
38
|
+
name: schemaManager.getName(name, { type: 'function' }),
|
|
39
|
+
file: schemaManager.getFile(name),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const type = {
|
|
43
|
+
name: schemaManager.getName(name, { type: 'type', pluginKey: [pluginTsName] }),
|
|
44
|
+
file: schemaManager.getFile(options.operationName || name, { pluginKey: [pluginTsName], tag: options.operation?.getTags()[0]?.name }),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const canOverride = tree.some(
|
|
48
|
+
({ keyword }) =>
|
|
49
|
+
keyword === schemaKeywords.array ||
|
|
50
|
+
keyword === schemaKeywords.and ||
|
|
51
|
+
keyword === schemaKeywords.object ||
|
|
52
|
+
keyword === schemaKeywords.union ||
|
|
53
|
+
keyword === schemaKeywords.tuple,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Oas.Schema key={i} name={name} value={schema} tree={tree}>
|
|
58
|
+
{canOverride && <File.Import isTypeOnly root={file.path} path={type.file.path} name={[type.name]} />}
|
|
59
|
+
{imports.map((imp, index) => (
|
|
60
|
+
<File.Import key={index} root={file.path} path={imp.path} name={imp.name} />
|
|
61
|
+
))}
|
|
62
|
+
<Faker
|
|
63
|
+
name={faker.name}
|
|
64
|
+
typeName={type.name}
|
|
65
|
+
description={description}
|
|
66
|
+
tree={tree}
|
|
67
|
+
regexGenerator={regexGenerator}
|
|
68
|
+
dateParser={dateParser}
|
|
69
|
+
mapper={mapper}
|
|
70
|
+
seed={seed}
|
|
71
|
+
canOverride={canOverride}
|
|
72
|
+
/>
|
|
73
|
+
</Oas.Schema>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<File baseName={file.baseName} path={file.path} meta={file.meta} banner={plugin.options.output?.banner} footer={plugin.options.output?.footer}>
|
|
79
|
+
<File.Import name={['faker']} path="@faker-js/faker" />
|
|
80
|
+
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
81
|
+
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
82
|
+
{operationSchemas.map(mapOperationSchema)}
|
|
83
|
+
</File>
|
|
84
|
+
)
|
|
85
|
+
},
|
|
86
|
+
Schema({ schema, options }) {
|
|
87
|
+
const { dateParser, regexGenerator, seed, mapper } = options
|
|
88
|
+
|
|
89
|
+
const { getName, getFile, getImports } = useSchemaManager()
|
|
90
|
+
const {
|
|
91
|
+
plugin: {
|
|
92
|
+
options: { output },
|
|
93
|
+
},
|
|
94
|
+
} = useApp<PluginFaker>()
|
|
95
|
+
const imports = getImports(schema.tree)
|
|
96
|
+
|
|
97
|
+
const faker = {
|
|
98
|
+
name: getName(schema.name, { type: 'function' }),
|
|
99
|
+
file: getFile(schema.name),
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const type = {
|
|
103
|
+
name: getName(schema.name, { type: 'type', pluginKey: [pluginTsName] }),
|
|
104
|
+
file: getFile(schema.name, { pluginKey: [pluginTsName] }),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const canOverride = schema.tree.some(
|
|
108
|
+
({ keyword }) =>
|
|
109
|
+
keyword === schemaKeywords.array ||
|
|
110
|
+
keyword === schemaKeywords.and ||
|
|
111
|
+
keyword === schemaKeywords.object ||
|
|
112
|
+
keyword === schemaKeywords.union ||
|
|
113
|
+
keyword === schemaKeywords.tuple,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<File baseName={faker.file.baseName} path={faker.file.path} meta={faker.file.meta} banner={output?.banner} footer={output?.footer}>
|
|
118
|
+
<File.Import name={['faker']} path="@faker-js/faker" />
|
|
119
|
+
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
120
|
+
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
121
|
+
<File.Import isTypeOnly root={faker.file.path} path={type.file.path} name={[type.name]} />
|
|
122
|
+
{imports.map((imp, index) => (
|
|
123
|
+
<File.Import key={index} root={faker.file.path} path={imp.path} name={imp.name} />
|
|
124
|
+
))}
|
|
125
|
+
|
|
126
|
+
<Faker
|
|
127
|
+
name={faker.name}
|
|
128
|
+
typeName={type.name}
|
|
129
|
+
description={schema.value.description}
|
|
130
|
+
tree={schema.tree}
|
|
131
|
+
regexGenerator={regexGenerator}
|
|
132
|
+
dateParser={dateParser}
|
|
133
|
+
mapper={mapper}
|
|
134
|
+
seed={seed}
|
|
135
|
+
canOverride={canOverride}
|
|
136
|
+
/>
|
|
137
|
+
</File>
|
|
138
|
+
)
|
|
139
|
+
},
|
|
140
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fakerGenerator } from './fakerGenerator.tsx'
|
package/src/parser/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import transformers from '@kubb/core/transformers'
|
|
2
|
-
import { SchemaGenerator, isKeyword, schemaKeywords } from '@kubb/plugin-oas'
|
|
2
|
+
import { SchemaGenerator, type SchemaTree, isKeyword, schemaKeywords } from '@kubb/plugin-oas'
|
|
3
3
|
|
|
4
4
|
import type { Schema, SchemaKeywordBase, SchemaKeywordMapper, SchemaMapper } from '@kubb/plugin-oas'
|
|
5
5
|
import type { Options } from '../types.ts'
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const fakerKeywordMapper = {
|
|
8
8
|
any: () => 'undefined',
|
|
9
9
|
unknown: () => 'unknown',
|
|
10
10
|
number: (min?: number, max?: number) => {
|
|
@@ -55,7 +55,24 @@ export const fakerKeywordMapper = {
|
|
|
55
55
|
boolean: () => 'faker.datatype.boolean()',
|
|
56
56
|
undefined: () => 'undefined',
|
|
57
57
|
null: () => 'null',
|
|
58
|
-
array: (items: string[] = []
|
|
58
|
+
array: (items: string[] = [], min?: number, max?: number) => {
|
|
59
|
+
if (items.length > 1) {
|
|
60
|
+
return `faker.helpers.arrayElements([${items.join(', ')}]) as any`
|
|
61
|
+
}
|
|
62
|
+
const item = items.at(0)
|
|
63
|
+
|
|
64
|
+
if (min !== undefined && max !== undefined) {
|
|
65
|
+
return `faker.helpers.multiple(() => (${item}), { count: { min: ${min}, max: ${max} }}) as any`
|
|
66
|
+
}
|
|
67
|
+
if (min !== undefined) {
|
|
68
|
+
return `faker.helpers.multiple(() => (${item}), { count: ${min} }) as any`
|
|
69
|
+
}
|
|
70
|
+
if (max !== undefined) {
|
|
71
|
+
return `faker.helpers.multiple(() => (${item}), { count: { min: 0, max: ${max} }}) as any`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return `faker.helpers.multiple(() => (${item})) as any`
|
|
75
|
+
},
|
|
59
76
|
tuple: (items: string[] = []) => `faker.helpers.arrayElements([${items.join(', ')}]) as any`,
|
|
60
77
|
enum: (items: Array<string | number> = []) => `faker.helpers.arrayElement<any>([${items.join(', ')}])`,
|
|
61
78
|
union: (items: string[] = []) => `faker.helpers.arrayElement<any>([${items.join(', ')}])`,
|
|
@@ -68,13 +85,18 @@ export const fakerKeywordMapper = {
|
|
|
68
85
|
* Type `'string'` ISO date format (YYYY-MM-DD)
|
|
69
86
|
* @default ISO date format (YYYY-MM-DD)
|
|
70
87
|
*/
|
|
71
|
-
date: (type: 'date' | 'string' = 'string', parser
|
|
88
|
+
date: (type: 'date' | 'string' = 'string', parser: Options['dateParser'] = 'faker') => {
|
|
72
89
|
if (type === 'string') {
|
|
73
|
-
if (parser) {
|
|
90
|
+
if (parser !== 'faker') {
|
|
74
91
|
return `${parser}(faker.date.anytime()).format("YYYY-MM-DD")`
|
|
75
92
|
}
|
|
76
93
|
return 'faker.date.anytime().toString()'
|
|
77
94
|
}
|
|
95
|
+
|
|
96
|
+
if (parser !== 'faker') {
|
|
97
|
+
throw new Error(`type '${type}' and parser '${parser}' can not work together`)
|
|
98
|
+
}
|
|
99
|
+
|
|
78
100
|
return 'faker.date.anytime()'
|
|
79
101
|
},
|
|
80
102
|
/**
|
|
@@ -82,13 +104,18 @@ export const fakerKeywordMapper = {
|
|
|
82
104
|
* Type `'string'` ISO time format (HH:mm:ss[.SSSSSS])
|
|
83
105
|
* @default ISO time format (HH:mm:ss[.SSSSSS])
|
|
84
106
|
*/
|
|
85
|
-
time: (type: 'date' | 'string' = 'string', parser
|
|
107
|
+
time: (type: 'date' | 'string' = 'string', parser: Options['dateParser'] = 'faker') => {
|
|
86
108
|
if (type === 'string') {
|
|
87
|
-
if (parser) {
|
|
109
|
+
if (parser !== 'faker') {
|
|
88
110
|
return `${parser}(faker.date.anytime()).format("HH:mm:ss")`
|
|
89
111
|
}
|
|
90
112
|
return 'faker.date.anytime().toString()'
|
|
91
113
|
}
|
|
114
|
+
|
|
115
|
+
if (parser !== 'faker') {
|
|
116
|
+
throw new Error(`type '${type}' and parser '${parser}' can not work together`)
|
|
117
|
+
}
|
|
118
|
+
|
|
92
119
|
return 'faker.date.anytime()'
|
|
93
120
|
},
|
|
94
121
|
uuid: () => 'faker.string.uuid()',
|
|
@@ -107,7 +134,7 @@ export const fakerKeywordMapper = {
|
|
|
107
134
|
lastName: () => 'faker.person.lastName()',
|
|
108
135
|
password: () => 'faker.internet.password()',
|
|
109
136
|
phone: () => 'faker.phone.number()',
|
|
110
|
-
blob: () => 'faker.image.
|
|
137
|
+
blob: () => 'faker.image.url() as unknown as Blob',
|
|
111
138
|
default: undefined,
|
|
112
139
|
describe: undefined,
|
|
113
140
|
const: (value?: string | number) => (value as string) ?? '',
|
|
@@ -117,6 +144,7 @@ export const fakerKeywordMapper = {
|
|
|
117
144
|
nullish: undefined,
|
|
118
145
|
optional: undefined,
|
|
119
146
|
readOnly: undefined,
|
|
147
|
+
writeOnly: undefined,
|
|
120
148
|
strict: undefined,
|
|
121
149
|
deprecated: undefined,
|
|
122
150
|
example: undefined,
|
|
@@ -155,12 +183,12 @@ type ParserOptions = {
|
|
|
155
183
|
|
|
156
184
|
seed?: number | number[]
|
|
157
185
|
regexGenerator?: 'faker' | 'randexp'
|
|
158
|
-
|
|
186
|
+
canOverride?: boolean
|
|
159
187
|
dateParser?: Options['dateParser']
|
|
160
188
|
mapper?: Record<string, string>
|
|
161
189
|
}
|
|
162
190
|
|
|
163
|
-
export function parse(parent
|
|
191
|
+
export function parse({ parent, current, siblings }: SchemaTree, options: ParserOptions): string | null | undefined {
|
|
164
192
|
const value = fakerKeywordMapper[current.keyword as keyof typeof fakerKeywordMapper]
|
|
165
193
|
|
|
166
194
|
if (!value) {
|
|
@@ -168,15 +196,23 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
168
196
|
}
|
|
169
197
|
|
|
170
198
|
if (isKeyword(current, schemaKeywords.union)) {
|
|
171
|
-
return fakerKeywordMapper.union(
|
|
199
|
+
return fakerKeywordMapper.union(
|
|
200
|
+
current.args.map((schema) => parse({ parent: current, current: schema, siblings }, { ...options, canOverride: false })).filter(Boolean),
|
|
201
|
+
)
|
|
172
202
|
}
|
|
173
203
|
|
|
174
204
|
if (isKeyword(current, schemaKeywords.and)) {
|
|
175
|
-
return fakerKeywordMapper.and(
|
|
205
|
+
return fakerKeywordMapper.and(
|
|
206
|
+
current.args.map((schema) => parse({ parent: current, current: schema, siblings }, { ...options, canOverride: false })).filter(Boolean),
|
|
207
|
+
)
|
|
176
208
|
}
|
|
177
209
|
|
|
178
210
|
if (isKeyword(current, schemaKeywords.array)) {
|
|
179
|
-
return fakerKeywordMapper.array(
|
|
211
|
+
return fakerKeywordMapper.array(
|
|
212
|
+
current.args.items.map((schema) => parse({ parent: current, current: schema, siblings }, { ...options, canOverride: false })).filter(Boolean),
|
|
213
|
+
current.args.min,
|
|
214
|
+
current.args.max,
|
|
215
|
+
)
|
|
180
216
|
}
|
|
181
217
|
|
|
182
218
|
if (isKeyword(current, schemaKeywords.enum)) {
|
|
@@ -195,7 +231,7 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
195
231
|
throw new Error(`Name not defined for keyword ${current.keyword}`)
|
|
196
232
|
}
|
|
197
233
|
|
|
198
|
-
if (options.
|
|
234
|
+
if (options.canOverride) {
|
|
199
235
|
return `${current.args.name}(data)`
|
|
200
236
|
}
|
|
201
237
|
|
|
@@ -220,7 +256,7 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
220
256
|
return `"${name}": ${joinItems(
|
|
221
257
|
schemas
|
|
222
258
|
.sort(schemaKeywordsorter)
|
|
223
|
-
.map((schema) => parse(current, schema, { ...options,
|
|
259
|
+
.map((schema) => parse({ parent: current, current: schema, siblings }, { ...options, canOverride: false }))
|
|
224
260
|
.filter(Boolean),
|
|
225
261
|
)}`
|
|
226
262
|
})
|
|
@@ -231,10 +267,12 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
231
267
|
|
|
232
268
|
if (isKeyword(current, schemaKeywords.tuple)) {
|
|
233
269
|
if (Array.isArray(current.args.items)) {
|
|
234
|
-
return fakerKeywordMapper.tuple(
|
|
270
|
+
return fakerKeywordMapper.tuple(
|
|
271
|
+
current.args.items.map((schema) => parse({ parent: current, current: schema, siblings }, { ...options, canOverride: false })).filter(Boolean),
|
|
272
|
+
)
|
|
235
273
|
}
|
|
236
274
|
|
|
237
|
-
return parse(current, current.args.items, { ...options,
|
|
275
|
+
return parse({ parent: current, current: current.args.items, siblings }, { ...options, canOverride: false })
|
|
238
276
|
}
|
|
239
277
|
|
|
240
278
|
if (isKeyword(current, schemaKeywords.const)) {
|
package/src/plugin.ts
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
|
|
3
|
-
import { FileManager, PluginManager, createPlugin } from '@kubb/core'
|
|
3
|
+
import { FileManager, type Group, PluginManager, createPlugin } from '@kubb/core'
|
|
4
4
|
import { camelCase } from '@kubb/core/transformers'
|
|
5
|
-
import {
|
|
6
|
-
import { pluginOasName } from '@kubb/plugin-oas'
|
|
5
|
+
import { OperationGenerator, SchemaGenerator, pluginOasName } from '@kubb/plugin-oas'
|
|
7
6
|
|
|
8
7
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
9
8
|
|
|
10
|
-
import { OperationGenerator } from './OperationGenerator.tsx'
|
|
11
|
-
import { SchemaGenerator } from './SchemaGenerator.tsx'
|
|
12
|
-
|
|
13
9
|
import type { Plugin } from '@kubb/core'
|
|
14
10
|
import type { PluginOas } from '@kubb/plugin-oas'
|
|
11
|
+
import { fakerGenerator } from './generators/fakerGenerator.tsx'
|
|
15
12
|
import type { PluginFaker } from './types.ts'
|
|
16
13
|
|
|
17
14
|
export const pluginFakerName = 'plugin-faker' satisfies PluginFaker['name']
|
|
18
15
|
|
|
19
16
|
export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
20
17
|
const {
|
|
21
|
-
output = { path: 'mocks' },
|
|
18
|
+
output = { path: 'mocks', barrelType: 'named' },
|
|
22
19
|
seed,
|
|
23
20
|
group,
|
|
24
21
|
exclude = [],
|
|
@@ -26,24 +23,20 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
26
23
|
override = [],
|
|
27
24
|
transformers = {},
|
|
28
25
|
mapper = {},
|
|
29
|
-
dateType = 'string',
|
|
30
26
|
unknownType = 'any',
|
|
31
|
-
|
|
27
|
+
dateType = 'string',
|
|
28
|
+
dateParser = 'faker',
|
|
29
|
+
generators = [fakerGenerator].filter(Boolean),
|
|
32
30
|
regexGenerator = 'faker',
|
|
33
31
|
} = options
|
|
34
|
-
const template = group?.output ? group.output : `${output.path}/{{tag}}Controller`
|
|
35
32
|
|
|
36
33
|
return {
|
|
37
34
|
name: pluginFakerName,
|
|
38
|
-
output: {
|
|
39
|
-
exportType: 'barrelNamed',
|
|
40
|
-
...output,
|
|
41
|
-
},
|
|
42
35
|
options: {
|
|
43
|
-
|
|
36
|
+
output,
|
|
44
37
|
transformers,
|
|
45
|
-
dateType,
|
|
46
38
|
seed,
|
|
39
|
+
dateType,
|
|
47
40
|
unknownType,
|
|
48
41
|
dateParser,
|
|
49
42
|
mapper,
|
|
@@ -55,6 +48,12 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
55
48
|
const root = path.resolve(this.config.root, this.config.output.path)
|
|
56
49
|
const mode = pathMode ?? FileManager.getMode(path.resolve(root, output.path))
|
|
57
50
|
|
|
51
|
+
if (options?.tag && group?.type === 'tag') {
|
|
52
|
+
const groupName: Group['name'] = group?.name ? group.name : (ctx) => `${ctx.group}Controller`
|
|
53
|
+
|
|
54
|
+
return path.resolve(root, output.path, groupName({ group: camelCase(options.tag) }), baseName)
|
|
55
|
+
}
|
|
56
|
+
|
|
58
57
|
if (mode === 'single') {
|
|
59
58
|
/**
|
|
60
59
|
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
@@ -63,12 +62,6 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
63
62
|
return path.resolve(root, output.path)
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
if (options?.tag && group?.type === 'tag') {
|
|
67
|
-
const tag = camelCase(options.tag)
|
|
68
|
-
|
|
69
|
-
return path.resolve(root, renderTemplate(template, { tag }), baseName)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
65
|
return path.resolve(root, output.path, baseName)
|
|
73
66
|
},
|
|
74
67
|
resolveName(name, type) {
|
|
@@ -101,7 +94,7 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
101
94
|
output: output.path,
|
|
102
95
|
})
|
|
103
96
|
|
|
104
|
-
const schemaFiles = await schemaGenerator.build()
|
|
97
|
+
const schemaFiles = await schemaGenerator.build(...generators)
|
|
105
98
|
await this.addFile(...schemaFiles)
|
|
106
99
|
|
|
107
100
|
const operationGenerator = new OperationGenerator(this.plugin.options, {
|
|
@@ -115,22 +108,21 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
115
108
|
mode,
|
|
116
109
|
})
|
|
117
110
|
|
|
118
|
-
const operationFiles = await operationGenerator.build()
|
|
111
|
+
const operationFiles = await operationGenerator.build(...generators)
|
|
119
112
|
await this.addFile(...operationFiles)
|
|
120
113
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
114
|
+
const barrelFiles = await this.fileManager.getBarrelFiles({
|
|
115
|
+
type: output.barrelType ?? 'named',
|
|
116
|
+
root,
|
|
117
|
+
output,
|
|
118
|
+
files: this.fileManager.files,
|
|
119
|
+
meta: {
|
|
120
|
+
pluginKey: this.plugin.key,
|
|
121
|
+
},
|
|
122
|
+
logger: this.logger,
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
await this.addFile(...barrelFiles)
|
|
134
126
|
},
|
|
135
127
|
}
|
|
136
128
|
})
|
package/src/types.ts
CHANGED
|
@@ -1,54 +1,18 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type * as KubbFile from '@kubb/fs/types'
|
|
1
|
+
import type { Group, Output, PluginFactoryOptions, ResolveNameParams } from '@kubb/core'
|
|
3
2
|
|
|
4
3
|
import type { SchemaObject } from '@kubb/oas'
|
|
5
|
-
import type { Exclude, Include, Override, ResolvePathOptions, Schema } from '@kubb/plugin-oas'
|
|
4
|
+
import type { Exclude, Generator, Include, Override, ResolvePathOptions, Schema } from '@kubb/plugin-oas'
|
|
6
5
|
|
|
7
6
|
export type Options = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
path: string
|
|
15
|
-
/**
|
|
16
|
-
* Name to be used for the `export * as {{exportAs}} from './'`
|
|
17
|
-
*/
|
|
18
|
-
exportAs?: string
|
|
19
|
-
/**
|
|
20
|
-
* Add an extension to the generated imports and exports, default it will not use an extension
|
|
21
|
-
*/
|
|
22
|
-
extName?: KubbFile.Extname
|
|
23
|
-
/**
|
|
24
|
-
* Define what needs to exported, here you can also disable the export of barrel files
|
|
25
|
-
* @default `'barrel'`
|
|
26
|
-
*/
|
|
27
|
-
exportType?: 'barrel' | 'barrelNamed' | false
|
|
28
|
-
}
|
|
29
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Specify the export location for the files and define the behavior of the output
|
|
9
|
+
* @default { path: 'handlers', barrelType: 'named' }
|
|
10
|
+
*/
|
|
11
|
+
output?: Output
|
|
30
12
|
/**
|
|
31
13
|
* Group the Faker mocks based on the provided name.
|
|
32
14
|
*/
|
|
33
|
-
group?:
|
|
34
|
-
/**
|
|
35
|
-
* Tag will group based on the operation tag inside the Swagger file
|
|
36
|
-
*/
|
|
37
|
-
type: 'tag'
|
|
38
|
-
/**
|
|
39
|
-
* Relative path to save the grouped Faker mocks.
|
|
40
|
-
*
|
|
41
|
-
* `{{tag}}` will be replaced by the current tagName.
|
|
42
|
-
* @example `${output}/{{tag}}Controller` => `mocks/PetController`
|
|
43
|
-
* @default `${output}/{{tag}}Controller`
|
|
44
|
-
*/
|
|
45
|
-
output?: string
|
|
46
|
-
/**
|
|
47
|
-
* Name to be used for the `export * as {{exportAs}} from './`
|
|
48
|
-
* @default `"{{tag}}Mocks"`
|
|
49
|
-
*/
|
|
50
|
-
exportAs?: string
|
|
51
|
-
}
|
|
15
|
+
group?: Group
|
|
52
16
|
/**
|
|
53
17
|
* Array containing exclude parameters to exclude/skip tags/operations/methods/paths.
|
|
54
18
|
*/
|
|
@@ -74,26 +38,14 @@ export type Options = {
|
|
|
74
38
|
* - Schema with format 'time' will use ISO time format (HH:mm:ss[.SSSSSS])
|
|
75
39
|
* - `'dayjs'` will use `dayjs(faker.date.anytime()).format("HH:mm:ss")`.
|
|
76
40
|
* - `undefined` will use `faker.date.anytime().toString()`
|
|
77
|
-
* * @default
|
|
41
|
+
* * @default 'faker'
|
|
78
42
|
*/
|
|
79
|
-
dateParser?: 'dayjs' | 'moment' | (string & {})
|
|
43
|
+
dateParser?: 'faker' | 'dayjs' | 'moment' | (string & {})
|
|
80
44
|
/**
|
|
81
45
|
* Which type to use when the Swagger/OpenAPI file is not providing more information
|
|
82
46
|
* @default 'any'
|
|
83
47
|
*/
|
|
84
48
|
unknownType?: 'any' | 'unknown'
|
|
85
|
-
transformers?: {
|
|
86
|
-
/**
|
|
87
|
-
* Customize the names based on the type that is provided by the plugin.
|
|
88
|
-
*/
|
|
89
|
-
name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
|
|
90
|
-
/**
|
|
91
|
-
* Receive schema and baseName(propertName) and return FakerMeta array
|
|
92
|
-
* TODO TODO add docs
|
|
93
|
-
* @beta
|
|
94
|
-
*/
|
|
95
|
-
schema?: (props: { schema?: SchemaObject; name?: string; parentName?: string }, defaultSchemas: Schema[]) => Schema[] | undefined
|
|
96
|
-
}
|
|
97
49
|
/**
|
|
98
50
|
* Choose which generator to use when using Regexp.
|
|
99
51
|
*
|
|
@@ -108,23 +60,33 @@ export type Options = {
|
|
|
108
60
|
* The use of Seed is intended to allow for consistent values in a test.
|
|
109
61
|
*/
|
|
110
62
|
seed?: number | number[]
|
|
63
|
+
transformers?: {
|
|
64
|
+
/**
|
|
65
|
+
* Customize the names based on the type that is provided by the plugin.
|
|
66
|
+
*/
|
|
67
|
+
name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
|
|
68
|
+
/**
|
|
69
|
+
* Receive schema and baseName(propertName) and return FakerMeta array
|
|
70
|
+
* TODO TODO add docs
|
|
71
|
+
* @beta
|
|
72
|
+
*/
|
|
73
|
+
schema?: (props: { schema?: SchemaObject; name?: string; parentName?: string }, defaultSchemas: Schema[]) => Schema[] | undefined
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Define some generators next to the faker generators
|
|
77
|
+
*/
|
|
78
|
+
generators?: Array<Generator<PluginFaker>>
|
|
111
79
|
}
|
|
112
80
|
|
|
113
81
|
type ResolvedOptions = {
|
|
114
|
-
|
|
82
|
+
output: Output
|
|
83
|
+
override: NonNullable<Options['override']>
|
|
115
84
|
dateType: NonNullable<Options['dateType']>
|
|
116
|
-
dateParser: Options['dateParser']
|
|
85
|
+
dateParser: NonNullable<Options['dateParser']>
|
|
117
86
|
unknownType: NonNullable<Options['unknownType']>
|
|
118
87
|
transformers: NonNullable<Options['transformers']>
|
|
119
|
-
override: NonNullable<Options['override']>
|
|
120
88
|
seed: NonNullable<Options['seed']> | undefined
|
|
121
89
|
mapper: NonNullable<Options['mapper']>
|
|
122
90
|
regexGenerator: NonNullable<Options['regexGenerator']>
|
|
123
91
|
}
|
|
124
|
-
|
|
125
|
-
export type FileMeta = {
|
|
126
|
-
pluginKey?: Plugin['key']
|
|
127
|
-
tag?: string
|
|
128
|
-
}
|
|
129
|
-
|
|
130
92
|
export type PluginFaker = PluginFactoryOptions<'plugin-faker', Options, ResolvedOptions, never, ResolvePathOptions>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { OperationGenerator as Generator } from '@kubb/plugin-oas'
|
|
2
|
-
import { Oas } from '@kubb/plugin-oas/components'
|
|
3
|
-
import { App, createRoot } from '@kubb/react'
|
|
4
|
-
|
|
5
|
-
import { OperationSchema } from './components/OperationSchema.tsx'
|
|
6
|
-
|
|
7
|
-
import type { Operation } from '@kubb/oas'
|
|
8
|
-
import type { OperationMethodResult } from '@kubb/plugin-oas'
|
|
9
|
-
import type { FileMeta, PluginFaker } from './types.ts'
|
|
10
|
-
|
|
11
|
-
export class OperationGenerator extends Generator<PluginFaker['resolvedOptions'], PluginFaker> {
|
|
12
|
-
async operation(operation: Operation, options: PluginFaker['resolvedOptions']): OperationMethodResult<FileMeta> {
|
|
13
|
-
const { oas, pluginManager, plugin, mode } = this.context
|
|
14
|
-
|
|
15
|
-
const root = createRoot({
|
|
16
|
-
logger: pluginManager.logger,
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
root.render(
|
|
20
|
-
<App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
|
|
21
|
-
<Oas oas={oas} operations={[operation]} generator={this}>
|
|
22
|
-
<Oas.Operation operation={operation}>
|
|
23
|
-
<OperationSchema.File />
|
|
24
|
-
</Oas.Operation>
|
|
25
|
-
</Oas>
|
|
26
|
-
</App>,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
return root.files
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/SchemaGenerator.tsx
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { SchemaObject } from '@kubb/oas'
|
|
2
|
-
import { SchemaGenerator as Generator } from '@kubb/plugin-oas'
|
|
3
|
-
import type { SchemaMethodResult } from '@kubb/plugin-oas'
|
|
4
|
-
import { Oas } from '@kubb/plugin-oas/components'
|
|
5
|
-
import { App, createRoot } from '@kubb/react'
|
|
6
|
-
import { Schema } from './components/Schema.tsx'
|
|
7
|
-
import type { FileMeta, PluginFaker } from './types.ts'
|
|
8
|
-
|
|
9
|
-
export class SchemaGenerator extends Generator<PluginFaker['resolvedOptions'], PluginFaker> {
|
|
10
|
-
async schema(name: string, schema: SchemaObject, options: PluginFaker['resolvedOptions']): SchemaMethodResult<FileMeta> {
|
|
11
|
-
const { oas, pluginManager, plugin, mode, output } = this.context
|
|
12
|
-
|
|
13
|
-
const root = createRoot({
|
|
14
|
-
logger: pluginManager.logger,
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
const tree = this.parse({ schema, name })
|
|
18
|
-
|
|
19
|
-
root.render(
|
|
20
|
-
<App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
|
|
21
|
-
<Oas oas={oas}>
|
|
22
|
-
<Oas.Schema name={name} value={schema} tree={tree}>
|
|
23
|
-
<Schema.File />
|
|
24
|
-
</Oas.Schema>
|
|
25
|
-
</Oas>
|
|
26
|
-
</App>,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
return root.files
|
|
30
|
-
}
|
|
31
|
-
}
|