@kubb/plugin-ts 5.0.0-alpha.20 → 5.0.0-alpha.22
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/Type-Bf8raoQX.cjs +124 -0
- package/dist/Type-Bf8raoQX.cjs.map +1 -0
- package/dist/Type-BpXxT4l_.js +113 -0
- package/dist/Type-BpXxT4l_.js.map +1 -0
- package/dist/builderTs-COUg3xtQ.cjs +135 -0
- package/dist/builderTs-COUg3xtQ.cjs.map +1 -0
- package/dist/builderTs-DPpkJKd1.js +131 -0
- package/dist/builderTs-DPpkJKd1.js.map +1 -0
- package/dist/builders.cjs +3 -0
- package/dist/builders.d.ts +23 -0
- package/dist/builders.js +2 -0
- package/dist/{casing-Cp-jbC_k.js → casing-BJHFg-zZ.js} +1 -1
- package/dist/{casing-Cp-jbC_k.js.map → casing-BJHFg-zZ.js.map} +1 -1
- package/dist/{casing-D2uQKLWS.cjs → casing-DHfdqpLi.cjs} +2 -39
- package/dist/{casing-D2uQKLWS.cjs.map → casing-DHfdqpLi.cjs.map} +1 -1
- package/dist/chunk-ByKO4r7w.cjs +38 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +5 -2
- package/dist/components.js +1 -1
- package/dist/generators-DFDut8o-.js +555 -0
- package/dist/generators-DFDut8o-.js.map +1 -0
- package/dist/{generators-xHWQCNd9.cjs → generators-DKd7MYbx.cjs} +300 -293
- package/dist/generators-DKd7MYbx.cjs.map +1 -0
- package/dist/generators.cjs +2 -1
- package/dist/generators.d.ts +5 -2
- package/dist/generators.js +2 -2
- package/dist/index.cjs +75 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +21 -2
- package/dist/index.js +73 -35
- package/dist/index.js.map +1 -1
- package/dist/{Type-B70QnSzH.cjs → printerTs-BcHudagv.cjs} +41 -135
- package/dist/printerTs-BcHudagv.cjs.map +1 -0
- package/dist/{Type-CMC7L-38.js → printerTs-CMBCOuqd.js} +19 -132
- package/dist/printerTs-CMBCOuqd.js.map +1 -0
- package/dist/printers.cjs +3 -0
- package/dist/printers.d.ts +81 -0
- package/dist/printers.js +2 -0
- package/dist/{resolvers-DsKabI0F.js → resolverTsLegacy-CPiqqsO6.js} +10 -9
- package/dist/resolverTsLegacy-CPiqqsO6.js.map +1 -0
- package/dist/{resolvers-YIpeP5YD.cjs → resolverTsLegacy-CuR9XbKk.cjs} +11 -9
- package/dist/resolverTsLegacy-CuR9XbKk.cjs.map +1 -0
- package/dist/resolvers.cjs +3 -3
- package/dist/resolvers.d.ts +1 -1
- package/dist/resolvers.js +1 -1
- package/dist/{types-zqLMbIqZ.d.ts → types-CRtcZOCz.d.ts} +59 -25
- package/package.json +17 -5
- package/src/builders/builderTs.ts +107 -0
- package/src/builders/index.ts +1 -0
- package/src/components/Enum.tsx +15 -11
- package/src/components/Type.tsx +20 -9
- package/src/factory.ts +0 -32
- package/src/generators/index.ts +1 -0
- package/src/generators/typeGenerator.tsx +53 -141
- package/src/generators/typeGeneratorLegacy.tsx +348 -0
- package/src/index.ts +1 -1
- package/src/plugin.ts +36 -44
- package/src/presets.ts +27 -7
- package/src/printers/index.ts +1 -0
- package/src/{printer.ts → printers/printerTs.ts} +31 -19
- package/src/resolvers/resolverTs.ts +9 -6
- package/src/resolvers/resolverTsLegacy.ts +1 -1
- package/src/types.ts +72 -24
- package/dist/Type-B70QnSzH.cjs.map +0 -1
- package/dist/Type-CMC7L-38.js.map +0 -1
- package/dist/generators-BFkr7ecU.js +0 -556
- package/dist/generators-BFkr7ecU.js.map +0 -1
- package/dist/generators-xHWQCNd9.cjs.map +0 -1
- package/dist/resolvers-DsKabI0F.js.map +0 -1
- package/dist/resolvers-YIpeP5YD.cjs.map +0 -1
- package/src/generators/utils.ts +0 -308
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-ts",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.22",
|
|
4
4
|
"description": "TypeScript code generation plugin for Kubb, transforming OpenAPI schemas into TypeScript interfaces, types, and utility functions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"import": "./dist/index.js",
|
|
32
32
|
"require": "./dist/index.cjs"
|
|
33
33
|
},
|
|
34
|
+
"./builders": {
|
|
35
|
+
"import": "./dist/builders.js",
|
|
36
|
+
"require": "./dist/builders.cjs"
|
|
37
|
+
},
|
|
34
38
|
"./components": {
|
|
35
39
|
"import": "./dist/components.js",
|
|
36
40
|
"require": "./dist/components.cjs"
|
|
@@ -39,6 +43,10 @@
|
|
|
39
43
|
"import": "./dist/generators.js",
|
|
40
44
|
"require": "./dist/generators.cjs"
|
|
41
45
|
},
|
|
46
|
+
"./printers": {
|
|
47
|
+
"import": "./dist/printers.js",
|
|
48
|
+
"require": "./dist/printers.cjs"
|
|
49
|
+
},
|
|
42
50
|
"./resolvers": {
|
|
43
51
|
"import": "./dist/resolvers.js",
|
|
44
52
|
"require": "./dist/resolvers.cjs"
|
|
@@ -56,6 +64,12 @@
|
|
|
56
64
|
],
|
|
57
65
|
"resolvers": [
|
|
58
66
|
"./dist/resolvers.d.ts"
|
|
67
|
+
],
|
|
68
|
+
"builders": [
|
|
69
|
+
"./dist/builders.d.ts"
|
|
70
|
+
],
|
|
71
|
+
"printers": [
|
|
72
|
+
"./dist/printers.d.ts"
|
|
59
73
|
]
|
|
60
74
|
}
|
|
61
75
|
},
|
|
@@ -78,10 +92,8 @@
|
|
|
78
92
|
"@kubb/react-fabric": "0.15.1",
|
|
79
93
|
"remeda": "^2.33.6",
|
|
80
94
|
"typescript": "5.9.3",
|
|
81
|
-
"@kubb/ast": "5.0.0-alpha.
|
|
82
|
-
"@kubb/core": "5.0.0-alpha.
|
|
83
|
-
"@kubb/oas": "5.0.0-alpha.20",
|
|
84
|
-
"@kubb/plugin-oas": "5.0.0-alpha.20"
|
|
95
|
+
"@kubb/ast": "5.0.0-alpha.22",
|
|
96
|
+
"@kubb/core": "5.0.0-alpha.22"
|
|
85
97
|
},
|
|
86
98
|
"peerDependencies": {
|
|
87
99
|
"@kubb/react-fabric": "0.15.1"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createProperty, createSchema } from '@kubb/ast'
|
|
2
|
+
import { defineBuilder } from '@kubb/core'
|
|
3
|
+
import type { PluginTs } from '../types.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Default schema builder for `@kubb/plugin-ts`.
|
|
7
|
+
*
|
|
8
|
+
* Implements the `buildParams`, `buildData`, `buildResponses`, and `buildResponseUnion` helpers
|
|
9
|
+
* used by the TypeScript type generator to construct AST schema nodes for operation parameters,
|
|
10
|
+
* request bodies, and responses.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { builderTs } from '@kubb/plugin-ts'
|
|
15
|
+
*
|
|
16
|
+
* builderTs.buildData({ node, resolver })
|
|
17
|
+
* // → object schema with pathParams, queryParams, headerParams, data, url properties
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const builderTs = defineBuilder<PluginTs>(() => ({
|
|
21
|
+
name: 'default',
|
|
22
|
+
buildParams({ params, node, resolver }) {
|
|
23
|
+
return createSchema({
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: params.map((param) =>
|
|
26
|
+
createProperty({
|
|
27
|
+
name: param.name,
|
|
28
|
+
required: param.required,
|
|
29
|
+
schema: createSchema({
|
|
30
|
+
type: 'ref',
|
|
31
|
+
name: resolver.resolveParamName(node, param),
|
|
32
|
+
}),
|
|
33
|
+
}),
|
|
34
|
+
),
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
buildData({ node, resolver }) {
|
|
38
|
+
const pathParams = node.parameters.filter((p) => p.in === 'path')
|
|
39
|
+
const queryParams = node.parameters.filter((p) => p.in === 'query')
|
|
40
|
+
const headerParams = node.parameters.filter((p) => p.in === 'header')
|
|
41
|
+
|
|
42
|
+
return createSchema({
|
|
43
|
+
type: 'object',
|
|
44
|
+
deprecated: node.deprecated,
|
|
45
|
+
properties: [
|
|
46
|
+
createProperty({
|
|
47
|
+
name: 'data',
|
|
48
|
+
schema: node.requestBody?.schema
|
|
49
|
+
? createSchema({ type: 'ref', name: resolver.resolveDataTypedName(node), optional: true })
|
|
50
|
+
: createSchema({ type: 'never', optional: true }),
|
|
51
|
+
}),
|
|
52
|
+
createProperty({
|
|
53
|
+
name: 'pathParams',
|
|
54
|
+
required: pathParams.length > 0,
|
|
55
|
+
schema: pathParams.length > 0 ? this.buildParams({ params: pathParams, node, resolver }) : createSchema({ type: 'never' }),
|
|
56
|
+
}),
|
|
57
|
+
createProperty({
|
|
58
|
+
name: 'queryParams',
|
|
59
|
+
schema:
|
|
60
|
+
queryParams.length > 0
|
|
61
|
+
? createSchema({ ...this.buildParams({ params: queryParams, node, resolver }), optional: true })
|
|
62
|
+
: createSchema({ type: 'never', optional: true }),
|
|
63
|
+
}),
|
|
64
|
+
createProperty({
|
|
65
|
+
name: 'headerParams',
|
|
66
|
+
schema:
|
|
67
|
+
headerParams.length > 0
|
|
68
|
+
? createSchema({ ...this.buildParams({ params: headerParams, node, resolver }), optional: true })
|
|
69
|
+
: createSchema({ type: 'never', optional: true }),
|
|
70
|
+
}),
|
|
71
|
+
createProperty({
|
|
72
|
+
name: 'url',
|
|
73
|
+
required: true,
|
|
74
|
+
schema: createSchema({ type: 'url', path: node.path }),
|
|
75
|
+
}),
|
|
76
|
+
],
|
|
77
|
+
})
|
|
78
|
+
},
|
|
79
|
+
buildResponses({ node, resolver }) {
|
|
80
|
+
if (node.responses.length === 0) {
|
|
81
|
+
return null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return createSchema({
|
|
85
|
+
type: 'object',
|
|
86
|
+
properties: node.responses.map((res) =>
|
|
87
|
+
createProperty({
|
|
88
|
+
name: String(res.statusCode),
|
|
89
|
+
required: true,
|
|
90
|
+
schema: createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) }),
|
|
91
|
+
}),
|
|
92
|
+
),
|
|
93
|
+
})
|
|
94
|
+
},
|
|
95
|
+
buildResponseUnion({ node, resolver }) {
|
|
96
|
+
const responsesWithSchema = node.responses.filter((res) => res.schema)
|
|
97
|
+
|
|
98
|
+
if (responsesWithSchema.length === 0) {
|
|
99
|
+
return null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return createSchema({
|
|
103
|
+
type: 'union',
|
|
104
|
+
members: responsesWithSchema.map((res) => createSchema({ type: 'ref', name: resolver.resolveResponseStatusTypedName(node, res.statusCode) })),
|
|
105
|
+
})
|
|
106
|
+
},
|
|
107
|
+
}))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { builderTs } from './builderTs.ts'
|
package/src/components/Enum.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import type { PluginTs, ResolverTs } from '../types.ts'
|
|
|
10
10
|
type Props = {
|
|
11
11
|
node: EnumSchemaNode
|
|
12
12
|
enumType: PluginTs['resolvedOptions']['enumType']
|
|
13
|
+
enumTypeSuffix: PluginTs['resolvedOptions']['enumTypeSuffix']
|
|
13
14
|
enumKeyCasing: PluginTs['resolvedOptions']['enumKeyCasing']
|
|
14
15
|
resolver: ResolverTs
|
|
15
16
|
}
|
|
@@ -21,7 +22,17 @@ type Props = {
|
|
|
21
22
|
* valid TypeScript identifier. The resolver normalizes it; for inline enum
|
|
22
23
|
* properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
|
|
23
24
|
*/
|
|
24
|
-
export function getEnumNames({
|
|
25
|
+
export function getEnumNames({
|
|
26
|
+
node,
|
|
27
|
+
enumType,
|
|
28
|
+
enumTypeSuffix,
|
|
29
|
+
resolver,
|
|
30
|
+
}: {
|
|
31
|
+
node: EnumSchemaNode
|
|
32
|
+
enumType: PluginTs['resolvedOptions']['enumType']
|
|
33
|
+
enumTypeSuffix: PluginTs['resolvedOptions']['enumTypeSuffix']
|
|
34
|
+
resolver: ResolverTs
|
|
35
|
+
}): {
|
|
25
36
|
enumName: string
|
|
26
37
|
typeName: string
|
|
27
38
|
/**
|
|
@@ -32,7 +43,7 @@ export function getEnumNames({ node, enumType, resolver }: { node: EnumSchemaNod
|
|
|
32
43
|
} {
|
|
33
44
|
const resolved = resolver.default(node.name!, 'type')
|
|
34
45
|
const enumName = enumType === 'asPascalConst' ? resolved : camelCase(node.name!)
|
|
35
|
-
const typeName = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ?
|
|
46
|
+
const typeName = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? resolver.resolveEnumKeyTypedName(node, enumTypeSuffix) : resolved
|
|
36
47
|
|
|
37
48
|
return { enumName, typeName, refName: resolved }
|
|
38
49
|
}
|
|
@@ -48,8 +59,8 @@ export function getEnumNames({ node, enumType, resolver }: { node: EnumSchemaNod
|
|
|
48
59
|
* The emitted `File.Source` nodes carry the resolved names so that the barrel
|
|
49
60
|
* index picks up the correct export identifiers.
|
|
50
61
|
*/
|
|
51
|
-
export function Enum({ node, enumType, enumKeyCasing, resolver }: Props): FabricReactNode {
|
|
52
|
-
const { enumName, typeName
|
|
62
|
+
export function Enum({ node, enumType, enumTypeSuffix, enumKeyCasing, resolver }: Props): FabricReactNode {
|
|
63
|
+
const { enumName, typeName } = getEnumNames({ node, enumType, enumTypeSuffix, resolver })
|
|
53
64
|
|
|
54
65
|
const [nameNode, typeNode] = factory.createEnumDeclaration({
|
|
55
66
|
name: enumName,
|
|
@@ -61,8 +72,6 @@ export function Enum({ node, enumType, enumKeyCasing, resolver }: Props): Fabric
|
|
|
61
72
|
enumKeyCasing,
|
|
62
73
|
})
|
|
63
74
|
|
|
64
|
-
const needsRefAlias = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && refName !== typeName
|
|
65
|
-
|
|
66
75
|
return (
|
|
67
76
|
<>
|
|
68
77
|
{nameNode && (
|
|
@@ -73,11 +82,6 @@ export function Enum({ node, enumType, enumKeyCasing, resolver }: Props): Fabric
|
|
|
73
82
|
<File.Source name={typeName} isIndexable isExportable={ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType)} isTypeOnly={ENUM_TYPES_WITH_TYPE_ONLY.has(enumType)}>
|
|
74
83
|
{safePrint(typeNode)}
|
|
75
84
|
</File.Source>
|
|
76
|
-
{needsRefAlias && (
|
|
77
|
-
<File.Source name={refName} isExportable isIndexable isTypeOnly>
|
|
78
|
-
{`export type ${refName} = ${typeName}`}
|
|
79
|
-
</File.Source>
|
|
80
|
-
)}
|
|
81
85
|
</>
|
|
82
86
|
)
|
|
83
87
|
}
|
package/src/components/Type.tsx
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { collect, narrowSchema, schemaTypes } from '@kubb/ast'
|
|
2
2
|
import type { EnumSchemaNode, SchemaNode } from '@kubb/ast/types'
|
|
3
|
-
import { safePrint } from '@kubb/fabric-core/parsers/typescript'
|
|
4
3
|
import { File } from '@kubb/react-fabric'
|
|
5
4
|
import type { FabricReactNode } from '@kubb/react-fabric/types'
|
|
6
|
-
import { printerTs } from '../
|
|
5
|
+
import { printerTs } from '../printers/printerTs.ts'
|
|
7
6
|
import type { PluginTs } from '../types.ts'
|
|
8
7
|
import { Enum, getEnumNames } from './Enum.tsx'
|
|
9
8
|
|
|
@@ -14,10 +13,10 @@ type Props = {
|
|
|
14
13
|
optionalType: PluginTs['resolvedOptions']['optionalType']
|
|
15
14
|
arrayType: PluginTs['resolvedOptions']['arrayType']
|
|
16
15
|
enumType: PluginTs['resolvedOptions']['enumType']
|
|
16
|
+
enumTypeSuffix: PluginTs['resolvedOptions']['enumTypeSuffix']
|
|
17
17
|
enumKeyCasing: PluginTs['resolvedOptions']['enumKeyCasing']
|
|
18
18
|
syntaxType: PluginTs['resolvedOptions']['syntaxType']
|
|
19
19
|
resolver: PluginTs['resolvedOptions']['resolver']
|
|
20
|
-
legacy?: boolean
|
|
21
20
|
description?: string
|
|
22
21
|
keysToOmit?: string[]
|
|
23
22
|
}
|
|
@@ -31,6 +30,7 @@ export function Type({
|
|
|
31
30
|
arrayType,
|
|
32
31
|
syntaxType,
|
|
33
32
|
enumType,
|
|
33
|
+
enumTypeSuffix,
|
|
34
34
|
enumKeyCasing,
|
|
35
35
|
description,
|
|
36
36
|
resolver,
|
|
@@ -43,17 +43,27 @@ export function Type({
|
|
|
43
43
|
},
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
const printer = printerTs({
|
|
47
|
-
|
|
46
|
+
const printer = printerTs({
|
|
47
|
+
optionalType,
|
|
48
|
+
arrayType,
|
|
49
|
+
enumType,
|
|
50
|
+
enumTypeSuffix,
|
|
51
|
+
typeName: name,
|
|
52
|
+
syntaxType,
|
|
53
|
+
description: resolvedDescription,
|
|
54
|
+
keysToOmit,
|
|
55
|
+
resolver,
|
|
56
|
+
})
|
|
57
|
+
const output = printer.print(node)
|
|
48
58
|
|
|
49
|
-
if (!
|
|
59
|
+
if (!output) {
|
|
50
60
|
return
|
|
51
61
|
}
|
|
52
62
|
|
|
53
63
|
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
|
|
54
64
|
return {
|
|
55
65
|
node,
|
|
56
|
-
...getEnumNames({ node, enumType, resolver }),
|
|
66
|
+
...getEnumNames({ node, enumType, enumTypeSuffix, resolver }),
|
|
57
67
|
}
|
|
58
68
|
})
|
|
59
69
|
|
|
@@ -63,10 +73,11 @@ export function Type({
|
|
|
63
73
|
|
|
64
74
|
return (
|
|
65
75
|
<>
|
|
66
|
-
{shouldExportEnums &&
|
|
76
|
+
{shouldExportEnums &&
|
|
77
|
+
enums.map(({ node }) => <Enum node={node} enumType={enumType} enumTypeSuffix={enumTypeSuffix} enumKeyCasing={enumKeyCasing} resolver={resolver} />)}
|
|
67
78
|
{shouldExportType && (
|
|
68
79
|
<File.Source name={typedName} isTypeOnly isExportable isIndexable>
|
|
69
|
-
{
|
|
80
|
+
{output}
|
|
70
81
|
</File.Source>
|
|
71
82
|
)}
|
|
72
83
|
</>
|
package/src/factory.ts
CHANGED
|
@@ -19,16 +19,6 @@ export const syntaxKind = {
|
|
|
19
19
|
stringLiteral: SyntaxKind.StringLiteral,
|
|
20
20
|
} as const
|
|
21
21
|
|
|
22
|
-
export function getUnknownType(unknownType: 'any' | 'unknown' | 'void' | undefined) {
|
|
23
|
-
if (unknownType === 'any') {
|
|
24
|
-
return keywordTypeNodes.any
|
|
25
|
-
}
|
|
26
|
-
if (unknownType === 'void') {
|
|
27
|
-
return keywordTypeNodes.void
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return keywordTypeNodes.unknown
|
|
31
|
-
}
|
|
32
22
|
function isValidIdentifier(str: string): boolean {
|
|
33
23
|
if (!str.length || str.trim() !== str) {
|
|
34
24
|
return false
|
|
@@ -76,28 +66,6 @@ export function createIntersectionDeclaration({ nodes, withParentheses }: { node
|
|
|
76
66
|
return node
|
|
77
67
|
}
|
|
78
68
|
|
|
79
|
-
/**
|
|
80
|
-
* Minimum nodes length of 2
|
|
81
|
-
* @example `string & number`
|
|
82
|
-
*/
|
|
83
|
-
export function createTupleDeclaration({ nodes, withParentheses }: { nodes: Array<ts.TypeNode>; withParentheses?: boolean }): ts.TypeNode | null {
|
|
84
|
-
if (!nodes.length) {
|
|
85
|
-
return null
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (nodes.length === 1) {
|
|
89
|
-
return nodes[0] || null
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const node = factory.createTupleTypeNode(nodes)
|
|
93
|
-
|
|
94
|
-
if (withParentheses) {
|
|
95
|
-
return factory.createParenthesizedType(node)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return node
|
|
99
|
-
}
|
|
100
|
-
|
|
101
69
|
export function createArrayDeclaration({ nodes, arrayType = 'array' }: { nodes: Array<ts.TypeNode>; arrayType?: 'array' | 'generic' }): ts.TypeNode | null {
|
|
102
70
|
if (!nodes.length) {
|
|
103
71
|
return factory.createTupleTypeNode([])
|
package/src/generators/index.ts
CHANGED
|
@@ -1,50 +1,24 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
1
2
|
import { caseParams, composeTransformers, narrowSchema, schemaTypes, transform } from '@kubb/ast'
|
|
2
3
|
import type { SchemaNode } from '@kubb/ast/types'
|
|
3
|
-
import { defineGenerator } from '@kubb/core'
|
|
4
|
-
import { useKubb } from '@kubb/core/hooks'
|
|
4
|
+
import { defineGenerator, getMode } from '@kubb/core'
|
|
5
5
|
import { File } from '@kubb/react-fabric'
|
|
6
|
+
import { builderTs } from '../builders/builderTs.ts'
|
|
6
7
|
import { Type } from '../components/Type.tsx'
|
|
7
8
|
import { ENUM_TYPES_WITH_KEY_SUFFIX } from '../constants.ts'
|
|
8
9
|
import type { PluginTs } from '../types'
|
|
9
|
-
import {
|
|
10
|
-
buildDataSchemaNode,
|
|
11
|
-
buildGroupedParamsSchema,
|
|
12
|
-
buildLegacyResponsesSchemaNode,
|
|
13
|
-
buildLegacyResponseUnionSchemaNode,
|
|
14
|
-
buildParamsSchema,
|
|
15
|
-
buildResponsesSchemaNode,
|
|
16
|
-
buildResponseUnionSchemaNode,
|
|
17
|
-
nameUnnamedEnums,
|
|
18
|
-
} from './utils.ts'
|
|
19
10
|
|
|
20
11
|
export const typeGenerator = defineGenerator<PluginTs>({
|
|
21
12
|
name: 'typescript',
|
|
22
13
|
type: 'react',
|
|
23
|
-
Operation({ node, adapter, options }) {
|
|
24
|
-
const {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
paramsCasing,
|
|
31
|
-
group,
|
|
32
|
-
resolver,
|
|
33
|
-
baseResolver,
|
|
34
|
-
compatibilityPreset,
|
|
35
|
-
transformers = [],
|
|
36
|
-
} = options
|
|
37
|
-
const isKubbV4Compatibility = compatibilityPreset === 'kubbV4'
|
|
38
|
-
const { mode, getFile, resolveBanner, resolveFooter } = useKubb<PluginTs>()
|
|
14
|
+
Operation({ node, adapter, options, config }) {
|
|
15
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group, output, resolver, transformers = [] } = options
|
|
16
|
+
|
|
17
|
+
const root = path.resolve(config.root, config.output.path)
|
|
18
|
+
const mode = getMode(path.resolve(root, output.path))
|
|
19
|
+
|
|
20
|
+
const file = resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group })
|
|
39
21
|
|
|
40
|
-
const file = getFile({
|
|
41
|
-
name: node.operationId,
|
|
42
|
-
extname: '.ts',
|
|
43
|
-
mode,
|
|
44
|
-
options: {
|
|
45
|
-
group: group ? (group.type === 'tag' ? { tag: node.tags[0] ?? 'default' } : { path: node.path }) : undefined,
|
|
46
|
-
},
|
|
47
|
-
})
|
|
48
22
|
const params = caseParams(node.parameters, paramsCasing)
|
|
49
23
|
|
|
50
24
|
function renderSchemaType({
|
|
@@ -68,7 +42,7 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
68
42
|
|
|
69
43
|
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
70
44
|
name: resolver.default(schemaName, 'type'),
|
|
71
|
-
path:
|
|
45
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
72
46
|
}))
|
|
73
47
|
|
|
74
48
|
return (
|
|
@@ -81,44 +55,29 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
81
55
|
node={transformedNode}
|
|
82
56
|
description={description}
|
|
83
57
|
enumType={enumType}
|
|
58
|
+
enumTypeSuffix={enumTypeSuffix}
|
|
84
59
|
enumKeyCasing={enumKeyCasing}
|
|
85
60
|
optionalType={optionalType}
|
|
86
61
|
arrayType={arrayType}
|
|
87
62
|
syntaxType={syntaxType}
|
|
88
63
|
resolver={resolver}
|
|
89
64
|
keysToOmit={keysToOmit}
|
|
90
|
-
legacy={isKubbV4Compatibility}
|
|
91
65
|
/>
|
|
92
66
|
</>
|
|
93
67
|
)
|
|
94
68
|
}
|
|
95
69
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
name: responseName,
|
|
104
|
-
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
105
|
-
description: res.description,
|
|
106
|
-
keysToOmit: res.keysToOmit,
|
|
107
|
-
})
|
|
108
|
-
})
|
|
109
|
-
: node.responses.map((res) =>
|
|
110
|
-
renderSchemaType({
|
|
111
|
-
node: res.schema,
|
|
112
|
-
name: resolver.resolveResponseStatusName(node, res.statusCode),
|
|
113
|
-
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
114
|
-
description: res.description,
|
|
115
|
-
keysToOmit: res.keysToOmit,
|
|
116
|
-
}),
|
|
117
|
-
)
|
|
70
|
+
const paramTypes = params.map((param) =>
|
|
71
|
+
renderSchemaType({
|
|
72
|
+
node: param.schema,
|
|
73
|
+
name: resolver.resolveParamName(node, param),
|
|
74
|
+
typedName: resolver.resolveParamTypedName(node, param),
|
|
75
|
+
}),
|
|
76
|
+
)
|
|
118
77
|
|
|
119
78
|
const requestType = node.requestBody?.schema
|
|
120
79
|
? renderSchemaType({
|
|
121
|
-
node:
|
|
80
|
+
node: node.requestBody.schema,
|
|
122
81
|
name: resolver.resolveDataName(node),
|
|
123
82
|
typedName: resolver.resolveDataTypedName(node),
|
|
124
83
|
description: node.requestBody.description ?? node.requestBody.schema.description,
|
|
@@ -126,99 +85,44 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
126
85
|
})
|
|
127
86
|
: null
|
|
128
87
|
|
|
129
|
-
|
|
130
|
-
const pathParams = params.filter((p) => p.in === 'path')
|
|
131
|
-
const queryParams = params.filter((p) => p.in === 'query')
|
|
132
|
-
const headerParams = params.filter((p) => p.in === 'header')
|
|
133
|
-
|
|
134
|
-
const legacyParamTypes = [
|
|
135
|
-
pathParams.length > 0
|
|
136
|
-
? renderSchemaType({
|
|
137
|
-
node: buildGroupedParamsSchema({ params: pathParams, parentName: baseResolver.resolvePathParamsName!(node) }),
|
|
138
|
-
name: resolver.resolvePathParamsName!(node),
|
|
139
|
-
typedName: resolver.resolvePathParamsTypedName!(node),
|
|
140
|
-
})
|
|
141
|
-
: null,
|
|
142
|
-
queryParams.length > 0
|
|
143
|
-
? renderSchemaType({
|
|
144
|
-
node: buildGroupedParamsSchema({ params: queryParams, parentName: baseResolver.resolveQueryParamsName!(node) }),
|
|
145
|
-
name: resolver.resolveQueryParamsName!(node),
|
|
146
|
-
typedName: resolver.resolveQueryParamsTypedName!(node),
|
|
147
|
-
})
|
|
148
|
-
: null,
|
|
149
|
-
headerParams.length > 0
|
|
150
|
-
? renderSchemaType({
|
|
151
|
-
node: buildGroupedParamsSchema({ params: headerParams, parentName: baseResolver.resolveHeaderParamsName!(node) }),
|
|
152
|
-
name: resolver.resolveHeaderParamsName!(node),
|
|
153
|
-
typedName: resolver.resolveHeaderParamsTypedName!(node),
|
|
154
|
-
})
|
|
155
|
-
: null,
|
|
156
|
-
]
|
|
157
|
-
|
|
158
|
-
const legacyResponsesType = renderSchemaType({
|
|
159
|
-
node: buildLegacyResponsesSchemaNode({ node, resolver }),
|
|
160
|
-
name: resolver.resolveResponsesName(node),
|
|
161
|
-
typedName: resolver.resolveResponsesTypedName(node),
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const legacyResponseType = renderSchemaType({
|
|
165
|
-
node: buildLegacyResponseUnionSchemaNode({ node, resolver }),
|
|
166
|
-
name: resolver.resolveResponseName(node),
|
|
167
|
-
typedName: resolver.resolveResponseTypedName(node),
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<File baseName={file.baseName} path={file.path} meta={file.meta} banner={resolveBanner()} footer={resolveFooter()}>
|
|
172
|
-
{legacyParamTypes}
|
|
173
|
-
{responseTypes}
|
|
174
|
-
{requestType}
|
|
175
|
-
{legacyResponseType}
|
|
176
|
-
{legacyResponsesType}
|
|
177
|
-
</File>
|
|
178
|
-
)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const paramTypes = params.map((param) =>
|
|
88
|
+
const responseTypes = node.responses.map((res) =>
|
|
182
89
|
renderSchemaType({
|
|
183
|
-
node:
|
|
184
|
-
name: resolver.
|
|
185
|
-
typedName: resolver.
|
|
90
|
+
node: res.schema,
|
|
91
|
+
name: resolver.resolveResponseStatusName(node, res.statusCode),
|
|
92
|
+
typedName: resolver.resolveResponseStatusTypedName(node, res.statusCode),
|
|
93
|
+
description: res.description,
|
|
94
|
+
keysToOmit: res.keysToOmit,
|
|
186
95
|
}),
|
|
187
96
|
)
|
|
188
97
|
|
|
189
|
-
const queryParamsList = params.filter((p) => p.in === 'query')
|
|
190
|
-
const queryParamsType =
|
|
191
|
-
queryParamsList.length > 0
|
|
192
|
-
? renderSchemaType({
|
|
193
|
-
node: buildParamsSchema({ params: queryParamsList, node, resolver }),
|
|
194
|
-
name: resolver.resolveQueryParamsName!(node),
|
|
195
|
-
typedName: resolver.resolveQueryParamsTypedName!(node),
|
|
196
|
-
})
|
|
197
|
-
: null
|
|
198
|
-
|
|
199
98
|
const dataType = renderSchemaType({
|
|
200
|
-
node:
|
|
99
|
+
node: builderTs.buildData({ node: { ...node, parameters: params }, resolver }),
|
|
201
100
|
name: resolver.resolveRequestConfigName(node),
|
|
202
101
|
typedName: resolver.resolveRequestConfigTypedName(node),
|
|
203
102
|
})
|
|
204
103
|
|
|
205
104
|
const responsesType = renderSchemaType({
|
|
206
|
-
node:
|
|
105
|
+
node: builderTs.buildResponses({ node, resolver }),
|
|
207
106
|
name: resolver.resolveResponsesName(node),
|
|
208
107
|
typedName: resolver.resolveResponsesTypedName(node),
|
|
209
108
|
})
|
|
210
109
|
|
|
211
110
|
const responseType = renderSchemaType({
|
|
212
|
-
node:
|
|
111
|
+
node: builderTs.buildResponseUnion({ node, resolver }),
|
|
213
112
|
name: resolver.resolveResponseName(node),
|
|
214
113
|
typedName: resolver.resolveResponseTypedName(node),
|
|
215
114
|
description: 'Union of all possible responses',
|
|
216
115
|
})
|
|
217
116
|
|
|
218
117
|
return (
|
|
219
|
-
<File
|
|
118
|
+
<File
|
|
119
|
+
baseName={file.baseName}
|
|
120
|
+
path={file.path}
|
|
121
|
+
meta={file.meta}
|
|
122
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
123
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
124
|
+
>
|
|
220
125
|
{paramTypes}
|
|
221
|
-
{queryParamsType}
|
|
222
126
|
{responseTypes}
|
|
223
127
|
{requestType}
|
|
224
128
|
{dataType}
|
|
@@ -227,10 +131,11 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
227
131
|
</File>
|
|
228
132
|
)
|
|
229
133
|
},
|
|
230
|
-
Schema({ node, adapter, options }) {
|
|
231
|
-
const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType,
|
|
232
|
-
|
|
233
|
-
const
|
|
134
|
+
Schema({ node, adapter, options, config }) {
|
|
135
|
+
const { enumType, enumTypeSuffix, enumKeyCasing, syntaxType, optionalType, arrayType, output, group, resolver, transformers = [] } = options
|
|
136
|
+
|
|
137
|
+
const root = path.resolve(config.root, config.output.path)
|
|
138
|
+
const mode = getMode(path.resolve(root, output.path))
|
|
234
139
|
|
|
235
140
|
if (!node.name) {
|
|
236
141
|
return
|
|
@@ -240,21 +145,28 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
240
145
|
|
|
241
146
|
const imports = adapter.getImports(transformedNode, (schemaName) => ({
|
|
242
147
|
name: resolver.default(schemaName, 'type'),
|
|
243
|
-
path:
|
|
148
|
+
path: resolver.resolveFile({ name: schemaName, extname: '.ts' }, { root, output, group }).path,
|
|
244
149
|
}))
|
|
245
150
|
|
|
246
151
|
const isEnumSchema = !!narrowSchema(node, schemaTypes.enum)
|
|
247
152
|
|
|
248
|
-
const typedName =
|
|
153
|
+
const typedName =
|
|
154
|
+
ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema ? resolver.resolveEnumKeyTypedName(node, enumTypeSuffix) : resolver.resolveTypedName(node.name)
|
|
249
155
|
|
|
250
156
|
const type = {
|
|
251
157
|
name: resolver.resolveName(node.name),
|
|
252
158
|
typedName,
|
|
253
|
-
file:
|
|
159
|
+
file: resolver.resolveFile({ name: node.name, extname: '.ts' }, { root, output, group }),
|
|
254
160
|
} as const
|
|
255
161
|
|
|
256
162
|
return (
|
|
257
|
-
<File
|
|
163
|
+
<File
|
|
164
|
+
baseName={type.file.baseName}
|
|
165
|
+
path={type.file.path}
|
|
166
|
+
meta={type.file.meta}
|
|
167
|
+
banner={resolver.resolveBanner(adapter.rootNode, { output, config })}
|
|
168
|
+
footer={resolver.resolveFooter(adapter.rootNode, { output, config })}
|
|
169
|
+
>
|
|
258
170
|
{mode === 'split' &&
|
|
259
171
|
imports.map((imp) => (
|
|
260
172
|
<File.Import key={[node.name, imp.path, imp.isTypeOnly].join('-')} root={type.file.path} path={imp.path} name={imp.name} isTypeOnly />
|
|
@@ -264,12 +176,12 @@ export const typeGenerator = defineGenerator<PluginTs>({
|
|
|
264
176
|
typedName={type.typedName}
|
|
265
177
|
node={transformedNode}
|
|
266
178
|
enumType={enumType}
|
|
179
|
+
enumTypeSuffix={enumTypeSuffix}
|
|
267
180
|
enumKeyCasing={enumKeyCasing}
|
|
268
181
|
optionalType={optionalType}
|
|
269
182
|
arrayType={arrayType}
|
|
270
183
|
syntaxType={syntaxType}
|
|
271
184
|
resolver={resolver}
|
|
272
|
-
legacy={isKubbV4Compatibility}
|
|
273
185
|
/>
|
|
274
186
|
</File>
|
|
275
187
|
)
|