@kubb/plugin-ts 4.13.1 → 4.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{components-x14CeHxX.js → components-BE9rQGox.js} +74 -58
- package/dist/components-BE9rQGox.js.map +1 -0
- package/dist/{components-BkxV2jhh.cjs → components-CGcs8968.cjs} +103 -63
- package/dist/components-CGcs8968.cjs.map +1 -0
- package/dist/components.cjs +1 -2
- package/dist/components.d.cts +4 -17
- package/dist/components.d.ts +4 -17
- package/dist/components.js +2 -2
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.cts +1 -1
- package/dist/generators.d.ts +1 -1
- package/dist/generators.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{plugin-BM1VkXZS.cjs → plugin-B96TNDf4.cjs} +174 -21
- package/dist/plugin-B96TNDf4.cjs.map +1 -0
- package/dist/{plugin-BiVCDKei.js → plugin-DXyNbr_u.js} +175 -23
- package/dist/plugin-DXyNbr_u.js.map +1 -0
- package/dist/{types-WHo75HZq.d.cts → types-CKtzgWEC.d.cts} +22 -6
- package/dist/{types-De3dRAE2.d.ts → types-CnQREd_1.d.ts} +22 -6
- package/package.json +4 -4
- package/src/components/Type.tsx +33 -22
- package/src/components/index.ts +0 -1
- package/src/factory.ts +79 -5
- package/src/generators/__snapshots__/createPet.ts +1 -1
- package/src/generators/__snapshots__/createPetWithEmptySchemaTypeUnknown.ts +1 -1
- package/src/generators/__snapshots__/createPetWithEmptySchemaTypeVoid.ts +1 -1
- package/src/generators/__snapshots__/createPetWithUnknownTypeUnknown.ts +1 -1
- package/src/generators/__snapshots__/createPetWithUnknownTypeVoid.ts +1 -1
- package/src/generators/__snapshots__/deletePet.ts +1 -1
- package/src/generators/__snapshots__/enumNamesInlineLiteral.ts +6 -0
- package/src/generators/__snapshots__/getPets.ts +1 -1
- package/src/generators/__snapshots__/showPetById.ts +1 -1
- package/src/generators/__snapshots__/systemsWithExplodeForm.ts +1 -1
- package/src/generators/typeGenerator.tsx +232 -8
- package/src/parser.ts +28 -23
- package/src/plugin.ts +4 -0
- package/src/types.ts +16 -2
- package/dist/components-BkxV2jhh.cjs.map +0 -1
- package/dist/components-x14CeHxX.js.map +0 -1
- package/dist/plugin-BM1VkXZS.cjs.map +0 -1
- package/dist/plugin-BiVCDKei.js.map +0 -1
- package/src/components/OasType.tsx +0 -28
package/src/components/Type.tsx
CHANGED
|
@@ -15,6 +15,7 @@ type Props = {
|
|
|
15
15
|
schema: SchemaObject
|
|
16
16
|
tree: Array<Schema>
|
|
17
17
|
optionalType: PluginTs['resolvedOptions']['optionalType']
|
|
18
|
+
arrayType: PluginTs['resolvedOptions']['arrayType']
|
|
18
19
|
enumType: PluginTs['resolvedOptions']['enumType']
|
|
19
20
|
mapper: PluginTs['resolvedOptions']['mapper']
|
|
20
21
|
syntaxType: PluginTs['resolvedOptions']['syntaxType']
|
|
@@ -22,7 +23,7 @@ type Props = {
|
|
|
22
23
|
keysToOmit?: string[]
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export function Type({ name, typedName, tree, keysToOmit, schema, optionalType, syntaxType, enumType, mapper, description }: Props): KubbNode {
|
|
26
|
+
export function Type({ name, typedName, tree, keysToOmit, schema, optionalType, arrayType, syntaxType, enumType, mapper, description }: Props): KubbNode {
|
|
26
27
|
const typeNodes: ts.Node[] = []
|
|
27
28
|
|
|
28
29
|
if (!tree.length) {
|
|
@@ -39,6 +40,7 @@ export function Type({ name, typedName, tree, keysToOmit, schema, optionalType,
|
|
|
39
40
|
{ name, schema, parent: undefined, current, siblings },
|
|
40
41
|
{
|
|
41
42
|
optionalType,
|
|
43
|
+
arrayType,
|
|
42
44
|
enumType,
|
|
43
45
|
mapper,
|
|
44
46
|
},
|
|
@@ -59,7 +61,11 @@ export function Type({ name, typedName, tree, keysToOmit, schema, optionalType,
|
|
|
59
61
|
type = factory.createTypeReferenceNode(typeNameWithKey)
|
|
60
62
|
|
|
61
63
|
if (schema.type === 'array') {
|
|
62
|
-
|
|
64
|
+
if (arrayType === 'generic') {
|
|
65
|
+
type = factory.createTypeReferenceNode(factory.createIdentifier('Array'), [type])
|
|
66
|
+
} else {
|
|
67
|
+
type = factory.createArrayTypeNode(type)
|
|
68
|
+
}
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
}
|
|
@@ -135,28 +141,33 @@ export function Type({ name, typedName, tree, keysToOmit, schema, optionalType,
|
|
|
135
141
|
}
|
|
136
142
|
})
|
|
137
143
|
|
|
144
|
+
// Skip enum exports when using inlineLiteral
|
|
145
|
+
const shouldExportEnums = enumType !== 'inlineLiteral'
|
|
146
|
+
const shouldExportType = enumType === 'inlineLiteral' || enums.every((item) => item.typeName !== name)
|
|
147
|
+
|
|
138
148
|
return (
|
|
139
149
|
<>
|
|
140
|
-
{
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
{
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
{shouldExportEnums &&
|
|
151
|
+
enums.map(({ name, nameNode, typeName, typeNode }) => (
|
|
152
|
+
<>
|
|
153
|
+
{nameNode && (
|
|
154
|
+
<File.Source name={name} isExportable isIndexable>
|
|
155
|
+
{safePrint(nameNode)}
|
|
156
|
+
</File.Source>
|
|
157
|
+
)}
|
|
158
|
+
{
|
|
159
|
+
<File.Source
|
|
160
|
+
name={typeName}
|
|
161
|
+
isIndexable
|
|
162
|
+
isExportable={['enum', 'asConst', 'constEnum', 'literal', undefined].includes(enumType)}
|
|
163
|
+
isTypeOnly={['asConst', 'literal', undefined].includes(enumType)}
|
|
164
|
+
>
|
|
165
|
+
{safePrint(typeNode)}
|
|
166
|
+
</File.Source>
|
|
167
|
+
}
|
|
168
|
+
</>
|
|
169
|
+
))}
|
|
170
|
+
{shouldExportType && (
|
|
160
171
|
<File.Source name={typedName} isTypeOnly isExportable isIndexable>
|
|
161
172
|
{safePrint(...typeNodes)}
|
|
162
173
|
</File.Source>
|
package/src/components/index.ts
CHANGED
package/src/factory.ts
CHANGED
|
@@ -17,6 +17,16 @@ export const syntaxKind = {
|
|
|
17
17
|
union: SyntaxKind.UnionType as 192,
|
|
18
18
|
} as const
|
|
19
19
|
|
|
20
|
+
export function getUnknownType(unknownType: 'any' | 'unknown' | 'void' | undefined) {
|
|
21
|
+
if (unknownType === 'any') {
|
|
22
|
+
return keywordTypeNodes.any
|
|
23
|
+
}
|
|
24
|
+
if (unknownType === 'void') {
|
|
25
|
+
return keywordTypeNodes.void
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return keywordTypeNodes.unknown
|
|
29
|
+
}
|
|
20
30
|
function isValidIdentifier(str: string): boolean {
|
|
21
31
|
if (!str.length || str.trim() !== str) {
|
|
22
32
|
return false
|
|
@@ -86,16 +96,29 @@ export function createTupleDeclaration({ nodes, withParentheses }: { nodes: Arra
|
|
|
86
96
|
return node
|
|
87
97
|
}
|
|
88
98
|
|
|
89
|
-
export function createArrayDeclaration({ nodes }: { nodes: Array<ts.TypeNode
|
|
99
|
+
export function createArrayDeclaration({ nodes, arrayType = 'array' }: { nodes: Array<ts.TypeNode>; arrayType?: 'array' | 'generic' }): ts.TypeNode | null {
|
|
90
100
|
if (!nodes.length) {
|
|
91
101
|
return factory.createTupleTypeNode([])
|
|
92
102
|
}
|
|
93
103
|
|
|
94
104
|
if (nodes.length === 1) {
|
|
95
|
-
|
|
105
|
+
const node = nodes[0]
|
|
106
|
+
if (!node) {
|
|
107
|
+
return null
|
|
108
|
+
}
|
|
109
|
+
if (arrayType === 'generic') {
|
|
110
|
+
return factory.createTypeReferenceNode(factory.createIdentifier('Array'), [node])
|
|
111
|
+
}
|
|
112
|
+
return factory.createArrayTypeNode(node)
|
|
96
113
|
}
|
|
97
114
|
|
|
98
|
-
|
|
115
|
+
// For union types (multiple nodes), respect arrayType preference
|
|
116
|
+
const unionType = factory.createUnionTypeNode(nodes)
|
|
117
|
+
if (arrayType === 'generic') {
|
|
118
|
+
return factory.createTypeReferenceNode(factory.createIdentifier('Array'), [unionType])
|
|
119
|
+
}
|
|
120
|
+
// For array syntax with unions, we need parentheses: (string | number)[]
|
|
121
|
+
return factory.createArrayTypeNode(factory.createParenthesizedType(unionType))
|
|
99
122
|
}
|
|
100
123
|
|
|
101
124
|
/**
|
|
@@ -408,7 +431,7 @@ export function createEnumDeclaration({
|
|
|
408
431
|
* - `literal`: literal union type
|
|
409
432
|
* @default `'enum'`
|
|
410
433
|
*/
|
|
411
|
-
type?: 'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal'
|
|
434
|
+
type?: 'enum' | 'asConst' | 'asPascalConst' | 'constEnum' | 'literal' | 'inlineLiteral'
|
|
412
435
|
/**
|
|
413
436
|
* Enum name in camelCase.
|
|
414
437
|
*/
|
|
@@ -419,7 +442,7 @@ export function createEnumDeclaration({
|
|
|
419
442
|
typeName: string
|
|
420
443
|
enums: [key: string | number, value: string | number | boolean][]
|
|
421
444
|
}): [name: ts.Node | undefined, type: ts.Node] {
|
|
422
|
-
if (type === 'literal') {
|
|
445
|
+
if (type === 'literal' || type === 'inlineLiteral') {
|
|
423
446
|
return [
|
|
424
447
|
undefined,
|
|
425
448
|
factory.createTypeAliasDeclaration(
|
|
@@ -572,8 +595,56 @@ export const keywordTypeNodes = {
|
|
|
572
595
|
boolean: factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword),
|
|
573
596
|
undefined: factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),
|
|
574
597
|
null: factory.createLiteralTypeNode(factory.createToken(ts.SyntaxKind.NullKeyword)),
|
|
598
|
+
never: factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword),
|
|
575
599
|
} as const
|
|
576
600
|
|
|
601
|
+
/**
|
|
602
|
+
* Converts a path like '/pet/{petId}/uploadImage' to a template literal type
|
|
603
|
+
* like `/pet/${string}/uploadImage`
|
|
604
|
+
*/
|
|
605
|
+
export function createUrlTemplateType(path: string): ts.TypeNode {
|
|
606
|
+
// If no parameters, return literal string type
|
|
607
|
+
if (!path.includes('{')) {
|
|
608
|
+
return factory.createLiteralTypeNode(factory.createStringLiteral(path))
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Split path by parameter placeholders, e.g. '/pet/{petId}/upload' -> ['/pet/', 'petId', '/upload']
|
|
612
|
+
const segments = path.split(/(\{[^}]+\})/)
|
|
613
|
+
|
|
614
|
+
// Separate static parts from parameter placeholders
|
|
615
|
+
const parts: string[] = []
|
|
616
|
+
const parameterIndices: number[] = []
|
|
617
|
+
|
|
618
|
+
segments.forEach((segment) => {
|
|
619
|
+
if (segment.startsWith('{') && segment.endsWith('}')) {
|
|
620
|
+
// This is a parameter placeholder
|
|
621
|
+
parameterIndices.push(parts.length)
|
|
622
|
+
parts.push(segment) // Will be replaced with ${string}
|
|
623
|
+
} else if (segment) {
|
|
624
|
+
// This is a static part
|
|
625
|
+
parts.push(segment)
|
|
626
|
+
}
|
|
627
|
+
})
|
|
628
|
+
|
|
629
|
+
// Build template literal type
|
|
630
|
+
// Template literal structure: head + templateSpans[]
|
|
631
|
+
// For '/pet/{petId}/upload': head = '/pet/', spans = [{ type: string, literal: '/upload' }]
|
|
632
|
+
|
|
633
|
+
const head = ts.factory.createTemplateHead(parts[0] || '')
|
|
634
|
+
const templateSpans: ts.TemplateLiteralTypeSpan[] = []
|
|
635
|
+
|
|
636
|
+
parameterIndices.forEach((paramIndex, i) => {
|
|
637
|
+
const isLast = i === parameterIndices.length - 1
|
|
638
|
+
const nextPart = parts[paramIndex + 1] || ''
|
|
639
|
+
|
|
640
|
+
const literal = isLast ? ts.factory.createTemplateTail(nextPart) : ts.factory.createTemplateMiddle(nextPart)
|
|
641
|
+
|
|
642
|
+
templateSpans.push(ts.factory.createTemplateLiteralTypeSpan(keywordTypeNodes.string, literal))
|
|
643
|
+
})
|
|
644
|
+
|
|
645
|
+
return ts.factory.createTemplateLiteralType(head, templateSpans)
|
|
646
|
+
}
|
|
647
|
+
|
|
577
648
|
export const createTypeLiteralNode = factory.createTypeLiteralNode
|
|
578
649
|
|
|
579
650
|
export const createTypeReferenceNode = factory.createTypeReferenceNode
|
|
@@ -581,6 +652,7 @@ export const createNumericLiteral = factory.createNumericLiteral
|
|
|
581
652
|
export const createStringLiteral = factory.createStringLiteral
|
|
582
653
|
|
|
583
654
|
export const createArrayTypeNode = factory.createArrayTypeNode
|
|
655
|
+
export const createParenthesizedType = factory.createParenthesizedType
|
|
584
656
|
|
|
585
657
|
export const createLiteralTypeNode = factory.createLiteralTypeNode
|
|
586
658
|
export const createNull = factory.createNull
|
|
@@ -591,3 +663,5 @@ export const createTupleTypeNode = factory.createTupleTypeNode
|
|
|
591
663
|
export const createRestTypeNode = factory.createRestTypeNode
|
|
592
664
|
export const createTrue = factory.createTrue
|
|
593
665
|
export const createFalse = factory.createFalse
|
|
666
|
+
export const createIndexedAccessTypeNode = factory.createIndexedAccessTypeNode
|
|
667
|
+
export const createTypeOperatorNode = factory.createTypeOperatorNode
|
|
@@ -40,7 +40,7 @@ export type CreatePetsMutationRequest = {
|
|
|
40
40
|
|
|
41
41
|
export type CreatePetsMutationResponse = createPets201 | createPets202
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type CreatePetsMutation = {
|
|
44
44
|
Response: createPets201 | createPets202
|
|
45
45
|
Request: createPetsMutationRequest
|
|
46
46
|
Errors: any
|
|
@@ -40,7 +40,7 @@ export type CreatePetsMutationRequest = {
|
|
|
40
40
|
|
|
41
41
|
export type CreatePetsMutationResponse = createPets201 | createPets202
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type CreatePetsMutation = {
|
|
44
44
|
Response: createPets201 | createPets202
|
|
45
45
|
Request: createPetsMutationRequest
|
|
46
46
|
Errors: any
|
|
@@ -40,7 +40,7 @@ export type CreatePetsMutationRequest = {
|
|
|
40
40
|
|
|
41
41
|
export type CreatePetsMutationResponse = createPets201 | createPets202
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type CreatePetsMutation = {
|
|
44
44
|
Response: createPets201 | createPets202
|
|
45
45
|
Request: createPetsMutationRequest
|
|
46
46
|
Errors: any
|
|
@@ -40,7 +40,7 @@ export type CreatePetsMutationRequest = {
|
|
|
40
40
|
|
|
41
41
|
export type CreatePetsMutationResponse = createPets201 | createPets202
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type CreatePetsMutation = {
|
|
44
44
|
Response: createPets201 | createPets202
|
|
45
45
|
Request: createPetsMutationRequest
|
|
46
46
|
Errors: any
|
|
@@ -40,7 +40,7 @@ export type CreatePetsMutationRequest = {
|
|
|
40
40
|
|
|
41
41
|
export type CreatePetsMutationResponse = createPets201 | createPets202
|
|
42
42
|
|
|
43
|
-
export type
|
|
43
|
+
export type CreatePetsMutation = {
|
|
44
44
|
Response: createPets201 | createPets202
|
|
45
45
|
Request: createPetsMutationRequest
|
|
46
46
|
Errors: any
|
|
@@ -2,14 +2,16 @@ import type { PluginManager } from '@kubb/core'
|
|
|
2
2
|
import { useMode, usePluginManager } from '@kubb/core/hooks'
|
|
3
3
|
import transformers from '@kubb/core/transformers'
|
|
4
4
|
import { safePrint } from '@kubb/fabric-core/parsers/typescript'
|
|
5
|
+
import type { Operation } from '@kubb/oas'
|
|
5
6
|
import { isKeyword, type OperationSchemas, type OperationSchema as OperationSchemaType, SchemaGenerator, schemaKeywords } from '@kubb/plugin-oas'
|
|
6
7
|
import { createReactGenerator } from '@kubb/plugin-oas/generators'
|
|
7
8
|
import { useOas, useOperationManager, useSchemaManager } from '@kubb/plugin-oas/hooks'
|
|
8
9
|
import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
|
|
9
10
|
import { File } from '@kubb/react-fabric'
|
|
10
|
-
import
|
|
11
|
+
import ts from 'typescript'
|
|
11
12
|
import { Type } from '../components'
|
|
12
13
|
import * as factory from '../factory.ts'
|
|
14
|
+
import { createUrlTemplateType, getUnknownType, keywordTypeNodes } from '../factory.ts'
|
|
13
15
|
import { pluginTsName } from '../plugin.ts'
|
|
14
16
|
import type { PluginTs } from '../types'
|
|
15
17
|
|
|
@@ -103,12 +105,216 @@ function printCombinedSchema({ name, schemas, pluginManager }: { name: string; s
|
|
|
103
105
|
return safePrint(namespaceNode)
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
function printRequestSchema({
|
|
109
|
+
baseName,
|
|
110
|
+
operation,
|
|
111
|
+
schemas,
|
|
112
|
+
pluginManager,
|
|
113
|
+
}: {
|
|
114
|
+
baseName: string
|
|
115
|
+
operation: Operation
|
|
116
|
+
schemas: OperationSchemas
|
|
117
|
+
pluginManager: PluginManager
|
|
118
|
+
}): string {
|
|
119
|
+
const name = pluginManager.resolveName({
|
|
120
|
+
name: `${baseName} Request`,
|
|
121
|
+
pluginKey: [pluginTsName],
|
|
122
|
+
type: 'type',
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
const results: string[] = []
|
|
126
|
+
|
|
127
|
+
// Generate DataRequest type
|
|
128
|
+
const dataRequestProperties: ts.PropertySignature[] = []
|
|
129
|
+
|
|
130
|
+
if (schemas.request) {
|
|
131
|
+
const identifier = pluginManager.resolveName({
|
|
132
|
+
name: schemas.request.name,
|
|
133
|
+
pluginKey: [pluginTsName],
|
|
134
|
+
type: 'type',
|
|
135
|
+
})
|
|
136
|
+
dataRequestProperties.push(
|
|
137
|
+
factory.createPropertySignature({
|
|
138
|
+
name: 'data',
|
|
139
|
+
questionToken: true,
|
|
140
|
+
type: factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined),
|
|
141
|
+
}),
|
|
142
|
+
)
|
|
143
|
+
} else {
|
|
144
|
+
dataRequestProperties.push(
|
|
145
|
+
factory.createPropertySignature({
|
|
146
|
+
name: 'data',
|
|
147
|
+
questionToken: true,
|
|
148
|
+
type: keywordTypeNodes.never,
|
|
149
|
+
}),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Add pathParams property
|
|
154
|
+
if (schemas.pathParams) {
|
|
155
|
+
const identifier = pluginManager.resolveName({
|
|
156
|
+
name: schemas.pathParams.name,
|
|
157
|
+
pluginKey: [pluginTsName],
|
|
158
|
+
type: 'type',
|
|
159
|
+
})
|
|
160
|
+
dataRequestProperties.push(
|
|
161
|
+
factory.createPropertySignature({
|
|
162
|
+
name: 'pathParams',
|
|
163
|
+
type: factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined),
|
|
164
|
+
}),
|
|
165
|
+
)
|
|
166
|
+
} else {
|
|
167
|
+
dataRequestProperties.push(
|
|
168
|
+
factory.createPropertySignature({
|
|
169
|
+
name: 'pathParams',
|
|
170
|
+
questionToken: true,
|
|
171
|
+
type: keywordTypeNodes.never,
|
|
172
|
+
}),
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Add queryParams property
|
|
177
|
+
if (schemas.queryParams) {
|
|
178
|
+
const identifier = pluginManager.resolveName({
|
|
179
|
+
name: schemas.queryParams.name,
|
|
180
|
+
pluginKey: [pluginTsName],
|
|
181
|
+
type: 'type',
|
|
182
|
+
})
|
|
183
|
+
dataRequestProperties.push(
|
|
184
|
+
factory.createPropertySignature({
|
|
185
|
+
name: 'queryParams',
|
|
186
|
+
questionToken: true,
|
|
187
|
+
type: factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined),
|
|
188
|
+
}),
|
|
189
|
+
)
|
|
190
|
+
} else {
|
|
191
|
+
dataRequestProperties.push(
|
|
192
|
+
factory.createPropertySignature({
|
|
193
|
+
name: 'queryParams',
|
|
194
|
+
questionToken: true,
|
|
195
|
+
type: keywordTypeNodes.never,
|
|
196
|
+
}),
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Add headerParams property
|
|
201
|
+
if (schemas.headerParams) {
|
|
202
|
+
const identifier = pluginManager.resolveName({
|
|
203
|
+
name: schemas.headerParams.name,
|
|
204
|
+
pluginKey: [pluginTsName],
|
|
205
|
+
type: 'type',
|
|
206
|
+
})
|
|
207
|
+
dataRequestProperties.push(
|
|
208
|
+
factory.createPropertySignature({
|
|
209
|
+
name: 'headerParams',
|
|
210
|
+
questionToken: true,
|
|
211
|
+
type: factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined),
|
|
212
|
+
}),
|
|
213
|
+
)
|
|
214
|
+
} else {
|
|
215
|
+
dataRequestProperties.push(
|
|
216
|
+
factory.createPropertySignature({
|
|
217
|
+
name: 'headerParams',
|
|
218
|
+
questionToken: true,
|
|
219
|
+
type: keywordTypeNodes.never,
|
|
220
|
+
}),
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Add url property with template literal type
|
|
225
|
+
dataRequestProperties.push(
|
|
226
|
+
factory.createPropertySignature({
|
|
227
|
+
name: 'url',
|
|
228
|
+
type: createUrlTemplateType(operation.path),
|
|
229
|
+
}),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
const dataRequestNode = factory.createTypeAliasDeclaration({
|
|
233
|
+
name,
|
|
234
|
+
type: factory.createTypeLiteralNode(dataRequestProperties),
|
|
235
|
+
modifiers: [factory.modifiers.export],
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
results.push(safePrint(dataRequestNode))
|
|
239
|
+
|
|
240
|
+
return results.join('\n\n')
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function printResponseSchema({
|
|
244
|
+
baseName,
|
|
245
|
+
schemas,
|
|
246
|
+
pluginManager,
|
|
247
|
+
unknownType,
|
|
248
|
+
}: {
|
|
249
|
+
baseName: string
|
|
250
|
+
schemas: OperationSchemas
|
|
251
|
+
pluginManager: PluginManager
|
|
252
|
+
unknownType: PluginTs['resolvedOptions']['unknownType']
|
|
253
|
+
}): string {
|
|
254
|
+
const results: string[] = []
|
|
255
|
+
|
|
256
|
+
const name = pluginManager.resolveName({
|
|
257
|
+
name: `${baseName} ResponseData`,
|
|
258
|
+
pluginKey: [pluginTsName],
|
|
259
|
+
type: 'type',
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// Generate Responses type (mapping status codes to response types)
|
|
263
|
+
if (schemas.responses && schemas.responses.length > 0) {
|
|
264
|
+
const responsesProperties: ts.PropertySignature[] = schemas.responses.map((res) => {
|
|
265
|
+
const identifier = pluginManager.resolveName({
|
|
266
|
+
name: res.name,
|
|
267
|
+
pluginKey: [pluginTsName],
|
|
268
|
+
type: 'type',
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
return factory.createPropertySignature({
|
|
272
|
+
name: res.statusCode?.toString() ?? 'default',
|
|
273
|
+
type: factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined),
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
const responsesNode = factory.createTypeAliasDeclaration({
|
|
278
|
+
name: `${baseName}Responses`,
|
|
279
|
+
type: factory.createTypeLiteralNode(responsesProperties),
|
|
280
|
+
modifiers: [factory.modifiers.export],
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
results.push(safePrint(responsesNode))
|
|
284
|
+
|
|
285
|
+
// Generate Response type (union via indexed access)
|
|
286
|
+
const responseNode = factory.createTypeAliasDeclaration({
|
|
287
|
+
name,
|
|
288
|
+
type: factory.createIndexedAccessTypeNode(
|
|
289
|
+
factory.createTypeReferenceNode(factory.createIdentifier(`${baseName}Responses`), undefined),
|
|
290
|
+
factory.createTypeOperatorNode(
|
|
291
|
+
ts.SyntaxKind.KeyOfKeyword,
|
|
292
|
+
factory.createTypeReferenceNode(factory.createIdentifier(`${baseName}Responses`), undefined),
|
|
293
|
+
),
|
|
294
|
+
),
|
|
295
|
+
modifiers: [factory.modifiers.export],
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
results.push(safePrint(responseNode))
|
|
299
|
+
} else {
|
|
300
|
+
const responseNode = factory.createTypeAliasDeclaration({
|
|
301
|
+
name,
|
|
302
|
+
modifiers: [factory.modifiers.export],
|
|
303
|
+
type: getUnknownType(unknownType),
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
results.push(safePrint(responseNode))
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return results.join('\n\n')
|
|
310
|
+
}
|
|
311
|
+
|
|
106
312
|
export const typeGenerator = createReactGenerator<PluginTs>({
|
|
107
313
|
name: 'typescript',
|
|
108
314
|
Operation({ operation, generator, plugin }) {
|
|
109
315
|
const {
|
|
110
316
|
options,
|
|
111
|
-
options: { mapper, enumType, syntaxType, optionalType },
|
|
317
|
+
options: { mapper, enumType, syntaxType, optionalType, arrayType, unknownType },
|
|
112
318
|
} = plugin
|
|
113
319
|
|
|
114
320
|
const mode = useMode()
|
|
@@ -118,10 +324,10 @@ export const typeGenerator = createReactGenerator<PluginTs>({
|
|
|
118
324
|
const { getSchemas, getFile, getName, getGroup } = useOperationManager(generator)
|
|
119
325
|
const schemaManager = useSchemaManager()
|
|
120
326
|
|
|
327
|
+
const name = getName(operation, { type: 'type', pluginKey: [pluginTsName] })
|
|
328
|
+
|
|
121
329
|
const file = getFile(operation)
|
|
122
330
|
const schemas = getSchemas(operation)
|
|
123
|
-
const type = getName(operation, { type: 'function', pluginKey: [pluginTsName] })
|
|
124
|
-
const combinedSchemaName = operation.method === 'get' ? `${type}Query` : `${type}Mutation`
|
|
125
331
|
const schemaGenerator = new SchemaGenerator(options, {
|
|
126
332
|
fabric: generator.context.fabric,
|
|
127
333
|
oas,
|
|
@@ -162,6 +368,7 @@ export const typeGenerator = createReactGenerator<PluginTs>({
|
|
|
162
368
|
mapper={mapper}
|
|
163
369
|
enumType={enumType}
|
|
164
370
|
optionalType={optionalType}
|
|
371
|
+
arrayType={arrayType}
|
|
165
372
|
keysToOmit={keysToOmit}
|
|
166
373
|
syntaxType={syntaxType}
|
|
167
374
|
/>
|
|
@@ -169,6 +376,11 @@ export const typeGenerator = createReactGenerator<PluginTs>({
|
|
|
169
376
|
)
|
|
170
377
|
}
|
|
171
378
|
|
|
379
|
+
const responseName = schemaManager.getName(schemas.response.name, {
|
|
380
|
+
type: 'type',
|
|
381
|
+
})
|
|
382
|
+
const combinedSchemaName = operation.method === 'get' ? `${name}Query` : `${name}Mutation`
|
|
383
|
+
|
|
172
384
|
return (
|
|
173
385
|
<File
|
|
174
386
|
baseName={file.baseName}
|
|
@@ -179,15 +391,26 @@ export const typeGenerator = createReactGenerator<PluginTs>({
|
|
|
179
391
|
>
|
|
180
392
|
{operationSchemas.map(mapOperationSchema)}
|
|
181
393
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
394
|
+
{generator.context.UNSTABLE_NAMING ? (
|
|
395
|
+
<>
|
|
396
|
+
<File.Source name={`${name}Request`} isExportable isIndexable isTypeOnly>
|
|
397
|
+
{printRequestSchema({ baseName: name, operation, schemas, pluginManager })}
|
|
398
|
+
</File.Source>
|
|
399
|
+
<File.Source name={responseName} isExportable isIndexable isTypeOnly>
|
|
400
|
+
{printResponseSchema({ baseName: name, schemas, pluginManager, unknownType })}
|
|
401
|
+
</File.Source>
|
|
402
|
+
</>
|
|
403
|
+
) : (
|
|
404
|
+
<File.Source name={combinedSchemaName} isExportable isIndexable isTypeOnly>
|
|
405
|
+
{printCombinedSchema({ name: combinedSchemaName, schemas, pluginManager })}
|
|
406
|
+
</File.Source>
|
|
407
|
+
)}
|
|
185
408
|
</File>
|
|
186
409
|
)
|
|
187
410
|
},
|
|
188
411
|
Schema({ schema, plugin }) {
|
|
189
412
|
const {
|
|
190
|
-
options: { mapper, enumType, syntaxType, optionalType, output },
|
|
413
|
+
options: { mapper, enumType, syntaxType, optionalType, arrayType, output },
|
|
191
414
|
} = plugin
|
|
192
415
|
const mode = useMode()
|
|
193
416
|
|
|
@@ -231,6 +454,7 @@ export const typeGenerator = createReactGenerator<PluginTs>({
|
|
|
231
454
|
mapper={mapper}
|
|
232
455
|
enumType={enumType}
|
|
233
456
|
optionalType={optionalType}
|
|
457
|
+
arrayType={arrayType}
|
|
234
458
|
syntaxType={syntaxType}
|
|
235
459
|
/>
|
|
236
460
|
</File>
|