@kubb/plugin-oas 3.0.0-alpha.3 → 3.0.0-alpha.31
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 +13 -4
- package/dist/OperationGenerator-BgQeGRzk.d.cts +550 -0
- package/dist/OperationGenerator-BgQeGRzk.d.ts +550 -0
- package/dist/Schema-1iM2I0dK.d.ts +22 -0
- package/dist/Schema-5o-c5UOy.d.cts +22 -0
- package/dist/chunk-ABOQ73FL.cjs +36 -0
- package/dist/chunk-ABOQ73FL.cjs.map +1 -0
- package/dist/chunk-BG77DP54.js +30 -0
- package/dist/chunk-BG77DP54.js.map +1 -0
- package/dist/chunk-GF26SDHQ.js +28 -0
- package/dist/chunk-GF26SDHQ.js.map +1 -0
- package/dist/chunk-PADR76WZ.cjs +4 -0
- package/dist/chunk-PADR76WZ.cjs.map +1 -0
- package/dist/chunk-QAFBZLJA.cjs +48 -0
- package/dist/chunk-QAFBZLJA.cjs.map +1 -0
- package/dist/chunk-QT6ZFRNJ.cjs +752 -0
- package/dist/chunk-QT6ZFRNJ.cjs.map +1 -0
- package/dist/chunk-QWO5NQGQ.js +88 -0
- package/dist/chunk-QWO5NQGQ.js.map +1 -0
- package/dist/chunk-R47XMJ32.js +3 -0
- package/dist/chunk-R47XMJ32.js.map +1 -0
- package/dist/chunk-SR63CBLH.cjs +92 -0
- package/dist/chunk-SR63CBLH.cjs.map +1 -0
- package/dist/chunk-V2JO6RHI.js +744 -0
- package/dist/chunk-V2JO6RHI.js.map +1 -0
- package/dist/chunk-XNCEFOE6.js +45 -0
- package/dist/chunk-XNCEFOE6.js.map +1 -0
- package/dist/chunk-ZWHQ54JM.cjs +32 -0
- package/dist/chunk-ZWHQ54JM.cjs.map +1 -0
- package/dist/components.cjs +20 -12
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +4 -7
- package/dist/components.d.ts +4 -7
- package/dist/components.js +3 -12
- package/dist/components.js.map +1 -1
- package/dist/generators.cjs +14 -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 +5 -0
- package/dist/generators.js.map +1 -0
- package/dist/hooks.cjs +102 -57
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +41 -10
- package/dist/hooks.d.ts +41 -10
- package/dist/hooks.js +91 -53
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +192 -258
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -6
- package/dist/index.d.ts +3 -6
- package/dist/index.js +135 -228
- package/dist/index.js.map +1 -1
- package/dist/utils.cjs +32 -87
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +8 -43
- package/dist/utils.d.ts +8 -43
- package/dist/utils.js +8 -86
- package/dist/utils.js.map +1 -1
- package/package.json +20 -14
- package/src/OperationGenerator.ts +23 -30
- package/src/SchemaGenerator.ts +80 -23
- package/src/SchemaMapper.ts +7 -5
- package/src/components/Oas.tsx +1 -1
- package/src/components/Operation.tsx +1 -1
- package/src/components/Schema.tsx +2 -102
- package/src/{parser.tsx → generator.tsx} +31 -22
- package/src/generators/index.ts +1 -0
- package/src/generators/jsonGenerator.ts +32 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useOperationManager.ts +77 -29
- package/src/hooks/useSchemaManager.ts +77 -0
- package/src/index.ts +3 -3
- package/src/plugin.ts +67 -59
- package/src/types.ts +24 -16
- package/src/utils/getParams.ts +2 -2
- package/src/utils/getSchemaFactory.ts +1 -1
- package/src/utils/index.ts +2 -2
- package/src/utils/parseFromConfig.ts +7 -7
- package/dist/OperationGenerator-D7rSlflc.d.cts +0 -158
- package/dist/OperationGenerator-vw0Zf-Mi.d.ts +0 -158
- package/dist/Schema-DxyOIX7q.d.cts +0 -35
- package/dist/Schema-gHgN14i2.d.ts +0 -35
- package/dist/SchemaMapper-BM1IGWqD.d.cts +0 -248
- package/dist/SchemaMapper-BM1IGWqD.d.ts +0 -248
- package/dist/chunk-264TCCJF.cjs +0 -3973
- package/dist/chunk-264TCCJF.cjs.map +0 -1
- package/dist/chunk-7KIEQOVZ.cjs +0 -7
- package/dist/chunk-7KIEQOVZ.cjs.map +0 -1
- package/dist/chunk-FZN3PBEK.js +0 -3973
- package/dist/chunk-FZN3PBEK.js.map +0 -1
- package/dist/chunk-P42X362U.cjs +0 -101
- package/dist/chunk-P42X362U.cjs.map +0 -1
- package/dist/chunk-QLJIL3U5.cjs +0 -35
- package/dist/chunk-QLJIL3U5.cjs.map +0 -1
- package/dist/chunk-TWKZEVSM.js +0 -7
- package/dist/chunk-TWKZEVSM.js.map +0 -1
- package/dist/chunk-UB552H4J.js +0 -101
- package/dist/chunk-UB552H4J.js.map +0 -1
- package/dist/chunk-Y4V7HHX7.js +0 -35
- package/dist/chunk-Y4V7HHX7.js.map +0 -1
- package/dist/types-C2RXaY0_.d.cts +0 -143
- package/dist/types-C2RXaY0_.d.ts +0 -143
- package/src/utils/getGroupedByTagFiles.ts +0 -82
- package/src/utils/refSorter.ts +0 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-oas",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.31",
|
|
4
4
|
"description": "Generator swagger",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"require": "./dist/index.cjs",
|
|
26
26
|
"default": "./dist/index.cjs"
|
|
27
27
|
},
|
|
28
|
+
"./generators": {
|
|
29
|
+
"import": "./dist/generators.js",
|
|
30
|
+
"require": "./dist/generators.cjs",
|
|
31
|
+
"default": "./dist/generators.cjs"
|
|
32
|
+
},
|
|
28
33
|
"./utils": {
|
|
29
34
|
"import": "./dist/utils.js",
|
|
30
35
|
"require": "./dist/utils.cjs",
|
|
@@ -56,6 +61,9 @@
|
|
|
56
61
|
],
|
|
57
62
|
"components": [
|
|
58
63
|
"./dist/components.d.ts"
|
|
64
|
+
],
|
|
65
|
+
"generators": [
|
|
66
|
+
"./dist/generators.d.ts"
|
|
59
67
|
]
|
|
60
68
|
}
|
|
61
69
|
},
|
|
@@ -67,24 +75,22 @@
|
|
|
67
75
|
],
|
|
68
76
|
"dependencies": {
|
|
69
77
|
"@stoplight/yaml": "^4.3.0",
|
|
70
|
-
"remeda": "^2.
|
|
71
|
-
"@kubb/core": "3.0.0-alpha.
|
|
72
|
-
"@kubb/fs": "3.0.0-alpha.
|
|
73
|
-
"@kubb/oas": "3.0.0-alpha.
|
|
74
|
-
"@kubb/react": "3.0.0-alpha.
|
|
78
|
+
"remeda": "^2.14.0",
|
|
79
|
+
"@kubb/core": "3.0.0-alpha.31",
|
|
80
|
+
"@kubb/fs": "3.0.0-alpha.31",
|
|
81
|
+
"@kubb/oas": "3.0.0-alpha.31",
|
|
82
|
+
"@kubb/react": "3.0.0-alpha.31"
|
|
75
83
|
},
|
|
76
84
|
"devDependencies": {
|
|
77
|
-
"@types/react": "^18.3.
|
|
78
|
-
"@types/react-dom": "^18.3.0",
|
|
85
|
+
"@types/react": "^18.3.10",
|
|
79
86
|
"react": "^18.3.1",
|
|
80
|
-
"tsup": "^8.
|
|
81
|
-
"typescript": "^5.
|
|
82
|
-
"@kubb/config-
|
|
83
|
-
"@kubb/config-
|
|
84
|
-
"@kubb/config-tsup": "3.0.0-alpha.3"
|
|
87
|
+
"tsup": "^8.3.0",
|
|
88
|
+
"typescript": "^5.6.2",
|
|
89
|
+
"@kubb/config-ts": "3.0.0-alpha.31",
|
|
90
|
+
"@kubb/config-tsup": "3.0.0-alpha.31"
|
|
85
91
|
},
|
|
86
92
|
"peerDependencies": {
|
|
87
|
-
"@kubb/react": "3.0.0-alpha.
|
|
93
|
+
"@kubb/react": "3.0.0-alpha.31"
|
|
88
94
|
},
|
|
89
95
|
"engines": {
|
|
90
96
|
"node": ">=20"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FileMetaBase
|
|
1
|
+
import { BaseGenerator, type FileMetaBase } from '@kubb/core'
|
|
2
2
|
import transformers from '@kubb/core/transformers'
|
|
3
3
|
|
|
4
4
|
import type { PluginFactoryOptions, PluginManager } from '@kubb/core'
|
|
@@ -6,10 +6,13 @@ import type * as KubbFile from '@kubb/fs/types'
|
|
|
6
6
|
|
|
7
7
|
import type { Plugin } from '@kubb/core'
|
|
8
8
|
import type { HttpMethod, Oas, OasTypes, Operation, contentType } from '@kubb/oas'
|
|
9
|
+
import type { Generator } from './generator.tsx'
|
|
9
10
|
import type { Exclude, Include, OperationSchemas, OperationsByMethod, Override } from './types.ts'
|
|
10
|
-
import type { Parser } from './parser.tsx'
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated
|
|
14
|
+
*/
|
|
15
|
+
export type GetOperationGeneratorOptions<T = any> = any
|
|
13
16
|
|
|
14
17
|
export type OperationMethodResult<TFileMeta extends FileMetaBase> = Promise<KubbFile.File<TFileMeta> | Array<KubbFile.File<TFileMeta>> | null>
|
|
15
18
|
|
|
@@ -28,10 +31,9 @@ type Context<TOptions, TPluginOptions extends PluginFactoryOptions> = {
|
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export class OperationGenerator<
|
|
31
|
-
TOptions = unknown,
|
|
32
34
|
TPluginOptions extends PluginFactoryOptions = PluginFactoryOptions,
|
|
33
35
|
TFileMeta extends FileMetaBase = FileMetaBase,
|
|
34
|
-
> extends
|
|
36
|
+
> extends BaseGenerator<TPluginOptions['resolvedOptions'], Context<TPluginOptions['resolvedOptions'], TPluginOptions>> {
|
|
35
37
|
#operationsByMethod: OperationsByMethod = {}
|
|
36
38
|
get operationsByMethod(): OperationsByMethod {
|
|
37
39
|
return this.#operationsByMethod
|
|
@@ -41,7 +43,7 @@ export class OperationGenerator<
|
|
|
41
43
|
this.#operationsByMethod = paths
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
#getOptions(operation: Operation, method: HttpMethod): Partial<
|
|
46
|
+
#getOptions(operation: Operation, method: HttpMethod): Partial<TPluginOptions['resolvedOptions']> {
|
|
45
47
|
const { override = [] } = this.context
|
|
46
48
|
|
|
47
49
|
return (
|
|
@@ -67,10 +69,6 @@ export class OperationGenerator<
|
|
|
67
69
|
)
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
* @deprecated
|
|
73
|
-
*/
|
|
74
72
|
#isExcluded(operation: Operation, method: HttpMethod): boolean {
|
|
75
73
|
const { exclude = [] } = this.context
|
|
76
74
|
let matched = false
|
|
@@ -96,10 +94,6 @@ export class OperationGenerator<
|
|
|
96
94
|
return matched
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
* @deprecated
|
|
102
|
-
*/
|
|
103
97
|
#isIncluded(operation: Operation, method: HttpMethod): boolean {
|
|
104
98
|
const { include = [] } = this.context
|
|
105
99
|
let matched = false
|
|
@@ -128,10 +122,8 @@ export class OperationGenerator<
|
|
|
128
122
|
getSchemas(
|
|
129
123
|
operation: Operation,
|
|
130
124
|
{
|
|
131
|
-
forStatusCode,
|
|
132
125
|
resolveName = (name) => name,
|
|
133
126
|
}: {
|
|
134
|
-
forStatusCode?: string | number
|
|
135
127
|
resolveName?: (name: string) => string
|
|
136
128
|
} = {},
|
|
137
129
|
): OperationSchemas {
|
|
@@ -139,8 +131,7 @@ export class OperationGenerator<
|
|
|
139
131
|
const queryParamsSchema = this.context.oas.getParametersSchema(operation, 'query')
|
|
140
132
|
const headerParamsSchema = this.context.oas.getParametersSchema(operation, 'header')
|
|
141
133
|
const requestSchema = this.context.oas.getRequestSchema(operation)
|
|
142
|
-
const responseStatusCode =
|
|
143
|
-
forStatusCode || (operation.schema.responses && Object.keys(operation.schema.responses).find((key) => key.startsWith('2'))) || 200
|
|
134
|
+
const responseStatusCode = (operation.schema.responses && Object.keys(operation.schema.responses).find((key) => key.startsWith('2'))) || 200
|
|
144
135
|
const responseSchema = this.context.oas.getResponseSchema(operation, responseStatusCode)
|
|
145
136
|
const statusCodes = operation.getResponseStatusCodes().map((statusCode) => {
|
|
146
137
|
let name = statusCode
|
|
@@ -226,7 +217,9 @@ export class OperationGenerator<
|
|
|
226
217
|
}
|
|
227
218
|
}
|
|
228
219
|
|
|
229
|
-
|
|
220
|
+
#methods = ['get', 'post', 'patch', 'put', 'delete']
|
|
221
|
+
|
|
222
|
+
async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
230
223
|
const { oas } = this.context
|
|
231
224
|
|
|
232
225
|
const paths = oas.getPaths()
|
|
@@ -235,7 +228,7 @@ export class OperationGenerator<
|
|
|
235
228
|
|
|
236
229
|
methods.forEach((method) => {
|
|
237
230
|
const operation = oas.operation(path, method)
|
|
238
|
-
if (operation) {
|
|
231
|
+
if (operation && [this.#methods].some((methods) => method === operation.method)) {
|
|
239
232
|
const isExcluded = this.#isExcluded(operation, method)
|
|
240
233
|
const isIncluded = this.context.include ? this.#isIncluded(operation, method) : true
|
|
241
234
|
|
|
@@ -286,8 +279,8 @@ export class OperationGenerator<
|
|
|
286
279
|
acc.push(promiseOperation)
|
|
287
280
|
}
|
|
288
281
|
|
|
289
|
-
|
|
290
|
-
const promise =
|
|
282
|
+
generators?.forEach((generator) => {
|
|
283
|
+
const promise = generator.operation?.({
|
|
291
284
|
instance: this,
|
|
292
285
|
operation,
|
|
293
286
|
options: {
|
|
@@ -309,8 +302,8 @@ export class OperationGenerator<
|
|
|
309
302
|
|
|
310
303
|
promises.push(this.all(operations.flat().filter(Boolean), this.operationsByMethod))
|
|
311
304
|
|
|
312
|
-
|
|
313
|
-
const promise =
|
|
305
|
+
generators?.forEach((generator) => {
|
|
306
|
+
const promise = generator.operations?.({
|
|
314
307
|
instance: this,
|
|
315
308
|
operations: operations.flat().filter(Boolean),
|
|
316
309
|
operationsByMethod: this.operationsByMethod,
|
|
@@ -331,41 +324,41 @@ export class OperationGenerator<
|
|
|
331
324
|
/**
|
|
332
325
|
* Operation
|
|
333
326
|
*/
|
|
334
|
-
async operation(operation: Operation, options:
|
|
327
|
+
async operation(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
335
328
|
return []
|
|
336
329
|
}
|
|
337
330
|
|
|
338
331
|
/**
|
|
339
332
|
* GET
|
|
340
333
|
*/
|
|
341
|
-
async get(operation: Operation, options:
|
|
334
|
+
async get(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
342
335
|
return []
|
|
343
336
|
}
|
|
344
337
|
|
|
345
338
|
/**
|
|
346
339
|
* POST
|
|
347
340
|
*/
|
|
348
|
-
async post(operation: Operation, options:
|
|
341
|
+
async post(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
349
342
|
return []
|
|
350
343
|
}
|
|
351
344
|
/**
|
|
352
345
|
* PATCH
|
|
353
346
|
*/
|
|
354
|
-
async patch(operation: Operation, options:
|
|
347
|
+
async patch(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
355
348
|
return []
|
|
356
349
|
}
|
|
357
350
|
|
|
358
351
|
/**
|
|
359
352
|
* PUT
|
|
360
353
|
*/
|
|
361
|
-
async put(operation: Operation, options:
|
|
354
|
+
async put(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
362
355
|
return []
|
|
363
356
|
}
|
|
364
357
|
|
|
365
358
|
/**
|
|
366
359
|
* DELETE
|
|
367
360
|
*/
|
|
368
|
-
async delete(operation: Operation, options:
|
|
361
|
+
async delete(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
|
|
369
362
|
return []
|
|
370
363
|
}
|
|
371
364
|
|
package/src/SchemaGenerator.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FileMetaBase
|
|
1
|
+
import { BaseGenerator, type FileMetaBase } from '@kubb/core'
|
|
2
2
|
import transformers, { pascalCase } from '@kubb/core/transformers'
|
|
3
3
|
import { getUniqueName } from '@kubb/core/utils'
|
|
4
4
|
|
|
@@ -13,8 +13,8 @@ import type * as KubbFile from '@kubb/fs/types'
|
|
|
13
13
|
|
|
14
14
|
import type { Oas, OpenAPIV3, SchemaObject, contentType } from '@kubb/oas'
|
|
15
15
|
import type { Schema, SchemaKeywordMapper } from './SchemaMapper.ts'
|
|
16
|
+
import type { Generator } from './generator.tsx'
|
|
16
17
|
import type { OperationSchema, Override, Refs } from './types.ts'
|
|
17
|
-
import type { Parser } from './parser.tsx'
|
|
18
18
|
|
|
19
19
|
export type GetSchemaGeneratorOptions<T extends SchemaGenerator<any, any, any>> = T extends SchemaGenerator<infer Options, any, any> ? Options : never
|
|
20
20
|
|
|
@@ -68,7 +68,7 @@ export class SchemaGenerator<
|
|
|
68
68
|
TOptions extends SchemaGeneratorOptions = SchemaGeneratorOptions,
|
|
69
69
|
TPluginOptions extends PluginFactoryOptions = PluginFactoryOptions,
|
|
70
70
|
TFileMeta extends FileMetaBase = FileMetaBase,
|
|
71
|
-
> extends
|
|
71
|
+
> extends BaseGenerator<TOptions, Context<TOptions, TPluginOptions>> {
|
|
72
72
|
// Collect the types of all referenced schemas, so we can export them later
|
|
73
73
|
refs: Refs = {}
|
|
74
74
|
|
|
@@ -302,7 +302,7 @@ export class SchemaGenerator<
|
|
|
302
302
|
|
|
303
303
|
if (additionalProperties) {
|
|
304
304
|
additionalPropertiesSchemas =
|
|
305
|
-
additionalProperties === true
|
|
305
|
+
additionalProperties === true || !Object.keys(additionalProperties).length
|
|
306
306
|
? [{ keyword: this.#getUnknownReturn({ schema, name }) }]
|
|
307
307
|
: this.parse({ schema: additionalProperties as SchemaObject, parentName: name })
|
|
308
308
|
}
|
|
@@ -349,7 +349,7 @@ export class SchemaGenerator<
|
|
|
349
349
|
const file = this.context.pluginManager.getFile({
|
|
350
350
|
name: fileName,
|
|
351
351
|
pluginKey: this.context.plugin.key,
|
|
352
|
-
|
|
352
|
+
extname: '.ts',
|
|
353
353
|
})
|
|
354
354
|
|
|
355
355
|
ref = this.refs[$ref] = {
|
|
@@ -361,7 +361,7 @@ export class SchemaGenerator<
|
|
|
361
361
|
return [
|
|
362
362
|
{
|
|
363
363
|
keyword: schemaKeywords.ref,
|
|
364
|
-
args: { name: ref.propertyName, path: ref?.path
|
|
364
|
+
args: { name: ref.propertyName, path: ref?.path },
|
|
365
365
|
},
|
|
366
366
|
]
|
|
367
367
|
}
|
|
@@ -379,12 +379,6 @@ export class SchemaGenerator<
|
|
|
379
379
|
const options = this.#getOptions({ schema: _schema, name })
|
|
380
380
|
const unknownReturn = this.#getUnknownReturn({ schema: _schema, name })
|
|
381
381
|
const { schema, version } = this.#getParsedSchemaObject(_schema)
|
|
382
|
-
const resolvedName = this.context.pluginManager.resolveName({
|
|
383
|
-
name: `${parentName || ''} ${name}`,
|
|
384
|
-
pluginKey: this.context.plugin.key,
|
|
385
|
-
type: 'type',
|
|
386
|
-
})
|
|
387
|
-
|
|
388
382
|
if (!schema) {
|
|
389
383
|
return [{ keyword: unknownReturn }]
|
|
390
384
|
}
|
|
@@ -408,12 +402,16 @@ export class SchemaGenerator<
|
|
|
408
402
|
keyword: schemaKeywords.default,
|
|
409
403
|
args: transformers.stringify(schema.default),
|
|
410
404
|
})
|
|
411
|
-
}
|
|
412
|
-
if (typeof schema.default === 'boolean') {
|
|
405
|
+
} else if (typeof schema.default === 'boolean') {
|
|
413
406
|
baseItems.push({
|
|
414
407
|
keyword: schemaKeywords.default,
|
|
415
408
|
args: schema.default ?? false,
|
|
416
409
|
})
|
|
410
|
+
} else {
|
|
411
|
+
baseItems.push({
|
|
412
|
+
keyword: schemaKeywords.default,
|
|
413
|
+
args: schema.default,
|
|
414
|
+
})
|
|
417
415
|
}
|
|
418
416
|
}
|
|
419
417
|
|
|
@@ -455,10 +453,16 @@ export class SchemaGenerator<
|
|
|
455
453
|
baseItems.push({ keyword: schemaKeywords.readOnly })
|
|
456
454
|
}
|
|
457
455
|
|
|
456
|
+
if (schema.writeOnly) {
|
|
457
|
+
baseItems.push({ keyword: schemaKeywords.writeOnly })
|
|
458
|
+
}
|
|
459
|
+
|
|
458
460
|
if (isReference(schema)) {
|
|
459
461
|
return [
|
|
460
462
|
...this.#getRefAlias(schema),
|
|
461
463
|
nullable && { keyword: schemaKeywords.nullable },
|
|
464
|
+
schema.readOnly && { keyword: schemaKeywords.readOnly },
|
|
465
|
+
schema.writeOnly && { keyword: schemaKeywords.writeOnly },
|
|
462
466
|
{
|
|
463
467
|
keyword: schemaKeywords.schema,
|
|
464
468
|
args: {
|
|
@@ -485,7 +489,20 @@ export class SchemaGenerator<
|
|
|
485
489
|
}),
|
|
486
490
|
}
|
|
487
491
|
if (schemaWithoutOneOf.properties) {
|
|
488
|
-
|
|
492
|
+
const propertySchemas = this.parse({ schema: schemaWithoutOneOf, name, parentName })
|
|
493
|
+
|
|
494
|
+
return [
|
|
495
|
+
{
|
|
496
|
+
...union,
|
|
497
|
+
args: union.args.map((arg) => {
|
|
498
|
+
return {
|
|
499
|
+
keyword: schemaKeywords.and,
|
|
500
|
+
args: [arg, ...propertySchemas],
|
|
501
|
+
}
|
|
502
|
+
}),
|
|
503
|
+
},
|
|
504
|
+
...baseItems,
|
|
505
|
+
]
|
|
489
506
|
}
|
|
490
507
|
|
|
491
508
|
return [union, ...baseItems]
|
|
@@ -620,6 +637,35 @@ export class SchemaGenerator<
|
|
|
620
637
|
]
|
|
621
638
|
}
|
|
622
639
|
|
|
640
|
+
if (schema.type === 'boolean') {
|
|
641
|
+
// we cannot use z.enum when enum type is boolean
|
|
642
|
+
const enumNames = extensionEnums[0]?.find((item) => isKeyword(item, schemaKeywords.enum)) as unknown as SchemaKeywordMapper['enum']
|
|
643
|
+
return [
|
|
644
|
+
{
|
|
645
|
+
keyword: schemaKeywords.enum,
|
|
646
|
+
args: {
|
|
647
|
+
name: enumName,
|
|
648
|
+
typeName,
|
|
649
|
+
asConst: true,
|
|
650
|
+
items: enumNames?.args?.items
|
|
651
|
+
? [...new Set(enumNames.args.items)].map(({ name, value }) => ({
|
|
652
|
+
name,
|
|
653
|
+
value,
|
|
654
|
+
format: 'boolean',
|
|
655
|
+
}))
|
|
656
|
+
: [...new Set(filteredValues)].map((value: string) => {
|
|
657
|
+
return {
|
|
658
|
+
name: value,
|
|
659
|
+
value,
|
|
660
|
+
format: 'boolean',
|
|
661
|
+
}
|
|
662
|
+
}),
|
|
663
|
+
},
|
|
664
|
+
},
|
|
665
|
+
...baseItems.filter((item) => item.keyword !== schemaKeywords.matches),
|
|
666
|
+
]
|
|
667
|
+
}
|
|
668
|
+
|
|
623
669
|
if (extensionEnums.length > 0 && extensionEnums[0]) {
|
|
624
670
|
return extensionEnums[0]
|
|
625
671
|
}
|
|
@@ -810,7 +856,7 @@ export class SchemaGenerator<
|
|
|
810
856
|
].filter(Boolean)
|
|
811
857
|
}
|
|
812
858
|
|
|
813
|
-
if (!['boolean', 'object', 'number', 'string', 'integer'].includes(schema.type)) {
|
|
859
|
+
if (!['boolean', 'object', 'number', 'string', 'integer', 'null'].includes(schema.type)) {
|
|
814
860
|
this.context.pluginManager.logger.emit('warning', `Schema type '${schema.type}' is not valid for schema ${parentName}.${name}`)
|
|
815
861
|
}
|
|
816
862
|
|
|
@@ -821,14 +867,20 @@ export class SchemaGenerator<
|
|
|
821
867
|
return [{ keyword: unknownReturn }]
|
|
822
868
|
}
|
|
823
869
|
|
|
824
|
-
async build(...
|
|
870
|
+
async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
825
871
|
const { oas, contentType, include } = this.context
|
|
826
872
|
|
|
873
|
+
oas.resolveDiscriminators()
|
|
874
|
+
|
|
827
875
|
const schemas = getSchemas({ oas, contentType, includes: include })
|
|
828
876
|
|
|
829
|
-
const promises = Object.entries(schemas).reduce((acc, [name,
|
|
877
|
+
const promises = Object.entries(schemas).reduce((acc, [name, value]) => {
|
|
878
|
+
if (!value) {
|
|
879
|
+
return acc
|
|
880
|
+
}
|
|
881
|
+
|
|
830
882
|
const options = this.#getOptions({ name })
|
|
831
|
-
const promiseOperation = this.schema.call(this, name,
|
|
883
|
+
const promiseOperation = this.schema.call(this, name, value, {
|
|
832
884
|
...this.options,
|
|
833
885
|
...options,
|
|
834
886
|
})
|
|
@@ -837,11 +889,16 @@ export class SchemaGenerator<
|
|
|
837
889
|
acc.push(promiseOperation)
|
|
838
890
|
}
|
|
839
891
|
|
|
840
|
-
|
|
841
|
-
const
|
|
892
|
+
generators?.forEach((generator) => {
|
|
893
|
+
const tree = this.parse({ schema: value, name: name })
|
|
894
|
+
|
|
895
|
+
const promise = generator.schema?.({
|
|
842
896
|
instance: this,
|
|
843
|
-
|
|
844
|
-
|
|
897
|
+
schema: {
|
|
898
|
+
name,
|
|
899
|
+
value,
|
|
900
|
+
tree,
|
|
901
|
+
},
|
|
845
902
|
options: {
|
|
846
903
|
...this.options,
|
|
847
904
|
...options,
|
package/src/SchemaMapper.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type SchemaKeywordMapper = {
|
|
|
12
12
|
strict: { keyword: 'strict' }
|
|
13
13
|
url: { keyword: 'url' }
|
|
14
14
|
readOnly: { keyword: 'readOnly' }
|
|
15
|
+
writeOnly: { keyword: 'writeOnly' }
|
|
15
16
|
uuid: { keyword: 'uuid' }
|
|
16
17
|
email: { keyword: 'email' }
|
|
17
18
|
firstName: { keyword: 'firstName' }
|
|
@@ -34,8 +35,8 @@ export type SchemaKeywordMapper = {
|
|
|
34
35
|
asConst: boolean
|
|
35
36
|
items: Array<{
|
|
36
37
|
name: string | number
|
|
37
|
-
format: 'string' | 'number'
|
|
38
|
-
value?: string | number
|
|
38
|
+
format: 'string' | 'number' | 'boolean'
|
|
39
|
+
value?: string | number | boolean
|
|
39
40
|
}>
|
|
40
41
|
}
|
|
41
42
|
}
|
|
@@ -44,14 +45,14 @@ export type SchemaKeywordMapper = {
|
|
|
44
45
|
keyword: 'const'
|
|
45
46
|
args: {
|
|
46
47
|
name: string | number
|
|
47
|
-
format: 'string' | 'number'
|
|
48
|
-
value?: string | number
|
|
48
|
+
format: 'string' | 'number' | 'boolean'
|
|
49
|
+
value?: string | number | boolean
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
union: { keyword: 'union'; args: Schema[] }
|
|
52
53
|
ref: {
|
|
53
54
|
keyword: 'ref'
|
|
54
|
-
args: { name: string; path: KubbFile.OptionalPath
|
|
55
|
+
args: { name: string; path: KubbFile.OptionalPath }
|
|
55
56
|
}
|
|
56
57
|
matches: { keyword: 'matches'; args?: string }
|
|
57
58
|
boolean: { keyword: 'boolean' }
|
|
@@ -107,6 +108,7 @@ export const schemaKeywords = {
|
|
|
107
108
|
max: 'max',
|
|
108
109
|
optional: 'optional',
|
|
109
110
|
readOnly: 'readOnly',
|
|
111
|
+
writeOnly: 'writeOnly',
|
|
110
112
|
|
|
111
113
|
// custom ones
|
|
112
114
|
object: 'object',
|
package/src/components/Oas.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { Operation } from './Operation.tsx'
|
|
|
4
4
|
import { Schema } from './Schema.tsx'
|
|
5
5
|
|
|
6
6
|
import type { Oas as OasType, Operation as OperationType } from '@kubb/oas'
|
|
7
|
-
import type { KubbNode } from '@kubb/react'
|
|
7
|
+
import type { KubbNode } from '@kubb/react/types'
|
|
8
8
|
import type { OperationGenerator } from '../OperationGenerator.ts'
|
|
9
9
|
|
|
10
10
|
type Props = {
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createContext } from '@kubb/react'
|
|
2
2
|
|
|
3
|
-
import { schemaKeywords } from '../SchemaMapper.ts'
|
|
4
|
-
import { useSchema } from '../hooks/useSchema.ts'
|
|
5
|
-
|
|
6
|
-
import type * as KubbFile from '@kubb/fs/types'
|
|
7
3
|
import type { SchemaObject } from '@kubb/oas'
|
|
8
|
-
import type { KubbNode } from '@kubb/react'
|
|
9
|
-
import type { ReactNode } from 'react'
|
|
10
|
-
import { SchemaGenerator } from '../SchemaGenerator.ts'
|
|
4
|
+
import type { KubbNode } from '@kubb/react/types'
|
|
11
5
|
import type { Schema as SchemaType } from '../SchemaMapper.ts'
|
|
12
|
-
import type { PluginOas } from '../types.ts'
|
|
13
6
|
|
|
14
7
|
export type SchemaContextProps = {
|
|
15
8
|
name: string
|
|
@@ -33,97 +26,4 @@ export function Schema({ name, value, tree = [], children }: Props): KubbNode {
|
|
|
33
26
|
return <SchemaContext.Provider value={{ name, schema: value, tree }}>{children}</SchemaContext.Provider>
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
type FileProps = {
|
|
37
|
-
isTypeOnly?: boolean
|
|
38
|
-
output: string | undefined
|
|
39
|
-
children?: KubbNode
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
Schema.File = function ({ output, isTypeOnly, children }: FileProps): ReactNode {
|
|
43
|
-
const { plugin, pluginManager, mode } = useApp<PluginOas>()
|
|
44
|
-
const { name } = useSchema()
|
|
45
|
-
|
|
46
|
-
if (mode === 'single') {
|
|
47
|
-
const baseName = output as KubbFile.BaseName
|
|
48
|
-
const resolvedPath = pluginManager.resolvePath({
|
|
49
|
-
baseName: '',
|
|
50
|
-
pluginKey: plugin.key,
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
if (!resolvedPath) {
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<Parser language="typescript">
|
|
59
|
-
<File
|
|
60
|
-
baseName={baseName}
|
|
61
|
-
path={resolvedPath}
|
|
62
|
-
meta={{
|
|
63
|
-
pluginKey: plugin.key,
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
66
|
-
{children}
|
|
67
|
-
</File>
|
|
68
|
-
</Parser>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const baseName = `${pluginManager.resolveName({
|
|
73
|
-
name,
|
|
74
|
-
pluginKey: plugin.key,
|
|
75
|
-
type: 'file',
|
|
76
|
-
})}.ts` as const
|
|
77
|
-
const resolvedPath = pluginManager.resolvePath({
|
|
78
|
-
baseName,
|
|
79
|
-
pluginKey: plugin.key,
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
if (!resolvedPath) {
|
|
83
|
-
return null
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<Parser language="typescript">
|
|
88
|
-
<File
|
|
89
|
-
baseName={baseName}
|
|
90
|
-
path={resolvedPath}
|
|
91
|
-
meta={{
|
|
92
|
-
pluginKey: plugin.key,
|
|
93
|
-
}}
|
|
94
|
-
>
|
|
95
|
-
<Schema.Imports isTypeOnly={isTypeOnly} />
|
|
96
|
-
{children}
|
|
97
|
-
</File>
|
|
98
|
-
</Parser>
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
type SchemaImportsProps = {
|
|
103
|
-
isTypeOnly?: boolean
|
|
104
|
-
extName?: KubbFile.Extname
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
Schema.Imports = ({ isTypeOnly, extName }: SchemaImportsProps): ReactNode => {
|
|
108
|
-
const { tree } = useSchema()
|
|
109
|
-
const { path: root } = useFile()
|
|
110
|
-
|
|
111
|
-
const refs = SchemaGenerator.deepSearch(tree, schemaKeywords.ref)
|
|
112
|
-
|
|
113
|
-
return (
|
|
114
|
-
<>
|
|
115
|
-
{refs
|
|
116
|
-
?.map((item, i) => {
|
|
117
|
-
if (!item.args.path) {
|
|
118
|
-
return undefined
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<File.Import key={i} extName={extName} root={root} name={[item.args.name]} path={item.args.path} isTypeOnly={item.args.isTypeOnly ?? isTypeOnly} />
|
|
123
|
-
)
|
|
124
|
-
})
|
|
125
|
-
.filter(Boolean)}
|
|
126
|
-
</>
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
29
|
Schema.Context = SchemaContext
|