@kubb/plugin-cypress 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/index.cjs +511 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +179 -4
- package/dist/index.js +505 -62
- package/dist/index.js.map +1 -1
- package/extension.yaml +441 -0
- package/package.json +43 -64
- package/src/components/Request.tsx +75 -108
- package/src/generators/cypressGenerator.tsx +51 -44
- package/src/index.ts +9 -2
- package/src/plugin.ts +68 -92
- package/src/resolvers/resolverCypress.ts +22 -0
- package/src/types.ts +75 -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 -505
- 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
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { URLPath } from '@internals/utils'
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import { File, Function
|
|
6
|
-
import type {
|
|
1
|
+
import { camelCase, URLPath } from '@internals/utils'
|
|
2
|
+
import { ast } from '@kubb/core'
|
|
3
|
+
import type { ResolverTs } from '@kubb/plugin-ts'
|
|
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
7
|
import type { PluginCypress } from '../types.ts'
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
@@ -11,137 +11,104 @@ type Props = {
|
|
|
11
11
|
* Name of the function
|
|
12
12
|
*/
|
|
13
13
|
name: string
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* AST operation node
|
|
16
|
+
*/
|
|
17
|
+
node: ast.OperationNode
|
|
18
|
+
/**
|
|
19
|
+
* TypeScript resolver for resolving param/data/response type names
|
|
20
|
+
*/
|
|
21
|
+
resolver: ResolverTs
|
|
16
22
|
baseURL: string | undefined
|
|
17
23
|
dataReturnType: PluginCypress['resolvedOptions']['dataReturnType']
|
|
18
24
|
paramsCasing: PluginCypress['resolvedOptions']['paramsCasing']
|
|
19
25
|
paramsType: PluginCypress['resolvedOptions']['paramsType']
|
|
20
26
|
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
27
|
}
|
|
30
28
|
|
|
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>',
|
|
29
|
+
const declarationPrinter = functionPrinter({ mode: 'declaration' })
|
|
30
|
+
|
|
31
|
+
export function Request({ baseURL = '', name, dataReturnType, resolver, node, paramsType, pathParamsType, paramsCasing }: Props): KubbReactNode {
|
|
32
|
+
const paramsNode = ast.createOperationParams(node, {
|
|
33
|
+
paramsType,
|
|
34
|
+
pathParamsType,
|
|
35
|
+
paramsCasing,
|
|
36
|
+
resolver,
|
|
37
|
+
extraParams: [
|
|
38
|
+
ast.createFunctionParameter({
|
|
39
|
+
name: 'options',
|
|
40
|
+
type: ast.createParamsType({ variant: 'reference', name: 'Partial<Cypress.RequestOptions>' }),
|
|
62
41
|
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
|
-
},
|
|
42
|
+
}),
|
|
43
|
+
],
|
|
97
44
|
})
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
export function Request({ baseURL = '', name, dataReturnType, typeSchemas, url, method, paramsType, paramsCasing, pathParamsType }: Props): FabricReactNode {
|
|
101
|
-
const path = new URLPath(url, { casing: paramsCasing })
|
|
102
|
-
|
|
103
|
-
const params = getParams({ paramsType, paramsCasing, pathParamsType, typeSchemas })
|
|
45
|
+
const paramsSignature = declarationPrinter.print(paramsNode) ?? ''
|
|
104
46
|
|
|
105
|
-
const
|
|
106
|
-
|
|
47
|
+
const responseType = resolver.resolveResponseName(node)
|
|
48
|
+
const returnType = dataReturnType === 'data' ? `Cypress.Chainable<${responseType}>` : `Cypress.Chainable<Cypress.Response<${responseType}>>`
|
|
107
49
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
50
|
+
const casedPathParams = ast.caseParams(
|
|
51
|
+
node.parameters.filter((p) => p.in === 'path'),
|
|
52
|
+
paramsCasing,
|
|
53
|
+
)
|
|
54
|
+
// Build a lookup keyed by camelCase-normalized name so that path-template names
|
|
55
|
+
// (e.g. `{pet_id}`) correctly resolve to the function-parameter name (`petId`)
|
|
56
|
+
// even when the OpenAPI spec has inconsistent casing between the two.
|
|
57
|
+
const pathParamNameMap = new Map(casedPathParams.map((p) => [camelCase(p.name), p.name]))
|
|
58
|
+
|
|
59
|
+
const urlPath = new URLPath(node.path, { casing: paramsCasing })
|
|
60
|
+
const urlTemplate = urlPath.toTemplateString({
|
|
61
|
+
prefix: baseURL,
|
|
62
|
+
replacer: (param) => pathParamNameMap.get(camelCase(param)) ?? param,
|
|
63
|
+
})
|
|
113
64
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
65
|
+
const requestOptions: string[] = [`method: '${node.method}'`, `url: ${urlTemplate}`]
|
|
66
|
+
|
|
67
|
+
const queryParams = node.parameters.filter((p) => p.in === 'query')
|
|
68
|
+
if (queryParams.length > 0) {
|
|
69
|
+
const casedQueryParams = ast.caseParams(queryParams, paramsCasing)
|
|
70
|
+
// When paramsCasing renames query params (e.g. page_size → pageSize), we must remap
|
|
71
|
+
// the camelCase keys back to the original API names before passing them to `qs`.
|
|
72
|
+
const needsQsTransform = casedQueryParams.some((p, i) => p.name !== queryParams[i]!.name)
|
|
73
|
+
if (needsQsTransform) {
|
|
74
|
+
const pairs = queryParams.map((orig, i) => `${orig.name}: params.${casedQueryParams[i]!.name}`).join(', ')
|
|
75
|
+
requestOptions.push(`qs: params ? { ${pairs} } : undefined`)
|
|
76
|
+
} else {
|
|
77
|
+
requestOptions.push('qs: params')
|
|
78
|
+
}
|
|
117
79
|
}
|
|
118
80
|
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
|
|
81
|
+
const headerParams = node.parameters.filter((p) => p.in === 'header')
|
|
82
|
+
if (headerParams.length > 0) {
|
|
83
|
+
const casedHeaderParams = ast.caseParams(headerParams, paramsCasing)
|
|
84
|
+
// When paramsCasing renames header params (e.g. x-api-key → xApiKey), we must remap
|
|
85
|
+
// the camelCase keys back to the original API names before passing them to `headers`.
|
|
86
|
+
const needsHeaderTransform = casedHeaderParams.some((p, i) => p.name !== headerParams[i]!.name)
|
|
87
|
+
if (needsHeaderTransform) {
|
|
88
|
+
const pairs = headerParams.map((orig, i) => `'${orig.name}': headers.${casedHeaderParams[i]!.name}`).join(', ')
|
|
89
|
+
requestOptions.push(`headers: headers ? { ${pairs} } : undefined`)
|
|
90
|
+
} else {
|
|
91
|
+
requestOptions.push('headers')
|
|
92
|
+
}
|
|
122
93
|
}
|
|
123
94
|
|
|
124
|
-
|
|
125
|
-
if (typeSchemas.request?.name) {
|
|
95
|
+
if (node.requestBody?.content?.[0]?.schema) {
|
|
126
96
|
requestOptions.push('body: data')
|
|
127
97
|
}
|
|
128
98
|
|
|
129
|
-
// Spread additional Cypress options
|
|
130
99
|
requestOptions.push('...options')
|
|
131
100
|
|
|
132
101
|
return (
|
|
133
102
|
<File.Source name={name} isIndexable isExportable>
|
|
134
|
-
<Function name={name} export params={
|
|
103
|
+
<Function name={name} export params={paramsSignature} returnType={returnType}>
|
|
135
104
|
{dataReturnType === 'data'
|
|
136
|
-
? `return cy.request<${
|
|
105
|
+
? `return cy.request<${responseType}>({
|
|
137
106
|
${requestOptions.join(',\n ')}
|
|
138
107
|
}).then((res) => res.body)`
|
|
139
|
-
: `return cy.request<${
|
|
108
|
+
: `return cy.request<${responseType}>({
|
|
140
109
|
${requestOptions.join(',\n ')}
|
|
141
110
|
})`}
|
|
142
111
|
</Function>
|
|
143
112
|
</File.Source>
|
|
144
113
|
)
|
|
145
114
|
}
|
|
146
|
-
|
|
147
|
-
Request.getParams = getParams
|
|
@@ -1,64 +1,71 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createReactGenerator } from '@kubb/plugin-oas/generators'
|
|
3
|
-
import { useOas, useOperationManager } from '@kubb/plugin-oas/hooks'
|
|
4
|
-
import { getBanner, getFooter } from '@kubb/plugin-oas/utils'
|
|
1
|
+
import { ast, defineGenerator } from '@kubb/core'
|
|
5
2
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
6
|
-
import { File } from '@kubb/
|
|
7
|
-
import { Request } from '../components'
|
|
8
|
-
import type { PluginCypress } from '../types'
|
|
3
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
4
|
+
import { Request } from '../components/Request.tsx'
|
|
5
|
+
import type { PluginCypress } from '../types.ts'
|
|
9
6
|
|
|
10
|
-
export const cypressGenerator =
|
|
7
|
+
export const cypressGenerator = defineGenerator<PluginCypress>({
|
|
11
8
|
name: 'cypress',
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} =
|
|
16
|
-
const driver = usePluginDriver()
|
|
9
|
+
renderer: jsxRenderer,
|
|
10
|
+
operation(node, ctx) {
|
|
11
|
+
const { adapter, config, resolver, driver, root } = ctx
|
|
12
|
+
const { output, baseURL, dataReturnType, paramsCasing, paramsType, pathParamsType, group } = ctx.options
|
|
17
13
|
|
|
18
|
-
const
|
|
19
|
-
const { getSchemas, getName, getFile } = useOperationManager(generator)
|
|
14
|
+
const pluginTs = driver.getPlugin(pluginTsName)
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
file: getFile(operation),
|
|
16
|
+
if (!pluginTs) {
|
|
17
|
+
return null
|
|
24
18
|
}
|
|
25
19
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
const tsResolver = driver.getResolver(pluginTsName)
|
|
21
|
+
|
|
22
|
+
const casedParams = ast.caseParams(node.parameters, paramsCasing)
|
|
23
|
+
|
|
24
|
+
const pathParams = casedParams.filter((p) => p.in === 'path')
|
|
25
|
+
const queryParams = casedParams.filter((p) => p.in === 'query')
|
|
26
|
+
const headerParams = casedParams.filter((p) => p.in === 'header')
|
|
27
|
+
|
|
28
|
+
const importedTypeNames = [
|
|
29
|
+
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
30
|
+
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
31
|
+
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
32
|
+
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : undefined,
|
|
33
|
+
tsResolver.resolveResponseName(node),
|
|
34
|
+
].filter(Boolean)
|
|
35
|
+
|
|
36
|
+
const meta = {
|
|
37
|
+
name: resolver.resolveName(node.operationId),
|
|
38
|
+
file: resolver.resolveFile({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path }, { root, output, group }),
|
|
39
|
+
fileTs: tsResolver.resolveFile(
|
|
40
|
+
{ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
41
|
+
{
|
|
42
|
+
root,
|
|
43
|
+
output: pluginTs.options?.output ?? output,
|
|
44
|
+
group: pluginTs.options?.group,
|
|
45
|
+
},
|
|
46
|
+
),
|
|
47
|
+
} as const
|
|
30
48
|
|
|
31
49
|
return (
|
|
32
50
|
<File
|
|
33
|
-
baseName={
|
|
34
|
-
path={
|
|
35
|
-
meta={
|
|
36
|
-
banner={
|
|
37
|
-
footer={
|
|
51
|
+
baseName={meta.file.baseName}
|
|
52
|
+
path={meta.file.path}
|
|
53
|
+
meta={meta.file.meta}
|
|
54
|
+
banner={resolver.resolveBanner(adapter.inputNode, { output, config })}
|
|
55
|
+
footer={resolver.resolveFooter(adapter.inputNode, { output, config })}
|
|
38
56
|
>
|
|
39
|
-
|
|
40
|
-
name={
|
|
41
|
-
|
|
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
|
-
/>
|
|
57
|
+
{meta.fileTs && importedTypeNames.length > 0 && (
|
|
58
|
+
<File.Import name={Array.from(new Set(importedTypeNames))} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />
|
|
59
|
+
)}
|
|
52
60
|
<Request
|
|
53
|
-
name={
|
|
61
|
+
name={meta.name}
|
|
62
|
+
node={node}
|
|
63
|
+
resolver={tsResolver}
|
|
54
64
|
dataReturnType={dataReturnType}
|
|
55
65
|
paramsCasing={paramsCasing}
|
|
56
66
|
paramsType={paramsType}
|
|
57
67
|
pathParamsType={pathParamsType}
|
|
58
|
-
typeSchemas={type.schemas}
|
|
59
|
-
method={operation.method}
|
|
60
68
|
baseURL={baseURL}
|
|
61
|
-
url={operation.path}
|
|
62
69
|
/>
|
|
63
70
|
</File>
|
|
64
71
|
)
|
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
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { camelCase } from '@internals/utils'
|
|
2
|
+
import { defineResolver } from '@kubb/core'
|
|
3
|
+
import type { PluginCypress } from '../types.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Naming convention resolver for Cypress plugin.
|
|
7
|
+
*
|
|
8
|
+
* Provides default naming helpers using camelCase for functions and file paths.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* `resolverCypress.default('list pets', 'function') // → 'listPets'`
|
|
12
|
+
*/
|
|
13
|
+
export const resolverCypress = defineResolver<PluginCypress>((ctx) => ({
|
|
14
|
+
name: 'default',
|
|
15
|
+
pluginName: 'plugin-cypress',
|
|
16
|
+
default(name, type) {
|
|
17
|
+
return camelCase(name, { isFile: type === 'file' })
|
|
18
|
+
},
|
|
19
|
+
resolveName(name) {
|
|
20
|
+
return ctx.default(name, 'function')
|
|
21
|
+
},
|
|
22
|
+
}))
|