@kubb/plugin-msw 5.0.0-alpha.9 → 5.0.0-beta.4
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 +17 -10
- package/README.md +1 -3
- package/dist/components-CLQ77DVn.cjs +584 -0
- package/dist/components-CLQ77DVn.cjs.map +1 -0
- package/dist/components-vO0FIb2i.js +519 -0
- package/dist/components-vO0FIb2i.js.map +1 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +17 -21
- package/dist/components.js +1 -1
- package/dist/generators-BPJCs1x1.js +176 -0
- package/dist/generators-BPJCs1x1.js.map +1 -0
- package/dist/generators-CrmMwWE4.cjs +186 -0
- package/dist/generators-CrmMwWE4.cjs.map +1 -0
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +4 -500
- package/dist/generators.js +1 -1
- package/dist/index.cjs +54 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +51 -65
- package/dist/index.js.map +1 -1
- package/dist/types-Dxu0KMQ4.d.ts +89 -0
- package/extension.yaml +260 -0
- package/package.json +59 -57
- package/src/components/Handlers.tsx +3 -3
- package/src/components/Mock.tsx +36 -28
- package/src/components/MockWithFaker.tsx +36 -24
- package/src/components/Response.tsx +23 -17
- package/src/generators/handlersGenerator.tsx +18 -18
- package/src/generators/mswGenerator.tsx +49 -60
- package/src/index.ts +1 -1
- package/src/plugin.ts +48 -85
- package/src/resolvers/resolverMsw.ts +19 -0
- package/src/types.ts +45 -22
- package/src/utils.ts +109 -0
- package/dist/components-8XBwMbFa.cjs +0 -343
- package/dist/components-8XBwMbFa.cjs.map +0 -1
- package/dist/components-DgtTZkWX.js +0 -277
- package/dist/components-DgtTZkWX.js.map +0 -1
- package/dist/generators-CY1SNd5X.cjs +0 -171
- package/dist/generators-CY1SNd5X.cjs.map +0 -1
- package/dist/generators-CvyZTxOm.js +0 -161
- package/dist/generators-CvyZTxOm.js.map +0 -1
- package/dist/types-MdHRNpgi.d.ts +0 -68
package/package.json
CHANGED
|
@@ -1,49 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-msw",
|
|
3
|
-
"version": "5.0.0-
|
|
3
|
+
"version": "5.0.0-beta.4",
|
|
4
4
|
"description": "Mock Service Worker (MSW) handlers generator plugin for Kubb, creating API mocks from OpenAPI specifications for frontend development and testing.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"msw",
|
|
7
|
-
"mock-service-worker",
|
|
8
6
|
"api-mocking",
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"testing",
|
|
7
|
+
"code-generator",
|
|
8
|
+
"codegen",
|
|
12
9
|
"development",
|
|
13
10
|
"interceptor",
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
11
|
+
"kubb",
|
|
12
|
+
"mock-service-worker",
|
|
13
|
+
"mocking",
|
|
14
|
+
"mocks",
|
|
15
|
+
"msw",
|
|
17
16
|
"oas",
|
|
18
|
-
"
|
|
19
|
-
"codegen",
|
|
17
|
+
"openapi",
|
|
20
18
|
"plugins",
|
|
21
|
-
"
|
|
19
|
+
"swagger",
|
|
20
|
+
"testing",
|
|
21
|
+
"typescript"
|
|
22
22
|
],
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "stijnvanhulle",
|
|
23
25
|
"repository": {
|
|
24
26
|
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/kubb-labs/
|
|
27
|
+
"url": "git+https://github.com/kubb-labs/plugins.git",
|
|
26
28
|
"directory": "packages/plugin-msw"
|
|
27
29
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
"files": [
|
|
31
|
+
"src",
|
|
32
|
+
"dist",
|
|
33
|
+
"extension.yaml",
|
|
34
|
+
"!/**/**.test.**",
|
|
35
|
+
"!/**/__tests__/**",
|
|
36
|
+
"!/**/__snapshots__/**"
|
|
37
|
+
],
|
|
31
38
|
"type": "module",
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"require": "./dist/index.cjs"
|
|
36
|
-
},
|
|
37
|
-
"./components": {
|
|
38
|
-
"import": "./dist/components.js",
|
|
39
|
-
"require": "./dist/components.cjs"
|
|
40
|
-
},
|
|
41
|
-
"./generators": {
|
|
42
|
-
"import": "./dist/generators.js",
|
|
43
|
-
"require": "./dist/generators.cjs"
|
|
44
|
-
},
|
|
45
|
-
"./package.json": "./package.json"
|
|
46
|
-
},
|
|
39
|
+
"sideEffects": false,
|
|
40
|
+
"main": "./dist/index.cjs",
|
|
41
|
+
"module": "./dist/index.js",
|
|
47
42
|
"types": "./dist/index.d.ts",
|
|
48
43
|
"typesVersions": {
|
|
49
44
|
"*": {
|
|
@@ -61,13 +56,37 @@
|
|
|
61
56
|
]
|
|
62
57
|
}
|
|
63
58
|
},
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
59
|
+
"exports": {
|
|
60
|
+
".": {
|
|
61
|
+
"import": "./dist/index.js",
|
|
62
|
+
"require": "./dist/index.cjs"
|
|
63
|
+
},
|
|
64
|
+
"./components": {
|
|
65
|
+
"import": "./dist/components.js",
|
|
66
|
+
"require": "./dist/components.cjs"
|
|
67
|
+
},
|
|
68
|
+
"./generators": {
|
|
69
|
+
"import": "./dist/generators.js",
|
|
70
|
+
"require": "./dist/generators.cjs"
|
|
71
|
+
},
|
|
72
|
+
"./package.json": "./package.json"
|
|
73
|
+
},
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public",
|
|
76
|
+
"registry": "https://registry.npmjs.org/"
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"@kubb/core": "5.0.0-beta.4",
|
|
80
|
+
"@kubb/renderer-jsx": "5.0.0-beta.4",
|
|
81
|
+
"@kubb/plugin-faker": "5.0.0-beta.4",
|
|
82
|
+
"@kubb/plugin-ts": "5.0.0-beta.4"
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@internals/utils": "0.0.0"
|
|
86
|
+
},
|
|
87
|
+
"peerDependencies": {
|
|
88
|
+
"@kubb/renderer-jsx": "5.0.0-beta.4"
|
|
89
|
+
},
|
|
71
90
|
"size-limit": [
|
|
72
91
|
{
|
|
73
92
|
"path": "./dist/*.js",
|
|
@@ -75,31 +94,14 @@
|
|
|
75
94
|
"gzip": true
|
|
76
95
|
}
|
|
77
96
|
],
|
|
78
|
-
"dependencies": {
|
|
79
|
-
"@kubb/react-fabric": "0.14.0",
|
|
80
|
-
"@kubb/core": "5.0.0-alpha.9",
|
|
81
|
-
"@kubb/oas": "5.0.0-alpha.9",
|
|
82
|
-
"@kubb/plugin-oas": "5.0.0-alpha.9",
|
|
83
|
-
"@kubb/plugin-faker": "5.0.0-alpha.9",
|
|
84
|
-
"@kubb/plugin-ts": "5.0.0-alpha.9"
|
|
85
|
-
},
|
|
86
|
-
"devDependencies": {
|
|
87
|
-
"@internals/utils": "0.0.0"
|
|
88
|
-
},
|
|
89
97
|
"engines": {
|
|
90
98
|
"node": ">=22"
|
|
91
99
|
},
|
|
92
|
-
"publishConfig": {
|
|
93
|
-
"access": "public",
|
|
94
|
-
"registry": "https://registry.npmjs.org/"
|
|
95
|
-
},
|
|
96
|
-
"main": "./dist/index.cjs",
|
|
97
|
-
"module": "./dist/index.js",
|
|
98
100
|
"scripts": {
|
|
99
101
|
"build": "tsdown && size-limit",
|
|
100
102
|
"clean": "npx rimraf ./dist",
|
|
101
|
-
"lint": "
|
|
102
|
-
"lint:fix": "
|
|
103
|
+
"lint": "oxlint .",
|
|
104
|
+
"lint:fix": "oxlint --fix .",
|
|
103
105
|
"release": "pnpm publish --no-git-check",
|
|
104
106
|
"release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
|
|
105
107
|
"start": "tsdown --watch",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { File } from '@kubb/
|
|
2
|
-
import type {
|
|
1
|
+
import { File } from '@kubb/renderer-jsx'
|
|
2
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
3
3
|
|
|
4
4
|
type HandlersProps = {
|
|
5
5
|
/**
|
|
@@ -10,7 +10,7 @@ type HandlersProps = {
|
|
|
10
10
|
handlers: string[]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function Handlers({ name, handlers }: HandlersProps):
|
|
13
|
+
export function Handlers({ name, handlers }: HandlersProps): KubbReactNode {
|
|
14
14
|
return (
|
|
15
15
|
<File.Source name={name} isIndexable isExportable>
|
|
16
16
|
{`export const ${name} = ${JSON.stringify(handlers).replaceAll(`"`, '')} as const`}
|
package/src/components/Mock.tsx
CHANGED
|
@@ -1,48 +1,56 @@
|
|
|
1
1
|
import { URLPath } from '@internals/utils'
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
2
|
+
import { ast } from '@kubb/core'
|
|
3
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
4
|
+
import { File, Function } from '@kubb/renderer-jsx'
|
|
5
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
6
|
+
import { getContentType, getMswMethod, getMswUrl, getPrimarySuccessResponse, hasResponseSchema } from '../utils.ts'
|
|
5
7
|
|
|
6
8
|
type Props = {
|
|
7
|
-
/**
|
|
8
|
-
* Name of the function
|
|
9
|
-
*/
|
|
10
9
|
name: string
|
|
11
10
|
typeName: string
|
|
12
|
-
|
|
11
|
+
requestTypeName?: string
|
|
13
12
|
baseURL: string | undefined
|
|
14
|
-
|
|
13
|
+
node: ast.OperationNode
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
const method = operation.method
|
|
19
|
-
const successStatusCodes = operation.getResponseStatusCodes().filter((code) => code.startsWith('2'))
|
|
20
|
-
const statusCode = successStatusCodes.length > 0 ? Number(successStatusCodes[0]) : 200
|
|
16
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
18
|
+
export function Mock({ baseURL = '', name, typeName, requestTypeName, node }: Props): KubbReactNode {
|
|
19
|
+
const method = getMswMethod(node)
|
|
20
|
+
const successResponse = getPrimarySuccessResponse(node)
|
|
21
|
+
const statusCode = successResponse ? Number(successResponse.statusCode) : 200
|
|
22
|
+
const contentType = getContentType(successResponse)
|
|
23
|
+
const url = new URLPath(getMswUrl(node)).toURLPath()
|
|
25
24
|
|
|
26
25
|
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
26
|
+
const responseHasSchema = hasResponseSchema(successResponse)
|
|
27
|
+
const dataType = responseHasSchema ? typeName : 'string | number | boolean | null | object'
|
|
27
28
|
|
|
28
|
-
const
|
|
29
|
+
const callbackType = requestTypeName
|
|
30
|
+
? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>`
|
|
31
|
+
: `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
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: `${dataType} | ${callbackType}`,
|
|
41
|
+
}),
|
|
42
|
+
optional: true,
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
32
47
|
|
|
33
|
-
const
|
|
34
|
-
data: {
|
|
35
|
-
type: `${dataType} | ((
|
|
36
|
-
info: Parameters<Parameters<typeof http.${method}>[1]>[0],
|
|
37
|
-
) => Response | Promise<Response>)`,
|
|
38
|
-
optional: true,
|
|
39
|
-
},
|
|
40
|
-
})
|
|
48
|
+
const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`
|
|
41
49
|
|
|
42
50
|
return (
|
|
43
51
|
<File.Source name={name} isIndexable isExportable>
|
|
44
|
-
<Function name={name} export params={params
|
|
45
|
-
{`return
|
|
52
|
+
<Function name={name} export params={params ?? ''}>
|
|
53
|
+
{`return ${httpCall}(\`${baseURL}${url.replace(/([^/]):/g, '$1\\\\:')}\`, function handler(info) {
|
|
46
54
|
if(typeof data === 'function') return data(info)
|
|
47
55
|
|
|
48
56
|
return new Response(JSON.stringify(data), {
|
|
@@ -1,43 +1,55 @@
|
|
|
1
1
|
import { URLPath } from '@internals/utils'
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
2
|
+
import { ast } from '@kubb/core'
|
|
3
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
4
|
+
import { File, Function } from '@kubb/renderer-jsx'
|
|
5
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
6
|
+
import { getContentType, getMswMethod, getMswUrl, getPrimarySuccessResponse } from '../utils.ts'
|
|
5
7
|
|
|
6
8
|
type Props = {
|
|
7
|
-
/**
|
|
8
|
-
* Name of the function
|
|
9
|
-
*/
|
|
10
9
|
name: string
|
|
11
10
|
typeName: string
|
|
11
|
+
requestTypeName?: string
|
|
12
12
|
fakerName: string
|
|
13
13
|
baseURL: string | undefined
|
|
14
|
-
|
|
14
|
+
node: ast.OperationNode
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
const method = operation.method
|
|
19
|
-
const successStatusCodes = operation.getResponseStatusCodes().filter((code) => code.startsWith('2'))
|
|
20
|
-
const statusCode = successStatusCodes.length > 0 ? Number(successStatusCodes[0]) : 200
|
|
17
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
19
|
+
export function MockWithFaker({ baseURL = '', name, fakerName, 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
25
|
|
|
26
26
|
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
const callbackType = requestTypeName
|
|
29
|
+
? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>`
|
|
30
|
+
: `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`
|
|
31
|
+
|
|
32
|
+
const params = declarationPrinter.print(
|
|
33
|
+
ast.createFunctionParameters({
|
|
34
|
+
params: [
|
|
35
|
+
ast.createFunctionParameter({
|
|
36
|
+
name: 'data',
|
|
37
|
+
type: ast.createParamsType({
|
|
38
|
+
variant: 'reference',
|
|
39
|
+
name: `${typeName} | ${callbackType}`,
|
|
40
|
+
}),
|
|
41
|
+
optional: true,
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
44
|
+
}),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`
|
|
36
48
|
|
|
37
49
|
return (
|
|
38
50
|
<File.Source name={name} isIndexable isExportable>
|
|
39
|
-
<Function name={name} export params={params
|
|
40
|
-
{`return
|
|
51
|
+
<Function name={name} export params={params ?? ''}>
|
|
52
|
+
{`return ${httpCall}('${baseURL}${url.replace(/([^/]):/g, '$1\\\\:')}', function handler(info) {
|
|
41
53
|
if(typeof data === 'function') return data(info)
|
|
42
54
|
|
|
43
55
|
return new Response(JSON.stringify(data || ${fakerName}(data)), {
|
|
@@ -1,34 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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'
|
|
4
6
|
|
|
5
7
|
type Props = {
|
|
6
8
|
typeName: string
|
|
7
|
-
operation: Operation
|
|
8
9
|
name: string
|
|
9
|
-
|
|
10
|
+
response: ast.ResponseNode
|
|
11
|
+
key?: string | number | null
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
const responseObject = operation.getResponseByStatusCode(statusCode) as OasTypes.ResponseObject
|
|
14
|
-
const contentType = Object.keys(responseObject.content || {})?.[0]
|
|
14
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
15
15
|
|
|
16
|
+
export function Response({ name, typeName, response }: Props): KubbReactNode {
|
|
17
|
+
const statusCode = Number(response.statusCode)
|
|
18
|
+
const contentType = getContentType(response)
|
|
16
19
|
const headers = [contentType ? `'Content-Type': '${contentType}'` : undefined].filter(Boolean)
|
|
17
20
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
+
)
|
|
26
32
|
|
|
27
33
|
const responseName = `${name}Response${statusCode}`
|
|
28
34
|
|
|
29
35
|
return (
|
|
30
36
|
<File.Source name={responseName} isIndexable isExportable>
|
|
31
|
-
<Function name={responseName} export params={params
|
|
37
|
+
<Function name={responseName} export params={params ?? ''}>
|
|
32
38
|
{`
|
|
33
39
|
return new Response(JSON.stringify(data), {
|
|
34
40
|
status: ${statusCode},
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
4
|
-
import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
|
|
5
|
-
import { File } from '@kubb/react-fabric'
|
|
1
|
+
import { defineGenerator } from '@kubb/core'
|
|
2
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
6
3
|
import { Handlers } from '../components/Handlers.tsx'
|
|
7
4
|
import type { PluginMsw } from '../types'
|
|
5
|
+
import { transformName } from '../utils.ts'
|
|
8
6
|
|
|
9
|
-
export const handlersGenerator =
|
|
7
|
+
export const handlersGenerator = defineGenerator<PluginMsw>({
|
|
10
8
|
name: 'plugin-msw',
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
renderer: jsxRenderer,
|
|
10
|
+
operations(nodes, ctx) {
|
|
11
|
+
const { resolver, config, root, adapter } = ctx
|
|
12
|
+
const { output, group, transformers } = ctx.options
|
|
13
13
|
|
|
14
|
-
const
|
|
15
|
-
const { getName, getFile } = useOperationManager(generator)
|
|
14
|
+
const file = resolver.resolveFile({ name: 'handlers', extname: '.ts' }, { root, output, group })
|
|
16
15
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
const imports = nodes.map((node) => {
|
|
17
|
+
const operationName = transformName(resolver.resolveName(node.operationId), 'function', transformers)
|
|
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
22
|
|
|
23
23
|
return <File.Import key={operationFile.path} name={[operationName]} root={file.path} path={operationFile.path} />
|
|
24
24
|
})
|
|
25
25
|
|
|
26
|
-
const handlers =
|
|
26
|
+
const handlers = nodes.map((node) => `${transformName(resolver.resolveName(node.operationId), 'function', transformers)}()`)
|
|
27
27
|
|
|
28
28
|
return (
|
|
29
29
|
<File
|
|
30
30
|
baseName={file.baseName}
|
|
31
31
|
path={file.path}
|
|
32
32
|
meta={file.meta}
|
|
33
|
-
banner={
|
|
34
|
-
footer={
|
|
33
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
34
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
35
35
|
>
|
|
36
36
|
{imports}
|
|
37
37
|
<Handlers name={'handlers'} handlers={handlers} />
|
|
@@ -1,94 +1,83 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defineGenerator } from '@kubb/core'
|
|
2
2
|
import { pluginFakerName } from '@kubb/plugin-faker'
|
|
3
|
-
import { createReactGenerator } from '@kubb/plugin-oas/generators'
|
|
4
|
-
import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
5
|
-
import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
|
|
6
3
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
7
|
-
import { File } from '@kubb/
|
|
4
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
8
5
|
import { Mock, MockWithFaker, Response } from '../components'
|
|
9
6
|
import type { PluginMsw } from '../types'
|
|
7
|
+
import { getResponseTypes, getSuccessResponses, resolveFakerMeta, transformName } from '../utils.ts'
|
|
10
8
|
|
|
11
|
-
export const mswGenerator =
|
|
9
|
+
export const mswGenerator = defineGenerator<PluginMsw>({
|
|
12
10
|
name: 'msw',
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} =
|
|
17
|
-
const driver = usePluginDriver()
|
|
18
|
-
|
|
19
|
-
const oas = useOas()
|
|
20
|
-
const { getSchemas, getName, getFile } = useOperationManager(generator)
|
|
11
|
+
renderer: jsxRenderer,
|
|
12
|
+
operation(node, ctx) {
|
|
13
|
+
const { driver, resolver, config, root, adapter } = ctx
|
|
14
|
+
const { output, parser, baseURL, group, transformers } = ctx.options
|
|
21
15
|
|
|
16
|
+
const fileName = resolver.resolveName(node.operationId)
|
|
22
17
|
const mock = {
|
|
23
|
-
name:
|
|
24
|
-
file:
|
|
18
|
+
name: transformName(fileName, 'function', transformers),
|
|
19
|
+
file: resolver.resolveFile({ name: fileName, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
const fakerPlugin = parser === 'faker' ? driver.getPlugin(pluginFakerName) : undefined
|
|
23
|
+
const faker =
|
|
24
|
+
parser === 'faker' && fakerPlugin
|
|
25
|
+
? resolveFakerMeta(node, {
|
|
26
|
+
root,
|
|
27
|
+
fakerResolver: driver.getResolver(pluginFakerName),
|
|
28
|
+
fakerOutput: fakerPlugin.options?.output ?? output,
|
|
29
|
+
fakerGroup: fakerPlugin.options?.group,
|
|
30
|
+
})
|
|
31
|
+
: undefined
|
|
32
|
+
|
|
33
|
+
const pluginTs = driver.getPlugin(pluginTsName)
|
|
34
|
+
if (!pluginTs) return null
|
|
35
|
+
const tsResolver = driver.getResolver(pluginTsName)
|
|
31
36
|
|
|
32
37
|
const type = {
|
|
33
|
-
file:
|
|
34
|
-
|
|
38
|
+
file: tsResolver.resolveFile(
|
|
39
|
+
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
40
|
+
{ root, output: pluginTs.options?.output ?? output, group: pluginTs.options?.group },
|
|
41
|
+
),
|
|
42
|
+
responseName: tsResolver.resolveResponseName(node),
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
for (const code of responseStatusCodes) {
|
|
42
|
-
if (code === 'default') {
|
|
43
|
-
types.push(['default', type.schemas.response.name])
|
|
44
|
-
continue
|
|
45
|
-
}
|
|
45
|
+
const types = getResponseTypes(node, tsResolver)
|
|
46
|
+
const successResponses = getSuccessResponses(node)
|
|
47
|
+
const hasSuccessSchema = successResponses.some((response) => !!response.schema)
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
types.push([Number(code), type.schemas.response.name])
|
|
49
|
-
continue
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const codeType = type.schemas.errors?.find((err) => err.statusCode === Number(code))
|
|
53
|
-
if (codeType) types.push([Number(code), codeType.name])
|
|
54
|
-
}
|
|
49
|
+
const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined
|
|
55
50
|
|
|
56
51
|
return (
|
|
57
52
|
<File
|
|
58
53
|
baseName={mock.file.baseName}
|
|
59
54
|
path={mock.file.path}
|
|
60
55
|
meta={mock.file.meta}
|
|
61
|
-
banner={
|
|
62
|
-
footer={
|
|
56
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
57
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
63
58
|
>
|
|
64
59
|
<File.Import name={['http']} path="msw" />
|
|
65
|
-
<File.Import name={['
|
|
60
|
+
<File.Import name={['HttpResponseResolver']} isTypeOnly path="msw" />
|
|
66
61
|
<File.Import
|
|
67
|
-
name={Array.from(new Set([type.
|
|
62
|
+
name={Array.from(new Set([type.responseName, ...types.map((t) => t[1]), ...(requestName ? [requestName] : [])]))}
|
|
68
63
|
path={type.file.path}
|
|
69
64
|
root={mock.file.path}
|
|
70
65
|
isTypeOnly
|
|
71
66
|
/>
|
|
72
|
-
{parser === 'faker' && faker
|
|
73
|
-
<File.Import name={[faker.schemas.response.name]} root={mock.file.path} path={faker.file.path} />
|
|
74
|
-
)}
|
|
67
|
+
{parser === 'faker' && faker && <File.Import name={[faker.name]} root={mock.file.path} path={faker.file.path} />}
|
|
75
68
|
|
|
76
69
|
{types
|
|
77
70
|
.filter(([code]) => code !== 'default')
|
|
78
|
-
.map(([code, typeName]) =>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
/>
|
|
89
|
-
)}
|
|
90
|
-
{parser === 'data' && (
|
|
91
|
-
<Mock name={mock.name} typeName={type.schemas.response.name} fakerName={faker.schemas.response.name} operation={operation} baseURL={baseURL} />
|
|
71
|
+
.map(([code, typeName]) => {
|
|
72
|
+
const response = node.responses.find((item) => item.statusCode === String(code))
|
|
73
|
+
if (!response) return null
|
|
74
|
+
return <Response key={typeName} typeName={typeName} response={response} name={mock.name} />
|
|
75
|
+
})}
|
|
76
|
+
|
|
77
|
+
{parser === 'faker' && faker && hasSuccessSchema ? (
|
|
78
|
+
<MockWithFaker name={mock.name} typeName={type.responseName} requestTypeName={requestName} fakerName={faker.name} node={node} baseURL={baseURL} />
|
|
79
|
+
) : (
|
|
80
|
+
<Mock name={mock.name} typeName={type.responseName} requestTypeName={requestName} node={node} baseURL={baseURL} />
|
|
92
81
|
)}
|
|
93
82
|
</File>
|
|
94
83
|
)
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { pluginMsw, pluginMswName } from './plugin.ts'
|
|
1
|
+
export { default, pluginMsw, pluginMswName } from './plugin.ts'
|
|
2
2
|
export type { PluginMsw } from './types.ts'
|