@kubb/plugin-cypress 5.0.0-beta.42 → 5.0.0-beta.64
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/dist/index.cjs +100 -157
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -14
- package/dist/index.js +101 -158
- package/dist/index.js.map +1 -1
- package/package.json +8 -16
- package/extension.yaml +0 -908
- package/src/components/Request.tsx +0 -113
- package/src/generators/cypressGenerator.tsx +0 -69
- package/src/index.ts +0 -9
- package/src/plugin.ts +0 -90
- package/src/resolvers/resolverCypress.ts +0 -29
- package/src/types.ts +0 -127
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperties(exports, {
|
|
|
4
4
|
});
|
|
5
5
|
//#endregion
|
|
6
6
|
let _kubb_core = require("@kubb/core");
|
|
7
|
+
let _kubb_ast_utils = require("@kubb/ast/utils");
|
|
7
8
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
8
9
|
let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
|
|
9
10
|
let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
@@ -18,36 +19,45 @@ let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
|
|
|
18
19
|
function toCamelOrPascal(text, pascal) {
|
|
19
20
|
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
20
21
|
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
21
|
-
|
|
22
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
22
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
23
23
|
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* Converts `text` to camelCase.
|
|
27
|
+
*
|
|
28
|
+
* @example Word boundaries
|
|
29
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
29
30
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
31
|
+
* @example With a prefix
|
|
32
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
32
33
|
*/
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
34
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
35
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
36
36
|
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../../internals/utils/src/fs.ts
|
|
37
39
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
41
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
42
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
40
43
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
45
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
46
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
47
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
48
|
+
*
|
|
49
|
+
* @example Nested path from a dotted name
|
|
50
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
51
|
+
*
|
|
52
|
+
* @example PascalCase the final segment
|
|
53
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
54
|
+
*
|
|
55
|
+
* @example Suffix applied to the final segment only
|
|
56
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
44
57
|
*/
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
suffix
|
|
49
|
-
} : {}));
|
|
50
|
-
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
58
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
59
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
60
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
51
61
|
}
|
|
52
62
|
//#endregion
|
|
53
63
|
//#region ../../internals/utils/src/reserved.ts
|
|
@@ -153,99 +163,80 @@ function isValidVarName(name) {
|
|
|
153
163
|
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
154
164
|
}
|
|
155
165
|
//#endregion
|
|
156
|
-
//#region ../../internals/utils/src/
|
|
166
|
+
//#region ../../internals/utils/src/url.ts
|
|
167
|
+
function transformParam(raw, casing) {
|
|
168
|
+
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
169
|
+
return casing === "camelcase" ? camelCase(param) : param;
|
|
170
|
+
}
|
|
171
|
+
function toParamsObject(path, { replacer, casing } = {}) {
|
|
172
|
+
const params = {};
|
|
173
|
+
for (const match of path.matchAll(/\{([^}]+)\}/g)) {
|
|
174
|
+
const param = transformParam(match[1], casing);
|
|
175
|
+
const key = replacer ? replacer(param) : param;
|
|
176
|
+
params[key] = key;
|
|
177
|
+
}
|
|
178
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
179
|
+
}
|
|
157
180
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* @example
|
|
161
|
-
* const p = new URLPath('/pet/{petId}')
|
|
162
|
-
* p.URL // '/pet/:petId'
|
|
163
|
-
* p.template // '`/pet/${petId}`'
|
|
181
|
+
* Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
|
|
164
182
|
*/
|
|
165
|
-
var
|
|
183
|
+
var Url = class Url {
|
|
166
184
|
/**
|
|
167
|
-
*
|
|
168
|
-
*/
|
|
169
|
-
path;
|
|
170
|
-
#options;
|
|
171
|
-
constructor(path, options = {}) {
|
|
172
|
-
this.path = path;
|
|
173
|
-
this.#options = options;
|
|
174
|
-
}
|
|
175
|
-
/** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.
|
|
185
|
+
* Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
|
|
176
186
|
*
|
|
177
187
|
* @example
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
* ```
|
|
188
|
+
* Url.canParse('https://petstore.swagger.io/v2') // true
|
|
189
|
+
* Url.canParse('/pet/{petId}') // false
|
|
181
190
|
*/
|
|
182
|
-
|
|
183
|
-
return
|
|
191
|
+
static canParse(url, base) {
|
|
192
|
+
return URL.canParse(url, base);
|
|
184
193
|
}
|
|
185
|
-
/**
|
|
194
|
+
/**
|
|
195
|
+
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
186
196
|
*
|
|
187
197
|
* @example
|
|
188
|
-
*
|
|
189
|
-
* new URLPath('https://petstore.swagger.io/v2/pet').isURL // true
|
|
190
|
-
* new URLPath('/pet/{petId}').isURL // false
|
|
191
|
-
* ```
|
|
198
|
+
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
192
199
|
*/
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return !!new URL(this.path).href;
|
|
196
|
-
} catch {
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
200
|
+
static toPath(path) {
|
|
201
|
+
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
199
202
|
}
|
|
200
203
|
/**
|
|
201
|
-
* Converts
|
|
204
|
+
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
205
|
+
* `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
|
|
206
|
+
* and `casing` controls parameter identifier casing.
|
|
202
207
|
*
|
|
203
208
|
* @example
|
|
204
|
-
*
|
|
205
|
-
* new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'
|
|
206
|
-
*/
|
|
207
|
-
get template() {
|
|
208
|
-
return this.toTemplateString();
|
|
209
|
-
}
|
|
210
|
-
/** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.
|
|
209
|
+
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
211
210
|
*
|
|
212
211
|
* @example
|
|
213
|
-
*
|
|
214
|
-
* new URLPath('/pet/{petId}').object
|
|
215
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
216
|
-
* ```
|
|
212
|
+
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
217
213
|
*/
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
static toTemplateString(path, { prefix, replacer, casing } = {}) {
|
|
215
|
+
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
216
|
+
if (i % 2 === 0) return part;
|
|
217
|
+
const param = transformParam(part, casing);
|
|
218
|
+
return `\${${replacer ? replacer(param) : param}}`;
|
|
219
|
+
}).join("");
|
|
220
|
+
return `\`${prefix ?? ""}${result}\``;
|
|
220
221
|
}
|
|
221
|
-
/**
|
|
222
|
+
/**
|
|
223
|
+
* Returns the path and its extracted params as a structured `URLObject`, or as a stringified
|
|
224
|
+
* expression when `stringify` is set.
|
|
222
225
|
*
|
|
223
226
|
* @example
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* new URLPath('/pet').params // null
|
|
227
|
-
* ```
|
|
228
|
-
*/
|
|
229
|
-
get params() {
|
|
230
|
-
return this.toParamsObject();
|
|
231
|
-
}
|
|
232
|
-
#transformParam(raw) {
|
|
233
|
-
const param = isValidVarName(raw) ? raw : camelCase(raw);
|
|
234
|
-
return this.#options.casing === "camelcase" ? camelCase(param) : param;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.
|
|
227
|
+
* Url.toObject('/pet/{petId}')
|
|
228
|
+
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
238
229
|
*/
|
|
239
|
-
|
|
240
|
-
for (const match of this.path.matchAll(/\{([^}]+)\}/g)) {
|
|
241
|
-
const raw = match[1];
|
|
242
|
-
fn(raw, this.#transformParam(raw));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
toObject({ type = "path", replacer, stringify } = {}) {
|
|
230
|
+
static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
|
|
246
231
|
const object = {
|
|
247
|
-
url: type === "path" ?
|
|
248
|
-
|
|
232
|
+
url: type === "path" ? Url.toPath(path) : Url.toTemplateString(path, {
|
|
233
|
+
replacer,
|
|
234
|
+
casing
|
|
235
|
+
}),
|
|
236
|
+
params: toParamsObject(path, {
|
|
237
|
+
replacer,
|
|
238
|
+
casing
|
|
239
|
+
})
|
|
249
240
|
};
|
|
250
241
|
if (stringify) {
|
|
251
242
|
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
@@ -254,55 +245,11 @@ var URLPath = class {
|
|
|
254
245
|
}
|
|
255
246
|
return object;
|
|
256
247
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Converts the OpenAPI path to a TypeScript template literal string.
|
|
259
|
-
* An optional `replacer` can transform each extracted parameter name before interpolation.
|
|
260
|
-
*
|
|
261
|
-
* @example
|
|
262
|
-
* new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'
|
|
263
|
-
*/
|
|
264
|
-
toTemplateString({ prefix, replacer } = {}) {
|
|
265
|
-
const result = this.path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
266
|
-
if (i % 2 === 0) return part;
|
|
267
|
-
const param = this.#transformParam(part);
|
|
268
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
269
|
-
}).join("");
|
|
270
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Extracts all `{param}` segments from the path and returns them as a key-value map.
|
|
274
|
-
* An optional `replacer` transforms each parameter name in both key and value positions.
|
|
275
|
-
* Returns `undefined` when no path parameters are found.
|
|
276
|
-
*
|
|
277
|
-
* @example
|
|
278
|
-
* ```ts
|
|
279
|
-
* new URLPath('/pet/{petId}/tag/{tagId}').toParamsObject()
|
|
280
|
-
* // { petId: 'petId', tagId: 'tagId' }
|
|
281
|
-
* ```
|
|
282
|
-
*/
|
|
283
|
-
toParamsObject(replacer) {
|
|
284
|
-
const params = {};
|
|
285
|
-
this.#eachParam((_raw, param) => {
|
|
286
|
-
const key = replacer ? replacer(param) : param;
|
|
287
|
-
params[key] = key;
|
|
288
|
-
});
|
|
289
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
290
|
-
}
|
|
291
|
-
/** Converts the OpenAPI path to Express-style colon syntax.
|
|
292
|
-
*
|
|
293
|
-
* @example
|
|
294
|
-
* ```ts
|
|
295
|
-
* new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'
|
|
296
|
-
* ```
|
|
297
|
-
*/
|
|
298
|
-
toURLPath() {
|
|
299
|
-
return this.path.replace(/\{([^}]+)\}/g, ":$1");
|
|
300
|
-
}
|
|
301
248
|
};
|
|
302
249
|
//#endregion
|
|
303
250
|
//#region ../../internals/shared/src/operation.ts
|
|
304
251
|
function getOperationParameters(node, options = {}) {
|
|
305
|
-
const params =
|
|
252
|
+
const params = (0, _kubb_ast_utils.caseParams)(node.parameters, options.paramsCasing);
|
|
306
253
|
return {
|
|
307
254
|
path: params.filter((param) => param.in === "path"),
|
|
308
255
|
query: params.filter((param) => param.in === "query"),
|
|
@@ -363,26 +310,24 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
363
310
|
* shared default naming so every plugin groups output consistently:
|
|
364
311
|
*
|
|
365
312
|
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
366
|
-
* - other groups use
|
|
313
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
367
314
|
*
|
|
368
315
|
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
369
316
|
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
370
317
|
* per-plugin convention.
|
|
371
318
|
*
|
|
372
319
|
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
373
|
-
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
374
320
|
*
|
|
375
321
|
* @example
|
|
376
322
|
* ```ts
|
|
377
|
-
* createGroupConfig(group
|
|
378
|
-
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
323
|
+
* createGroupConfig(group) // shared across every plugin
|
|
379
324
|
* ```
|
|
380
325
|
*/
|
|
381
|
-
function createGroupConfig(group
|
|
326
|
+
function createGroupConfig(group) {
|
|
382
327
|
if (!group) return null;
|
|
383
328
|
const defaultName = (ctx) => {
|
|
384
329
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
385
|
-
return
|
|
330
|
+
return camelCase(ctx.group);
|
|
386
331
|
};
|
|
387
332
|
return {
|
|
388
333
|
...group,
|
|
@@ -394,17 +339,14 @@ function createGroupConfig(group, options) {
|
|
|
394
339
|
const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
|
|
395
340
|
function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsType, pathParamsType, paramsCasing }) {
|
|
396
341
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
397
|
-
const paramsNode =
|
|
342
|
+
const paramsNode = (0, _kubb_ast_utils.createOperationParams)(node, {
|
|
398
343
|
paramsType,
|
|
399
344
|
pathParamsType,
|
|
400
345
|
paramsCasing,
|
|
401
346
|
resolver,
|
|
402
|
-
extraParams: [_kubb_core.ast.createFunctionParameter({
|
|
347
|
+
extraParams: [_kubb_core.ast.factory.createFunctionParameter({
|
|
403
348
|
name: "options",
|
|
404
|
-
type:
|
|
405
|
-
variant: "reference",
|
|
406
|
-
name: "Partial<Cypress.RequestOptions>"
|
|
407
|
-
}),
|
|
349
|
+
type: "Partial<Cypress.RequestOptions>",
|
|
408
350
|
default: "{}"
|
|
409
351
|
})]
|
|
410
352
|
});
|
|
@@ -413,9 +355,10 @@ function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsTyp
|
|
|
413
355
|
const returnType = dataReturnType === "data" ? `Cypress.Chainable<${responseType}>` : `Cypress.Chainable<Cypress.Response<${responseType}>>`;
|
|
414
356
|
const casedPathParams = getOperationParameters(node, { paramsCasing }).path;
|
|
415
357
|
const pathParamNameMap = new Map(casedPathParams.map((p) => [camelCase(p.name), p.name]));
|
|
416
|
-
const urlTemplate =
|
|
358
|
+
const urlTemplate = Url.toTemplateString(node.path, {
|
|
417
359
|
prefix: baseURL,
|
|
418
|
-
replacer: (param) => pathParamNameMap.get(camelCase(param)) ?? param
|
|
360
|
+
replacer: (param) => pathParamNameMap.get(camelCase(param)) ?? param,
|
|
361
|
+
casing: paramsCasing
|
|
419
362
|
});
|
|
420
363
|
const requestOptions = [`method: '${node.method}'`, `url: ${urlTemplate}`];
|
|
421
364
|
const queryParams = getOperationParameters(node).query;
|
|
@@ -462,7 +405,7 @@ function Request({ baseURL = "", name, dataReturnType, resolver, node, paramsTyp
|
|
|
462
405
|
*/
|
|
463
406
|
const cypressGenerator = (0, _kubb_core.defineGenerator)({
|
|
464
407
|
name: "cypress",
|
|
465
|
-
renderer: _kubb_renderer_jsx.
|
|
408
|
+
renderer: _kubb_renderer_jsx.jsxRenderer,
|
|
466
409
|
operation(node, ctx) {
|
|
467
410
|
if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
|
|
468
411
|
const { config, resolver, driver, root } = ctx;
|
|
@@ -550,7 +493,7 @@ const resolverCypress = (0, _kubb_core.defineResolver)(() => ({
|
|
|
550
493
|
name: "default",
|
|
551
494
|
pluginName: "plugin-cypress",
|
|
552
495
|
default(name, type) {
|
|
553
|
-
return
|
|
496
|
+
return type === "file" ? toFilePath(name) : camelCase(name);
|
|
554
497
|
},
|
|
555
498
|
resolveName(name) {
|
|
556
499
|
return this.default(name, "function");
|
|
@@ -592,9 +535,9 @@ const pluginCypressName = "plugin-cypress";
|
|
|
592
535
|
const pluginCypress = (0, _kubb_core.definePlugin)((options) => {
|
|
593
536
|
const { output = {
|
|
594
537
|
path: "cypress",
|
|
595
|
-
|
|
596
|
-
}, group, exclude = [], include, override = [], dataReturnType = "data", baseURL, paramsCasing, paramsType = "inline", pathParamsType = paramsType === "object" ? "object" : options.pathParamsType || "inline", resolver: userResolver,
|
|
597
|
-
const groupConfig = createGroupConfig(group
|
|
538
|
+
barrel: { type: "named" }
|
|
539
|
+
}, group, exclude = [], include, override = [], dataReturnType = "data", baseURL, paramsCasing, paramsType = "inline", pathParamsType = paramsType === "object" ? "object" : options.pathParamsType || "inline", resolver: userResolver, macros: userMacros, generators: userGenerators = [] } = options;
|
|
540
|
+
const groupConfig = createGroupConfig(group);
|
|
598
541
|
return {
|
|
599
542
|
name: pluginCypressName,
|
|
600
543
|
options,
|
|
@@ -618,7 +561,7 @@ const pluginCypress = (0, _kubb_core.definePlugin)((options) => {
|
|
|
618
561
|
resolver
|
|
619
562
|
});
|
|
620
563
|
ctx.setResolver(resolver);
|
|
621
|
-
if (
|
|
564
|
+
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
622
565
|
ctx.addGenerator(cypressGenerator);
|
|
623
566
|
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
624
567
|
} }
|