@kubb/plugin-oas 3.0.0-alpha.3 → 3.0.0-alpha.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +13 -4
  2. package/dist/OperationGenerator-DhPriVDJ.d.cts +554 -0
  3. package/dist/OperationGenerator-DhPriVDJ.d.ts +554 -0
  4. package/dist/Schema-BfZVq77f.d.cts +22 -0
  5. package/dist/Schema-IlDbvlbP.d.ts +22 -0
  6. package/dist/chunk-4H2KTGZM.cjs +92 -0
  7. package/dist/chunk-4H2KTGZM.cjs.map +1 -0
  8. package/dist/chunk-ABIWUCV7.js +88 -0
  9. package/dist/chunk-ABIWUCV7.js.map +1 -0
  10. package/dist/chunk-ABOQ73FL.cjs +36 -0
  11. package/dist/chunk-ABOQ73FL.cjs.map +1 -0
  12. package/dist/chunk-BG77DP54.js +30 -0
  13. package/dist/chunk-BG77DP54.js.map +1 -0
  14. package/dist/chunk-GF26SDHQ.js +28 -0
  15. package/dist/chunk-GF26SDHQ.js.map +1 -0
  16. package/dist/chunk-PADR76WZ.cjs +4 -0
  17. package/dist/chunk-PADR76WZ.cjs.map +1 -0
  18. package/dist/chunk-QAFBZLJA.cjs +48 -0
  19. package/dist/chunk-QAFBZLJA.cjs.map +1 -0
  20. package/dist/chunk-QT6ZFRNJ.cjs +752 -0
  21. package/dist/chunk-QT6ZFRNJ.cjs.map +1 -0
  22. package/dist/chunk-R47XMJ32.js +3 -0
  23. package/dist/chunk-R47XMJ32.js.map +1 -0
  24. package/dist/chunk-V2JO6RHI.js +744 -0
  25. package/dist/chunk-V2JO6RHI.js.map +1 -0
  26. package/dist/chunk-XNCEFOE6.js +45 -0
  27. package/dist/chunk-XNCEFOE6.js.map +1 -0
  28. package/dist/chunk-ZWHQ54JM.cjs +32 -0
  29. package/dist/chunk-ZWHQ54JM.cjs.map +1 -0
  30. package/dist/components.cjs +20 -12
  31. package/dist/components.cjs.map +1 -1
  32. package/dist/components.d.cts +4 -7
  33. package/dist/components.d.ts +4 -7
  34. package/dist/components.js +3 -12
  35. package/dist/components.js.map +1 -1
  36. package/dist/generators.cjs +14 -0
  37. package/dist/generators.cjs.map +1 -0
  38. package/dist/generators.d.cts +9 -0
  39. package/dist/generators.d.ts +9 -0
  40. package/dist/generators.js +5 -0
  41. package/dist/generators.js.map +1 -0
  42. package/dist/hooks.cjs +102 -57
  43. package/dist/hooks.cjs.map +1 -1
  44. package/dist/hooks.d.cts +41 -10
  45. package/dist/hooks.d.ts +41 -10
  46. package/dist/hooks.js +91 -53
  47. package/dist/hooks.js.map +1 -1
  48. package/dist/index.cjs +192 -258
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +3 -6
  51. package/dist/index.d.ts +3 -6
  52. package/dist/index.js +135 -228
  53. package/dist/index.js.map +1 -1
  54. package/dist/utils.cjs +32 -87
  55. package/dist/utils.cjs.map +1 -1
  56. package/dist/utils.d.cts +8 -43
  57. package/dist/utils.d.ts +8 -43
  58. package/dist/utils.js +8 -86
  59. package/dist/utils.js.map +1 -1
  60. package/package.json +20 -14
  61. package/src/OperationGenerator.ts +23 -30
  62. package/src/SchemaGenerator.ts +80 -23
  63. package/src/SchemaMapper.ts +7 -5
  64. package/src/components/Oas.tsx +1 -1
  65. package/src/components/Operation.tsx +1 -1
  66. package/src/components/Schema.tsx +2 -102
  67. package/src/{parser.tsx → generator.tsx} +35 -22
  68. package/src/generators/index.ts +1 -0
  69. package/src/generators/jsonGenerator.ts +32 -0
  70. package/src/hooks/index.ts +2 -0
  71. package/src/hooks/useOperationManager.ts +77 -29
  72. package/src/hooks/useSchemaManager.ts +77 -0
  73. package/src/index.ts +3 -3
  74. package/src/plugin.ts +67 -59
  75. package/src/types.ts +24 -16
  76. package/src/utils/getParams.ts +2 -2
  77. package/src/utils/getSchemaFactory.ts +1 -1
  78. package/src/utils/index.ts +2 -2
  79. package/src/utils/parseFromConfig.ts +7 -7
  80. package/dist/OperationGenerator-D7rSlflc.d.cts +0 -158
  81. package/dist/OperationGenerator-vw0Zf-Mi.d.ts +0 -158
  82. package/dist/Schema-DxyOIX7q.d.cts +0 -35
  83. package/dist/Schema-gHgN14i2.d.ts +0 -35
  84. package/dist/SchemaMapper-BM1IGWqD.d.cts +0 -248
  85. package/dist/SchemaMapper-BM1IGWqD.d.ts +0 -248
  86. package/dist/chunk-264TCCJF.cjs +0 -3973
  87. package/dist/chunk-264TCCJF.cjs.map +0 -1
  88. package/dist/chunk-7KIEQOVZ.cjs +0 -7
  89. package/dist/chunk-7KIEQOVZ.cjs.map +0 -1
  90. package/dist/chunk-FZN3PBEK.js +0 -3973
  91. package/dist/chunk-FZN3PBEK.js.map +0 -1
  92. package/dist/chunk-P42X362U.cjs +0 -101
  93. package/dist/chunk-P42X362U.cjs.map +0 -1
  94. package/dist/chunk-QLJIL3U5.cjs +0 -35
  95. package/dist/chunk-QLJIL3U5.cjs.map +0 -1
  96. package/dist/chunk-TWKZEVSM.js +0 -7
  97. package/dist/chunk-TWKZEVSM.js.map +0 -1
  98. package/dist/chunk-UB552H4J.js +0 -101
  99. package/dist/chunk-UB552H4J.js.map +0 -1
  100. package/dist/chunk-Y4V7HHX7.js +0 -35
  101. package/dist/chunk-Y4V7HHX7.js.map +0 -1
  102. package/dist/types-C2RXaY0_.d.cts +0 -143
  103. package/dist/types-C2RXaY0_.d.ts +0 -143
  104. package/src/utils/getGroupedByTagFiles.ts +0 -82
  105. 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",
