@kubb/plugin-faker 3.0.0-alpha.15 → 3.0.0-alpha.16
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/dist/chunk-7JKM5LCT.cjs +310 -0
- package/dist/chunk-7JKM5LCT.cjs.map +1 -0
- package/dist/chunk-CJMJFFHG.cjs +110 -0
- package/dist/chunk-CJMJFFHG.cjs.map +1 -0
- package/dist/chunk-JE7K2NAC.js +108 -0
- package/dist/chunk-JE7K2NAC.js.map +1 -0
- package/dist/chunk-Q5K4KJXX.js +304 -0
- package/dist/chunk-Q5K4KJXX.js.map +1 -0
- package/dist/components.cjs +4 -530
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +16 -18
- package/dist/components.d.ts +16 -18
- package/dist/components.js +1 -528
- 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 +9 -0
- package/dist/generators.d.ts +9 -0
- package/dist/generators.js +4 -0
- package/dist/generators.js.map +1 -0
- package/dist/index.cjs +12 -430
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -125
- package/dist/index.d.ts +5 -125
- package/dist/index.js +13 -430
- package/dist/index.js.map +1 -1
- package/dist/types-DrJPCRvZ.d.cts +125 -0
- package/dist/types-DrJPCRvZ.d.ts +125 -0
- package/package.json +21 -13
- package/src/components/Faker.tsx +80 -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 +29 -0
- package/src/generators/__snapshots__/pet.ts +15 -0
- package/src/generators/__snapshots__/petWithDateString.ts +15 -0
- package/src/generators/__snapshots__/petWithDayjs.ts +16 -0
- package/src/generators/__snapshots__/petWithMapper.ts +15 -0
- package/src/generators/__snapshots__/petWithRandExp.ts +16 -0
- package/src/generators/__snapshots__/pets.ts +5 -0
- package/src/generators/__snapshots__/showPetById.ts +29 -0
- package/src/generators/fakerGenerator.tsx +135 -0
- package/src/generators/index.ts +1 -0
- package/src/parser/index.ts +22 -12
- package/src/plugin.ts +7 -10
- package/src/types.ts +17 -17
- package/src/OperationGenerator.tsx +0 -31
- package/src/SchemaGenerator.tsx +0 -31
- package/src/components/OperationSchema.tsx +0 -81
- package/src/components/Schema.tsx +0 -148
|
@@ -0,0 +1,135 @@
|
|
|
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}>
|
|
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 imports = getImports(schema.tree)
|
|
91
|
+
|
|
92
|
+
const faker = {
|
|
93
|
+
name: getName(schema.name, { type: 'function' }),
|
|
94
|
+
file: getFile(schema.name),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const type = {
|
|
98
|
+
name: getName(schema.name, { type: 'type', pluginKey: [pluginTsName] }),
|
|
99
|
+
file: getFile(schema.name, { pluginKey: [pluginTsName] }),
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const canOverride = schema.tree.some(
|
|
103
|
+
({ keyword }) =>
|
|
104
|
+
keyword === schemaKeywords.array ||
|
|
105
|
+
keyword === schemaKeywords.and ||
|
|
106
|
+
keyword === schemaKeywords.object ||
|
|
107
|
+
keyword === schemaKeywords.union ||
|
|
108
|
+
keyword === schemaKeywords.tuple,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<File baseName={faker.file.baseName} path={faker.file.path} meta={faker.file.meta}>
|
|
113
|
+
<File.Import name={['faker']} path="@faker-js/faker" />
|
|
114
|
+
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
115
|
+
{dateParser !== 'faker' && <File.Import path={dateParser} name={dateParser} />}
|
|
116
|
+
<File.Import isTypeOnly root={faker.file.path} path={type.file.path} name={[type.name]} />
|
|
117
|
+
{imports.map((imp, index) => (
|
|
118
|
+
<File.Import key={index} root={faker.file.path} path={imp.path} name={imp.name} />
|
|
119
|
+
))}
|
|
120
|
+
|
|
121
|
+
<Faker
|
|
122
|
+
name={faker.name}
|
|
123
|
+
typeName={type.name}
|
|
124
|
+
description={schema.value.description}
|
|
125
|
+
tree={schema.tree}
|
|
126
|
+
regexGenerator={regexGenerator}
|
|
127
|
+
dateParser={dateParser}
|
|
128
|
+
mapper={mapper}
|
|
129
|
+
seed={seed}
|
|
130
|
+
canOverride={canOverride}
|
|
131
|
+
/>
|
|
132
|
+
</File>
|
|
133
|
+
)
|
|
134
|
+
},
|
|
135
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { fakerGenerator } from './fakerGenerator.tsx'
|
package/src/parser/index.ts
CHANGED
|
@@ -68,13 +68,18 @@ export const fakerKeywordMapper = {
|
|
|
68
68
|
* Type `'string'` ISO date format (YYYY-MM-DD)
|
|
69
69
|
* @default ISO date format (YYYY-MM-DD)
|
|
70
70
|
*/
|
|
71
|
-
date: (type: 'date' | 'string' = 'string', parser
|
|
71
|
+
date: (type: 'date' | 'string' = 'string', parser: Options['dateParser'] = 'faker') => {
|
|
72
72
|
if (type === 'string') {
|
|
73
|
-
if (parser) {
|
|
73
|
+
if (parser !== 'faker') {
|
|
74
74
|
return `${parser}(faker.date.anytime()).format("YYYY-MM-DD")`
|
|
75
75
|
}
|
|
76
76
|
return 'faker.date.anytime().toString()'
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
if (parser !== 'faker') {
|
|
80
|
+
throw new Error(`type '${type}' and parser '${parser}' can not work together`)
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
return 'faker.date.anytime()'
|
|
79
84
|
},
|
|
80
85
|
/**
|
|
@@ -82,13 +87,18 @@ export const fakerKeywordMapper = {
|
|
|
82
87
|
* Type `'string'` ISO time format (HH:mm:ss[.SSSSSS])
|
|
83
88
|
* @default ISO time format (HH:mm:ss[.SSSSSS])
|
|
84
89
|
*/
|
|
85
|
-
time: (type: 'date' | 'string' = 'string', parser
|
|
90
|
+
time: (type: 'date' | 'string' = 'string', parser: Options['dateParser'] = 'faker') => {
|
|
86
91
|
if (type === 'string') {
|
|
87
|
-
if (parser) {
|
|
92
|
+
if (parser !== 'faker') {
|
|
88
93
|
return `${parser}(faker.date.anytime()).format("HH:mm:ss")`
|
|
89
94
|
}
|
|
90
95
|
return 'faker.date.anytime().toString()'
|
|
91
96
|
}
|
|
97
|
+
|
|
98
|
+
if (parser !== 'faker') {
|
|
99
|
+
throw new Error(`type '${type}' and parser '${parser}' can not work together`)
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
return 'faker.date.anytime()'
|
|
93
103
|
},
|
|
94
104
|
uuid: () => 'faker.string.uuid()',
|
|
@@ -155,7 +165,7 @@ type ParserOptions = {
|
|
|
155
165
|
|
|
156
166
|
seed?: number | number[]
|
|
157
167
|
regexGenerator?: 'faker' | 'randexp'
|
|
158
|
-
|
|
168
|
+
canOverride?: boolean
|
|
159
169
|
dateParser?: Options['dateParser']
|
|
160
170
|
mapper?: Record<string, string>
|
|
161
171
|
}
|
|
@@ -168,15 +178,15 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
168
178
|
}
|
|
169
179
|
|
|
170
180
|
if (isKeyword(current, schemaKeywords.union)) {
|
|
171
|
-
return fakerKeywordMapper.union(current.args.map((schema) => parse(current, schema, { ...options,
|
|
181
|
+
return fakerKeywordMapper.union(current.args.map((schema) => parse(current, schema, { ...options, canOverride: false })).filter(Boolean))
|
|
172
182
|
}
|
|
173
183
|
|
|
174
184
|
if (isKeyword(current, schemaKeywords.and)) {
|
|
175
|
-
return fakerKeywordMapper.and(current.args.map((schema) => parse(current, schema, { ...options,
|
|
185
|
+
return fakerKeywordMapper.and(current.args.map((schema) => parse(current, schema, { ...options, canOverride: false })).filter(Boolean))
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
if (isKeyword(current, schemaKeywords.array)) {
|
|
179
|
-
return fakerKeywordMapper.array(current.args.items.map((schema) => parse(current, schema, { ...options,
|
|
189
|
+
return fakerKeywordMapper.array(current.args.items.map((schema) => parse(current, schema, { ...options, canOverride: false })).filter(Boolean))
|
|
180
190
|
}
|
|
181
191
|
|
|
182
192
|
if (isKeyword(current, schemaKeywords.enum)) {
|
|
@@ -195,7 +205,7 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
195
205
|
throw new Error(`Name not defined for keyword ${current.keyword}`)
|
|
196
206
|
}
|
|
197
207
|
|
|
198
|
-
if (options.
|
|
208
|
+
if (options.canOverride) {
|
|
199
209
|
return `${current.args.name}(data)`
|
|
200
210
|
}
|
|
201
211
|
|
|
@@ -220,7 +230,7 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
220
230
|
return `"${name}": ${joinItems(
|
|
221
231
|
schemas
|
|
222
232
|
.sort(schemaKeywordsorter)
|
|
223
|
-
.map((schema) => parse(current, schema, { ...options,
|
|
233
|
+
.map((schema) => parse(current, schema, { ...options, canOverride: false }))
|
|
224
234
|
.filter(Boolean),
|
|
225
235
|
)}`
|
|
226
236
|
})
|
|
@@ -231,10 +241,10 @@ export function parse(parent: Schema | undefined, current: Schema, options: Pars
|
|
|
231
241
|
|
|
232
242
|
if (isKeyword(current, schemaKeywords.tuple)) {
|
|
233
243
|
if (Array.isArray(current.args.items)) {
|
|
234
|
-
return fakerKeywordMapper.tuple(current.args.items.map((schema) => parse(current, schema, { ...options,
|
|
244
|
+
return fakerKeywordMapper.tuple(current.args.items.map((schema) => parse(current, schema, { ...options, canOverride: false })).filter(Boolean))
|
|
235
245
|
}
|
|
236
246
|
|
|
237
|
-
return parse(current, current.args.items, { ...options,
|
|
247
|
+
return parse(current, current.args.items, { ...options, canOverride: false })
|
|
238
248
|
}
|
|
239
249
|
|
|
240
250
|
if (isKeyword(current, schemaKeywords.const)) {
|
package/src/plugin.ts
CHANGED
|
@@ -3,15 +3,13 @@ import path from 'node:path'
|
|
|
3
3
|
import { FileManager, PluginManager, createPlugin } from '@kubb/core'
|
|
4
4
|
import { camelCase } from '@kubb/core/transformers'
|
|
5
5
|
import { renderTemplate } from '@kubb/core/utils'
|
|
6
|
-
import { pluginOasName } from '@kubb/plugin-oas'
|
|
6
|
+
import { OperationGenerator, SchemaGenerator, pluginOasName } from '@kubb/plugin-oas'
|
|
7
7
|
|
|
8
8
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
9
9
|
|
|
10
|
-
import { OperationGenerator } from './OperationGenerator.tsx'
|
|
11
|
-
import { SchemaGenerator } from './SchemaGenerator.tsx'
|
|
12
|
-
|
|
13
10
|
import type { Plugin } from '@kubb/core'
|
|
14
11
|
import type { PluginOas } from '@kubb/plugin-oas'
|
|
12
|
+
import { fakerGenerator } from './generators/fakerGenerator.tsx'
|
|
15
13
|
import type { PluginFaker } from './types.ts'
|
|
16
14
|
|
|
17
15
|
export const pluginFakerName = 'plugin-faker' satisfies PluginFaker['name']
|
|
@@ -26,9 +24,9 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
26
24
|
override = [],
|
|
27
25
|
transformers = {},
|
|
28
26
|
mapper = {},
|
|
29
|
-
dateType = 'string',
|
|
30
27
|
unknownType = 'any',
|
|
31
|
-
|
|
28
|
+
dateType = 'string',
|
|
29
|
+
dateParser = 'faker',
|
|
32
30
|
regexGenerator = 'faker',
|
|
33
31
|
} = options
|
|
34
32
|
const template = group?.output ? group.output : `${output.path}/{{tag}}Controller`
|
|
@@ -40,10 +38,9 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
40
38
|
...output,
|
|
41
39
|
},
|
|
42
40
|
options: {
|
|
43
|
-
extName: output.extName,
|
|
44
41
|
transformers,
|
|
45
|
-
dateType,
|
|
46
42
|
seed,
|
|
43
|
+
dateType,
|
|
47
44
|
unknownType,
|
|
48
45
|
dateParser,
|
|
49
46
|
mapper,
|
|
@@ -101,7 +98,7 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
101
98
|
output: output.path,
|
|
102
99
|
})
|
|
103
100
|
|
|
104
|
-
const schemaFiles = await schemaGenerator.build()
|
|
101
|
+
const schemaFiles = await schemaGenerator.build(fakerGenerator)
|
|
105
102
|
await this.addFile(...schemaFiles)
|
|
106
103
|
|
|
107
104
|
const operationGenerator = new OperationGenerator(this.plugin.options, {
|
|
@@ -115,7 +112,7 @@ export const pluginFaker = createPlugin<PluginFaker>((options) => {
|
|
|
115
112
|
mode,
|
|
116
113
|
})
|
|
117
114
|
|
|
118
|
-
const operationFiles = await operationGenerator.build()
|
|
115
|
+
const operationFiles = await operationGenerator.build(fakerGenerator)
|
|
119
116
|
await this.addFile(...operationFiles)
|
|
120
117
|
|
|
121
118
|
if (this.config.output.exportType) {
|
package/src/types.ts
CHANGED
|
@@ -74,26 +74,14 @@ export type Options = {
|
|
|
74
74
|
* - Schema with format 'time' will use ISO time format (HH:mm:ss[.SSSSSS])
|
|
75
75
|
* - `'dayjs'` will use `dayjs(faker.date.anytime()).format("HH:mm:ss")`.
|
|
76
76
|
* - `undefined` will use `faker.date.anytime().toString()`
|
|
77
|
-
* * @default
|
|
77
|
+
* * @default 'faker'
|
|
78
78
|
*/
|
|
79
|
-
dateParser?: 'dayjs' | 'moment' | (string & {})
|
|
79
|
+
dateParser?: 'faker' | 'dayjs' | 'moment' | (string & {})
|
|
80
80
|
/**
|
|
81
81
|
* Which type to use when the Swagger/OpenAPI file is not providing more information
|
|
82
82
|
* @default 'any'
|
|
83
83
|
*/
|
|
84
84
|
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
85
|
/**
|
|
98
86
|
* Choose which generator to use when using Regexp.
|
|
99
87
|
*
|
|
@@ -108,15 +96,27 @@ export type Options = {
|
|
|
108
96
|
* The use of Seed is intended to allow for consistent values in a test.
|
|
109
97
|
*/
|
|
110
98
|
seed?: number | number[]
|
|
99
|
+
transformers?: {
|
|
100
|
+
/**
|
|
101
|
+
* Customize the names based on the type that is provided by the plugin.
|
|
102
|
+
*/
|
|
103
|
+
name?: (name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
|
|
104
|
+
/**
|
|
105
|
+
* Receive schema and baseName(propertName) and return FakerMeta array
|
|
106
|
+
* TODO TODO add docs
|
|
107
|
+
* @beta
|
|
108
|
+
*/
|
|
109
|
+
schema?: (props: { schema?: SchemaObject; name?: string; parentName?: string }, defaultSchemas: Schema[]) => Schema[] | undefined
|
|
110
|
+
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
type ResolvedOptions = {
|
|
114
|
-
|
|
114
|
+
override: NonNullable<Options['override']>
|
|
115
|
+
|
|
115
116
|
dateType: NonNullable<Options['dateType']>
|
|
116
|
-
dateParser: Options['dateParser']
|
|
117
|
+
dateParser: NonNullable<Options['dateParser']>
|
|
117
118
|
unknownType: NonNullable<Options['unknownType']>
|
|
118
119
|
transformers: NonNullable<Options['transformers']>
|
|
119
|
-
override: NonNullable<Options['override']>
|
|
120
120
|
seed: NonNullable<Options['seed']> | undefined
|
|
121
121
|
mapper: NonNullable<Options['mapper']>
|
|
122
122
|
regexGenerator: NonNullable<Options['regexGenerator']>
|
|
@@ -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
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Oas } from '@kubb/plugin-oas/components'
|
|
2
|
-
import { useOas, useOperation, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
3
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
4
|
-
import { File, useApp } from '@kubb/react'
|
|
5
|
-
|
|
6
|
-
import { SchemaGenerator } from '../SchemaGenerator.tsx'
|
|
7
|
-
|
|
8
|
-
import type { OperationSchema as OperationSchemaType } from '@kubb/plugin-oas'
|
|
9
|
-
import type { ReactNode } from 'react'
|
|
10
|
-
import type { FileMeta, PluginFaker } from '../types.ts'
|
|
11
|
-
import { Schema } from './Schema.tsx'
|
|
12
|
-
|
|
13
|
-
type Props = {
|
|
14
|
-
description?: string
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function OperationSchema({ description }: Props): ReactNode {
|
|
18
|
-
return <Schema withData={false} description={description} />
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
type FileProps = {}
|
|
22
|
-
|
|
23
|
-
OperationSchema.File = function ({}: FileProps): ReactNode {
|
|
24
|
-
const { plugin, pluginManager, mode } = useApp<PluginFaker>()
|
|
25
|
-
|
|
26
|
-
const oas = useOas()
|
|
27
|
-
const { getSchemas, getFile } = useOperationManager()
|
|
28
|
-
const operation = useOperation()
|
|
29
|
-
|
|
30
|
-
const file = getFile(operation)
|
|
31
|
-
const schemas = getSchemas(operation)
|
|
32
|
-
const generator = new SchemaGenerator(plugin.options, {
|
|
33
|
-
oas,
|
|
34
|
-
plugin,
|
|
35
|
-
pluginManager,
|
|
36
|
-
mode,
|
|
37
|
-
override: plugin.options.override,
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
const items = [schemas.pathParams, schemas.queryParams, schemas.headerParams, schemas.statusCodes, schemas.request, schemas.response].flat().filter(Boolean)
|
|
41
|
-
|
|
42
|
-
const mapItem = ({ name, schema, description, ...options }: OperationSchemaType, i: number) => {
|
|
43
|
-
// used for this.options.typed
|
|
44
|
-
const typeName = pluginManager.resolveName({
|
|
45
|
-
name,
|
|
46
|
-
pluginKey: [pluginTsName],
|
|
47
|
-
type: 'type',
|
|
48
|
-
})
|
|
49
|
-
const typeFileName = pluginManager.resolveName({
|
|
50
|
-
name: options.operationName || name,
|
|
51
|
-
pluginKey: [pluginTsName],
|
|
52
|
-
type: 'file',
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
// todo replace by getFile
|
|
56
|
-
const typePath = pluginManager.resolvePath({
|
|
57
|
-
baseName: typeFileName,
|
|
58
|
-
pluginKey: [pluginTsName],
|
|
59
|
-
options: { tag: options.operation?.getTags()[0]?.name },
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
const tree = generator.parse({ schema, name })
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<Oas.Schema key={i} name={name} value={schema} tree={tree}>
|
|
66
|
-
{typeName && typePath && <File.Import isTypeOnly root={file.path} path={typePath} name={[typeName]} />}
|
|
67
|
-
{plugin.options.dateParser && <File.Import path={plugin.options.dateParser} name={plugin.options.dateParser} />}
|
|
68
|
-
|
|
69
|
-
{mode === 'split' && <Oas.Schema.Imports />}
|
|
70
|
-
<OperationSchema description={description} />
|
|
71
|
-
</Oas.Schema>
|
|
72
|
-
)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<File<FileMeta> baseName={file.baseName} path={file.path} meta={file.meta}>
|
|
77
|
-
{plugin.options.regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
78
|
-
{items.map(mapItem)}
|
|
79
|
-
</File>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { Oas } from '@kubb/plugin-oas/components'
|
|
2
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
3
|
-
import { File, Function, useApp, useFile } from '@kubb/react'
|
|
4
|
-
|
|
5
|
-
import transformers from '@kubb/core/transformers'
|
|
6
|
-
import { schemaKeywords } from '@kubb/plugin-oas'
|
|
7
|
-
import { useSchema } from '@kubb/plugin-oas/hooks'
|
|
8
|
-
import type { ReactNode } from 'react'
|
|
9
|
-
import * as parserFaker from '../parser/index.ts'
|
|
10
|
-
import { pluginFakerName } from '../plugin.ts'
|
|
11
|
-
import type { PluginFaker } from '../types.ts'
|
|
12
|
-
|
|
13
|
-
type Props = {
|
|
14
|
-
description?: string
|
|
15
|
-
withData?: boolean
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function Schema(props: Props): ReactNode {
|
|
19
|
-
const { withData, description } = props
|
|
20
|
-
const { tree, name } = useSchema()
|
|
21
|
-
const {
|
|
22
|
-
pluginManager,
|
|
23
|
-
plugin: {
|
|
24
|
-
options: { dateParser, regexGenerator, mapper, seed },
|
|
25
|
-
},
|
|
26
|
-
} = useApp<PluginFaker>()
|
|
27
|
-
|
|
28
|
-
// all checks are also inside this.schema(React)
|
|
29
|
-
const resolvedName = pluginManager.resolveName({
|
|
30
|
-
name,
|
|
31
|
-
pluginKey: [pluginFakerName],
|
|
32
|
-
type: 'function',
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
const typeName = pluginManager.resolveName({
|
|
36
|
-
name,
|
|
37
|
-
pluginKey: [pluginTsName],
|
|
38
|
-
type: 'type',
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
const fakerText = parserFaker.joinItems(
|
|
42
|
-
tree
|
|
43
|
-
.map((schema) => parserFaker.parse(undefined, schema, { name: resolvedName, typeName, seed, regexGenerator, mapper, withData, dateParser }))
|
|
44
|
-
.filter(Boolean),
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
let fakerDefaultOverride: '' | '[]' | '{}' | undefined = undefined
|
|
48
|
-
let fakerTextWithOverride = fakerText
|
|
49
|
-
|
|
50
|
-
if (withData && fakerText.startsWith('{')) {
|
|
51
|
-
fakerDefaultOverride = '{}'
|
|
52
|
-
fakerTextWithOverride = `{
|
|
53
|
-
...${fakerText},
|
|
54
|
-
...data
|
|
55
|
-
}`
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (withData && fakerText.startsWith('faker.helpers.arrayElements')) {
|
|
59
|
-
fakerDefaultOverride = '[]'
|
|
60
|
-
fakerTextWithOverride = `[
|
|
61
|
-
...${fakerText},
|
|
62
|
-
...data
|
|
63
|
-
]`
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const params = fakerDefaultOverride ? `data: NonNullable<Partial<${typeName}>> = ${fakerDefaultOverride}` : `data?: NonNullable<Partial<${typeName}>>`
|
|
67
|
-
|
|
68
|
-
const containsFaker = !!fakerTextWithOverride.match(/faker/) || !!seed
|
|
69
|
-
|
|
70
|
-
return (
|
|
71
|
-
<>
|
|
72
|
-
{containsFaker && <File.Import name={['faker']} path="@faker-js/faker" />}
|
|
73
|
-
<File.Source name={resolvedName} isExportable isIndexable>
|
|
74
|
-
<Function
|
|
75
|
-
export
|
|
76
|
-
name={resolvedName}
|
|
77
|
-
JSDoc={{ comments: [description ? `@description ${transformers.jsStringEscape(description)}` : undefined].filter(Boolean) }}
|
|
78
|
-
params={withData ? params : ''}
|
|
79
|
-
returnType={typeName ? `NonNullable<${typeName}>` : ''}
|
|
80
|
-
>
|
|
81
|
-
{seed ? `faker.seed(${JSON.stringify(seed)})` : ''}
|
|
82
|
-
<br />
|
|
83
|
-
<Function.Return>{fakerTextWithOverride}</Function.Return>
|
|
84
|
-
</Function>
|
|
85
|
-
<br />
|
|
86
|
-
</File.Source>
|
|
87
|
-
</>
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
type FileProps = {}
|
|
92
|
-
|
|
93
|
-
Schema.File = function ({}: FileProps): ReactNode {
|
|
94
|
-
const { pluginManager } = useApp<PluginFaker>()
|
|
95
|
-
const { tree, schema } = useSchema()
|
|
96
|
-
|
|
97
|
-
const withData = tree.some(
|
|
98
|
-
(schema) =>
|
|
99
|
-
schema.keyword === schemaKeywords.array ||
|
|
100
|
-
schema.keyword === schemaKeywords.and ||
|
|
101
|
-
schema.keyword === schemaKeywords.object ||
|
|
102
|
-
schema.keyword === schemaKeywords.union ||
|
|
103
|
-
schema.keyword === schemaKeywords.tuple,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
return (
|
|
107
|
-
<Oas.Schema.File output={pluginManager.config.output.path}>
|
|
108
|
-
<Schema.Imports />
|
|
109
|
-
<Schema description={schema?.description} withData={withData} />
|
|
110
|
-
</Oas.Schema.File>
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
Schema.Imports = (): ReactNode => {
|
|
114
|
-
const {
|
|
115
|
-
pluginManager,
|
|
116
|
-
plugin: {
|
|
117
|
-
options: { extName, dateParser, regexGenerator },
|
|
118
|
-
},
|
|
119
|
-
} = useApp<PluginFaker>()
|
|
120
|
-
const { path: root } = useFile()
|
|
121
|
-
const { name, tree, schema } = useSchema()
|
|
122
|
-
|
|
123
|
-
// used for this.options.typed
|
|
124
|
-
const typeName = pluginManager.resolveName({
|
|
125
|
-
name,
|
|
126
|
-
pluginKey: [pluginTsName],
|
|
127
|
-
type: 'type',
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
const typeFileName = pluginManager.resolveName({
|
|
131
|
-
name: name,
|
|
132
|
-
pluginKey: [pluginTsName],
|
|
133
|
-
type: 'file',
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
const typePath = pluginManager.resolvePath({
|
|
137
|
-
baseName: typeFileName,
|
|
138
|
-
pluginKey: [pluginTsName],
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<>
|
|
143
|
-
{regexGenerator === 'randexp' && <File.Import name={'RandExp'} path={'randexp'} />}
|
|
144
|
-
{dateParser && <File.Import path={dateParser} name={dateParser} />}
|
|
145
|
-
{typeName && typePath && <File.Import isTypeOnly root={root} path={typePath} name={[typeName]} />}
|
|
146
|
-
</>
|
|
147
|
-
)
|
|
148
|
-
}
|