@kubb/swagger-ts 2.0.0-beta.3 → 2.0.0-beta.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/swagger-ts",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.4",
4
4
  "description": "Generator swagger-ts",
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
+ "./components": {
29
+ "import": "./dist/components.js",
30
+ "require": "./dist/components.cjs",
31
+ "default": "./dist/components.cjs"
32
+ },
28
33
  "./package.json": "./package.json",
29
34
  "./*": "./*"
30
35
  },
@@ -38,21 +43,24 @@
38
43
  "!/**/__tests__/**"
39
44
  ],
40
45
  "dependencies": {
41
- "change-case": "^4.1.2",
42
46
  "typescript": "^5.3.2",
43
- "@kubb/core": "2.0.0-beta.3",
44
- "@kubb/parser": "2.0.0-beta.2",
45
- "@kubb/swagger": "2.0.0-beta.3"
47
+ "@kubb/core": "2.0.0-beta.4",
48
+ "@kubb/parser": "2.0.0-beta.4",
49
+ "@kubb/react": "2.0.0-beta.4",
50
+ "@kubb/swagger": "2.0.0-beta.4"
46
51
  },
47
52
  "devDependencies": {
53
+ "@types/react": "^18.2.38",
48
54
  "eslint": "^8.54.0",
55
+ "react": "^18.2.0",
49
56
  "tsup": "^8.0.1",
50
57
  "@kubb/eslint-config": "1.1.8",
51
58
  "@kubb/ts-config": "0.1.0",
52
59
  "@kubb/tsup-config": "1.1.8"
53
60
  },
54
61
  "peerDependencies": {
55
- "typescript": "^5.3.0"
62
+ "typescript": "^5.3.0",
63
+ "@kubb/react": "2.0.0-beta.4"
56
64
  },
57
65
  "packageManager": "pnpm@8.3.0",