3
+ "version": "3.0.0-alpha.30",
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.11.0",
71
- "@kubb/core": "3.0.0-alpha.3",
72
- "@kubb/fs": "3.0.0-alpha.3",
73
- "@kubb/oas": "3.0.0-alpha.3",
74
- "@kubb/react": "3.0.0-alpha.3"
78
+ "remeda": "^2.14.0",
79
+ "@kubb/core": "3.0.0-alpha.30",
80
+ "@kubb/fs": "3.0.0-alpha.30",
81
+ "@kubb/react": "3.0.0-alpha.30",
82
+ "@kubb/oas": "3.0.0-alpha.30"
75
83
  },
76
84
  "devDependencies": {
77
- "@types/react": "^18.3.4",
78
- "@types/react-dom": "^18.3.0",
85
+ "@types/react": "^18.3.10",
79
86
  "react": "^18.3.1",
80
- "tsup": "^8.2.4",
81
- "typescript": "^5.5.4",
82
- "@kubb/config-biome": "3.0.0-alpha.3",
83
- "@kubb/config-ts": "3.0.0-alpha.3",
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.30",
90
+ "@kubb/config-tsup": "3.0.0-alpha.30"
85
91
  },
86
92
  "peerDependencies": {
87
- "@kubb/react": "3.0.0-alpha.3"
93
+ "@kubb/react": "3.0.0-alpha.30"
88
94
  },
89
95
  "engines": {
90
96
  "node": ">=20"
@@ -1,4 +1,4 @@
1
- import { type FileMetaBase, Generator } from '@kubb/core'
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
- export type GetOperationGeneratorOptions<T extends OperationGenerator<any, any, any>> = T extends OperationGenerator<infer Options, any, any> ? Options : never
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 Generator<TOptions, Context<TOptions, TPluginOptions>> {
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<TOptions> {
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
- async build(...parsers: Array<Parser<Extract<TOptions, PluginFactoryOptions>>>): Promise<Array<KubbFile.File<TFileMeta>>> {
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
- parsers?.forEach((parser) => {
290
- const promise = parser.operation?.({
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
- parsers?.forEach((parser) => {
313
- const promise = parser.operations?.({
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: TOptions): OperationMethodResult<TFileMeta> {
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: TOptions): OperationMethodResult<TFileMeta> {
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: TOptions): OperationMethodResult<TFileMeta> {
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: TOptions): OperationMethodResult<TFileMeta> {
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: TOptions): OperationMethodResult<TFileMeta> {
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: TOptions): OperationMethodResult<TFileMeta> {
361
+ async delete(operation: Operation, options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
369
362
  return []
370
363
  }
371
364
 
@@ -1,4 +1,4 @@
1
- import { type FileMetaBase, Generator } from '@kubb/core'
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 Generator<TOptions, Context<TOptions, TPluginOptions>> {
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
- extName: '.ts',
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, isTypeOnly: false },
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
- return [...this.parse({ schema: schemaWithoutOneOf, name, parentName }), union, ...baseItems]
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(...parsers: Array<Parser<Extract<TOptions, PluginFactoryOptions>>>): Promise<Array<KubbFile.File<TFileMeta>>> {
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, schema]) => {
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, schema, {
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
- parsers?.forEach((parser) => {
841
- const promise = parser.schema?.({
892
+ generators?.forEach((generator) => {
893
+ const tree = this.parse({ schema: value, name: name })
894
+
895
+ const promise = generator.schema?.({
842
896
  instance: this,
843
- name,
844
- schema,
897
+ schema: {
898
+ name,
899
+ value,
900
+ tree,
901
+ },
845
902
  options: {
846
903
  ...this.options,
847
904
  ...options,
@@ -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; isTypeOnly?: boolean }
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',
@@ -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,7 +1,7 @@
1
1
  import { createContext } from '@kubb/react'
2
2
 
3
3
  import type { Operation as OperationType } from '@kubb/oas'
4
- import type { KubbNode } from '@kubb/react'
4
+ import type { KubbNode } from '@kubb/react/types'
5
5
 
6
6
  type Props = {
7
7
  operation: OperationType
@@ -1,15 +1,8 @@
1
- import { File, Parser, createContext, useApp, useFile } from '@kubb/react'
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