@kubb/plugin-cypress 5.0.0-beta.3 → 5.0.0-beta.30
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 +25 -5
- package/dist/index.cjs +126 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +59 -31
- package/dist/index.js +127 -52
- package/dist/index.js.map +1 -1
- package/extension.yaml +906 -0
- package/package.json +9 -14
- package/src/components/Request.tsx +8 -10
- package/src/generators/cypressGenerator.tsx +19 -24
- package/src/plugin.ts +17 -10
- package/src/resolvers/resolverCypress.ts +13 -6
- package/src/types.ts +29 -17
package/dist/index.d.ts
CHANGED
|
@@ -16,26 +16,32 @@ type ResolverCypress = Resolver & {
|
|
|
16
16
|
* `resolver.resolveName('show pet by id') // -> 'showPetById'`
|
|
17
17
|
*/
|
|
18
18
|
resolveName(this: ResolverCypress, name: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves the output file name for a Cypress request module.
|
|
21
|
+
*/
|
|
22
|
+
resolvePathName(this: ResolverCypress, name: string, type?: 'file' | 'function' | 'type' | 'const'): string;
|
|
19
23
|
};
|
|
20
24
|
/**
|
|
21
25
|
* Parameter handling mode that determines how path params and query/body params are arranged in function signatures.
|
|
22
26
|
*/
|
|
23
27
|
type ParamsTypeOptions = {
|
|
24
28
|
/**
|
|
25
|
-
*
|
|
29
|
+
* Every operation parameter is wrapped in a single destructured object argument.
|
|
26
30
|
*/
|
|
27
31
|
paramsType: 'object';
|
|
28
32
|
/**
|
|
29
|
-
*
|
|
33
|
+
* `pathParamsType` has no effect when `paramsType` is `'object'`.
|
|
30
34
|
*/
|
|
31
35
|
pathParamsType?: never;
|
|
32
36
|
} | {
|
|
33
37
|
/**
|
|
34
|
-
* Each parameter group emitted as a separate function argument.
|
|
38
|
+
* Each parameter group is emitted as a separate positional function argument.
|
|
35
39
|
*/
|
|
36
40
|
paramsType?: 'inline';
|
|
37
41
|
/**
|
|
38
|
-
* How path parameters are arranged
|
|
42
|
+
* How URL path parameters are arranged inside the inline argument list.
|
|
43
|
+
* - `'object'` groups them into one destructured object.
|
|
44
|
+
* - `'inline'` emits each path param as its own argument.
|
|
39
45
|
*
|
|
40
46
|
* @default 'inline'
|
|
41
47
|
*/
|
|
@@ -43,50 +49,56 @@ type ParamsTypeOptions = {
|
|
|
43
49
|
};
|
|
44
50
|
type Options = {
|
|
45
51
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
52
|
+
* Where the generated Cypress helpers are written and how they are exported.
|
|
53
|
+
*
|
|
54
|
+
* @default { path: 'cypress', barrel: { type: 'named' } }
|
|
48
55
|
*/
|
|
49
56
|
output?: Output;
|
|
50
57
|
/**
|
|
51
|
-
*
|
|
58
|
+
* Shape of the value returned from each helper.
|
|
59
|
+
* - `'data'` — only the response body.
|
|
60
|
+
* - `'full'` — the full Cypress response object (headers, status, body).
|
|
52
61
|
*
|
|
53
62
|
* @default 'data'
|
|
54
63
|
*/
|
|
55
64
|
dataReturnType?: 'data' | 'full';
|
|
56
65
|
/**
|
|
57
|
-
*
|
|
66
|
+
* Rename parameter properties in the generated helpers (path, query, headers).
|
|
67
|
+
*
|
|
68
|
+
* @note Must match the value of `paramsCasing` on `@kubb/plugin-ts`.
|
|
58
69
|
*/
|
|
59
70
|
paramsCasing?: 'camelcase';
|
|
60
71
|
/**
|
|
61
|
-
* Base URL prepended to every
|
|
72
|
+
* Base URL prepended to every request URL. When omitted, falls back to the
|
|
73
|
+
* adapter's server URL (typically `servers[0].url`).
|
|
62
74
|
*/
|
|
63
75
|
baseURL?: string;
|
|
64
76
|
/**
|
|
65
|
-
*
|
|
77
|
+
* Split generated files into subfolders based on the operation's tag.
|
|
66
78
|
*/
|
|
67
79
|
group?: Group;
|
|
68
80
|
/**
|
|
69
|
-
*
|
|
81
|
+
* Skip operations matching at least one entry in the list.
|
|
70
82
|
*/
|
|
71
83
|
exclude?: Array<Exclude>;
|
|
72
84
|
/**
|
|
73
|
-
*
|
|
85
|
+
* Restrict generation to operations matching at least one entry in the list.
|
|
74
86
|
*/
|
|
75
87
|
include?: Array<Include>;
|
|
76
88
|
/**
|
|
77
|
-
*
|
|
89
|
+
* Apply a different options object to operations matching a pattern.
|
|
78
90
|
*/
|
|
79
91
|
override?: Array<Override<ResolvedOptions>>;
|
|
80
92
|
/**
|
|
81
|
-
* Override
|
|
93
|
+
* Override how helper names and file paths are built.
|
|
82
94
|
*/
|
|
83
95
|
resolver?: Partial<ResolverCypress> & ThisType<ResolverCypress>;
|
|
84
96
|
/**
|
|
85
|
-
* AST visitor to
|
|
97
|
+
* AST visitor applied to each operation node before printing.
|
|
86
98
|
*/
|
|
87
99
|
transformer?: ast.Visitor;
|
|
88
100
|
/**
|
|
89
|
-
*
|
|
101
|
+
* Custom generators that run alongside the built-in Cypress generators.
|
|
90
102
|
*/
|
|
91
103
|
generators?: Array<Generator<PluginCypress>>;
|
|
92
104
|
} & ParamsTypeOptions;
|
|
@@ -95,7 +107,7 @@ type ResolvedOptions = {
|
|
|
95
107
|
exclude: Array<Exclude>;
|
|
96
108
|
include: Array<Include> | undefined;
|
|
97
109
|
override: Array<Override<ResolvedOptions>>;
|
|
98
|
-
group: Group |
|
|
110
|
+
group: Group | null;
|
|
99
111
|
baseURL: Options['baseURL'] | undefined;
|
|
100
112
|
dataReturnType: NonNullable<Options['dataReturnType']>;
|
|
101
113
|
pathParamsType: NonNullable<NonNullable<Options['pathParamsType']>>;
|
|
@@ -126,7 +138,7 @@ type Props = {
|
|
|
126
138
|
* TypeScript resolver for resolving param/data/response type names
|
|
127
139
|
*/
|
|
128
140
|
resolver: ResolverTs;
|
|
129
|
-
baseURL: string | undefined;
|
|
141
|
+
baseURL: string | null | undefined;
|
|
130
142
|
dataReturnType: PluginCypress['resolvedOptions']['dataReturnType'];
|
|
131
143
|
paramsCasing: PluginCypress['resolvedOptions']['paramsCasing'];
|
|
132
144
|
paramsType: PluginCypress['resolvedOptions']['paramsType'];
|
|
@@ -144,27 +156,39 @@ declare function Request({
|
|
|
144
156
|
}: Props): KubbReactNode;
|
|
145
157
|
//#endregion
|
|
146
158
|
//#region src/generators/cypressGenerator.d.ts
|
|
159
|
+
/**
|
|
160
|
+
* Built-in generator for `@kubb/plugin-cypress`. Emits one typed
|
|
161
|
+
* `cy.request()` wrapper per OpenAPI operation, ready to call inside Cypress
|
|
162
|
+
* test specs and custom commands.
|
|
163
|
+
*/
|
|
147
164
|
declare const cypressGenerator: _$_kubb_core0.Generator<PluginCypress, unknown>;
|
|
148
165
|
//#endregion
|
|
149
166
|
//#region src/plugin.d.ts
|
|
150
167
|
/**
|
|
151
|
-
* Canonical plugin name for `@kubb/plugin-cypress
|
|
152
|
-
*
|
|
168
|
+
* Canonical plugin name for `@kubb/plugin-cypress`. Used for driver lookups and
|
|
169
|
+
* cross-plugin dependency references.
|
|
153
170
|
*/
|
|
154
171
|
declare const pluginCypressName = "plugin-cypress";
|
|
155
172
|
/**
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* Walks operations, delegates rendering to the active generators,
|
|
160
|
-
* and writes barrel files based on `output.barrelType`.
|
|
173
|
+
* Generates one typed `cy.request()` wrapper per OpenAPI operation. Each helper
|
|
174
|
+
* has typed path params, body, query, and a typed response, so failing API
|
|
175
|
+
* calls in Cypress show up at compile time instead of inside the test runner.
|
|
161
176
|
*
|
|
162
177
|
* @example
|
|
163
178
|
* ```ts
|
|
164
|
-
* import
|
|
179
|
+
* import { defineConfig } from 'kubb'
|
|
180
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
181
|
+
* import { pluginCypress } from '@kubb/plugin-cypress'
|
|
165
182
|
*
|
|
166
183
|
* export default defineConfig({
|
|
167
|
-
*
|
|
184
|
+
* input: { path: './petStore.yaml' },
|
|
185
|
+
* output: { path: './src/gen' },
|
|
186
|
+
* plugins: [
|
|
187
|
+
* pluginTs(),
|
|
188
|
+
* pluginCypress({
|
|
189
|
+
* output: { path: './cypress' },
|
|
190
|
+
* }),
|
|
191
|
+
* ],
|
|
168
192
|
* })
|
|
169
193
|
* ```
|
|
170
194
|
*/
|
|
@@ -172,12 +196,16 @@ declare const pluginCypress: (options?: Options | undefined) => _$_kubb_core0.Pl
|
|
|
172
196
|
//#endregion
|
|
173
197
|
//#region src/resolvers/resolverCypress.d.ts
|
|
174
198
|
/**
|
|
175
|
-
*
|
|
199
|
+
* Default resolver used by `@kubb/plugin-cypress`. Decides the names and file
|
|
200
|
+
* paths for every generated `cy.request()` wrapper. Functions and files use
|
|
201
|
+
* camelCase, matching the convention from `@kubb/plugin-client`.
|
|
176
202
|
*
|
|
177
|
-
*
|
|
203
|
+
* @example Resolve a helper name
|
|
204
|
+
* ```ts
|
|
205
|
+
* import { resolverCypress } from '@kubb/plugin-cypress'
|
|
178
206
|
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
207
|
+
* resolverCypress.default('list pets', 'function') // 'listPets'
|
|
208
|
+
* ```
|
|
181
209
|
*/
|
|
182
210
|
declare const resolverCypress: ResolverCypress;
|
|
183
211
|
//#endregion
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
2
|
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
3
3
|
import { functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
4
|
-
import { File, Function,
|
|
4
|
+
import { File, Function, jsxRendererSync } from "@kubb/renderer-jsx";
|
|
5
5
|
import { jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
|
|
6
6
|
//#region ../../internals/utils/src/casing.ts
|
|
7
7
|
/**
|
|
@@ -214,16 +214,16 @@ var URLPath = class {
|
|
|
214
214
|
get object() {
|
|
215
215
|
return this.toObject();
|
|
216
216
|
}
|
|
217
|
-
/** Returns a map of path parameter names, or `
|
|
217
|
+
/** Returns a map of path parameter names, or `null` when the path has no parameters.
|
|
218
218
|
*
|
|
219
219
|
* @example
|
|
220
220
|
* ```ts
|
|
221
221
|
* new URLPath('/pet/{petId}').params // { petId: 'petId' }
|
|
222
|
-
* new URLPath('/pet').params //
|
|
222
|
+
* new URLPath('/pet').params // null
|
|
223
223
|
* ```
|
|
224
224
|
*/
|
|
225
225
|
get params() {
|
|
226
|
-
return this.
|
|
226
|
+
return this.toParamsObject();
|
|
227
227
|
}
|
|
228
228
|
#transformParam(raw) {
|
|
229
229
|
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
@@ -241,7 +241,7 @@ var URLPath = class {
|
|
|
241
241
|
toObject({ type = "path", replacer, stringify } = {}) {
|
|
242
242
|
const object = {
|
|
243
243
|
url: type === "path" ? this.toURLPath() : this.toTemplateString({ replacer }),
|
|
244
|
-
params: this.
|
|
244
|
+
params: this.toParamsObject()
|
|
245
245
|
};
|
|
246
246
|
if (stringify) {
|
|
247
247
|
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
@@ -257,12 +257,13 @@ var URLPath = class {
|
|
|
257
257
|
* @example
|
|
258
258
|
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
259
259
|
*/
|
|
260
|
-
toTemplateString({ prefix
|
|
261
|
-
|
|
260
|
+
toTemplateString({ prefix, replacer } = {}) {
|
|
261
|
+
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
262
262
|
if (i % 2 === 0) return part;
|
|
263
263
|
const param = this.#transformParam(part);
|
|
264
264
|
return `\${${replacer ? replacer(param) : param}}`;
|
|
265
|
-
}).join("")
|
|
265
|
+
}).join("");
|
|
266
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
266
267
|
}
|
|
267
268
|
/**
|
|
268
269
|
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
@@ -271,17 +272,17 @@ var URLPath = class {
|
|
|
271
272
|
*
|
|
272
273
|
* @example
|
|
273
274
|
* ```ts
|
|
274
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').
|
|
275
|
+
* new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
|
|
275
276
|
* // { petId: 'petId', tagId: 'tagId' }
|
|
276
277
|
* ```
|
|
277
278
|
*/
|
|
278
|
-
|
|
279
|
+
toParamsObject(replacer) {
|
|
279
280
|
const params = {};
|
|
280
281
|
this.#eachParam((_raw, param) => {
|
|
281
282
|
const key = replacer ? replacer(param) : param;
|
|
282
283
|
params[key] = key;
|
|
283
284
|
});
|
|
284
|
-
return Object.keys(params).length > 0 ? params :
|
|
285
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
285
286
|
}
|
|
286
287
|
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
287
288
|
*
|
|
@@ -295,6 +296,63 @@ var URLPath = class {
|
|
|
295
296
|
}
|
|
296
297
|
};
|
|
297
298
|
//#endregion
|
|
299
|
+
//#region ../../internals/shared/src/operation.ts
|
|
300
|
+
function getOperationParameters(node, options = {}) {
|
|
301
|
+
const params = ast.caseParams(node.parameters, options.paramsCasing);
|
|
302
|
+
return {
|
|
303
|
+
path: params.filter((param) => param.in === "path"),
|
|
304
|
+
query: params.filter((param) => param.in === "query"),
|
|
305
|
+
header: params.filter((param) => param.in === "header"),
|
|
306
|
+
cookie: params.filter((param) => param.in === "cookie")
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function getStatusCodeNumber(statusCode) {
|
|
310
|
+
const code = Number(statusCode);
|
|
311
|
+
return Number.isNaN(code) ? null : code;
|
|
312
|
+
}
|
|
313
|
+
function isErrorStatusCode(statusCode) {
|
|
314
|
+
const code = getStatusCodeNumber(statusCode);
|
|
315
|
+
return code !== null && code >= 400;
|
|
316
|
+
}
|
|
317
|
+
function resolveErrorNames(node, resolver) {
|
|
318
|
+
return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
319
|
+
}
|
|
320
|
+
function resolveStatusCodeNames(node, resolver) {
|
|
321
|
+
return node.responses.map((response) => resolver.resolveResponseStatusName(node, response.statusCode));
|
|
322
|
+
}
|
|
323
|
+
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
324
|
+
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
325
|
+
const cacheKey = `${node.operationId}\0${options.paramsCasing ?? ""}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${(options.exclude ?? []).join(",")}`;
|
|
326
|
+
let byResolver = typeNamesByResolver.get(resolver);
|
|
327
|
+
if (byResolver) {
|
|
328
|
+
const cached = byResolver.get(cacheKey);
|
|
329
|
+
if (cached) return cached;
|
|
330
|
+
} else {
|
|
331
|
+
byResolver = /* @__PURE__ */ new Map();
|
|
332
|
+
typeNamesByResolver.set(resolver, byResolver);
|
|
333
|
+
}
|
|
334
|
+
const { path, query, header } = getOperationParameters(node, { paramsCasing: options.paramsCasing });
|
|
335
|
+
const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
|
|
336
|
+
const exclude = new Set(options.exclude ?? []);
|
|
337
|
+
const paramNames = [
|
|
338
|
+
...path.map((param) => resolver.resolvePathParamsName(node, param)),
|
|
339
|
+
...query.map((param) => resolver.resolveQueryParamsName(node, param)),
|
|
340
|
+
...header.map((param) => resolver.resolveHeaderParamsName(node, param))
|
|
341
|
+
];
|
|
342
|
+
const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.resolveDataName(node) : null, resolver.resolveResponseName(node)];
|
|
343
|
+
const result = (options.order === "body-response-first" ? [
|
|
344
|
+
...bodyAndResponseNames,
|
|
345
|
+
...paramNames,
|
|
346
|
+
...responseStatusNames
|
|
347
|
+
] : [
|
|
348
|
+
...paramNames,
|
|
349
|
+
...bodyAndResponseNames,
|
|
350
|
+
...responseStatusNames
|
|
351
|
+
]).filter((name) => Boolean(name) && !exclude.has(name));
|
|
352
|
+
byResolver.set(cacheKey, result);
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
//#endregion
|
|
298
356
|
//#region src/components/Request.tsx
|
|
299
357
|
const declarationPrinter = functionPrinter({ mode: "declaration" });
|
|
300
358
|
function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsType, pathParamsType, paramsCasing }) {
|
|
@@ -315,24 +373,24 @@ function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsTyp
|
|
|
315
373
|
const paramsSignature = declarationPrinter.print(paramsNode) ?? "";
|
|
316
374
|
const responseType = resolver.resolveResponseName(node);
|
|
317
375
|
const returnType = dataReturnType === "data" ? `Cypress.Chainable<${responseType}>` : `Cypress.Chainable<Cypress.Response<${responseType}>>`;
|
|
318
|
-
const casedPathParams =
|
|
376
|
+
const casedPathParams = getOperationParameters(node, { paramsCasing }).path;
|
|
319
377
|
const pathParamNameMap = new Map(casedPathParams.map((p) => [camelCase(p.name), p.name]));
|
|
320
378
|
const urlTemplate = new URLPath(node.path, { casing: paramsCasing }).toTemplateString({
|
|
321
379
|
prefix: baseURL,
|
|
322
380
|
replacer: (param) => pathParamNameMap.get(camelCase(param)) ?? param
|
|
323
381
|
});
|
|
324
382
|
const requestOptions = [`method: '${node.method}'`, `url: ${urlTemplate}`];
|
|
325
|
-
const queryParams = node
|
|
383
|
+
const queryParams = getOperationParameters(node).query;
|
|
326
384
|
if (queryParams.length > 0) {
|
|
327
|
-
const casedQueryParams =
|
|
385
|
+
const casedQueryParams = getOperationParameters(node, { paramsCasing }).query;
|
|
328
386
|
if (casedQueryParams.some((p, i) => p.name !== queryParams[i].name)) {
|
|
329
387
|
const pairs = queryParams.map((orig, i) => `${orig.name}: params.${casedQueryParams[i].name}`).join(", ");
|
|
330
388
|
requestOptions.push(`qs: params ? { ${pairs} } : undefined`);
|
|
331
389
|
} else requestOptions.push("qs: params");
|
|
332
390
|
}
|
|
333
|
-
const headerParams = node
|
|
391
|
+
const headerParams = getOperationParameters(node).header;
|
|
334
392
|
if (headerParams.length > 0) {
|
|
335
|
-
const casedHeaderParams =
|
|
393
|
+
const casedHeaderParams = getOperationParameters(node, { paramsCasing }).header;
|
|
336
394
|
if (casedHeaderParams.some((p, i) => p.name !== headerParams[i].name)) {
|
|
337
395
|
const pairs = headerParams.map((orig, i) => `'${orig.name}': headers.${casedHeaderParams[i].name}`).join(", ");
|
|
338
396
|
requestOptions.push(`headers: headers ? { ${pairs} } : undefined`);
|
|
@@ -359,26 +417,21 @@ function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsTyp
|
|
|
359
417
|
}
|
|
360
418
|
//#endregion
|
|
361
419
|
//#region src/generators/cypressGenerator.tsx
|
|
420
|
+
/**
|
|
421
|
+
* Built-in generator for `@kubb/plugin-cypress`. Emits one typed
|
|
422
|
+
* `cy.request()` wrapper per OpenAPI operation, ready to call inside Cypress
|
|
423
|
+
* test specs and custom commands.
|
|
424
|
+
*/
|
|
362
425
|
const cypressGenerator = defineGenerator({
|
|
363
426
|
name: "cypress",
|
|
364
|
-
renderer:
|
|
427
|
+
renderer: jsxRendererSync,
|
|
365
428
|
operation(node, ctx) {
|
|
366
|
-
const {
|
|
429
|
+
const { config, resolver, driver, root } = ctx;
|
|
367
430
|
const { output, baseURL, dataReturnType, paramsCasing, paramsType, pathParamsType, group } = ctx.options;
|
|
368
431
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
369
432
|
if (!pluginTs) return null;
|
|
370
433
|
const tsResolver = driver.getResolver(pluginTsName);
|
|
371
|
-
const
|
|
372
|
-
const pathParams = casedParams.filter((p) => p.in === "path");
|
|
373
|
-
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
374
|
-
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
375
|
-
const importedTypeNames = [
|
|
376
|
-
...pathParams.map((p) => tsResolver.resolvePathParamsName(node, p)),
|
|
377
|
-
...queryParams.map((p) => tsResolver.resolveQueryParamsName(node, p)),
|
|
378
|
-
...headerParams.map((p) => tsResolver.resolveHeaderParamsName(node, p)),
|
|
379
|
-
node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : void 0,
|
|
380
|
-
tsResolver.resolveResponseName(node)
|
|
381
|
-
].filter(Boolean);
|
|
434
|
+
const importedTypeNames = resolveOperationTypeNames(node, tsResolver, { paramsCasing });
|
|
382
435
|
const meta = {
|
|
383
436
|
name: resolver.resolveName(node.operationId),
|
|
384
437
|
file: resolver.resolveFile({
|
|
@@ -389,7 +442,7 @@ const cypressGenerator = defineGenerator({
|
|
|
389
442
|
}, {
|
|
390
443
|
root,
|
|
391
444
|
output,
|
|
392
|
-
group
|
|
445
|
+
group: group ?? void 0
|
|
393
446
|
}),
|
|
394
447
|
fileTs: tsResolver.resolveFile({
|
|
395
448
|
name: node.operationId,
|
|
@@ -399,23 +452,31 @@ const cypressGenerator = defineGenerator({
|
|
|
399
452
|
}, {
|
|
400
453
|
root,
|
|
401
454
|
output: pluginTs.options?.output ?? output,
|
|
402
|
-
group: pluginTs.options?.group
|
|
455
|
+
group: pluginTs.options?.group ?? void 0
|
|
403
456
|
})
|
|
404
457
|
};
|
|
405
458
|
return /* @__PURE__ */ jsxs(File, {
|
|
406
459
|
baseName: meta.file.baseName,
|
|
407
460
|
path: meta.file.path,
|
|
408
461
|
meta: meta.file.meta,
|
|
409
|
-
banner: resolver.resolveBanner(
|
|
462
|
+
banner: resolver.resolveBanner(ctx.meta, {
|
|
410
463
|
output,
|
|
411
|
-
config
|
|
464
|
+
config,
|
|
465
|
+
file: {
|
|
466
|
+
path: meta.file.path,
|
|
467
|
+
baseName: meta.file.baseName
|
|
468
|
+
}
|
|
412
469
|
}),
|
|
413
|
-
footer: resolver.resolveFooter(
|
|
470
|
+
footer: resolver.resolveFooter(ctx.meta, {
|
|
414
471
|
output,
|
|
415
|
-
config
|
|
472
|
+
config,
|
|
473
|
+
file: {
|
|
474
|
+
path: meta.file.path,
|
|
475
|
+
baseName: meta.file.baseName
|
|
476
|
+
}
|
|
416
477
|
}),
|
|
417
478
|
children: [meta.fileTs && importedTypeNames.length > 0 && /* @__PURE__ */ jsx(File.Import, {
|
|
418
|
-
name:
|
|
479
|
+
name: importedTypeNames,
|
|
419
480
|
root: meta.file.path,
|
|
420
481
|
path: meta.fileTs.path,
|
|
421
482
|
isTypeOnly: true
|
|
@@ -435,43 +496,57 @@ const cypressGenerator = defineGenerator({
|
|
|
435
496
|
//#endregion
|
|
436
497
|
//#region src/resolvers/resolverCypress.ts
|
|
437
498
|
/**
|
|
438
|
-
*
|
|
499
|
+
* Default resolver used by `@kubb/plugin-cypress`. Decides the names and file
|
|
500
|
+
* paths for every generated `cy.request()` wrapper. Functions and files use
|
|
501
|
+
* camelCase, matching the convention from `@kubb/plugin-client`.
|
|
439
502
|
*
|
|
440
|
-
*
|
|
503
|
+
* @example Resolve a helper name
|
|
504
|
+
* ```ts
|
|
505
|
+
* import { resolverCypress } from '@kubb/plugin-cypress'
|
|
441
506
|
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
507
|
+
* resolverCypress.default('list pets', 'function') // 'listPets'
|
|
508
|
+
* ```
|
|
444
509
|
*/
|
|
445
|
-
const resolverCypress = defineResolver((
|
|
510
|
+
const resolverCypress = defineResolver(() => ({
|
|
446
511
|
name: "default",
|
|
447
512
|
pluginName: "plugin-cypress",
|
|
448
513
|
default(name, type) {
|
|
449
514
|
return camelCase(name, { isFile: type === "file" });
|
|
450
515
|
},
|
|
451
516
|
resolveName(name) {
|
|
452
|
-
return
|
|
517
|
+
return this.default(name, "function");
|
|
518
|
+
},
|
|
519
|
+
resolvePathName(name, type) {
|
|
520
|
+
return this.default(name, type);
|
|
453
521
|
}
|
|
454
522
|
}));
|
|
455
523
|
//#endregion
|
|
456
524
|
//#region src/plugin.ts
|
|
457
525
|
/**
|
|
458
|
-
* Canonical plugin name for `@kubb/plugin-cypress
|
|
459
|
-
*
|
|
526
|
+
* Canonical plugin name for `@kubb/plugin-cypress`. Used for driver lookups and
|
|
527
|
+
* cross-plugin dependency references.
|
|
460
528
|
*/
|
|
461
529
|
const pluginCypressName = "plugin-cypress";
|
|
462
530
|
/**
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
* Walks operations, delegates rendering to the active generators,
|
|
467
|
-
* and writes barrel files based on `output.barrelType`.
|
|
531
|
+
* Generates one typed `cy.request()` wrapper per OpenAPI operation. Each helper
|
|
532
|
+
* has typed path params, body, query, and a typed response, so failing API
|
|
533
|
+
* calls in Cypress show up at compile time instead of inside the test runner.
|
|
468
534
|
*
|
|
469
535
|
* @example
|
|
470
536
|
* ```ts
|
|
471
|
-
* import
|
|
537
|
+
* import { defineConfig } from 'kubb'
|
|
538
|
+
* import { pluginTs } from '@kubb/plugin-ts'
|
|
539
|
+
* import { pluginCypress } from '@kubb/plugin-cypress'
|
|
472
540
|
*
|
|
473
541
|
* export default defineConfig({
|
|
474
|
-
*
|
|
542
|
+
* input: { path: './petStore.yaml' },
|
|
543
|
+
* output: { path: './src/gen' },
|
|
544
|
+
* plugins: [
|
|
545
|
+
* pluginTs(),
|
|
546
|
+
* pluginCypress({
|
|
547
|
+
* output: { path: './cypress' },
|
|
548
|
+
* }),
|
|
549
|
+
* ],
|
|
475
550
|
* })
|
|
476
551
|
* ```
|
|
477
552
|
*/
|
|
@@ -486,7 +561,7 @@ const pluginCypress = definePlugin((options) => {
|
|
|
486
561
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
487
562
|
return `${camelCase(ctx.group)}Requests`;
|
|
488
563
|
}
|
|
489
|
-
} :
|
|
564
|
+
} : null;
|
|
490
565
|
return {
|
|
491
566
|
name: pluginCypressName,
|
|
492
567
|
options,
|