@kubb/plugin-msw 5.0.0-beta.10 → 5.0.0-beta.100
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/README.md +22 -26
- package/dist/index.cjs +478 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +139 -6
- package/dist/index.js +475 -39
- package/dist/index.js.map +1 -1
- package/package.json +9 -30
- package/dist/components-BYvgvrY7.cjs +0 -569
- package/dist/components-BYvgvrY7.cjs.map +0 -1
- package/dist/components-Cm17DMTE.js +0 -510
- package/dist/components-Cm17DMTE.js.map +0 -1
- package/dist/components.cjs +0 -6
- package/dist/components.d.ts +0 -66
- package/dist/components.js +0 -2
- package/dist/generators-D9gvdP7Z.js +0 -177
- package/dist/generators-D9gvdP7Z.js.map +0 -1
- package/dist/generators-rZ99WaWQ.cjs +0 -187
- package/dist/generators-rZ99WaWQ.cjs.map +0 -1
- package/dist/generators.cjs +0 -4
- package/dist/generators.d.ts +0 -12
- package/dist/generators.js +0 -2
- package/dist/types-ItsHsMvC.d.ts +0 -94
- package/extension.yaml +0 -233
- package/src/components/Handlers.tsx +0 -19
- package/src/components/Mock.tsx +0 -71
- package/src/components/MockWithFaker.tsx +0 -70
- package/src/components/Response.tsx +0 -52
- package/src/components/index.ts +0 -4
- package/src/generators/handlersGenerator.tsx +0 -41
- package/src/generators/index.ts +0 -2
- package/src/generators/mswGenerator.tsx +0 -86
- package/src/index.ts +0 -2
- package/src/plugin.ts +0 -76
- package/src/resolvers/resolverMsw.ts +0 -28
- package/src/types.ts +0 -93
- package/src/utils.ts +0 -58
- /package/dist/{chunk--u3MIqq1.js → rolldown-runtime-C0LytTxp.js} +0 -0
package/extension.yaml
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
$schema: https://kubb.dev/schemas/extension.json
|
|
2
|
-
kind: plugin
|
|
3
|
-
id: plugin-msw
|
|
4
|
-
name: MSW
|
|
5
|
-
description: Generate Mock Service Worker (MSW) handlers from OpenAPI specifications.
|
|
6
|
-
category: mocks
|
|
7
|
-
type: official
|
|
8
|
-
npmPackage: '@kubb/plugin-msw'
|
|
9
|
-
docsPath: /plugins/plugin-msw
|
|
10
|
-
repo: https://github.com/kubb-labs/plugins
|
|
11
|
-
maintainers:
|
|
12
|
-
- name: Stijn Van Hulle
|
|
13
|
-
github: stijnvanhulle
|
|
14
|
-
compatibility:
|
|
15
|
-
kubb: '>=5.0.0'
|
|
16
|
-
node: '>=22'
|
|
17
|
-
tags:
|
|
18
|
-
- msw
|
|
19
|
-
- mock-service-worker
|
|
20
|
-
- api-mocking
|
|
21
|
-
- mocks
|
|
22
|
-
- testing
|
|
23
|
-
- codegen
|
|
24
|
-
- openapi
|
|
25
|
-
dependencies:
|
|
26
|
-
- plugin-ts
|
|
27
|
-
- plugin-faker
|
|
28
|
-
resources:
|
|
29
|
-
documentation: https://kubb.dev/plugins/plugin-msw
|
|
30
|
-
repository: https://github.com/kubb-labs/plugins
|
|
31
|
-
issues: https://github.com/kubb-labs/plugins/issues
|
|
32
|
-
changelog: https://github.com/kubb-labs/plugins/blob/main/packages/plugin-msw/CHANGELOG.md
|
|
33
|
-
codesandbox: https://codesandbox.io/p/github/kubb-labs/plugins/main/examples/msw
|
|
34
|
-
featured: false
|
|
35
|
-
icon:
|
|
36
|
-
light: https://kubb.dev/feature/msw.svg
|
|
37
|
-
intro: |
|
|
38
|
-
# @kubb/plugin-msw
|
|
39
|
-
|
|
40
|
-
Generate [MSW](https://mswjs.io/) API mock handlers from your OpenAPI schema. Mock API requests in development and tests with type-safe handlers.
|
|
41
|
-
options:
|
|
42
|
-
- name: output
|
|
43
|
-
type: Output
|
|
44
|
-
required: false
|
|
45
|
-
default: "{ path: 'handlers', barrel: { type: 'named' } }"
|
|
46
|
-
description: Specify the export location for the files and define the behavior of the output.
|
|
47
|
-
properties:
|
|
48
|
-
- name: path
|
|
49
|
-
type: string
|
|
50
|
-
required: true
|
|
51
|
-
description: Output directory or file for the generated code, relative to the global `output.path`.
|
|
52
|
-
tip: |
|
|
53
|
-
if `output.path` is a file, `group` cannot be used.
|
|
54
|
-
default: "'handlers'"
|
|
55
|
-
- name: barrel
|
|
56
|
-
type: "{ type: 'named' | 'all', nested?: boolean } | false"
|
|
57
|
-
required: false
|
|
58
|
-
default: "{ type: 'named' }"
|
|
59
|
-
description: "Configure barrel file export strategy. Use `type` to control named vs. wildcard exports; set `nested: true` to generate hierarchical barrels in subdirectories."
|
|
60
|
-
examples:
|
|
61
|
-
- name: all
|
|
62
|
-
files:
|
|
63
|
-
- lang: typescript
|
|
64
|
-
code: |
|
|
65
|
-
export * from './gen/petService.ts'
|
|
66
|
-
twoslash: false
|
|
67
|
-
- name: named
|
|
68
|
-
files:
|
|
69
|
-
- lang: typescript
|
|
70
|
-
code: |
|
|
71
|
-
export { PetService } from './gen/petService.ts'
|
|
72
|
-
twoslash: false
|
|
73
|
-
- name: 'false'
|
|
74
|
-
files:
|
|
75
|
-
- lang: typescript
|
|
76
|
-
code: ''
|
|
77
|
-
twoslash: false
|
|
78
|
-
- name: banner
|
|
79
|
-
type: 'string | ((node: RootNode) => string)'
|
|
80
|
-
required: false
|
|
81
|
-
description: Add a banner comment at the top of every generated file. Accepts a static string or a function that receives the `RootNode` and returns a string.
|
|
82
|
-
- name: footer
|
|
83
|
-
type: 'string | ((node: RootNode) => string)'
|
|
84
|
-
required: false
|
|
85
|
-
description: Add a footer comment at the end of every generated file. Accepts a static string or a function that receives the `RootNode` and returns a string.
|
|
86
|
-
- name: override
|
|
87
|
-
type: boolean
|
|
88
|
-
required: false
|
|
89
|
-
default: 'false'
|
|
90
|
-
description: Whether Kubb overrides existing external files that can be generated if they already exist.
|
|
91
|
-
- name: handlers
|
|
92
|
-
type: boolean
|
|
93
|
-
required: false
|
|
94
|
-
default: 'false'
|
|
95
|
-
description: Create a `handlers.ts` file with all handlers grouped by methods.
|
|
96
|
-
- name: baseURL
|
|
97
|
-
type: string
|
|
98
|
-
required: false
|
|
99
|
-
description: Sets a custom base URL for all generated calls. When not set, the base URL is automatically taken from the OAS spec via the adapter (e.g. the `servers[0].url` field).
|
|
100
|
-
- name: group
|
|
101
|
-
type: Group
|
|
102
|
-
required: false
|
|
103
|
-
description: |
|
|
104
|
-
Grouping combines files in a folder based on a specific `type`.
|
|
105
|
-
examples:
|
|
106
|
-
- name: kubb.config.ts
|
|
107
|
-
files:
|
|
108
|
-
- lang: typescript
|
|
109
|
-
code: |
|
|
110
|
-
group: {
|
|
111
|
-
type: 'tag',
|
|
112
|
-
name({ group }) {
|
|
113
|
-
return `${group}Controller`
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
twoslash: false
|
|
117
|
-
body: |
|
|
118
|
-
With the configuration above, the generator emits:
|
|
119
|
-
|
|
120
|
-
```text
|
|
121
|
-
.
|
|
122
|
-
├── src/
|
|
123
|
-
│ └── petController/
|
|
124
|
-
│ │ ├── addPet.ts
|
|
125
|
-
│ │ └── getPet.ts
|
|
126
|
-
│ └── storeController/
|
|
127
|
-
│ ├── createStore.ts
|
|
128
|
-
│ └── getStoreById.ts
|
|
129
|
-
├── petStore.yaml
|
|
130
|
-
├── kubb.config.ts
|
|
131
|
-
└── package.json
|
|
132
|
-
```
|
|
133
|
-
properties:
|
|
134
|
-
- name: type
|
|
135
|
-
type: "'tag'"
|
|
136
|
-
required: true
|
|
137
|
-
description: Specify the property to group files by. Required when `group` is defined.
|
|
138
|
-
note: |
|
|
139
|
-
`Required: true*` means this is required only when the `group` option is used. The `group` option itself is optional.
|
|
140
|
-
body: |
|
|
141
|
-
- `'tag'`: Uses the first tag from `operation.getTags().at(0)?.name`
|
|
142
|
-
- name: name
|
|
143
|
-
type: '(context: GroupContext) => string'
|
|
144
|
-
required: false
|
|
145
|
-
default: (ctx) => `${ctx.group}Controller`
|
|
146
|
-
description: Return the name of a group based on the group name. This is used for file and identifier generation.
|
|
147
|
-
- name: parser
|
|
148
|
-
type: "'data' | 'faker'"
|
|
149
|
-
required: false
|
|
150
|
-
default: "'data'"
|
|
151
|
-
description: Choose which parser to use when generating response data.
|
|
152
|
-
body: |
|
|
153
|
-
- `'faker'` will use `@kubb/plugin-faker` to generate the data for the response.
|
|
154
|
-
- `'data'` will use your custom data to generate the data for the response.
|
|
155
|
-
- name: include
|
|
156
|
-
type: Array<Include>
|
|
157
|
-
required: false
|
|
158
|
-
description: Array containing include parameters to include tags, operations, methods, paths, or content types.
|
|
159
|
-
codeBlock:
|
|
160
|
-
lang: typescript
|
|
161
|
-
title: Include
|
|
162
|
-
code: |
|
|
163
|
-
export type Include = {
|
|
164
|
-
type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
|
|
165
|
-
pattern: string | RegExp
|
|
166
|
-
}
|
|
167
|
-
- name: exclude
|
|
168
|
-
type: Array<Exclude>
|
|
169
|
-
required: false
|
|
170
|
-
description: Array containing exclude parameters to exclude or skip tags, operations, methods, paths, or content types.
|
|
171
|
-
codeBlock:
|
|
172
|
-
lang: typescript
|
|
173
|
-
title: Exclude
|
|
174
|
-
code: |
|
|
175
|
-
export type Exclude = {
|
|
176
|
-
type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
|
|
177
|
-
pattern: string | RegExp
|
|
178
|
-
}
|
|
179
|
-
- name: override
|
|
180
|
-
type: Array<Override>
|
|
181
|
-
required: false
|
|
182
|
-
description: Array containing override parameters to override `options` based on tags, operations, methods, paths, or content types.
|
|
183
|
-
codeBlock:
|
|
184
|
-
lang: typescript
|
|
185
|
-
title: Override
|
|
186
|
-
code: |
|
|
187
|
-
export type Override = {
|
|
188
|
-
type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
|
|
189
|
-
pattern: string | RegExp
|
|
190
|
-
options: PluginOptions
|
|
191
|
-
}
|
|
192
|
-
- name: generators
|
|
193
|
-
type: Array<Generator<PluginMsw>>
|
|
194
|
-
required: false
|
|
195
|
-
experimental: true
|
|
196
|
-
description: |
|
|
197
|
-
Define additional generators next to the built-in generators.
|
|
198
|
-
|
|
199
|
-
See [Generators](https://kubb.dev/docs/5.x/guides/creating-plugins) for more information on how to use generators.
|
|
200
|
-
examples:
|
|
201
|
-
- name: kubb.config.ts
|
|
202
|
-
files:
|
|
203
|
-
- lang: typescript
|
|
204
|
-
code: |
|
|
205
|
-
import { defineConfig } from 'kubb'
|
|
206
|
-
import { pluginMsw } from '@kubb/plugin-msw'
|
|
207
|
-
import { pluginTs } from '@kubb/plugin-ts'
|
|
208
|
-
|
|
209
|
-
export default defineConfig({
|
|
210
|
-
input: {
|
|
211
|
-
path: './petStore.yaml',
|
|
212
|
-
},
|
|
213
|
-
output: {
|
|
214
|
-
path: './src/gen',
|
|
215
|
-
},
|
|
216
|
-
plugins: [
|
|
217
|
-
pluginTs(),
|
|
218
|
-
pluginMsw({
|
|
219
|
-
output: {
|
|
220
|
-
path: './mocks',
|
|
221
|
-
barrel: { type: 'named' },
|
|
222
|
-
banner: '/* eslint-disable no-alert, no-console */',
|
|
223
|
-
footer: '',
|
|
224
|
-
},
|
|
225
|
-
group: {
|
|
226
|
-
type: 'tag',
|
|
227
|
-
name: ({ group }) => `${group}Service`,
|
|
228
|
-
},
|
|
229
|
-
handlers: true,
|
|
230
|
-
}),
|
|
231
|
-
],
|
|
232
|
-
})
|
|
233
|
-
twoslash: false
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { File } from '@kubb/renderer-jsx'
|
|
2
|
-
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
3
|
-
|
|
4
|
-
type HandlersProps = {
|
|
5
|
-
/**
|
|
6
|
-
* Name of the function
|
|
7
|
-
*/
|
|
8
|
-
name: string
|
|
9
|
-
// custom
|
|
10
|
-
handlers: string[]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function Handlers({ name, handlers }: HandlersProps): KubbReactNode {
|
|
14
|
-
return (
|
|
15
|
-
<File.Source name={name} isIndexable isExportable>
|
|
16
|
-
{`export const ${name} = ${JSON.stringify(handlers).replaceAll(`"`, '')} as const`}
|
|
17
|
-
</File.Source>
|
|
18
|
-
)
|
|
19
|
-
}
|
package/src/components/Mock.tsx
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { getPrimarySuccessResponse } from '@internals/shared'
|
|
2
|
-
import { URLPath } from '@internals/utils'
|
|
3
|
-
import { ast } from '@kubb/core'
|
|
4
|
-
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
|
-
import { File, Function } from '@kubb/renderer-jsx'
|
|
6
|
-
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
7
|
-
import { getContentType, getMswMethod, getMswUrl, hasResponseSchema } from '../utils.ts'
|
|
8
|
-
|
|
9
|
-
type Props = {
|
|
10
|
-
name: string
|
|
11
|
-
typeName: string
|
|
12
|
-
requestTypeName?: string
|
|
13
|
-
baseURL: string | undefined
|
|
14
|
-
node: ast.OperationNode
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
18
|
-
|
|
19
|
-
export function Mock({ baseURL = '', name, typeName, requestTypeName, node }: Props): KubbReactNode {
|
|
20
|
-
const method = getMswMethod(node)
|
|
21
|
-
const successResponse = getPrimarySuccessResponse(node)
|
|
22
|
-
const statusCode = successResponse ? Number(successResponse.statusCode) : 200
|
|
23
|
-
const contentType = getContentType(successResponse)
|
|
24
|
-
const url = new URLPath(getMswUrl(node)).toURLPath()
|
|
25
|
-
|
|
26
|
-
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
27
|
-
const responseHasSchema = hasResponseSchema(successResponse)
|
|
28
|
-
const dataType = responseHasSchema ? typeName : 'string | number | boolean | null | object'
|
|
29
|
-
|
|
30
|
-
const callbackType = requestTypeName
|
|
31
|
-
? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>`
|
|
32
|
-
: `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`
|
|
33
|
-
|
|
34
|
-
const params = declarationPrinter.print(
|
|
35
|
-
ast.createFunctionParameters({
|
|
36
|
-
params: [
|
|
37
|
-
ast.createFunctionParameter({
|
|
38
|
-
name: 'data',
|
|
39
|
-
type: ast.createParamsType({
|
|
40
|
-
variant: 'reference',
|
|
41
|
-
name: `${dataType} | ${callbackType}`,
|
|
42
|
-
}),
|
|
43
|
-
optional: true,
|
|
44
|
-
}),
|
|
45
|
-
],
|
|
46
|
-
}),
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<File.Source name={name} isIndexable isExportable>
|
|
53
|
-
<Function name={name} export params={params ?? ''}>
|
|
54
|
-
{`return ${httpCall}(\`${baseURL}${url.replace(/([^/]):/g, '$1\\\\:')}\`, function handler(info) {
|
|
55
|
-
if(typeof data === 'function') return data(info)
|
|
56
|
-
|
|
57
|
-
return new Response(JSON.stringify(data), {
|
|
58
|
-
status: ${statusCode},
|
|
59
|
-
${
|
|
60
|
-
headers.length
|
|
61
|
-
? ` headers: {
|
|
62
|
-
${headers.join(', \n')}
|
|
63
|
-
},`
|
|
64
|
-
: ''
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
})`}
|
|
68
|
-
</Function>
|
|
69
|
-
</File.Source>
|
|
70
|
-
)
|
|
71
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { getPrimarySuccessResponse } from '@internals/shared'
|
|
2
|
-
import { URLPath } from '@internals/utils'
|
|
3
|
-
import { ast } from '@kubb/core'
|
|
4
|
-
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
|
-
import { File, Function } from '@kubb/renderer-jsx'
|
|
6
|
-
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
7
|
-
import { getContentType, getMswMethod, getMswUrl } from '../utils.ts'
|
|
8
|
-
|
|
9
|
-
type Props = {
|
|
10
|
-
name: string
|
|
11
|
-
typeName: string
|
|
12
|
-
requestTypeName?: string
|
|
13
|
-
fakerName: string
|
|
14
|
-
baseURL: string | undefined
|
|
15
|
-
node: ast.OperationNode
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
19
|
-
|
|
20
|
-
export function MockWithFaker({ baseURL = '', name, fakerName, typeName, requestTypeName, node }: Props): KubbReactNode {
|
|
21
|
-
const method = getMswMethod(node)
|
|
22
|
-
const successResponse = getPrimarySuccessResponse(node)
|
|
23
|
-
const statusCode = successResponse ? Number(successResponse.statusCode) : 200
|
|
24
|
-
const contentType = getContentType(successResponse)
|
|
25
|
-
const url = new URLPath(getMswUrl(node)).toURLPath()
|
|
26
|
-
|
|
27
|
-
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
28
|
-
|
|
29
|
-
const callbackType = requestTypeName
|
|
30
|
-
? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>`
|
|
31
|
-
: `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`
|
|
32
|
-
|
|
33
|
-
const params = declarationPrinter.print(
|
|
34
|
-
ast.createFunctionParameters({
|
|
35
|
-
params: [
|
|
36
|
-
ast.createFunctionParameter({
|
|
37
|
-
name: 'data',
|
|
38
|
-
type: ast.createParamsType({
|
|
39
|
-
variant: 'reference',
|
|
40
|
-
name: `${typeName} | ${callbackType}`,
|
|
41
|
-
}),
|
|
42
|
-
optional: true,
|
|
43
|
-
}),
|
|
44
|
-
],
|
|
45
|
-
}),
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<File.Source name={name} isIndexable isExportable>
|
|
52
|
-
<Function name={name} export params={params ?? ''}>
|
|
53
|
-
{`return ${httpCall}('${baseURL}${url.replace(/([^/]):/g, '$1\\\\:')}', function handler(info) {
|
|
54
|
-
if(typeof data === 'function') return data(info)
|
|
55
|
-
|
|
56
|
-
return new Response(JSON.stringify(data || ${fakerName}(data)), {
|
|
57
|
-
status: ${statusCode},
|
|
58
|
-
${
|
|
59
|
-
headers.length
|
|
60
|
-
? ` headers: {
|
|
61
|
-
${headers.join(', \n')}
|
|
62
|
-
},`
|
|
63
|
-
: ''
|
|
64
|
-
}
|
|
65
|
-
})
|
|
66
|
-
})`}
|
|
67
|
-
</Function>
|
|
68
|
-
</File.Source>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { ast } from '@kubb/core'
|
|
2
|
-
import { functionPrinter } from '@kubb/plugin-ts'
|
|
3
|
-
import { File, Function } from '@kubb/renderer-jsx'
|
|
4
|
-
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
5
|
-
import { getContentType, hasResponseSchema } from '../utils.ts'
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
typeName: string
|
|
9
|
-
name: string
|
|
10
|
-
response: ast.ResponseNode
|
|
11
|
-
key?: string | number | null
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
15
|
-
|
|
16
|
-
export function Response({ name, typeName, response }: Props): KubbReactNode {
|
|
17
|
-
const statusCode = Number(response.statusCode)
|
|
18
|
-
const contentType = getContentType(response)
|
|
19
|
-
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
20
|
-
|
|
21
|
-
const params = declarationPrinter.print(
|
|
22
|
-
ast.createFunctionParameters({
|
|
23
|
-
params: [
|
|
24
|
-
ast.createFunctionParameter({
|
|
25
|
-
name: 'data',
|
|
26
|
-
type: ast.createParamsType({ variant: 'reference', name: typeName }),
|
|
27
|
-
optional: !hasResponseSchema(response),
|
|
28
|
-
}),
|
|
29
|
-
],
|
|
30
|
-
}),
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
const responseName = `${name}Response${statusCode}`
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<File.Source name={responseName} isIndexable isExportable>
|
|
37
|
-
<Function name={responseName} export params={params ?? ''}>
|
|
38
|
-
{`
|
|
39
|
-
return new Response(JSON.stringify(data), {
|
|
40
|
-
status: ${statusCode},
|
|
41
|
-
${
|
|
42
|
-
headers.length
|
|
43
|
-
? ` headers: {
|
|
44
|
-
${headers.join(', \n')}
|
|
45
|
-
},`
|
|
46
|
-
: ''
|
|
47
|
-
}
|
|
48
|
-
})`}
|
|
49
|
-
</Function>
|
|
50
|
-
</File.Source>
|
|
51
|
-
)
|
|
52
|
-
}
|
package/src/components/index.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { defineGenerator } from '@kubb/core'
|
|
2
|
-
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
3
|
-
import { Handlers } from '../components/Handlers.tsx'
|
|
4
|
-
import type { PluginMsw } from '../types'
|
|
5
|
-
|
|
6
|
-
export const handlersGenerator = defineGenerator<PluginMsw>({
|
|
7
|
-
name: 'plugin-msw',
|
|
8
|
-
renderer: jsxRenderer,
|
|
9
|
-
operations(nodes, ctx) {
|
|
10
|
-
const { resolver, config, root, adapter } = ctx
|
|
11
|
-
const { output, group } = ctx.options
|
|
12
|
-
|
|
13
|
-
const handlersName = resolver.resolveHandlersName()
|
|
14
|
-
const file = resolver.resolveFile({ name: resolver.resolvePathName(handlersName, 'file'), extname: '.ts' }, { root, output, group })
|
|
15
|
-
|
|
16
|
-
const imports = nodes.map((node) => {
|
|
17
|
-
const operationName = resolver.resolveHandlerName(node)
|
|
18
|
-
const operationFile = resolver.resolveFile(
|
|
19
|
-
{ name: resolver.resolveName(node.operationId), extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
20
|
-
{ root, output, group },
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
return <File.Import key={operationFile.path} name={[operationName]} root={file.path} path={operationFile.path} />
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
const handlers = nodes.map((node) => `${resolver.resolveHandlerName(node)}()`)
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<File
|
|
30
|
-
baseName={file.baseName}
|
|
31
|
-
path={file.path}
|
|
32
|
-
meta={file.meta}
|
|
33
|
-
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
34
|
-
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
35
|
-
>
|
|
36
|
-
{imports}
|
|
37
|
-
<Handlers name={handlersName} handlers={handlers} />
|
|
38
|
-
</File>
|
|
39
|
-
)
|
|
40
|
-
},
|
|
41
|
-
})
|
package/src/generators/index.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { getOperationSuccessResponses, resolveResponseTypes } from '@internals/shared'
|
|
2
|
-
import { defineGenerator } from '@kubb/core'
|
|
3
|
-
import { pluginFakerName } from '@kubb/plugin-faker'
|
|
4
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
|
-
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
6
|
-
import { Mock, MockWithFaker, Response } from '../components'
|
|
7
|
-
import type { PluginMsw } from '../types'
|
|
8
|
-
import { resolveFakerMeta } from '../utils.ts'
|
|
9
|
-
|
|
10
|
-
export const mswGenerator = defineGenerator<PluginMsw>({
|
|
11
|
-
name: 'msw',
|
|
12
|
-
renderer: jsxRenderer,
|
|
13
|
-
operation(node, ctx) {
|
|
14
|
-
const { driver, resolver, config, root, adapter } = ctx
|
|
15
|
-
const { output, parser, baseURL, group } = ctx.options
|
|
16
|
-
|
|
17
|
-
const fileName = resolver.resolveName(node.operationId)
|
|
18
|
-
const mock = {
|
|
19
|
-
name: resolver.resolveHandlerName(node),
|
|
20
|
-
file: resolver.resolveFile({ name: fileName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const fakerPlugin = parser === 'faker' ? driver.getPlugin(pluginFakerName) : undefined
|
|
24
|
-
const faker =
|
|
25
|
-
parser === 'faker' && fakerPlugin
|
|
26
|
-
? resolveFakerMeta(node, {
|
|
27
|
-
root,
|
|
28
|
-
fakerResolver: driver.getResolver(pluginFakerName),
|
|
29
|
-
fakerOutput: fakerPlugin.options?.output ?? output,
|
|
30
|
-
fakerGroup: fakerPlugin.options?.group,
|
|
31
|
-
})
|
|
32
|
-
: undefined
|
|
33
|
-
|
|
34
|
-
const pluginTs = driver.getPlugin(pluginTsName)
|
|
35
|
-
if (!pluginTs) return null
|
|
36
|
-
const tsResolver = driver.getResolver(pluginTsName)
|
|
37
|
-
|
|
38
|
-
const type = {
|
|
39
|
-
file: tsResolver.resolveFile(
|
|
40
|
-
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
41
|
-
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
42
|
-
),
|
|
43
|
-
responseName: tsResolver.resolveResponseName(node),
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const types = resolveResponseTypes(node, tsResolver)
|
|
47
|
-
const successResponses = getOperationSuccessResponses(node)
|
|
48
|
-
const hasSuccessSchema = successResponses.some((response) => !!response.schema)
|
|
49
|
-
|
|
50
|
-
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<File
|
|
54
|
-
baseName={mock.file.baseName}
|
|
55
|
-
path={mock.file.path}
|
|
56
|
-
meta={mock.file.meta}
|
|
57
|
-
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
58
|
-
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
59
|
-
>
|
|
60
|
-
<File.Import name={['http']} path="msw" />
|
|
61
|
-
<File.Import name={['HttpResponseResolver']} isTypeOnly path="msw" />
|
|
62
|
-
<File.Import
|
|
63
|
-
name={Array.from(new Set([type.responseName, ...types.map((t) => t[1]), ...(requestName ? [requestName] : [])]))}
|
|
64
|
-
path={type.file.path}
|
|
65
|
-
root={mock.file.path}
|
|
66
|
-
isTypeOnly
|
|
67
|
-
/>
|
|
68
|
-
{parser === 'faker' && faker && <File.Import name={[faker.name]} root={mock.file.path} path={faker.file.path} />}
|
|
69
|
-
|
|
70
|
-
{types
|
|
71
|
-
.filter(([code]) => code !== 'default')
|
|
72
|
-
.map(([code, typeName]) => {
|
|
73
|
-
const response = node.responses.find((item) => item.statusCode === String(code))
|
|
74
|
-
if (!response) return null
|
|
75
|
-
return <Response key={typeName} typeName={typeName} response={response} name={mock.name} />
|
|
76
|
-
})}
|
|
77
|
-
|
|
78
|
-
{parser === 'faker' && faker && hasSuccessSchema ? (
|
|
79
|
-
<MockWithFaker name={mock.name} typeName={type.responseName} requestTypeName={requestName} fakerName={faker.name} node={node} baseURL={baseURL} />
|
|
80
|
-
) : (
|
|
81
|
-
<Mock name={mock.name} typeName={type.responseName} requestTypeName={requestName} node={node} baseURL={baseURL} />
|
|
82
|
-
)}
|
|
83
|
-
</File>
|
|
84
|
-
)
|
|
85
|
-
},
|
|
86
|
-
})
|
package/src/index.ts
DELETED
package/src/plugin.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { camelCase } from '@internals/utils'
|
|
2
|
-
import { definePlugin, type Group } from '@kubb/core'
|
|
3
|
-
import { pluginFakerName } from '@kubb/plugin-faker'
|
|
4
|
-
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
|
-
import { handlersGenerator, mswGenerator } from './generators'
|
|
6
|
-
import { resolverMsw } from './resolvers/resolverMsw.ts'
|
|
7
|
-
import type { PluginMsw } from './types.ts'
|
|
8
|
-
|
|
9
|
-
export const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']
|
|
10
|
-
|
|
11
|
-
export const pluginMsw = definePlugin<PluginMsw>((options) => {
|
|
12
|
-
const {
|
|
13
|
-
output = { path: 'handlers', barrelType: 'named' },
|
|
14
|
-
group,
|
|
15
|
-
exclude = [],
|
|
16
|
-
include,
|
|
17
|
-
override = [],
|
|
18
|
-
handlers = false,
|
|
19
|
-
parser = 'data',
|
|
20
|
-
baseURL,
|
|
21
|
-
resolver: userResolver,
|
|
22
|
-
transformer: userTransformer,
|
|
23
|
-
generators: userGenerators = [],
|
|
24
|
-
} = options
|
|
25
|
-
|
|
26
|
-
const groupConfig = group
|
|
27
|
-
? ({
|
|
28
|
-
...group,
|
|
29
|
-
name: group.name
|
|
30
|
-
? group.name
|
|
31
|
-
: (ctx: { group: string }) => {
|
|
32
|
-
if (group.type === 'path') {
|
|
33
|
-
return `${ctx.group.split('/')[1]}`
|
|
34
|
-
}
|
|
35
|
-
return `${camelCase(ctx.group)}Controller`
|
|
36
|
-
},
|
|
37
|
-
} satisfies Group)
|
|
38
|
-
: undefined
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
name: pluginMswName,
|
|
42
|
-
options,
|
|
43
|
-
dependencies: [pluginTsName, parser === 'faker' ? pluginFakerName : undefined].filter((dependency): dependency is string => Boolean(dependency)),
|
|
44
|
-
hooks: {
|
|
45
|
-
'kubb:plugin:setup'(ctx) {
|
|
46
|
-
const resolver = userResolver ? { ...resolverMsw, ...userResolver } : resolverMsw
|
|
47
|
-
|
|
48
|
-
ctx.setOptions({
|
|
49
|
-
output,
|
|
50
|
-
parser,
|
|
51
|
-
baseURL,
|
|
52
|
-
group: groupConfig,
|
|
53
|
-
exclude,
|
|
54
|
-
include,
|
|
55
|
-
override,
|
|
56
|
-
handlers,
|
|
57
|
-
resolver,
|
|
58
|
-
})
|
|
59
|
-
ctx.setResolver(resolver)
|
|
60
|
-
if (userTransformer) {
|
|
61
|
-
ctx.setTransformer(userTransformer)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
ctx.addGenerator(mswGenerator)
|
|
65
|
-
if (handlers) {
|
|
66
|
-
ctx.addGenerator(handlersGenerator)
|
|
67
|
-
}
|
|
68
|
-
for (const gen of userGenerators) {
|
|
69
|
-
ctx.addGenerator(gen)
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
export default pluginMsw
|