@kubb/plugin-cypress 5.0.0-alpha.8 → 5.0.0-beta.10
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 +25 -7
- package/dist/index.cjs +549 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +183 -4
- package/dist/index.js +543 -62
- package/dist/index.js.map +1 -1
- package/extension.yaml +441 -0
- package/package.json +41 -67
- package/src/components/Request.tsx +72 -107
- package/src/generators/cypressGenerator.tsx +38 -44
- package/src/index.ts +9 -2
- package/src/plugin.ts +68 -92
- package/src/resolvers/resolverCypress.ts +25 -0
- package/src/types.ts +79 -43
- package/dist/components-BK_6GU4v.js +0 -257
- package/dist/components-BK_6GU4v.js.map +0 -1
- package/dist/components-Drg_gLu2.cjs +0 -305
- package/dist/components-Drg_gLu2.cjs.map +0 -1
- package/dist/components.cjs +0 -3
- package/dist/components.d.ts +0 -50
- package/dist/components.js +0 -2
- package/dist/generators-B3FWG2Ck.js +0 -71
- package/dist/generators-B3FWG2Ck.js.map +0 -1
- package/dist/generators-C73nd-xB.cjs +0 -75
- package/dist/generators-C73nd-xB.cjs.map +0 -1
- package/dist/generators.cjs +0 -3
- package/dist/generators.d.ts +0 -476
- package/dist/generators.js +0 -2
- package/dist/types-DGvL0jsn.d.ts +0 -85
- package/src/components/index.ts +0 -1
- package/src/generators/index.ts +0 -1
package/package.json
CHANGED
|
@@ -1,73 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-cypress",
|
|
3
|
-
"version": "5.0.0-
|
|
4
|
-
"description": "Cypress
|
|
3
|
+
"version": "5.0.0-beta.10",
|
|
4
|
+
"description": "Generate Cypress request commands and e2e test fixtures from your OpenAPI specification, enabling automated API testing with zero manual setup.",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"code-generation",
|
|
7
|
+
"codegen",
|
|
6
8
|
"cypress",
|
|
7
9
|
"e2e-testing",
|
|
8
|
-
"
|
|
9
|
-
"testing",
|
|
10
|
-
"test-generation",
|
|
11
|
-
"api-testing",
|
|
12
|
-
"test-automation",
|
|
13
|
-
"integration-testing",
|
|
14
|
-
"typescript",
|
|
10
|
+
"kubb",
|
|
15
11
|
"openapi",
|
|
16
12
|
"swagger",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"plugins",
|
|
21
|
-
"kubb"
|
|
13
|
+
"test-generation",
|
|
14
|
+
"testing",
|
|
15
|
+
"typescript"
|
|
22
16
|
],
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "stijnvanhulle",
|
|
23
19
|
"repository": {
|
|
24
20
|
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/kubb-labs/
|
|
21
|
+
"url": "git+https://github.com/kubb-labs/plugins.git",
|
|
26
22
|
"directory": "packages/plugin-cypress"
|
|
27
23
|
},
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
"files": [
|
|
25
|
+
"src",
|
|
26
|
+
"dist",
|
|
27
|
+
"extension.yaml",
|
|
28
|
+
"!/**/**.test.**",
|
|
29
|
+
"!/**/__tests__/**",
|
|
30
|
+
"!/**/__snapshots__/**"
|
|
31
|
+
],
|
|
31
32
|
"type": "module",
|
|
33
|
+
"sideEffects": false,
|
|
34
|
+
"main": "./dist/index.cjs",
|
|
35
|
+
"module": "./dist/index.js",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"typesVersions": {},
|
|
32
38
|
"exports": {
|
|
33
39
|
".": {
|
|
34
40
|
"import": "./dist/index.js",
|
|
35
41
|
"require": "./dist/index.cjs"
|
|
36
42
|
},
|
|
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
43
|
"./package.json": "./package.json"
|
|
46
44
|
},
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public",
|
|
47
|
+
"registry": "https://registry.npmjs.org/"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@kubb/core": "5.0.0-beta.10",
|
|
51
|
+
"@kubb/renderer-jsx": "5.0.0-beta.10",
|
|
52
|
+
"@kubb/plugin-ts": "5.0.0-beta.10"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@internals/shared": "0.0.0",
|
|
56
|
+
"@internals/utils": "0.0.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@kubb/renderer-jsx": "5.0.0-beta.10"
|
|
63
60
|
},
|
|
64
|
-
"files": [
|
|
65
|
-
"src",
|
|
66
|
-
"dist",
|
|
67
|
-
"!/**/**.test.**",
|
|
68
|
-
"!/**/__tests__/**",
|
|
69
|
-
"!/**/__snapshots__/**"
|
|
70
|
-
],
|
|
71
61
|
"size-limit": [
|
|
72
62
|
{
|
|
73
63
|
"path": "./dist/*.js",
|
|
@@ -75,30 +65,14 @@
|
|
|
75
65
|
"gzip": true
|
|
76
66
|
}
|
|
77
67
|
],
|
|
78
|
-
"dependencies": {
|
|
79
|
-
"@kubb/react-fabric": "0.14.0",
|
|
80
|
-
"@kubb/core": "5.0.0-alpha.8",
|
|
81
|
-
"@kubb/oas": "5.0.0-alpha.8",
|
|
82
|
-
"@kubb/plugin-oas": "5.0.0-alpha.8",
|
|
83
|
-
"@kubb/plugin-ts": "5.0.0-alpha.8"
|
|
84
|
-
},
|
|
85
68
|
"engines": {
|
|
86
69
|
"node": ">=22"
|
|
87
70
|
},
|
|
88
|
-
"publishConfig": {
|
|
89
|
-
"access": "public",
|
|
90
|
-
"registry": "https://registry.npmjs.org/"
|
|
91
|
-
},
|
|
92
|
-
"main": "./dist/index.cjs",
|
|
93
|
-
"module": "./dist/index.js",
|
|
94
|
-
"devDependencies": {
|
|
95
|
-
"@internals/utils": "0.0.0"
|
|
96
|
-
},
|
|
97
71
|
"scripts": {
|
|
98
72
|
"build": "tsdown && size-limit",
|
|
99
73
|
"clean": "npx rimraf ./dist",
|
|
100
|
-
"lint": "
|
|
101
|
-
"lint:fix": "
|
|
74
|
+
"lint": "oxlint .",
|
|
75
|
+
"lint:fix": "oxlint --fix .",
|
|
102
76
|
"release": "pnpm publish --no-git-check",
|
|
103
77
|
"release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
|
|
104
78
|
"start": "tsdown --watch",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
1
|
+
import { getOperationParameters } from '@internals/shared'
|
|
2
|
+
import { camelCase, URLPath } from '@internals/utils'
|
|
3
|
+
import { ast } from '@kubb/core'
|
|
4
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
5
|
+
import { functionPrinter } from '@kubb/plugin-ts'
|
|
6
|
+
import { File, Function } from '@kubb/renderer-jsx'
|
|
7
|
+
import type { KubbReactNode } from '@kubb/renderer-jsx/types'
|
|
7
8
|
import type { PluginCypress } from '../types.ts'
|
|
8
9
|
|
|
9
10
|
type Props = {
|
|
@@ -11,137 +12,101 @@ type Props = {
|
|
|
11
12
|
* Name of the function
|
|
12
13
|
*/
|
|
13
14
|
name: string
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* AST operation node
|
|
17
|
+
*/
|
|
18
|
+
node: ast.OperationNode
|
|
19
|
+
/**
|
|
20
|
+
* TypeScript resolver for resolving param/data/response type names
|
|
21
|
+
*/
|
|
22
|
+
resolver: ResolverTs
|
|
16
23
|
baseURL: string | undefined
|
|
17
24
|
dataReturnType: PluginCypress['resolvedOptions']['dataReturnType']
|
|
18
25
|
paramsCasing: PluginCypress['resolvedOptions']['paramsCasing']
|
|
19
26
|
paramsType: PluginCypress['resolvedOptions']['paramsType']
|
|
20
27
|
pathParamsType: PluginCypress['resolvedOptions']['pathParamsType']
|
|
21
|
-
method: HttpMethod
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type GetParamsProps = {
|
|
25
|
-
paramsCasing: PluginCypress['resolvedOptions']['paramsCasing']
|
|
26
|
-
paramsType: PluginCypress['resolvedOptions']['paramsType']
|
|
27
|
-
pathParamsType: PluginCypress['resolvedOptions']['pathParamsType']
|
|
28
|
-
typeSchemas: OperationSchemas
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
optional: isOptional(typeSchemas.request?.schema),
|
|
44
|
-
}
|
|
45
|
-
: undefined,
|
|
46
|
-
params: typeSchemas.queryParams?.name
|
|
47
|
-
? {
|
|
48
|
-
type: typeSchemas.queryParams?.name,
|
|
49
|
-
optional: isOptional(typeSchemas.queryParams?.schema),
|
|
50
|
-
}
|
|
51
|
-
: undefined,
|
|
52
|
-
headers: typeSchemas.headerParams?.name
|
|
53
|
-
? {
|
|
54
|
-
type: typeSchemas.headerParams?.name,
|
|
55
|
-
optional: isOptional(typeSchemas.headerParams?.schema),
|
|
56
|
-
}
|
|
57
|
-
: undefined,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
options: {
|
|
61
|
-
type: 'Partial<Cypress.RequestOptions>',
|
|
30
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
31
|
+
|
|
32
|
+
export function Request({ baseURL = '', name, dataReturnType, resolver, node, paramsType, pathParamsType, paramsCasing }: Props): KubbReactNode {
|
|
33
|
+
const paramsNode = ast.createOperationParams(node, {
|
|
34
|
+
paramsType,
|
|
35
|
+
pathParamsType,
|
|
36
|
+
paramsCasing,
|
|
37
|
+
resolver,
|
|
38
|
+
extraParams: [
|
|
39
|
+
ast.createFunctionParameter({
|
|
40
|
+
name: 'options',
|
|
41
|
+
type: ast.createParamsType({ variant: 'reference', name: 'Partial<Cypress.RequestOptions>' }),
|
|
62
42
|
default: '{}',
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return FunctionParams.factory({
|
|
68
|
-
pathParams: typeSchemas.pathParams?.name
|
|
69
|
-
? {
|
|
70
|
-
mode: pathParamsType === 'object' ? 'object' : 'inlineSpread',
|
|
71
|
-
children: getPathParams(typeSchemas.pathParams, { typed: true, casing: paramsCasing }),
|
|
72
|
-
default: isAllOptional(typeSchemas.pathParams?.schema) ? '{}' : undefined,
|
|
73
|
-
}
|
|
74
|
-
: undefined,
|
|
75
|
-
data: typeSchemas.request?.name
|
|
76
|
-
? {
|
|
77
|
-
type: typeSchemas.request?.name,
|
|
78
|
-
optional: isOptional(typeSchemas.request?.schema),
|
|
79
|
-
}
|
|
80
|
-
: undefined,
|
|
81
|
-
params: typeSchemas.queryParams?.name
|
|
82
|
-
? {
|
|
83
|
-
type: typeSchemas.queryParams?.name,
|
|
84
|
-
optional: isOptional(typeSchemas.queryParams?.schema),
|
|
85
|
-
}
|
|
86
|
-
: undefined,
|
|
87
|
-
headers: typeSchemas.headerParams?.name
|
|
88
|
-
? {
|
|
89
|
-
type: typeSchemas.headerParams?.name,
|
|
90
|
-
optional: isOptional(typeSchemas.headerParams?.schema),
|
|
91
|
-
}
|
|
92
|
-
: undefined,
|
|
93
|
-
options: {
|
|
94
|
-
type: 'Partial<Cypress.RequestOptions>',
|
|
95
|
-
default: '{}',
|
|
96
|
-
},
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
97
45
|
})
|
|
98
|
-
|
|
46
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
|
|
99
47
|
|
|
100
|
-
|
|
101
|
-
const
|
|
48
|
+
const responseType = resolver.resolveResponseName(node)
|
|
49
|
+
const returnType = dataReturnType === 'data' ? `Cypress.Chainable<${responseType}>` : `Cypress.Chainable<Cypress.Response<${responseType}>>`
|
|
102
50
|
|
|
103
|
-
const
|
|
51
|
+
const casedPathParams = getOperationParameters(node, { paramsCasing }).path
|
|
52
|
+
// Build a lookup keyed by camelCase-normalized name so that path-template names
|
|
53
|
+
// (e.g. `{pet_id}`) correctly resolve to the function-parameter name (`petId`)
|
|
54
|
+
// even when the OpenAPI spec has inconsistent casing between the two.
|
|
55
|
+
const pathParamNameMap = new Map(casedPathParams.map((p) => [camelCase(p.name), p.name]))
|
|
104
56
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// Build request options object
|
|
112
|
-
const requestOptions: string[] = [`method: '${method}'`, `url: ${urlTemplate}`]
|
|
57
|
+
const urlPath = new URLPath(node.path, { casing: paramsCasing })
|
|
58
|
+
const urlTemplate = urlPath.toTemplateString({
|
|
59
|
+
prefix: baseURL,
|
|
60
|
+
replacer: (param) => pathParamNameMap.get(camelCase(param)) ?? param,
|
|
61
|
+
})
|
|
113
62
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
63
|
+
const requestOptions: string[] = [`method: '${node.method}'`, `url: ${urlTemplate}`]
|
|
64
|
+
|
|
65
|
+
const queryParams = getOperationParameters(node).query
|
|
66
|
+
if (queryParams.length > 0) {
|
|
67
|
+
const casedQueryParams = getOperationParameters(node, { paramsCasing }).query
|
|
68
|
+
// When paramsCasing renames query params (e.g. page_size → pageSize), we must remap
|
|
69
|
+
// the camelCase keys back to the original API names before passing them to `qs`.
|
|
70
|
+
const needsQsTransform = casedQueryParams.some((p, i) => p.name !== queryParams[i]!.name)
|
|
71
|
+
if (needsQsTransform) {
|
|
72
|
+
const pairs = queryParams.map((orig, i) => `${orig.name}: params.${casedQueryParams[i]!.name}`).join(', ')
|
|
73
|
+
requestOptions.push(`qs: params ? { ${pairs} } : undefined`)
|
|
74
|
+
} else {
|
|
75
|
+
requestOptions.push('qs: params')
|
|
76
|
+
}
|
|
117
77
|
}
|
|
118
78
|
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
|
|
79
|
+
const headerParams = getOperationParameters(node).header
|
|
80
|
+
if (headerParams.length > 0) {
|
|
81
|
+
const casedHeaderParams = getOperationParameters(node, { paramsCasing }).header
|
|
82
|
+
// When paramsCasing renames header params (e.g. x-api-key → xApiKey), we must remap
|
|
83
|
+
// the camelCase keys back to the original API names before passing them to `headers`.
|
|
84
|
+
const needsHeaderTransform = casedHeaderParams.some((p, i) => p.name !== headerParams[i]!.name)
|
|
85
|
+
if (needsHeaderTransform) {
|
|
86
|
+
const pairs = headerParams.map((orig, i) => `'${orig.name}': headers.${casedHeaderParams[i]!.name}`).join(', ')
|
|
87
|
+
requestOptions.push(`headers: headers ? { ${pairs} } : undefined`)
|
|
88
|
+
} else {
|
|
89
|
+
requestOptions.push('headers')
|
|
90
|
+
}
|
|
122
91
|
}
|
|
123
92
|
|
|
124
|
-
|
|
125
|
-
if (typeSchemas.request?.name) {
|
|
93
|
+
if (node.requestBody?.content?.[0]?.schema) {
|
|
126
94
|
requestOptions.push('body: data')
|
|
127
95
|
}
|
|
128
96
|
|
|
129
|
-
// Spread additional Cypress options
|
|
130
97
|
requestOptions.push('...options')
|
|
131
98
|
|
|
132
99
|
return (
|
|
133
100
|
<File.Source name={name} isIndexable isExportable>
|
|
134
|
-
<Function name={name} export params={
|
|
101
|
+
<Function name={name} export params={paramsSignature} returnType={returnType}>
|
|
135
102
|
{dataReturnType === 'data'
|
|
136
|
-
? `return cy.request<${
|
|
103
|
+
? `return cy.request<${responseType}>({
|
|
137
104
|
${requestOptions.join(',\n ')}
|
|
138
105
|
}).then((res) => res.body)`
|
|
139
|
-
: `return cy.request<${
|
|
106
|
+
: `return cy.request<${responseType}>({
|
|
140
107
|
${requestOptions.join(',\n ')}
|
|
141
108
|
})`}
|
|
142
109
|
</Function>
|
|
143
110
|
</File.Source>
|
|
144
111
|
)
|
|
145
112
|
}
|
|
146
|
-
|
|
147
|
-
Request.getParams = getParams
|
|
@@ -1,64 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
4
|
-
import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
|
|
1
|
+
import { resolveOperationTypeNames } from '@internals/shared'
|
|
2
|
+
import { defineGenerator } from '@kubb/core'
|
|
5
3
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
6
|
-
import { File } from '@kubb/
|
|
7
|
-
import { Request } from '../components'
|
|
8
|
-
import type { PluginCypress } from '../types'
|
|
4
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
5
|
+
import { Request } from '../components/Request.tsx'
|
|
6
|
+
import type { PluginCypress } from '../types.ts'
|
|
9
7
|
|
|
10
|
-
export const cypressGenerator =
|
|
8
|
+
export const cypressGenerator = defineGenerator<PluginCypress>({
|
|
11
9
|
name: 'cypress',
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} =
|
|
16
|
-
const driver = usePluginDriver()
|
|
10
|
+
renderer: jsxRenderer,
|
|
11
|
+
operation(node, ctx) {
|
|
12
|
+
const { adapter, config, resolver, driver, root } = ctx
|
|
13
|
+
const { output, baseURL, dataReturnType, paramsCasing, paramsType, pathParamsType, group } = ctx.options
|
|
17
14
|
|
|
18
|
-
const
|
|
19
|
-
const { getSchemas, getName, getFile } = useOperationManager(generator)
|
|
15
|
+
const pluginTs = driver.getPlugin(pluginTsName)
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
file: getFile(operation),
|
|
17
|
+
if (!pluginTs) {
|
|
18
|
+
return null
|
|
24
19
|
}
|
|
25
20
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
const tsResolver = driver.getResolver(pluginTsName)
|
|
22
|
+
|
|
23
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing })
|
|
24
|
+
|
|
25
|
+
const meta = {
|
|
26
|
+
name: resolver.resolveName(node.operationId),
|
|
27
|
+
file: resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
|
|
28
|
+
fileTs: tsResolver.resolveFile(
|
|
29
|
+
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
30
|
+
{
|
|
31
|
+
root,
|
|
32
|
+
output: pluginTs.options?.output ?? output,
|
|
33
|
+
group: pluginTs.options?.group,
|
|
34
|
+
},
|
|
35
|
+
),
|
|
36
|
+
} as const
|
|
30
37
|
|
|
31
38
|
return (
|
|
32
39
|
<File
|
|
33
|
-
baseName={
|
|
34
|
-
path={
|
|
35
|
-
meta={
|
|
36
|
-
banner={
|
|
37
|
-
footer={
|
|
40
|
+
baseName={meta.file.baseName}
|
|
41
|
+
path={meta.file.path}
|
|
42
|
+
meta={meta.file.meta}
|
|
43
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
44
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
38
45
|
>
|
|
39
|
-
<File.Import
|
|
40
|
-
name={[
|
|
41
|
-
type.schemas.request?.name,
|
|
42
|
-
type.schemas.response.name,
|
|
43
|
-
type.schemas.pathParams?.name,
|
|
44
|
-
type.schemas.queryParams?.name,
|
|
45
|
-
type.schemas.headerParams?.name,
|
|
46
|
-
...(type.schemas.statusCodes?.map((item) => item.name) || []),
|
|
47
|
-
].filter(Boolean)}
|
|
48
|
-
root={request.file.path}
|
|
49
|
-
path={type.file.path}
|
|
50
|
-
isTypeOnly
|
|
51
|
-
/>
|
|
46
|
+
{meta.fileTs && importedTypeNames.length > 0 && <File.Import name={importedTypeNames} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />}
|
|
52
47
|
<Request
|
|
53
|
-
name={
|
|
48
|
+
name={meta.name}
|
|
49
|
+
node={node}
|
|
50
|
+
resolver={tsResolver}
|
|
54
51
|
dataReturnType={dataReturnType}
|
|
55
52
|
paramsCasing={paramsCasing}
|
|
56
53
|
paramsType={paramsType}
|
|
57
54
|
pathParamsType={pathParamsType}
|
|
58
|
-
typeSchemas={type.schemas}
|
|
59
|
-
method={operation.method}
|
|
60
55
|
baseURL={baseURL}
|
|
61
|
-
url={operation.path}
|
|
62
56
|
/>
|
|
63
57
|
</File>
|
|
64
58
|
)
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
1
|
+
export { Request } from './components/Request.tsx'
|
|
2
|
+
|
|
3
|
+
export { cypressGenerator } from './generators/cypressGenerator.tsx'
|
|
4
|
+
|
|
5
|
+
export { default, pluginCypress, pluginCypressName } from './plugin.ts'
|
|
6
|
+
|
|
7
|
+
export { resolverCypress } from './resolvers/resolverCypress.ts'
|
|
8
|
+
|
|
9
|
+
export type { PluginCypress, ResolverCypress } from './types.ts'
|
package/src/plugin.ts
CHANGED
|
@@ -1,119 +1,95 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
1
|
import { camelCase } from '@internals/utils'
|
|
3
|
-
import {
|
|
4
|
-
import { OperationGenerator, pluginOasName } from '@kubb/plugin-oas'
|
|
2
|
+
import { definePlugin, type Group } from '@kubb/core'
|
|
5
3
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
6
|
-
import { cypressGenerator } from './generators'
|
|
4
|
+
import { cypressGenerator } from './generators/cypressGenerator.tsx'
|
|
5
|
+
import { resolverCypress } from './resolvers/resolverCypress.ts'
|
|
7
6
|
import type { PluginCypress } from './types.ts'
|
|
8
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Canonical plugin name for `@kubb/plugin-cypress`, used to identify the plugin
|
|
10
|
+
* in driver lookups and warnings.
|
|
11
|
+
*/
|
|
9
12
|
export const pluginCypressName = 'plugin-cypress' satisfies PluginCypress['name']
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* The `@kubb/plugin-cypress` plugin factory.
|
|
16
|
+
*
|
|
17
|
+
* Generates Cypress `cy.request()` test functions from an OpenAPI/AST `RootNode`.
|
|
18
|
+
* Walks operations, delegates rendering to the active generators,
|
|
19
|
+
* and writes barrel files based on `output.barrelType`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import pluginCypress from '@kubb/plugin-cypress'
|
|
24
|
+
*
|
|
25
|
+
* export default defineConfig({
|
|
26
|
+
* plugins: [pluginCypress({ output: { path: 'cypress' } })],
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const pluginCypress = definePlugin<PluginCypress>((options) => {
|
|
12
31
|
const {
|
|
13
32
|
output = { path: 'cypress', barrelType: 'named' },
|
|
14
33
|
group,
|
|
15
|
-
dataReturnType = 'data',
|
|
16
34
|
exclude = [],
|
|
17
35
|
include,
|
|
18
36
|
override = [],
|
|
19
|
-
|
|
20
|
-
generators = [cypressGenerator].filter(Boolean),
|
|
21
|
-
contentType,
|
|
37
|
+
dataReturnType = 'data',
|
|
22
38
|
baseURL,
|
|
23
39
|
paramsCasing,
|
|
24
40
|
paramsType = 'inline',
|
|
25
41
|
pathParamsType = paramsType === 'object' ? 'object' : options.pathParamsType || 'inline',
|
|
42
|
+
resolver: userResolver,
|
|
43
|
+
transformer: userTransformer,
|
|
44
|
+
generators: userGenerators = [],
|
|
26
45
|
} = options
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
dataReturnType,
|
|
33
|
-
group,
|
|
34
|
-
baseURL,
|
|
35
|
-
|
|
36
|
-
paramsCasing,
|
|
37
|
-
paramsType,
|
|
38
|
-
pathParamsType,
|
|
39
|
-
},
|
|
40
|
-
pre: [pluginOasName, pluginTsName].filter(Boolean),
|
|
41
|
-
resolvePath(baseName, pathMode, options) {
|
|
42
|
-
const root = path.resolve(this.config.root, this.config.output.path)
|
|
43
|
-
const mode = pathMode ?? getMode(path.resolve(root, output.path))
|
|
44
|
-
|
|
45
|
-
if (mode === 'single') {
|
|
46
|
-
/**
|
|
47
|
-
* when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
|
|
48
|
-
* Other plugins then need to call addOrAppend instead of just add from the fileManager class
|
|
49
|
-
*/
|
|
50
|
-
return path.resolve(root, output.path)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (group && (options?.group?.path || options?.group?.tag)) {
|
|
54
|
-
const groupName: Group['name'] = group?.name
|
|
47
|
+
const groupConfig = group
|
|
48
|
+
? ({
|
|
49
|
+
...group,
|
|
50
|
+
name: group.name
|
|
55
51
|
? group.name
|
|
56
|
-
: (ctx) => {
|
|
57
|
-
if (group
|
|
52
|
+
: (ctx: { group: string }) => {
|
|
53
|
+
if (group.type === 'path') {
|
|
58
54
|
return `${ctx.group.split('/')[1]}`
|
|
59
55
|
}
|
|
60
56
|
return `${camelCase(ctx.group)}Requests`
|
|
61
|
-
}
|
|
57
|
+
},
|
|
58
|
+
} satisfies Group)
|
|
59
|
+
: undefined
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return path.resolve(root, output.path, baseName)
|
|
74
|
-
},
|
|
75
|
-
resolveName(name, type) {
|
|
76
|
-
const resolvedName = camelCase(name, {
|
|
77
|
-
isFile: type === 'file',
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
if (type) {
|
|
81
|
-
return transformers?.name?.(resolvedName, type) || resolvedName
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return resolvedName
|
|
85
|
-
},
|
|
86
|
-
async install() {
|
|
87
|
-
const root = path.resolve(this.config.root, this.config.output.path)
|
|
88
|
-
const mode = getMode(path.resolve(root, output.path))
|
|
89
|
-
const oas = await this.getOas()
|
|
90
|
-
|
|
91
|
-
const operationGenerator = new OperationGenerator(this.plugin.options, {
|
|
92
|
-
fabric: this.fabric,
|
|
93
|
-
oas,
|
|
94
|
-
driver: this.driver,
|
|
95
|
-
events: this.events,
|
|
96
|
-
plugin: this.plugin,
|
|
97
|
-
contentType,
|
|
98
|
-
exclude,
|
|
99
|
-
include,
|
|
100
|
-
override,
|
|
101
|
-
mode,
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
const files = await operationGenerator.build(...generators)
|
|
105
|
-
await this.upsertFile(...files)
|
|
106
|
-
|
|
107
|
-
const barrelFiles = await getBarrelFiles(this.fabric.files, {
|
|
108
|
-
type: output.barrelType ?? 'named',
|
|
109
|
-
root,
|
|
110
|
-
output,
|
|
111
|
-
meta: {
|
|
112
|
-
pluginName: this.plugin.name,
|
|
113
|
-
},
|
|
114
|
-
})
|
|
61
|
+
return {
|
|
62
|
+
name: pluginCypressName,
|
|
63
|
+
options,
|
|
64
|
+
dependencies: [pluginTsName],
|
|
65
|
+
hooks: {
|
|
66
|
+
'kubb:plugin:setup'(ctx) {
|
|
67
|
+
const resolver = userResolver ? { ...resolverCypress, ...userResolver } : resolverCypress
|
|
115
68
|
|
|
116
|
-
|
|
69
|
+
ctx.setOptions({
|
|
70
|
+
output,
|
|
71
|
+
exclude,
|
|
72
|
+
include,
|
|
73
|
+
override,
|
|
74
|
+
dataReturnType,
|
|
75
|
+
group: groupConfig,
|
|
76
|
+
baseURL,
|
|
77
|
+
paramsCasing,
|
|
78
|
+
paramsType,
|
|
79
|
+
pathParamsType,
|
|
80
|
+
resolver,
|
|
81
|
+
})
|
|
82
|
+
ctx.setResolver(resolver)
|
|
83
|
+
if (userTransformer) {
|
|
84
|
+
ctx.setTransformer(userTransformer)
|
|
85
|
+
}
|
|
86
|
+
ctx.addGenerator(cypressGenerator)
|
|
87
|
+
for (const gen of userGenerators) {
|
|
88
|
+
ctx.addGenerator(gen)
|
|
89
|
+
}
|
|
90
|
+
},
|
|
117
91
|
},
|
|
118
92
|
}
|
|
119
93
|
})
|
|
94
|
+
|
|
95
|
+
export default pluginCypress
|