58
66
  "engines": {
@@ -0,0 +1,50 @@
1
+ import { createRoot } from '@kubb/react'
2
+ import { OperationGenerator as Generator } from '@kubb/swagger'
3
+
4
+ import { Mutation } from './components/Mutation.tsx'
5
+ import { Query } from './components/Query.tsx'
6
+
7
+ import type { KubbFile } from '@kubb/core'
8
+ import type { AppContextProps } from '@kubb/react'
9
+ import type { Operation, OperationMethodResult, OperationSchemas } from '@kubb/swagger'
10
+ import type { FileMeta, PluginOptions } from './types.ts'
11
+
12
+ export class OperationGenerator extends Generator<PluginOptions['resolvedOptions'], PluginOptions> {
13
+ async all(): Promise<KubbFile.File | null> {
14
+ return null
15
+ }
16
+
17
+ async get(operation: Operation, schemas: OperationSchemas, options: PluginOptions['resolvedOptions']): OperationMethodResult<FileMeta> {
18
+ const { oas, pluginManager, plugin, mode = 'directory' } = this.context
19
+
20
+ const root = createRoot<AppContextProps<PluginOptions['appMeta']>>({ logger: pluginManager.logger })
21
+ root.render(
22
+ <Query.File mode={mode} />,
23
+ { meta: { oas, pluginManager, plugin: { ...plugin, options }, schemas, operation } },
24
+ )
25
+
26
+ return root.files
27
+ }
28
+
29
+ async post(operation: Operation, schemas: OperationSchemas, options: PluginOptions['resolvedOptions']): OperationMethodResult<FileMeta> {
30
+ const { oas, pluginManager, plugin, mode = 'directory' } = this.context
31
+
32
+ const root = createRoot<AppContextProps<PluginOptions['appMeta']>>({ logger: pluginManager.logger })
33
+ root.render(
34
+ <Mutation.File mode={mode} />,
35
+ { meta: { oas, pluginManager, plugin: { ...plugin, options }, schemas, operation } },
36
+ )
37
+
38
+ return root.files
39
+ }
40
+
41
+ async put(operation: Operation, schemas: OperationSchemas, options: PluginOptions['resolvedOptions']): OperationMethodResult<FileMeta> {
42
+ return this.post(operation, schemas, options)
43
+ }
44
+ async patch(operation: Operation, schemas: OperationSchemas, options: PluginOptions['resolvedOptions']): OperationMethodResult<FileMeta> {
45
+ return this.post(operation, schemas, options)
46
+ }
47
+ async delete(operation: Operation, schemas: OperationSchemas, options: PluginOptions['resolvedOptions']): OperationMethodResult<FileMeta> {
48
+ return this.post(operation, schemas, options)
49
+ }
50
+ }
@@ -0,0 +1,58 @@
1
+ import transformers from '@kubb/core/transformers'
2
+ import { print } from '@kubb/parser'
3
+ import { OasBuilder } from '@kubb/swagger'
4
+ import { refsSorter } from '@kubb/swagger/utils'
5
+
6
+ import { TypeGenerator } from './TypeGenerator.ts'
7
+
8
+ import type { KubbFile } from '@kubb/core'
9
+ import type { ImportMeta } from '@kubb/swagger'
10
+ import type { PluginOptions } from './types.ts'
11
+
12
+ export class TypeBuilder extends OasBuilder<PluginOptions['resolvedOptions']> {
13
+ build(name?: string): Required<Pick<KubbFile.File, 'imports' | 'source'>> {
14
+ const importMeta: ImportMeta[] = []
15
+ const codes: string[] = []
16
+
17
+ const generated = this.items
18
+ .filter((operationSchema) => (name ? operationSchema.name === name : true))
19
+ .sort(transformers.nameSorter)
20
+ .map((operationSchema) => {
21
+ const generator = new TypeGenerator(this.options, this.context)
22
+ const sources = generator.build({
23
+ schema: operationSchema.schema,
24
+ baseName: operationSchema.name,
25
+ description: operationSchema.description,
26
+ keysToOmit: operationSchema.keysToOmit,
27
+ })
28
+
29
+ importMeta.push(...generator.imports)
30
+
31
+ return {
32
+ import: {
33
+ refs: generator.refs,
34
+ name: operationSchema.name,
35
+ },
36
+ sources,
37
+ }
38
+ })
39
+ .sort(refsSorter)
40
+
41
+ generated.forEach((item) => {
42
+ codes.push(print(item.sources))
43
+ })
44
+
45
+ const imports: KubbFile.Import[] = importMeta.map((item) => {
46
+ return {
47
+ name: [item.ref.propertyName],
48
+ path: item.path,
49
+ isTypeOnly: item.isTypeOnly,
50
+ }
51
+ })
52
+
53
+ return {
54
+ imports,
55
+ source: transformers.combineCodes(codes),
56
+ }
57
+ }
58
+ }
@@ -1,30 +1,26 @@
1
- import { SchemaGenerator } from '@kubb/core'
1
+ import { Generator } from '@kubb/core'
2
+ import transformers from '@kubb/core/transformers'
2
3
  import { getUniqueName } from '@kubb/core/utils'
3
4
  import * as factory from '@kubb/parser/factory'
4
5
  import { getSchemaFactory, isReference } from '@kubb/swagger/utils'
5
6
 
6
- import { camelCase } from 'change-case'
7
+ import { pluginKey } from './plugin.ts'
7
8
 
8
- import type { PluginContext } from '@kubb/core'
9
+ import type { PluginManager } from '@kubb/core'
9
10
  import type { ts } from '@kubb/parser'
10
- import type { Oas, OasTypes, OpenAPIV3, OpenAPIV3_1, Refs } from '@kubb/swagger'
11
- import type { Options as CaseOptions } from 'change-case'
11
+ import type { ImportMeta, Oas, OasTypes, OpenAPIV3, OpenAPIV3_1, Refs } from '@kubb/swagger'
12
+ import type { PluginOptions } from './types.ts'
12
13
 
13
14
  // based on https://github.com/cellular/oazapfts/blob/7ba226ebb15374e8483cc53e7532f1663179a22c/src/codegen/generate.ts#L398
14
15
 
15
- type Options = {
16
+ type Context = {
16
17
  oas: Oas
17
- usedEnumNames: Record<string, number>
18
-
19
- withJSDocs?: boolean
20
- resolveName: PluginContext['resolveName']
21
- enumType: 'enum' | 'asConst' | 'asPascalConst'
22
- dateType: 'string' | 'date'
23
- optionalType: 'questionToken' | 'undefined' | 'questionTokenAndUndefined'
18
+ pluginManager: PluginManager
24
19
  }
25
20
 
26
- export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObject, ts.Node[]> {
21
+ export class TypeGenerator extends Generator<PluginOptions['resolvedOptions'], Context> {
27
22
  refs: Refs = {}
23
+ imports: ImportMeta[] = []
28
24
 
29
25
  extraNodes: ts.Node[] = []
30
26
 
@@ -33,19 +29,6 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
33
29
  // Keep track of already used type aliases
34
30
  #usedAliasNames: Record<string, number> = {}
35
31
 
36
- #caseOptions: CaseOptions = {
37
- delimiter: '',
38
- stripRegexp: /[^A-Z0-9$]/gi,
39
- }
40
-
41
- constructor(
42
- options: Options,
43
- ) {
44
- super(options)
45
-
46
- return this
47
- }
48
-
49
32
  build({
50
33
  schema,
51
34
  baseName,
@@ -58,7 +41,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
58
41
  keysToOmit?: string[]
59
42
  }): ts.Node[] {
60
43
  const nodes: ts.Node[] = []
61
- const type = this.#getTypeFromSchema(schema, baseName)
44
+ const type = this.getTypeFromSchema(schema, baseName)
62
45
 
63
46
  if (!type) {
64
47
  return this.extraNodes
@@ -66,7 +49,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
66
49
 
67
50
  const node = factory.createTypeAliasDeclaration({
68
51
  modifiers: [factory.modifiers.export],
69
- name: this.options.resolveName({ name: baseName }) || baseName,
52
+ name: this.context.pluginManager.resolveName({ name: baseName, pluginKey, type: 'type' }),
70
53
  type: keysToOmit?.length ? factory.createOmitDeclaration({ keys: keysToOmit, type, nonNullable: true }) : type,
71
54
  })
72
55
 
@@ -74,7 +57,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
74
57
  nodes.push(
75
58
  factory.appendJSDocToNode({
76
59
  node,
77
- comments: [`@description ${description}`],
60
+ comments: [`@description ${transformers.trim(description)}`],
78
61
  }),
79
62
  )
80
63
  } else {
@@ -97,7 +80,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
97
80
  * Delegates to getBaseTypeFromSchema internally and
98
81
  * optionally adds a union with null.
99
82
  */
100
- #getTypeFromSchema(schema?: OasTypes.SchemaObject, name?: string): ts.TypeNode | null {
83
+ getTypeFromSchema(schema?: OasTypes.SchemaObject, name?: string): ts.TypeNode | null {
101
84
  const type = this.#getBaseTypeFromSchema(schema, name)
102
85
 
103
86
  if (!type) {
@@ -114,7 +97,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
114
97
  /**
115
98
  * Recursively creates a type literal with the given props.
116
99
  */
117
- #getTypeFromProperties(baseSchema?: OasTypes.SchemaObject, baseName?: string) {
100
+ #getTypeFromProperties(baseSchema?: OasTypes.SchemaObject, baseName?: string): ts.TypeNode | null {
118
101
  const { optionalType } = this.options
119
102
  const properties = baseSchema?.properties || {}
120
103
  const required = baseSchema?.required
@@ -124,39 +107,38 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
124
107
  const schema = properties[name] as OasTypes.SchemaObject
125
108
 
126
109
  const isRequired = Array.isArray(required) ? required.includes(name) : !!required
127
- let type = this.#getTypeFromSchema(schema, this.options.resolveName({ name: `${baseName || ''} ${name}` }))
110
+ let type = this.getTypeFromSchema(schema, this.context.pluginManager.resolveName({ name: `${baseName || ''} ${name}`, pluginKey, type: 'type' }))
128
111
 
129
112
  if (!type) {
130
113
  return null
131
114
  }
132
115
 
133
- if (!isRequired && ['undefined', 'questionTokenAndUndefined'].includes(optionalType)) {
116
+ if (!isRequired && ['undefined', 'questionTokenAndUndefined'].includes(optionalType as string)) {
134
117
  type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
135
118
  }
136
119
  const propertySignature = factory.createPropertySignature({
137
- questionToken: ['questionToken', 'questionTokenAndUndefined'].includes(optionalType) && !isRequired,
120
+ questionToken: ['questionToken', 'questionTokenAndUndefined'].includes(optionalType as string) && !isRequired,
138
121
  name,
139
122
  type: type as ts.TypeNode,
140
123
  readOnly: schema.readOnly,
141
124
  })
142
- if (this.options.withJSDocs) {
143
- return factory.appendJSDocToNode({
144
- node: propertySignature,
145
- comments: [
146
- schema.description ? `@description ${schema.description}` : undefined,
147
- schema.type ? `@type ${schema.type?.toString()}${isRequired ? '' : ' | undefined'} ${schema.format || ''}` : undefined,
148
- schema.example ? `@example ${schema.example as string}` : undefined,
149
- schema.deprecated ? `@deprecated` : undefined,
150
- schema.default !== undefined && typeof schema.default === 'string' ? `@default '${schema.default}'` : undefined,
151
- schema.default !== undefined && typeof schema.default !== 'string' ? `@default ${schema.default as string}` : undefined,
152
- ].filter(Boolean),
153
- })
154
- }
125
+
126
+ return factory.appendJSDocToNode({
127
+ node: propertySignature,
128
+ comments: [
129
+ schema.description ? `@description ${schema.description}` : undefined,
130
+ schema.type ? `@type ${schema.type?.toString()}${isRequired ? '' : ' | undefined'} ${schema.format || ''}` : undefined,
131
+ schema.example ? `@example ${schema.example as string}` : undefined,
132
+ schema.deprecated ? `@deprecated` : undefined,
133
+ schema.default !== undefined && typeof schema.default === 'string' ? `@default '${schema.default}'` : undefined,
134
+ schema.default !== undefined && typeof schema.default !== 'string' ? `@default ${schema.default as string}` : undefined,
135
+ ].filter(Boolean),
136
+ })
155
137
 
156
138
  return propertySignature
157
139
  })
158
140
  if (additionalProperties) {
159
- const type = additionalProperties === true ? factory.keywordTypeNodes.any : this.#getTypeFromSchema(additionalProperties as OasTypes.SchemaObject)
141
+ const type = additionalProperties === true ? factory.keywordTypeNodes.any : this.getTypeFromSchema(additionalProperties as OasTypes.SchemaObject)
160
142
 
161
143
  if (type) {
162
144
  members.push(factory.createIndexSignature(type))
@@ -177,18 +159,26 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
177
159
  }
178
160
 
179
161
  const originalName = getUniqueName($ref.replace(/.+\//, ''), this.#usedAliasNames)
180
- const propertyName = this.options.resolveName({ name: originalName }) || originalName
162
+ const propertyName = this.context.pluginManager.resolveName({ name: originalName, pluginKey, type: 'type' })
181
163
 
182
164
  ref = this.refs[$ref] = {
183
165
  propertyName,
184
166
  originalName,
185
167
  }
186
168
 
169
+ const path = this.context.pluginManager.resolvePath({ baseName: propertyName, pluginKey })
170
+
171
+ this.imports.push({
172
+ ref,
173
+ path: path || '',
174
+ isTypeOnly: true,
175
+ })
176
+
187
177
  return factory.createTypeReferenceNode(ref.propertyName, undefined)
188
178
  }
189
179
 
190
180
  #getParsedSchema(schema?: OasTypes.SchemaObject) {
191
- const parsedSchema = getSchemaFactory(this.options.oas)(schema)
181
+ const parsedSchema = getSchemaFactory(this.context.oas)(schema)
192
182
  return parsedSchema
193
183
  }
194
184
 
@@ -218,7 +208,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
218
208
  withParentheses: true,
219
209
  nodes: schema.oneOf
220
210
  .map((item) => {
221
- return item && this.#getBaseTypeFromSchema(item as OasTypes.SchemaObject)
211
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
222
212
  })
223
213
  .filter((item) => {
224
214
  return item && item !== factory.keywordTypeNodes.any
@@ -227,7 +217,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
227
217
 
228
218
  if (schemaWithoutOneOf.properties) {
229
219
  return factory.createIntersectionDeclaration({
230
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutOneOf, baseName), union].filter(Boolean),
220
+ nodes: [this.getTypeFromSchema(schemaWithoutOneOf, baseName), union].filter(Boolean),
231
221
  })
232
222
  }
233
223
 
@@ -241,7 +231,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
241
231
  withParentheses: true,
242
232
  nodes: schema.anyOf
243
233
  .map((item) => {
244
- return item && this.#getBaseTypeFromSchema(item as OasTypes.SchemaObject)
234
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
245
235
  })
246
236
  .filter((item) => {
247
237
  return item && item !== factory.keywordTypeNodes.any
@@ -250,7 +240,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
250
240
 
251
241
  if (schemaWithoutAnyOf.properties) {
252
242
  return factory.createIntersectionDeclaration({
253
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutAnyOf, baseName), union].filter(Boolean),
243
+ nodes: [this.getTypeFromSchema(schemaWithoutAnyOf, baseName), union].filter(Boolean),
254
244
  })
255
245
  }
256
246
 
@@ -264,7 +254,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
264
254
  withParentheses: true,
265
255
  nodes: schema.allOf
266
256
  .map((item) => {
267
- return item && this.#getBaseTypeFromSchema(item as OasTypes.SchemaObject)
257
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
268
258
  })
269
259
  .filter((item) => {
270
260
  return item && item !== factory.keywordTypeNodes.any
@@ -273,7 +263,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
273
263
 
274
264
  if (schemaWithoutAllOf.properties) {
275
265
  return factory.createIntersectionDeclaration({
276
- nodes: [this.#getBaseTypeFromSchema(schemaWithoutAllOf, baseName), and].filter(Boolean),
266
+ nodes: [this.getTypeFromSchema(schemaWithoutAllOf, baseName), and].filter(Boolean),
277
267
  })
278
268
  }
279
269
 
@@ -296,13 +286,13 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
296
286
 
297
287
  this.extraNodes.push(
298
288
  ...factory.createEnumDeclaration({
299
- name: camelCase(enumName, this.#caseOptions),
300
- typeName: this.options.resolveName({ name: enumName }),
289
+ name: transformers.camelCase(enumName),
290
+ typeName: this.context.pluginManager.resolveName({ name: enumName, pluginKey, type: 'type' }),
301
291
  enums,
302
292
  type: this.options.enumType,
303
293
  }),
304
294
  )
305
- return factory.createTypeReferenceNode(this.options.resolveName({ name: enumName }), undefined)
295
+ return factory.createTypeReferenceNode(this.context.pluginManager.resolveName({ name: enumName, pluginKey, type: 'type' }), undefined)
306
296
  }
307
297
 
308
298
  if (schema.enum) {
@@ -315,7 +305,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
315
305
 
316
306
  if ('items' in schema) {
317
307
  // items -> array
318
- const node = this.#getTypeFromSchema(schema.items as OasTypes.SchemaObject, baseName)
308
+ const node = this.getTypeFromSchema(schema.items as OasTypes.SchemaObject, baseName)
319
309
  if (node) {
320
310
  return factory.createArrayTypeNode(node)
321
311
  }
@@ -332,7 +322,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
332
322
  return factory.createTupleDeclaration({
333
323
  nodes: prefixItems.map((item) => {
334
324
  // no baseType so we can fall back on an union when using enum
335
- return this.#getBaseTypeFromSchema(item, undefined)
325
+ return this.getTypeFromSchema(item, undefined)
336
326
  }) as Array<ts.TypeNode>,
337
327
  })
338
328
  }
@@ -349,7 +339,7 @@ export class TypeGenerator extends SchemaGenerator<Options, OasTypes.SchemaObjec
349
339
 
350
340
  return factory.createUnionDeclaration({
351
341
  nodes: [
352
- this.#getBaseTypeFromSchema(
342
+ this.getTypeFromSchema(
353
343
  {
354
344
  ...schema,
355
345
  type,
@@ -0,0 +1,137 @@
1
+ import transformers from '@kubb/core/transformers'
2
+ import { print } from '@kubb/parser'
3
+ import * as factory from '@kubb/parser/factory'
4
+ import { File, usePlugin, usePluginManager } from '@kubb/react'
5
+ import { useOas, useOperation, useOperationFile, useOperationName, useSchemas } from '@kubb/swagger/hooks'
6
+
7
+ import { TypeBuilder } from '../TypeBuilder.ts'
8
+
9
+ import type { ts } from '@kubb/parser'
10
+ import type { Operation, OperationSchemas } from '@kubb/swagger'
11
+ import type { ReactNode } from 'react'
12
+ import type { FileMeta, PluginOptions } from '../types.ts'
13
+ import type { KubbFile } from '@kubb/core'
14
+
15
+ type Props = {
16
+ builder: TypeBuilder
17
+ }
18
+
19
+ function printCombinedSchema(name: string, operation: Operation, schemas: OperationSchemas): string {
20
+ const properties: Record<string, ts.TypeNode> = {
21
+ 'response': factory.createTypeReferenceNode(
22
+ factory.createIdentifier(schemas.response.name),
23
+ undefined,
24
+ ),
25
+ }
26
+
27
+ if (schemas.request) {
28
+ properties['request'] = factory.createTypeReferenceNode(
29
+ factory.createIdentifier(schemas.request.name),
30
+ undefined,
31
+ )
32
+ }
33
+
34
+ if (schemas.pathParams) {
35
+ properties['pathParams'] = factory.createTypeReferenceNode(
36
+ factory.createIdentifier(schemas.pathParams.name),
37
+ undefined,
38
+ )
39
+ }
40
+
41
+ if (schemas.queryParams) {
42
+ properties['queryParams'] = factory.createTypeReferenceNode(
43
+ factory.createIdentifier(schemas.queryParams.name),
44
+ undefined,
45
+ )
46
+ }
47
+
48
+ if (schemas.headerParams) {
49
+ properties['headerParams'] = factory.createTypeReferenceNode(
50
+ factory.createIdentifier(schemas.headerParams.name),
51
+ undefined,
52
+ )
53
+ }
54
+
55
+ if (schemas.errors) {
56
+ properties['errors'] = factory.createUnionDeclaration({
57
+ nodes: schemas.errors.map(error => {
58
+ return factory.createTypeReferenceNode(
59
+ factory.createIdentifier(error.name),
60
+ undefined,
61
+ )
62
+ }),
63
+ })!
64
+ }
65
+
66
+ const namespaceNode = factory.createNamespaceDeclaration({
67
+ name: operation.method === 'get' ? `${name}Query` : `${name}Mutation`,
68
+ statements: Object.keys(properties).map(key => {
69
+ const type = properties[key]
70
+ if (!type) {
71
+ return undefined
72
+ }
73
+ return factory.createTypeAliasDeclaration({
74
+ modifiers: [factory.modifiers.export],
75
+ name: transformers.pascalCase(key),
76
+ type,
77
+ })
78
+ }).filter(Boolean),
79
+ })
80
+
81
+ return print(namespaceNode)
82
+ }
83
+
84
+ export function Mutation({
85
+ builder,
86
+ }: Props): ReactNode {
87
+ const { source } = builder.build()
88
+
89
+ return (
90
+ <>
91
+ {source}
92
+ </>
93
+ )
94
+ }
95
+
96
+ type FileProps = {
97
+ mode: KubbFile.Mode
98
+ }
99
+
100
+ Mutation.File = function({ mode }: FileProps): ReactNode {
101
+ const { options } = usePlugin<PluginOptions>()
102
+
103
+ const schemas = useSchemas()
104
+ const pluginManager = usePluginManager()
105
+ const oas = useOas()
106
+ const file = useOperationFile()
107
+ const factoryName = useOperationName({ type: 'type' })
108
+ const operation = useOperation()
109
+
110
+ const builder = new TypeBuilder(options, { oas, pluginManager })
111
+ .add(schemas.pathParams)
112
+ .add(schemas.queryParams)
113
+ .add(schemas.headerParams)
114
+ .add(schemas.response)
115
+ .add(schemas.request)
116
+ .add(schemas.errors)
117
+
118
+ const { source, imports } = builder.build()
119
+
120
+ return (
121
+ <>
122
+ <File<FileMeta>
123
+ baseName={file.baseName}
124
+ path={file.path}
125
+ meta={file.meta}
126
+ >
127
+ {mode === 'directory' && imports.map((item, index) => {
128
+ return <File.Import key={index} root={file.path} {...item} />
129
+ })}
130
+ <File.Source>
131
+ {source}
132
+ {printCombinedSchema(factoryName, operation, schemas)}
133
+ </File.Source>
134
+ </File>
135
+ </>
136
+ )
137
+ }