@kubb/swagger-ts 2.0.0-canary.20231030T125204 → 2.0.0

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 (51) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-D7MXSC5P.cjs +787 -0
  3. package/dist/chunk-D7MXSC5P.cjs.map +1 -0
  4. package/dist/chunk-HCQOGZHE.js +760 -0
  5. package/dist/chunk-HCQOGZHE.js.map +1 -0
  6. package/dist/components.cjs +20 -0
  7. package/dist/components.cjs.map +1 -0
  8. package/dist/components.d.cts +69 -0
  9. package/dist/components.d.ts +69 -0
  10. package/dist/components.js +6 -0
  11. package/dist/components.js.map +1 -0
  12. package/dist/index-sycg8owy.d.cts +392 -0
  13. package/dist/index-sycg8owy.d.ts +392 -0
  14. package/dist/index.cjs +14 -652
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +11 -78
  17. package/dist/index.d.ts +11 -78
  18. package/dist/index.js +3 -625
  19. package/dist/index.js.map +1 -1
  20. package/dist/oas.cjs +4 -0
  21. package/dist/oas.cjs.map +1 -0
  22. package/dist/oas.d.cts +6 -0
  23. package/dist/oas.d.ts +6 -0
  24. package/dist/oas.js +5 -0
  25. package/dist/oas.js.map +1 -0
  26. package/dist/types-IAThMYCO.d.cts +105 -0
  27. package/dist/types-IAThMYCO.d.ts +105 -0
  28. package/package.json +27 -18
  29. package/src/OperationGenerator.tsx +63 -0
  30. package/src/TypeBuilder.ts +58 -0
  31. package/src/TypeGenerator.ts +396 -0
  32. package/src/components/Mutation.tsx +138 -0
  33. package/src/components/Oas.tsx +84 -0
  34. package/src/components/Query.tsx +137 -0
  35. package/src/components/index.ts +3 -0
  36. package/src/index.ts +6 -0
  37. package/src/oas/index.ts +7 -0
  38. package/src/oas/infer.ts +58 -0
  39. package/src/oas/mappers.ts +93 -0
  40. package/src/oas/model.ts +38 -0
  41. package/src/oas/requestParams.ts +170 -0
  42. package/src/oas/response.ts +39 -0
  43. package/src/oas/security.ts +158 -0
  44. package/src/plugin.ts +177 -0
  45. package/src/types.ts +110 -0
  46. package/dist/hooks.cjs +0 -656
  47. package/dist/hooks.cjs.map +0 -1
  48. package/dist/hooks.d.cts +0 -6
  49. package/dist/hooks.d.ts +0 -6
  50. package/dist/hooks.js +0 -634
  51. package/dist/hooks.js.map +0 -1
