@kubb/plugin-ts 3.0.0-alpha.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.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/chunk-WOQIHEJC.js +621 -0
- package/dist/chunk-WOQIHEJC.js.map +1 -0
- package/dist/chunk-XCNZFEPR.cjs +621 -0
- package/dist/chunk-XCNZFEPR.cjs.map +1 -0
- package/dist/components.cjs +11 -0
- package/dist/components.cjs.map +1 -0
- package/dist/components.d.cts +60 -0
- package/dist/components.d.ts +60 -0
- package/dist/components.js +11 -0
- package/dist/components.js.map +1 -0
- package/dist/index.cjs +13 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +141 -0
- package/dist/index.d.ts +141 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/oas.cjs +1 -0
- package/dist/oas.cjs.map +1 -0
- package/dist/oas.d.cts +1 -0
- package/dist/oas.d.ts +1 -0
- package/dist/oas.js +1 -0
- package/dist/oas.js.map +1 -0
- package/package.json +91 -0
- package/src/OperationGenerator.tsx +49 -0
- package/src/SchemaGenerator.tsx +31 -0
- package/src/components/OasType.tsx +76 -0
- package/src/components/OperationSchema.tsx +161 -0
- package/src/components/Schema.tsx +135 -0
- package/src/components/__snapshots__/Schema/pets.ts +23 -0
- package/src/components/__snapshots__/Schema/showPetById.ts +28 -0
- package/src/components/index.ts +3 -0
- package/src/index.ts +15 -0
- package/src/oas/index.ts +1 -0
- package/src/parser/index.ts +263 -0
- package/src/plugin.ts +138 -0
- package/src/types.ts +138 -0
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kubb/plugin-ts",
|
|
3
|
+
"version": "3.0.0-alpha.0",
|
|
4
|
+
"description": "Generator plugin-ts",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"zod",
|
|
7
|
+
"plugins",
|
|
8
|
+
"kubb",
|
|
9
|
+
"codegen",
|
|
10
|
+
"swagger",
|
|
11
|
+
"openapi"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git://github.com/kubb-labs/kubb.git",
|
|
16
|
+
"directory": "packages/plugin-ts"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Stijn Van Hulle <stijn@stijnvanhulle.be",
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"type": "module",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"require": "./dist/index.cjs",
|
|
26
|
+
"default": "./dist/index.cjs"
|
|
27
|
+
},
|
|
28
|
+
"./components": {
|
|
29
|
+
"import": "./dist/components.js",
|
|
30
|
+
"require": "./dist/components.cjs",
|
|
31
|
+
"default": "./dist/components.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json",
|
|
34
|
+
"./*": "./*"
|
|
35
|
+
},
|
|
36
|
+
"main": "dist/index.cjs",
|
|
37
|
+
"module": "dist/index.js",
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"typesVersions": {
|
|
40
|
+
"*": {
|
|
41
|
+
"components": [
|
|
42
|
+
"./dist/components.d.ts"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"src",
|
|
48
|
+
"dist",
|
|
49
|
+
"!/**/**.test.**",
|
|
50
|
+
"!/**/__tests__/**"
|
|
51
|
+
],
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@kubb/core": "3.0.0-alpha.0",
|
|
54
|
+
"@kubb/fs": "3.0.0-alpha.0",
|
|
55
|
+
"@kubb/oas": "3.0.0-alpha.0",
|
|
56
|
+
"@kubb/parser-ts": "3.0.0-alpha.0",
|
|
57
|
+
"@kubb/plugin-oas": "3.0.0-alpha.0",
|
|
58
|
+
"@kubb/react": "3.0.0-alpha.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/react": "^18.3.3",
|
|
62
|
+
"prettier": "^3.3.3",
|
|
63
|
+
"react": "^18.3.1",
|
|
64
|
+
"tsup": "^8.2.4",
|
|
65
|
+
"typescript": "^5.5.4",
|
|
66
|
+
"@kubb/config-biome": "3.0.0-alpha.0",
|
|
67
|
+
"@kubb/config-ts": "3.0.0-alpha.0",
|
|
68
|
+
"@kubb/config-tsup": "3.0.0-alpha.0"
|
|
69
|
+
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@kubb/react": "3.0.0-alpha.0"
|
|
72
|
+
},
|
|
73
|
+
"engines": {
|
|
74
|
+
"node": ">=20"
|
|
75
|
+
},
|
|
76
|
+
"publishConfig": {
|
|
77
|
+
"access": "public",
|
|
78
|
+
"registry": "https://registry.npmjs.org/"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "tsup",
|
|
82
|
+
"clean": "npx rimraf ./dist",
|
|
83
|
+
"lint": "bun biome lint .",
|
|
84
|
+
"lint:fix": "bun biome lint --apply-unsafe .",
|
|
85
|
+
"release": "pnpm publish --no-git-check",
|
|
86
|
+
"release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
|
|
87
|
+
"start": "tsup --watch",
|
|
88
|
+
"test": "vitest --passWithNoTests",
|
|
89
|
+
"typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { OperationGenerator as Generator } from '@kubb/plugin-oas'
|
|
2
|
+
import { Oas } from '@kubb/plugin-oas/components'
|
|
3
|
+
import { App, createRoot } from '@kubb/react'
|
|
4
|
+
|
|
5
|
+
import { OasType } from './components/OasType.tsx'
|
|
6
|
+
import { OperationSchema } from './components/OperationSchema.tsx'
|
|
7
|
+
|
|
8
|
+
import type { Operation } from '@kubb/oas'
|
|
9
|
+
import type { OperationMethodResult } from '@kubb/plugin-oas'
|
|
10
|
+
import type { FileMeta, PluginTs } from './types.ts'
|
|
11
|
+
|
|
12
|
+
export class OperationGenerator extends Generator<PluginTs['resolvedOptions'], PluginTs> {
|
|
13
|
+
async all(operations: Operation[]): OperationMethodResult<FileMeta> {
|
|
14
|
+
const { oas, pluginManager, plugin, mode } = this.context
|
|
15
|
+
|
|
16
|
+
const root = createRoot({
|
|
17
|
+
logger: pluginManager.logger,
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
root.render(
|
|
21
|
+
<App pluginManager={pluginManager} plugin={plugin} mode={mode}>
|
|
22
|
+
<Oas oas={oas} operations={operations} generator={this}>
|
|
23
|
+
{plugin.options.oasType && <OasType.File name="oas" typeName="Oas" />}
|
|
24
|
+
</Oas>
|
|
25
|
+
</App>,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
return root.files
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async operation(operation: Operation, options: PluginTs['resolvedOptions']): OperationMethodResult<FileMeta> {
|
|
32
|
+
const { oas, pluginManager, plugin, mode } = this.context
|
|
33
|
+
|
|
34
|
+
const root = createRoot({
|
|
35
|
+
logger: pluginManager.logger,
|
|
36
|
+
})
|
|
37
|
+
root.render(
|
|
38
|
+
<App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
|
|
39
|
+
<Oas oas={oas} operations={[operation]} generator={this}>
|
|
40
|
+
<Oas.Operation operation={operation}>
|
|
41
|
+
<OperationSchema.File />
|
|
42
|
+
</Oas.Operation>
|
|
43
|
+
</Oas>
|
|
44
|
+
</App>,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
return root.files
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SchemaObject } from '@kubb/oas'
|
|
2
|
+
import { SchemaGenerator as Generator } from '@kubb/plugin-oas'
|
|
3
|
+
import type { SchemaMethodResult } from '@kubb/plugin-oas'
|
|
4
|
+
import { Oas } from '@kubb/plugin-oas/components'
|
|
5
|
+
import { App, createRoot } from '@kubb/react'
|
|
6
|
+
import { Schema } from './components/Schema.tsx'
|
|
7
|
+
import type { FileMeta, PluginTs } from './types.ts'
|
|
8
|
+
|
|
9
|
+
export class SchemaGenerator extends Generator<PluginTs['resolvedOptions'], PluginTs> {
|
|
10
|
+
async schema(name: string, schema: SchemaObject, options: PluginTs['resolvedOptions']): SchemaMethodResult<FileMeta> {
|
|
11
|
+
const { oas, pluginManager, plugin, mode, output } = this.context
|
|
12
|
+
|
|
13
|
+
const root = createRoot({
|
|
14
|
+
logger: pluginManager.logger,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const tree = this.parse({ schema, name })
|
|
18
|
+
|
|
19
|
+
root.render(
|
|
20
|
+
<App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
|
|
21
|
+
<Oas oas={oas}>
|
|
22
|
+
<Oas.Schema name={name} value={schema} tree={tree}>
|
|
23
|
+
<Schema.File />
|
|
24
|
+
</Oas.Schema>
|
|
25
|
+
</Oas>
|
|
26
|
+
</App>,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
return root.files
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Parser, File, Type, useApp } from '@kubb/react'
|
|
2
|
+
import { useOas } from '@kubb/plugin-oas/hooks'
|
|
3
|
+
|
|
4
|
+
import type { OasTypes } from '@kubb/oas'
|
|
5
|
+
import type { ReactNode } from 'react'
|
|
6
|
+
import type { FileMeta, PluginTs } from '../types.ts'
|
|
7
|
+
|
|
8
|
+
type TemplateProps = {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the function
|
|
11
|
+
*/
|
|
12
|
+
name: string
|
|
13
|
+
typeName: string
|
|
14
|
+
api: OasTypes.OASDocument
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function Template({ name, typeName, api }: TemplateProps): ReactNode {
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
{`export const ${name} = ${JSON.stringify(api, undefined, 2)} as const`}
|
|
21
|
+
<br />
|
|
22
|
+
<Type name={typeName} export>
|
|
23
|
+
{`Infer<typeof ${name}>`}
|
|
24
|
+
</Type>
|
|
25
|
+
</>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const defaultTemplates = { default: Template } as const
|
|
30
|
+
|
|
31
|
+
type Props = {
|
|
32
|
+
name: string
|
|
33
|
+
typeName: string
|
|
34
|
+
/**
|
|
35
|
+
* This will make it possible to override the default behaviour.
|
|
36
|
+
*/
|
|
37
|
+
Template?: React.ComponentType<React.ComponentProps<typeof Template>>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function OasType({ name, typeName, Template = defaultTemplates.default }: Props): ReactNode {
|
|
41
|
+
const oas = useOas()
|
|
42
|
+
|
|
43
|
+
return <Template name={name} typeName={typeName} api={oas.api} />
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type FileProps = {
|
|
47
|
+
name: string
|
|
48
|
+
typeName: string
|
|
49
|
+
/**
|
|
50
|
+
* This will make it possible to override the default behaviour.
|
|
51
|
+
*/
|
|
52
|
+
templates?: typeof defaultTemplates
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
OasType.File = function ({ name, typeName, templates = defaultTemplates }: FileProps): ReactNode {
|
|
56
|
+
const {
|
|
57
|
+
pluginManager,
|
|
58
|
+
plugin: { key: pluginKey },
|
|
59
|
+
} = useApp<PluginTs>()
|
|
60
|
+
const file = pluginManager.getFile({ name, extName: '.ts', pluginKey })
|
|
61
|
+
|
|
62
|
+
const Template = templates.default
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Parser language="typescript">
|
|
66
|
+
<File<FileMeta> baseName={file.baseName} path={file.path} meta={file.meta}>
|
|
67
|
+
<File.Import name={['Infer']} path="@kubb/oas" isTypeOnly />
|
|
68
|
+
<File.Source>
|
|
69
|
+
<OasType Template={Template} name={name} typeName={typeName} />
|
|
70
|
+
</File.Source>
|
|
71
|
+
</File>
|
|
72
|
+
</Parser>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
OasType.templates = defaultTemplates
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import transformers from '@kubb/core/transformers'
|
|
2
|
+
import { print } from '@kubb/parser-ts'
|
|
3
|
+
import * as factory from '@kubb/parser-ts/factory'
|
|
4
|
+
import { Oas } from '@kubb/plugin-oas/components'
|
|
5
|
+
import { useOas, useOperation, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
6
|
+
import { File, Parser, useApp } from '@kubb/react'
|
|
7
|
+
|
|
8
|
+
import { SchemaGenerator } from '../SchemaGenerator.tsx'
|
|
9
|
+
|
|
10
|
+
import type { PluginManager } from '@kubb/core'
|
|
11
|
+
import type { Operation } from '@kubb/oas'
|
|
12
|
+
import type { ts } from '@kubb/parser-ts'
|
|
13
|
+
import type { OperationSchema as OperationSchemaType } from '@kubb/plugin-oas'
|
|
14
|
+
import type { OperationSchemas } from '@kubb/plugin-oas'
|
|
15
|
+
import { pluginTsName } from '@kubb/plugin-ts'
|
|
16
|
+
import type { ReactNode } from 'react'
|
|
17
|
+
import type { FileMeta, PluginTs } from '../types.ts'
|
|
18
|
+
import { Schema } from './Schema.tsx'
|
|
19
|
+
|
|
20
|
+
function printCombinedSchema({
|
|
21
|
+
name,
|
|
22
|
+
operation,
|
|
23
|
+
schemas,
|
|
24
|
+
pluginManager,
|
|
25
|
+
}: { name: string; operation: Operation; schemas: OperationSchemas; pluginManager: PluginManager }): string {
|
|
26
|
+
const properties: Record<string, ts.TypeNode> = {}
|
|
27
|
+
|
|
28
|
+
if (schemas.response) {
|
|
29
|
+
const identifier = pluginManager.resolveName({
|
|
30
|
+
name: schemas.response.name,
|
|
31
|
+
pluginKey: [pluginTsName],
|
|
32
|
+
type: 'function',
|
|
33
|
+
})
|
|
34
|
+
properties['response'] = factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (schemas.request) {
|
|
38
|
+
const identifier = pluginManager.resolveName({
|
|
39
|
+
name: schemas.request.name,
|
|
40
|
+
pluginKey: [pluginTsName],
|
|
41
|
+
type: 'function',
|
|
42
|
+
})
|
|
43
|
+
properties['request'] = factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (schemas.pathParams) {
|
|
47
|
+
const identifier = pluginManager.resolveName({
|
|
48
|
+
name: schemas.pathParams.name,
|
|
49
|
+
pluginKey: [pluginTsName],
|
|
50
|
+
type: 'function',
|
|
51
|
+
})
|
|
52
|
+
properties['pathParams'] = factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (schemas.queryParams) {
|
|
56
|
+
const identifier = pluginManager.resolveName({
|
|
57
|
+
name: schemas.queryParams.name,
|
|
58
|
+
pluginKey: [pluginTsName],
|
|
59
|
+
type: 'function',
|
|
60
|
+
})
|
|
61
|
+
properties['queryParams'] = factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (schemas.headerParams) {
|
|
65
|
+
const identifier = pluginManager.resolveName({
|
|
66
|
+
name: schemas.headerParams.name,
|
|
67
|
+
pluginKey: [pluginTsName],
|
|
68
|
+
type: 'function',
|
|
69
|
+
})
|
|
70
|
+
properties['headerParams'] = factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (schemas.errors) {
|
|
74
|
+
properties['errors'] = factory.createUnionDeclaration({
|
|
75
|
+
nodes: schemas.errors.map((error) => {
|
|
76
|
+
const identifier = pluginManager.resolveName({
|
|
77
|
+
name: error.name,
|
|
78
|
+
pluginKey: [pluginTsName],
|
|
79
|
+
type: 'function',
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return factory.createTypeReferenceNode(factory.createIdentifier(identifier), undefined)
|
|
83
|
+
}),
|
|
84
|
+
})!
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const namespaceNode = factory.createTypeAliasDeclaration({
|
|
88
|
+
name: operation.method === 'get' ? `${name}Query` : `${name}Mutation`,
|
|
89
|
+
type: factory.createTypeLiteralNode(
|
|
90
|
+
Object.keys(properties)
|
|
91
|
+
.map((key) => {
|
|
92
|
+
const type = properties[key]
|
|
93
|
+
if (!type) {
|
|
94
|
+
return undefined
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return factory.createPropertySignature({
|
|
98
|
+
name: transformers.pascalCase(key),
|
|
99
|
+
type,
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
.filter(Boolean),
|
|
103
|
+
),
|
|
104
|
+
modifiers: [factory.modifiers.export],
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
return print(namespaceNode)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type Props = {
|
|
111
|
+
description?: string
|
|
112
|
+
keysToOmit?: string[]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function OperationSchema({ keysToOmit, description }: Props): ReactNode {
|
|
116
|
+
return <Schema keysToOmit={keysToOmit} description={description} />
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
type FileProps = {}
|
|
120
|
+
|
|
121
|
+
OperationSchema.File = function ({}: FileProps): ReactNode {
|
|
122
|
+
const { pluginManager, plugin, mode, fileManager } = useApp<PluginTs>()
|
|
123
|
+
const oas = useOas()
|
|
124
|
+
const { getSchemas, getFile, getName } = useOperationManager()
|
|
125
|
+
const operation = useOperation()
|
|
126
|
+
|
|
127
|
+
const file = getFile(operation)
|
|
128
|
+
const schemas = getSchemas(operation)
|
|
129
|
+
const factoryName = getName(operation, { type: 'type' })
|
|
130
|
+
const generator = new SchemaGenerator(plugin.options, {
|
|
131
|
+
oas,
|
|
132
|
+
plugin,
|
|
133
|
+
pluginManager,
|
|
134
|
+
mode,
|
|
135
|
+
override: plugin.options.override,
|
|
136
|
+
})
|
|
137
|
+
const items = [schemas.pathParams, schemas.queryParams, schemas.headerParams, schemas.statusCodes, schemas.request, schemas.response].flat().filter(Boolean)
|
|
138
|
+
|
|
139
|
+
const mapItem = ({ name, schema, description, keysToOmit, ...options }: OperationSchemaType, i: number) => {
|
|
140
|
+
const tree = generator.parse({ schema, name })
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<Oas.Schema key={i} name={name} value={schema} tree={tree}>
|
|
144
|
+
{mode === 'split' && <Oas.Schema.Imports extName={plugin.options.extName} isTypeOnly />}
|
|
145
|
+
<File.Source>
|
|
146
|
+
<OperationSchema description={description} keysToOmit={keysToOmit} />
|
|
147
|
+
</File.Source>
|
|
148
|
+
</Oas.Schema>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<Parser language="typescript">
|
|
154
|
+
<File<FileMeta> baseName={file.baseName} path={file.path} meta={file.meta}>
|
|
155
|
+
{items.map(mapItem)}
|
|
156
|
+
|
|
157
|
+
<File.Source>{printCombinedSchema({ name: factoryName, operation, schemas, pluginManager })}</File.Source>
|
|
158
|
+
</File>
|
|
159
|
+
</Parser>
|
|
160
|
+
)
|
|
161
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Oas } from '@kubb/plugin-oas/components'
|
|
2
|
+
import { File, useApp } from '@kubb/react'
|
|
3
|
+
|
|
4
|
+
import transformers from '@kubb/core/transformers'
|
|
5
|
+
import { print, type ts } from '@kubb/parser-ts'
|
|
6
|
+
import * as factory from '@kubb/parser-ts/factory'
|
|
7
|
+
import { SchemaGenerator, schemaKeywords } from '@kubb/plugin-oas'
|
|
8
|
+
import { useSchema } from '@kubb/plugin-oas/hooks'
|
|
9
|
+
import type { ReactNode } from 'react'
|
|
10
|
+
import { parse, typeKeywordMapper } from '../parser/index.ts'
|
|
11
|
+
import { pluginTsName } from '../plugin.ts'
|
|
12
|
+
import type { PluginTs } from '../types.ts'
|
|
13
|
+
|
|
14
|
+
type Props = {
|
|
15
|
+
description?: string
|
|
16
|
+
keysToOmit?: string[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function Schema(props: Props): ReactNode {
|
|
20
|
+
const { keysToOmit, description } = props
|
|
21
|
+
const { tree, name } = useSchema()
|
|
22
|
+
const {
|
|
23
|
+
pluginManager,
|
|
24
|
+
plugin: {
|
|
25
|
+
options: { mapper, enumType, optionalType },
|
|
26
|
+
},
|
|
27
|
+
} = useApp<PluginTs>()
|
|
28
|
+
|
|
29
|
+
// all checks are also inside this.schema(React)
|
|
30
|
+
const resolvedName = pluginManager.resolveName({
|
|
31
|
+
name,
|
|
32
|
+
pluginKey: [pluginTsName],
|
|
33
|
+
type: 'function',
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const typeName = pluginManager.resolveName({
|
|
37
|
+
name,
|
|
38
|
+
pluginKey: [pluginTsName],
|
|
39
|
+
type: 'type',
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const nodes: ts.Node[] = []
|
|
43
|
+
const extraNodes: ts.Node[] = []
|
|
44
|
+
|
|
45
|
+
if (!tree.length) {
|
|
46
|
+
return ''
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const isNullish = tree.some((item) => item.keyword === schemaKeywords.nullish)
|
|
50
|
+
const isNullable = tree.some((item) => item.keyword === schemaKeywords.nullable)
|
|
51
|
+
const isOptional = tree.some((item) => item.keyword === schemaKeywords.optional)
|
|
52
|
+
|
|
53
|
+
let type =
|
|
54
|
+
(tree
|
|
55
|
+
.map((schema) => parse(undefined, schema, { name: resolvedName, typeName, description, keysToOmit, optionalType, enumType, mapper }))
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.at(0) as ts.TypeNode) || typeKeywordMapper.undefined()
|
|
58
|
+
|
|
59
|
+
if (isNullable) {
|
|
60
|
+
type = factory.createUnionDeclaration({
|
|
61
|
+
nodes: [type, factory.keywordTypeNodes.null],
|
|
62
|
+
}) as ts.TypeNode
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (isNullish && ['undefined', 'questionTokenAndUndefined'].includes(optionalType as string)) {
|
|
66
|
+
type = factory.createUnionDeclaration({
|
|
67
|
+
nodes: [type, factory.keywordTypeNodes.undefined],
|
|
68
|
+
}) as ts.TypeNode
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (isOptional && ['undefined', 'questionTokenAndUndefined'].includes(optionalType as string)) {
|
|
72
|
+
type = factory.createUnionDeclaration({
|
|
73
|
+
nodes: [type, factory.keywordTypeNodes.undefined],
|
|
74
|
+
}) as ts.TypeNode
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const node = factory.createTypeAliasDeclaration({
|
|
78
|
+
modifiers: [factory.modifiers.export],
|
|
79
|
+
name: resolvedName,
|
|
80
|
+
type: keysToOmit?.length
|
|
81
|
+
? factory.createOmitDeclaration({
|
|
82
|
+
keys: keysToOmit,
|
|
83
|
+
type,
|
|
84
|
+
nonNullable: true,
|
|
85
|
+
})
|
|
86
|
+
: type,
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const enumSchemas = SchemaGenerator.deepSearch(tree, schemaKeywords.enum)
|
|
90
|
+
if (enumSchemas) {
|
|
91
|
+
enumSchemas.forEach((enumSchema) => {
|
|
92
|
+
extraNodes.push(
|
|
93
|
+
...factory.createEnumDeclaration({
|
|
94
|
+
name: transformers.camelCase(enumSchema.args.name),
|
|
95
|
+
typeName: enumSchema.args.typeName,
|
|
96
|
+
enums: enumSchema.args.items
|
|
97
|
+
.map((item) => (item.value === undefined ? undefined : [transformers.trimQuotes(item.name?.toString()), item.value]))
|
|
98
|
+
.filter(Boolean) as unknown as [string, string][],
|
|
99
|
+
type: enumType,
|
|
100
|
+
}),
|
|
101
|
+
)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
nodes.push(
|
|
106
|
+
factory.appendJSDocToNode({
|
|
107
|
+
node,
|
|
108
|
+
comments: [description ? `@description ${transformers.jsStringEscape(description)}` : undefined].filter(Boolean),
|
|
109
|
+
}),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
const filterdNodes = nodes.filter(
|
|
113
|
+
(node: ts.Node) =>
|
|
114
|
+
!extraNodes.some(
|
|
115
|
+
(extraNode: ts.Node) => (extraNode as ts.TypeAliasDeclaration)?.name?.escapedText === (node as ts.TypeAliasDeclaration)?.name?.escapedText,
|
|
116
|
+
),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return print([...extraNodes, ...filterdNodes])
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
type FileProps = {}
|
|
123
|
+
|
|
124
|
+
Schema.File = function ({}: FileProps): ReactNode {
|
|
125
|
+
const { pluginManager } = useApp<PluginTs>()
|
|
126
|
+
const { schema } = useSchema()
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<Oas.Schema.File output={pluginManager.config.output.path}>
|
|
130
|
+
<File.Source>
|
|
131
|
+
<Schema description={schema?.description} />
|
|
132
|
+
</File.Source>
|
|
133
|
+
</Oas.Schema.File>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Null response
|
|
3
|
+
*/
|
|
4
|
+
export type CreatePets201 = any
|
|
5
|
+
/**
|
|
6
|
+
* @description unexpected error
|
|
7
|
+
*/
|
|
8
|
+
export type CreatePetsError = Error
|
|
9
|
+
export type CreatePetsMutationRequest = {
|
|
10
|
+
/**
|
|
11
|
+
* @type string
|
|
12
|
+
*/
|
|
13
|
+
name: string
|
|
14
|
+
/**
|
|
15
|
+
* @type string
|
|
16
|
+
*/
|
|
17
|
+
tag: string
|
|
18
|
+
}
|
|
19
|
+
export type CreatePetsMutationResponse = any
|
|
20
|
+
export type CreatePetsMutation = {
|
|
21
|
+
Response: CreatePetsMutationResponse
|
|
22
|
+
Request: CreatePetsMutationRequest
|
|
23
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type ShowPetByIdPathParams = {
|
|
2
|
+
/**
|
|
3
|
+
* @description The id of the pet to retrieve
|
|
4
|
+
* @type string
|
|
5
|
+
*/
|
|
6
|
+
petId: string
|
|
7
|
+
/**
|
|
8
|
+
* @description The id of the pet to retrieve
|
|
9
|
+
* @type string
|
|
10
|
+
*/
|
|
11
|
+
testId: string
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* @description Expected response to a valid request
|
|
15
|
+
*/
|
|
16
|
+
export type ShowPetById200 = Pet
|
|
17
|
+
/**
|
|
18
|
+
* @description unexpected error
|
|
19
|
+
*/
|
|
20
|
+
export type ShowPetByIdError = Error
|
|
21
|
+
/**
|
|
22
|
+
* @description Expected response to a valid request
|
|
23
|
+
*/
|
|
24
|
+
export type ShowPetByIdQueryResponse = Pet
|
|
25
|
+
export type ShowPetByIdQuery = {
|
|
26
|
+
Response: ShowPetByIdQueryResponse
|
|
27
|
+
PathParams: ShowPetByIdPathParams
|
|
28
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { pluginTs } from './plugin.ts'
|
|
2
|
+
|
|
3
|
+
export { pluginTs, pluginTsName } from './plugin.ts'
|
|
4
|
+
export type { PluginTs } from './types.ts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use `import { pluginTs } from '@kubb/plugin-ts'` instead
|
|
8
|
+
*/
|
|
9
|
+
const definePluginDefault = pluginTs
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use `import { pluginTs } from '@kubb/plugin-ts'` instead
|
|
12
|
+
*/
|
|
13
|
+
export const definePlugin = pluginTs
|
|
14
|
+
|
|
15
|
+
export default definePluginDefault
|
package/src/oas/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Infer, Response, RequestParams, Model } from '@kubb/oas'
|