@@ -0,0 +1,396 @@
1
+ import { Generator } from '@kubb/core'
2
+ import transformers from '@kubb/core/transformers'
3
+ import { getUniqueName } from '@kubb/core/utils'
4
+ import * as factory from '@kubb/parser/factory'
5
+ import { keywordTypeNodes } from '@kubb/parser/factory'
6
+ import { getSchemaFactory, isReference } from '@kubb/swagger/utils'
7
+
8
+ import { pluginKey } from './plugin.ts'
9
+
10
+ import type { PluginManager } from '@kubb/core'
11
+ import type { ts } from '@kubb/parser'
12
+ import type { ImportMeta, Refs } from '@kubb/swagger'
13
+ import type { Oas, OasTypes, OpenAPIV3, OpenAPIV3_1 } from '@kubb/swagger/oas'
14
+ import type { PluginOptions } from './types.ts'
15
+
16
+ // based on https://github.com/cellular/oazapfts/blob/7ba226ebb15374e8483cc53e7532f1663179a22c/src/codegen/generate.ts#L398
17
+
18
+ type Context = {
19
+ oas: Oas
20
+ pluginManager: PluginManager
21
+ }
22
+
23
+ export class TypeGenerator extends Generator<PluginOptions['resolvedOptions'], Context> {
24
+ refs: Refs = {}
25
+ imports: ImportMeta[] = []
26
+
27
+ extraNodes: ts.Node[] = []
28
+
29
+ aliases: ts.TypeAliasDeclaration[] = []
30
+
31
+ // Keep track of already used type aliases
32
+ #usedAliasNames: Record<string, number> = {}
33
+
34
+ build({
35
+ schema,
36
+ baseName,
37
+ description,
38
+ keysToOmit,
39
+ }: {
40
+ schema: OasTypes.SchemaObject
41
+ baseName: string
42
+ description?: string
43
+ keysToOmit?: string[]
44
+ }): ts.Node[] {
45
+ const nodes: ts.Node[] = []
46
+ const type = this.getTypeFromSchema(schema, baseName)
47
+
48
+ if (!type) {
49
+ return this.extraNodes
50
+ }
51
+
52
+ const node = factory.createTypeAliasDeclaration({
53
+ modifiers: [factory.modifiers.export],
54
+ name: this.context.pluginManager.resolveName({ name: baseName, pluginKey, type: 'type' }),
55
+ type: keysToOmit?.length ? factory.createOmitDeclaration({ keys: keysToOmit, type, nonNullable: true }) : type,
56
+ })
57
+
58
+ if (description) {
59
+ nodes.push(
60
+ factory.appendJSDocToNode({
61
+ node,
62
+ comments: [`@description ${transformers.trim(description)}`],
63
+ }),
64
+ )
65
+ } else {
66
+ nodes.push(node)
67
+ }
68
+
69
+ // filter out if the export name is the same as one that we already defined in extraNodes(see enum)
70
+ const filterdNodes = nodes.filter(
71
+ (node: ts.Node) =>
72
+ !this.extraNodes.some(
73
+ (extraNode: ts.Node) => (extraNode as ts.TypeAliasDeclaration)?.name?.escapedText === (node as ts.TypeAliasDeclaration)?.name?.escapedText,
74
+ ),
75
+ )
76
+
77
+ return [...this.extraNodes, ...filterdNodes]
78
+ }
79
+
80
+ /**
81
+ * Creates a type node from a given schema.
82
+ * Delegates to getBaseTypeFromSchema internally and
83
+ * optionally adds a union with null.
84
+ */
85
+ getTypeFromSchema(schema?: OasTypes.SchemaObject, name?: string): ts.TypeNode | null {
86
+ const type = this.#getBaseTypeFromSchema(schema, name)
87
+
88
+ if (!type) {
89
+ return null
90
+ }
91
+
92
+ if (schema && !schema.nullable) {
93
+ return type
94
+ }
95
+
96
+ return factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.null] })
97
+ }
98
+
99
+ /**
100
+ * Recursively creates a type literal with the given props.
101
+ */
102
+ #getTypeFromProperties(baseSchema?: OasTypes.SchemaObject, baseName?: string): ts.TypeNode | null {
103
+ const { optionalType } = this.options
104
+ const properties = baseSchema?.properties || {}
105
+ const required = baseSchema?.required
106
+ const additionalProperties = baseSchema?.additionalProperties
107
+
108
+ const members: Array<ts.TypeElement | null> = Object.keys(properties).map((name) => {
109
+ const schema = properties[name] as OasTypes.SchemaObject
110
+
111
+ const isRequired = Array.isArray(required) ? required.includes(name) : !!required
112
+ let type = this.getTypeFromSchema(schema, this.context.pluginManager.resolveName({ name: `${baseName || ''} ${name}`, pluginKey, type: 'type' }))
113
+
114
+ if (!type) {
115
+ return null
116
+ }
117
+
118
+ if (!isRequired && ['undefined', 'questionTokenAndUndefined'].includes(optionalType as string)) {
119
+ type = factory.createUnionDeclaration({ nodes: [type, factory.keywordTypeNodes.undefined] })
120
+ }
121
+ const propertySignature = factory.createPropertySignature({
122
+ questionToken: ['questionToken', 'questionTokenAndUndefined'].includes(optionalType as string) && !isRequired,
123
+ name,
124
+ type: type as ts.TypeNode,
125
+ readOnly: schema.readOnly,
126
+ })
127
+
128
+ return factory.appendJSDocToNode({
129
+ node: propertySignature,
130
+ comments: [
131
+ schema.description ? `@description ${schema.description}` : undefined,
132
+ schema.type ? `@type ${schema.type?.toString()}${isRequired ? '' : ' | undefined'} ${schema.format || ''}` : undefined,
133
+ schema.example ? `@example ${schema.example as string}` : undefined,
134
+ schema.deprecated ? `@deprecated` : undefined,
135
+ schema.default !== undefined && typeof schema.default === 'string' ? `@default '${schema.default}'` : undefined,
136
+ schema.default !== undefined && typeof schema.default !== 'string' ? `@default ${schema.default as string}` : undefined,
137
+ ].filter(Boolean),
138
+ })
139
+
140
+ return propertySignature
141
+ })
142
+ if (additionalProperties) {
143
+ const type = additionalProperties === true ? factory.keywordTypeNodes.any : this.getTypeFromSchema(additionalProperties as OasTypes.SchemaObject)
144
+
145
+ if (type) {
146
+ members.push(factory.createIndexSignature(type))
147
+ }
148
+ }
149
+ return factory.createTypeLiteralNode(members.filter(Boolean))
150
+ }
151
+
152
+ /**
153
+ * Create a type alias for the schema referenced by the given ReferenceObject
154
+ */
155
+ #getRefAlias(obj: OpenAPIV3.ReferenceObject, _baseName?: string) {
156
+ const { $ref } = obj
157
+ let ref = this.refs[$ref]
158
+
159
+ if (ref) {
160
+ return factory.createTypeReferenceNode(ref.propertyName, undefined)
161
+ }
162
+
163
+ const originalName = getUniqueName($ref.replace(/.+\//, ''), this.#usedAliasNames)
164
+ const propertyName = this.context.pluginManager.resolveName({ name: originalName, pluginKey, type: 'type' })
165
+
166
+ ref = this.refs[$ref] = {
167
+ propertyName,
168
+ originalName,
169
+ }
170
+
171
+ const path = this.context.pluginManager.resolvePath({ baseName: propertyName, pluginKey })
172
+
173
+ this.imports.push({
174
+ ref,
175
+ path: path || '',
176
+ isTypeOnly: true,
177
+ })
178
+
179
+ return factory.createTypeReferenceNode(ref.propertyName, undefined)
180
+ }
181
+
182
+ #getParsedSchema(schema?: OasTypes.SchemaObject) {
183
+ const parsedSchema = getSchemaFactory(this.context.oas)(schema)
184
+ return parsedSchema
185
+ }
186
+
187
+ /**
188
+ * This is the very core of the OpenAPI to TS conversion - it takes a
189
+ * schema and returns the appropriate type.
190
+ */
191
+ #getBaseTypeFromSchema(
192
+ _schema: OasTypes.SchemaObject | undefined,
193
+ baseName?: string,
194
+ ): ts.TypeNode | null {
195
+ const { schema, version } = this.#getParsedSchema(_schema)
196
+
197
+ if (!schema) {
198
+ return factory.keywordTypeNodes.any
199
+ }
200
+
201
+ if (isReference(schema)) {
202
+ return this.#getRefAlias(schema, baseName)
203
+ }
204
+
205
+ if (schema.oneOf) {
206
+ // union
207
+ const schemaWithoutOneOf = { ...schema, oneOf: undefined } as OasTypes.SchemaObject
208
+
209
+ const union = factory.createUnionDeclaration({
210
+ withParentheses: true,
211
+ nodes: schema.oneOf
212
+ .map((item) => {
213
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
214
+ })
215
+ .filter((item) => {
216
+ return item && item !== factory.keywordTypeNodes.any
217
+ }) as Array<ts.TypeNode>,
218
+ })
219
+
220
+ if (schemaWithoutOneOf.properties) {
221
+ return factory.createIntersectionDeclaration({
222
+ nodes: [this.getTypeFromSchema(schemaWithoutOneOf, baseName), union].filter(Boolean),
223
+ })
224
+ }
225
+
226
+ return union
227
+ }
228
+
229
+ if (schema.anyOf) {
230
+ const schemaWithoutAnyOf = { ...schema, anyOf: undefined } as OasTypes.SchemaObject
231
+
232
+ const union = factory.createUnionDeclaration({
233
+ withParentheses: true,
234
+ nodes: schema.anyOf
235
+ .map((item) => {
236
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
237
+ })
238
+ .filter((item) => {
239
+ return item && item !== factory.keywordTypeNodes.any
240
+ }) as Array<ts.TypeNode>,
241
+ })
242
+
243
+ if (schemaWithoutAnyOf.properties) {
244
+ return factory.createIntersectionDeclaration({
245
+ nodes: [this.getTypeFromSchema(schemaWithoutAnyOf, baseName), union].filter(Boolean),
246
+ })
247
+ }
248
+
249
+ return union
250
+ }
251
+ if (schema.allOf) {
252
+ // intersection/add
253
+ const schemaWithoutAllOf = { ...schema, allOf: undefined } as OasTypes.SchemaObject
254
+
255
+ const and = factory.createIntersectionDeclaration({
256
+ withParentheses: true,
257
+ nodes: schema.allOf
258
+ .map((item) => {
259
+ return item && this.getTypeFromSchema(item as OasTypes.SchemaObject)
260
+ })
261
+ .filter((item) => {
262
+ return item && item !== factory.keywordTypeNodes.any
263
+ }) as Array<ts.TypeNode>,
264
+ })
265
+
266
+ if (schemaWithoutAllOf.properties) {
267
+ return factory.createIntersectionDeclaration({
268
+ nodes: [this.getTypeFromSchema(schemaWithoutAllOf, baseName), and].filter(Boolean),
269
+ })
270
+ }
271
+
272
+ return and
273
+ }
274
+
275
+ /**
276
+ * Enum will be defined outside the baseType(hints the baseName check)
277
+ */
278
+ if (schema.enum && baseName) {
279
+ const enumName = getUniqueName(baseName, this.options.usedEnumNames)
280
+
281
+ let enums: [key: string, value: string | number][] = [...new Set(schema.enum)].map((key) => [key, key])
282
+
283
+ if ('x-enumNames' in schema) {
284
+ enums = [...new Set(schema['x-enumNames'] as string[])].map((key: string, index) => {
285
+ return [key, schema.enum?.[index] as string]
286
+ })
287
+ }
288
+
289
+ this.extraNodes.push(
290
+ ...factory.createEnumDeclaration({
291
+ name: transformers.camelCase(enumName),
292
+ typeName: this.context.pluginManager.resolveName({ name: enumName, pluginKey, type: 'type' }),
293
+ enums,
294
+ type: this.options.enumType,
295
+ }),
296
+ )
297
+ return factory.createTypeReferenceNode(this.context.pluginManager.resolveName({ name: enumName, pluginKey, type: 'type' }), undefined)
298
+ }
299
+
300
+ if (schema.enum) {
301
+ return factory.createUnionDeclaration({
302
+ nodes: schema.enum.map((name) => {
303
+ return factory.createLiteralTypeNode(typeof name === 'number' ? factory.createNumericLiteral(name) : factory.createStringLiteral(`${name}`))
304
+ }) as unknown as Array<ts.TypeNode>,
305
+ })
306
+ }
307
+
308
+ if ('items' in schema) {
309
+ // items -> array
310
+ const node = this.getTypeFromSchema(schema.items as OasTypes.SchemaObject, baseName)
311
+ if (node) {
312
+ return factory.createArrayTypeNode(node)
313
+ }
314
+ }
315
+
316
+ /**
317
+ * OpenAPI 3.1
318
+ * @link https://json-schema.org/understanding-json-schema/reference/array.html#tuple-validation
319
+ */
320
+
321
+ if ('prefixItems' in schema) {
322
+ const prefixItems = schema.prefixItems as OasTypes.SchemaObject[]
323
+
324
+ return factory.createTupleDeclaration({
325
+ nodes: prefixItems.map((item) => {
326
+ // no baseType so we can fall back on an union when using enum
327
+ return this.getTypeFromSchema(item, undefined)
328
+ }) as Array<ts.TypeNode>,
329
+ })
330
+ }
331
+
332
+ if (schema.properties || schema.additionalProperties) {
333
+ // properties -> literal type
334
+ return this.#getTypeFromProperties(schema, baseName)
335
+ }
336
+
337
+ /**
338
+ * validate "const" property as defined in JSON-Schema-Validation
339
+ *
340
+ * https://json-schema.org/draft/2020-12/json-schema-validation#name-const
341
+ *
342
+ * > 6.1.3. const
343
+ * > The value of this keyword MAY be of any type, including null.
344
+ * > Use of this keyword is functionally equivalent to an "enum" (Section 6.1.2) with a single value.
345
+ * > An instance validates successfully against this keyword if its value is equal to the value of the keyword.
346
+ */
347
+ if (version === '3.1' && 'const' in schema) {
348
+ // const keyword takes precendence over the actual type.
349
+ if (schema['const']) {
350
+ if (typeof schema['const'] === 'string') {
351
+ return factory.createLiteralTypeNode(factory.createStringLiteral(schema['const']))
352
+ } else if (typeof schema['const'] === 'number') {
353
+ return factory.createLiteralTypeNode(factory.createNumericLiteral(schema['const']))
354
+ }
355
+ } else {
356
+ return keywordTypeNodes.null
357
+ }
358
+ }
359
+
360
+ if (schema.type) {
361
+ if (Array.isArray(schema.type)) {
362
+ // TODO remove hardcoded first type, second nullable
363
+ // OPENAPI v3.1.0: https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
364
+ const [type, nullable] = schema.type as Array<OpenAPIV3_1.NonArraySchemaObjectType>
365
+
366
+ return factory.createUnionDeclaration({
367
+ nodes: [
368
+ this.getTypeFromSchema(
369
+ {
370
+ ...schema,
371
+ type,
372
+ },
373
+ baseName,
374
+ ),
375
+ nullable ? factory.createLiteralTypeNode(factory.createNull()) : undefined,
376
+ ].filter(Boolean),
377
+ })
378
+ }
379
+
380
+ if (this.options.dateType === 'date' && ['date', 'date-time'].some((item) => item === schema.format)) {
381
+ return factory.createTypeReferenceNode(factory.createIdentifier('Date'))
382
+ }
383
+
384
+ // string, boolean, null, number
385
+ if (schema.type in factory.keywordTypeNodes) {
386
+ return factory.keywordTypeNodes[schema.type as keyof typeof factory.keywordTypeNodes]
387
+ }
388
+ }
389
+
390
+ if (schema.format === 'binary') {
391
+ return factory.createTypeReferenceNode('Blob', [])
392
+ }
393
+
394
+ return factory.keywordTypeNodes.any
395
+ }
396
+ }
@@ -0,0 +1,138 @@
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 { KubbFile } from '@kubb/core'
10
+ import type { ts } from '@kubb/parser'
11
+ import type { OperationSchemas } from '@kubb/swagger'
12
+ import type { Operation } from '@kubb/swagger/oas'
13
+ import type { ReactNode } from 'react'
14
+ import type { FileMeta, PluginOptions } from '../types.ts'
15
+
16
+ type Props = {
17
+ builder: TypeBuilder
18
+ }
19
+
20
+ function printCombinedSchema(name: string, operation: Operation, schemas: OperationSchemas): string {
21
+ const properties: Record<string, ts.TypeNode> = {
22
+ 'response': factory.createTypeReferenceNode(
23
+ factory.createIdentifier(schemas.response.name),
24
+ undefined,
25
+ ),
26
+ }
27
+
28
+ if (schemas.request) {
29
+ properties['request'] = factory.createTypeReferenceNode(
30
+ factory.createIdentifier(schemas.request.name),
31
+ undefined,
32
+ )
33
+ }
34
+
35
+ if (schemas.pathParams) {
36
+ properties['pathParams'] = factory.createTypeReferenceNode(
37
+ factory.createIdentifier(schemas.pathParams.name),
38
+ undefined,
39
+ )
40
+ }
41
+
42
+ if (schemas.queryParams) {
43
+ properties['queryParams'] = factory.createTypeReferenceNode(
44
+ factory.createIdentifier(schemas.queryParams.name),
45
+ undefined,
46
+ )
47
+ }
48
+
49
+ if (schemas.headerParams) {
50
+ properties['headerParams'] = factory.createTypeReferenceNode(
51
+ factory.createIdentifier(schemas.headerParams.name),
52
+ undefined,
53
+ )
54
+ }
55
+
56
+ if (schemas.errors) {
57
+ properties['errors'] = factory.createUnionDeclaration({
58
+ nodes: schemas.errors.map(error => {
59
+ return factory.createTypeReferenceNode(
60
+ factory.createIdentifier(error.name),
61
+ undefined,
62
+ )
63
+ }),
64
+ })!
65
+ }
66
+
67
+ const namespaceNode = factory.createNamespaceDeclaration({
68
+ name: operation.method === 'get' ? `${name}Query` : `${name}Mutation`,
69
+ statements: Object.keys(properties).map(key => {
70
+ const type = properties[key]
71
+ if (!type) {
72
+ return undefined
73
+ }
74
+ return factory.createTypeAliasDeclaration({
75
+ modifiers: [factory.modifiers.export],
76
+ name: transformers.pascalCase(key),
77
+ type,
78
+ })
79
+ }).filter(Boolean),
80
+ })
81
+
82
+ return print(namespaceNode)
83
+ }
84
+
85
+ export function Mutation({
86
+ builder,
87
+ }: Props): ReactNode {
88
+ const { source } = builder.build()
89
+
90
+ return (
91
+ <>
92
+ {source}
93
+ </>
94
+ )
95
+ }
96
+
97
+ type FileProps = {
98
+ mode: KubbFile.Mode
99
+ }
100
+
101
+ Mutation.File = function({ mode }: FileProps): ReactNode {
102
+ const { options } = usePlugin<PluginOptions>()
103
+
104
+ const schemas = useSchemas()
105
+ const pluginManager = usePluginManager()
106
+ const oas = useOas()
107
+ const file = useOperationFile()
108
+ const factoryName = useOperationName({ type: 'type' })
109
+ const operation = useOperation()
110
+
111
+ const builder = new TypeBuilder(options, { oas, pluginManager })
112
+ .add(schemas.pathParams)
113
+ .add(schemas.queryParams)
114
+ .add(schemas.headerParams)
115
+ .add(schemas.response)
116
+ .add(schemas.request)
117
+ .add(schemas.errors)
118
+
119
+ const { source, imports } = builder.build()
120
+
121
+ return (
122
+ <>
123
+ <File<FileMeta>
124
+ baseName={file.baseName}
125
+ path={file.path}
126
+ meta={file.meta}
127
+ >
128
+ {mode === 'directory' && imports.map((item, index) => {
129
+ return <File.Import key={index} root={file.path} {...item} />
130
+ })}
131
+ <File.Source>
132
+ {source}
133
+ {printCombinedSchema(factoryName, operation, schemas)}
134
+ </File.Source>
135
+ </File>
136
+ </>
137
+ )
138
+ }
@@ -0,0 +1,84 @@
1
+ import { File, Type, usePlugin } from '@kubb/react'
2
+ import { useFile } from '@kubb/react'
3
+ import { useOas } from '@kubb/swagger/hooks'
4
+
5
+ import type { OasTypes } from '@kubb/swagger/oas'
6
+ import type { ReactNode } from 'react'
7
+ import type { FileMeta, PluginOptions } from '../types.ts'
8
+
9
+ type TemplateProps = {
10
+ /**
11
+ * Name of the function
12
+ */
13
+ name: string
14
+ typeName: string
15
+ api: OasTypes.OASDocument
16
+ }
17
+
18
+ function Template({
19
+ name,
20
+ typeName,
21
+ api,
22
+ }: TemplateProps): ReactNode {
23
+ return (
24
+ <>
25
+ {`export const ${name} = ${JSON.stringify(api, undefined, 2)} as const`}
26
+ <br />
27
+ <Type name={typeName} export>
28
+ {`Infer<typeof ${name}>`}
29
+ </Type>
30
+ </>
31
+ )
32
+ }
33
+
34
+ const defaultTemplates = { default: Template } as const
35
+
36
+ type Props = {
37
+ name: string
38
+ typeName: string
39
+ /**
40
+ * This will make it possible to override the default behaviour.
41
+ */
42
+ Template?: React.ComponentType<React.ComponentProps<typeof Template>>
43
+ }
44
+
45
+ export function Oas({
46
+ name,
47
+ typeName,
48
+ Template = defaultTemplates.default,
49
+ }: Props): ReactNode {
50
+ const oas = useOas()
51
+
52
+ return <Template name={name} typeName={typeName} api={oas.api} />
53
+ }
54
+
55
+ type FileProps = {
56
+ name: string
57
+ typeName: string
58
+ /**
59
+ * This will make it possible to override the default behaviour.
60
+ */
61
+ templates?: typeof defaultTemplates
62
+ }
63
+
64
+ Oas.File = function({ name, typeName, templates = defaultTemplates }: FileProps): ReactNode {
65
+ const { key: pluginKey } = usePlugin<PluginOptions>()
66
+ const file = useFile({ name, pluginKey })
67
+
68
+ const Template = templates.default
69
+
70
+ return (
71
+ <File<FileMeta>
72
+ baseName={file.baseName}
73
+ path={file.path}
74
+ meta={file.meta}
75
+ >
76
+ <File.Import name={['Infer']} path="@kubb/swagger-ts/oas" isTypeOnly />
77
+ <File.Source>
78
+ <Oas Template={Template} name={name} typeName={typeName} />
79
+ </File.Source>
80
+ </File>
81
+ )
82
+ }
83
+
84
+ Oas.templates = defaultTemplates