@kubb/plugin-cypress 5.0.0-beta.98 → 5.0.0
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 +93 -333
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +93 -333
- package/dist/index.js.map +1 -1
- package/package.json +4 -7
package/dist/index.js
CHANGED
|
@@ -1,333 +1,67 @@
|
|
|
1
1
|
import "./rolldown-runtime-C0LytTxp.js";
|
|
2
|
-
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
2
|
+
import { Resolver, Url, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
3
3
|
import { File, Function, jsxRenderer } from "kubb/jsx";
|
|
4
4
|
import { jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
5
5
|
import { pluginTsName } from "@kubb/plugin-ts";
|
|
6
|
-
//#region ../../internals/
|
|
7
|
-
/**
|
|
8
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
9
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
10
|
-
* and capitalizes each word according to `pascal`.
|
|
11
|
-
*
|
|
12
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
13
|
-
*/
|
|
14
|
-
function toCamelOrPascal(text, pascal) {
|
|
15
|
-
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) => {
|
|
16
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
17
|
-
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
18
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
19
|
-
}
|
|
6
|
+
//#region ../../internals/shared/src/params.ts
|
|
20
7
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @example Word boundaries
|
|
24
|
-
* `camelCase('hello-world') // 'helloWorld'`
|
|
8
|
+
* Drops parameters that share the same name, keeping the first.
|
|
25
9
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
10
|
+
* A malformed spec can declare the same parameter name twice within one `in` location. Both would
|
|
11
|
+
* resolve to the same output property, so emitting both would yield an object type with a duplicate
|
|
12
|
+
* member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:
|
|
13
|
+
* parameter names flow through unchanged, so no two distinct names ever collide here anymore.
|
|
28
14
|
*/
|
|
29
|
-
function
|
|
30
|
-
|
|
15
|
+
function dedupeParams(params) {
|
|
16
|
+
const seen = /* @__PURE__ */ new Set();
|
|
17
|
+
return params.filter((param) => {
|
|
18
|
+
if (seen.has(param.name)) return false;
|
|
19
|
+
seen.add(param.name);
|
|
20
|
+
return true;
|
|
21
|
+
});
|
|
31
22
|
}
|
|
32
23
|
//#endregion
|
|
33
|
-
//#region ../../internals/
|
|
34
|
-
/**
|
|
35
|
-
* JavaScript and Java reserved words.
|
|
36
|
-
* @link https://github.com/jonschlinkert/reserved/blob/master/index.js
|
|
37
|
-
*/
|
|
38
|
-
const reservedWords = /* @__PURE__ */ new Set([
|
|
39
|
-
"abstract",
|
|
40
|
-
"arguments",
|
|
41
|
-
"boolean",
|
|
42
|
-
"break",
|
|
43
|
-
"byte",
|
|
44
|
-
"case",
|
|
45
|
-
"catch",
|
|
46
|
-
"char",
|
|
47
|
-
"class",
|
|
48
|
-
"const",
|
|
49
|
-
"continue",
|
|
50
|
-
"debugger",
|
|
51
|
-
"default",
|
|
52
|
-
"delete",
|
|
53
|
-
"do",
|
|
54
|
-
"double",
|
|
55
|
-
"else",
|
|
56
|
-
"enum",
|
|
57
|
-
"eval",
|
|
58
|
-
"export",
|
|
59
|
-
"extends",
|
|
60
|
-
"false",
|
|
61
|
-
"final",
|
|
62
|
-
"finally",
|
|
63
|
-
"float",
|
|
64
|
-
"for",
|
|
65
|
-
"function",
|
|
66
|
-
"goto",
|
|
67
|
-
"if",
|
|
68
|
-
"implements",
|
|
69
|
-
"import",
|
|
70
|
-
"in",
|
|
71
|
-
"instanceof",
|
|
72
|
-
"int",
|
|
73
|
-
"interface",
|
|
74
|
-
"let",
|
|
75
|
-
"long",
|
|
76
|
-
"native",
|
|
77
|
-
"new",
|
|
78
|
-
"null",
|
|
79
|
-
"package",
|
|
80
|
-
"private",
|
|
81
|
-
"protected",
|
|
82
|
-
"public",
|
|
83
|
-
"return",
|
|
84
|
-
"short",
|
|
85
|
-
"static",
|
|
86
|
-
"super",
|
|
87
|
-
"switch",
|
|
88
|
-
"synchronized",
|
|
89
|
-
"this",
|
|
90
|
-
"throw",
|
|
91
|
-
"throws",
|
|
92
|
-
"transient",
|
|
93
|
-
"true",
|
|
94
|
-
"try",
|
|
95
|
-
"typeof",
|
|
96
|
-
"var",
|
|
97
|
-
"void",
|
|
98
|
-
"volatile",
|
|
99
|
-
"while",
|
|
100
|
-
"with",
|
|
101
|
-
"yield",
|
|
102
|
-
"Array",
|
|
103
|
-
"Date",
|
|
104
|
-
"hasOwnProperty",
|
|
105
|
-
"Infinity",
|
|
106
|
-
"isFinite",
|
|
107
|
-
"isNaN",
|
|
108
|
-
"isPrototypeOf",
|
|
109
|
-
"length",
|
|
110
|
-
"Math",
|
|
111
|
-
"name",
|
|
112
|
-
"NaN",
|
|
113
|
-
"Number",
|
|
114
|
-
"Object",
|
|
115
|
-
"prototype",
|
|
116
|
-
"String",
|
|
117
|
-
"toString",
|
|
118
|
-
"undefined",
|
|
119
|
-
"valueOf"
|
|
120
|
-
]);
|
|
24
|
+
//#region ../../internals/shared/src/operation.ts
|
|
121
25
|
/**
|
|
122
|
-
*
|
|
26
|
+
* Builds the `ResolverFileParams` every operation generator passes to
|
|
27
|
+
* `resolver.file`: a file named `name`, tagged by the operation's first
|
|
28
|
+
* tag (or `'default'`), at the operation's path. Centralizes the entry object
|
|
29
|
+
* that was repeated at dozens of call sites across the client and query plugins.
|
|
123
30
|
*
|
|
124
31
|
* @example
|
|
125
32
|
* ```ts
|
|
126
|
-
*
|
|
127
|
-
* isValidVarName('class') // false (reserved word)
|
|
128
|
-
* isValidVarName('42foo') // false (starts with digit)
|
|
33
|
+
* resolver.file(operationFileEntry(node, node.operationId), { root, output, group })
|
|
129
34
|
* ```
|
|
130
35
|
*/
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
|
|
36
|
+
function operationFileEntry(node, name, extname = ".ts") {
|
|
37
|
+
return {
|
|
38
|
+
name,
|
|
39
|
+
extname,
|
|
40
|
+
tag: node.tags[0] ?? "default",
|
|
41
|
+
path: node.path
|
|
42
|
+
};
|
|
134
43
|
}
|
|
135
44
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* deciding whether an object key needs quoting.
|
|
45
|
+
* Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the
|
|
46
|
+
* current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the
|
|
47
|
+
* same dependency for the same operation in one pass (a query plugin's several hook generators, the
|
|
48
|
+
* MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.
|
|
141
49
|
*
|
|
142
|
-
* @example
|
|
50
|
+
* @example Cache `plugin-ts`'s file for the current operation
|
|
143
51
|
* ```ts
|
|
144
|
-
*
|
|
145
|
-
* isIdentifier('x-total')// false
|
|
52
|
+
* const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })
|
|
146
53
|
* ```
|
|
147
54
|
*/
|
|
148
|
-
function
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return casing === "camelcase" ? camelCase(param) : param;
|
|
156
|
-
}
|
|
157
|
-
function toParamsObject(path, { replacer, casing } = {}) {
|
|
158
|
-
const params = {};
|
|
159
|
-
for (const match of path.matchAll(/\{([^}]+)\}/g)) {
|
|
160
|
-
const param = transformParam(match[1], casing);
|
|
161
|
-
const key = replacer ? replacer(param) : param;
|
|
162
|
-
params[key] = key;
|
|
163
|
-
}
|
|
164
|
-
return Object.keys(params).length > 0 ? params : null;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
|
|
168
|
-
*/
|
|
169
|
-
var Url = class Url {
|
|
170
|
-
/**
|
|
171
|
-
* Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
|
|
172
|
-
*
|
|
173
|
-
* @example
|
|
174
|
-
* Url.canParse('https://petstore.swagger.io/v2') // true
|
|
175
|
-
* Url.canParse('/pet/{petId}') // false
|
|
176
|
-
*/
|
|
177
|
-
static canParse(url, base) {
|
|
178
|
-
return URL.canParse(url, base);
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Converts an OpenAPI/Swagger path to Express-style colon syntax.
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* Url.toPath('/pet/{petId}') // '/pet/:petId'
|
|
185
|
-
*/
|
|
186
|
-
static toPath(path) {
|
|
187
|
-
return path.replace(/\{([^}]+)\}/g, ":$1");
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Rewrites OpenAPI placeholder names while keeping the `{...}` braces, so the generated `url`
|
|
191
|
-
* literal aligns with the grouped `path` request option that the runtime client interpolates by
|
|
192
|
-
* key.
|
|
193
|
-
*
|
|
194
|
-
* @example
|
|
195
|
-
* Url.toCasedTemplate('/projects/{project_id}', { casing: 'camelcase' }) // '/projects/{projectId}'
|
|
196
|
-
*/
|
|
197
|
-
static toCasedTemplate(path, { casing } = {}) {
|
|
198
|
-
return path.replace(/\{([^}]+)\}/g, (_, name) => `{${transformParam(name, casing)}}`);
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Converts an OpenAPI/Swagger path to a TypeScript template literal string.
|
|
202
|
-
* `prefix` is prepended inside the literal, `replacer` transforms each parameter name,
|
|
203
|
-
* and `casing` controls parameter identifier casing.
|
|
204
|
-
*
|
|
205
|
-
* @example
|
|
206
|
-
* Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
|
|
210
|
-
*/
|
|
211
|
-
static toTemplateString(path, { prefix, replacer, casing } = {}) {
|
|
212
|
-
const result = path.split(/\{([^}]+)\}/).map((part, i) => {
|
|
213
|
-
if (i % 2 === 0) return part;
|
|
214
|
-
const param = transformParam(part, casing);
|
|
215
|
-
return `\${${replacer ? replacer(param) : param}}`;
|
|
216
|
-
}).join("");
|
|
217
|
-
return `\`${prefix ?? ""}${result}\``;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
|
|
221
|
-
* grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
|
|
222
|
-
* names are camelCased to match the generated `path` type, and `prefix` is prepended inside the
|
|
223
|
-
* literal. Shared by the client and cypress generators that pass a grouped `path` object.
|
|
224
|
-
*
|
|
225
|
-
* @example
|
|
226
|
-
* Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
|
|
227
|
-
*/
|
|
228
|
-
static toGroupedTemplateString(path, { prefix } = {}) {
|
|
229
|
-
return Url.toTemplateString(path, {
|
|
230
|
-
prefix,
|
|
231
|
-
casing: "camelcase",
|
|
232
|
-
replacer: (name) => `path.${name}`
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Returns the path and its extracted params as a structured `URLObject`, or as a stringified
|
|
237
|
-
* expression when `stringify` is set.
|
|
238
|
-
*
|
|
239
|
-
* @example
|
|
240
|
-
* Url.toObject('/pet/{petId}')
|
|
241
|
-
* // { url: '/pet/:petId', params: { petId: 'petId' } }
|
|
242
|
-
*/
|
|
243
|
-
static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
|
|
244
|
-
const object = {
|
|
245
|
-
url: type === "path" ? Url.toPath(path) : Url.toTemplateString(path, {
|
|
246
|
-
replacer,
|
|
247
|
-
casing
|
|
248
|
-
}),
|
|
249
|
-
params: toParamsObject(path, {
|
|
250
|
-
replacer,
|
|
251
|
-
casing
|
|
252
|
-
})
|
|
253
|
-
};
|
|
254
|
-
if (stringify) {
|
|
255
|
-
if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
|
|
256
|
-
if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
|
|
257
|
-
return `{ url: '${object.url}' }`;
|
|
258
|
-
}
|
|
259
|
-
return object;
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
//#endregion
|
|
263
|
-
//#region ../../internals/shared/src/params.ts
|
|
264
|
-
const caseParamsCache = /* @__PURE__ */ new WeakMap();
|
|
265
|
-
/**
|
|
266
|
-
* Applies camelCase to parameter names and returns a new array without mutating the input.
|
|
267
|
-
*
|
|
268
|
-
* Run it before handing parameters to schema builders so output property keys get the right casing
|
|
269
|
-
* while `OperationNode.parameters` stays intact for other consumers. When `casing` is unset, the
|
|
270
|
-
* original array is returned unchanged. Results are cached per input array.
|
|
271
|
-
*/
|
|
272
|
-
function caseParams(params, casing) {
|
|
273
|
-
if (!casing) return params;
|
|
274
|
-
const cached = caseParamsCache.get(params);
|
|
275
|
-
if (cached) return cached;
|
|
276
|
-
const result = params.map((param) => ({
|
|
277
|
-
...param,
|
|
278
|
-
name: camelCase(param.name)
|
|
55
|
+
function resolveDependencyOperationFile(options) {
|
|
56
|
+
const { cache, node, resolver, root, output, group } = options;
|
|
57
|
+
return cache.ensureItem(`${resolver.pluginName}:operationFile`, () => resolver.file({
|
|
58
|
+
...operationFileEntry(node, node.operationId),
|
|
59
|
+
root,
|
|
60
|
+
output,
|
|
61
|
+
group: group ?? void 0
|
|
279
62
|
}));
|
|
280
|
-
caseParamsCache.set(params, result);
|
|
281
|
-
return result;
|
|
282
63
|
}
|
|
283
64
|
/**
|
|
284
|
-
* Drops parameters that collapse to the same property identity once camelCased, keeping the first.
|
|
285
|
-
*
|
|
286
|
-
* Some specs declare the same parameter twice under different casings (for example AWS S3 lists both
|
|
287
|
-
* `max-uploads` and `MaxUploads`). Both resolve to one output property, so emitting both would yield
|
|
288
|
-
* an object type with a duplicate member, which TypeScript rejects. De-duplicate by the camelCased
|
|
289
|
-
* identity so the resulting group is collision-free regardless of the names each caller carries.
|
|
290
|
-
*/
|
|
291
|
-
function dedupeByCasedName(params) {
|
|
292
|
-
const seen = /* @__PURE__ */ new Set();
|
|
293
|
-
return params.filter((param) => {
|
|
294
|
-
const key = camelCase(param.name);
|
|
295
|
-
if (seen.has(key)) return false;
|
|
296
|
-
seen.add(key);
|
|
297
|
-
return true;
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
function buildParamsMapping(originalParams, mappedParams) {
|
|
301
|
-
const mapping = {};
|
|
302
|
-
let hasChanged = false;
|
|
303
|
-
originalParams.forEach((param, i) => {
|
|
304
|
-
const mappedName = mappedParams[i]?.name ?? param.name;
|
|
305
|
-
mapping[param.name] = mappedName;
|
|
306
|
-
if (param.name !== mappedName) hasChanged = true;
|
|
307
|
-
});
|
|
308
|
-
return hasChanged ? mapping : null;
|
|
309
|
-
}
|
|
310
|
-
function toAccess(object, name) {
|
|
311
|
-
return isValidVarName(name) ? `${object}.${name}` : `${object}[${JSON.stringify(name)}]`;
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Renders the object-literal expression that renames the camelCased keys of a grouped request
|
|
315
|
-
* option back to the names the OpenAPI document declares, guarded so an omitted optional group
|
|
316
|
-
* stays omitted. Shared by the client and cypress generators, which pass a `buildParamsMapping`
|
|
317
|
-
* result and the source expression to read the keys from.
|
|
318
|
-
*
|
|
319
|
-
* @example
|
|
320
|
-
* ```ts
|
|
321
|
-
* buildParamsRemapExpression({ source: 'config.query', mapping: { include_deleted: 'includeDeleted' } })
|
|
322
|
-
* // 'config.query ? { "include_deleted": config.query.includeDeleted } : config.query'
|
|
323
|
-
* ```
|
|
324
|
-
*/
|
|
325
|
-
function buildParamsRemapExpression({ source, mapping }) {
|
|
326
|
-
return `${source} ? { ${Object.entries(mapping).map(([originalName, casedName]) => `${JSON.stringify(originalName)}: ${toAccess(source, casedName)}`).join(", ")} } : ${source}`;
|
|
327
|
-
}
|
|
328
|
-
//#endregion
|
|
329
|
-
//#region ../../internals/shared/src/operation.ts
|
|
330
|
-
/**
|
|
331
65
|
* Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several
|
|
332
66
|
* are present and the union, default, and form-data flags the client uses to pick one.
|
|
333
67
|
*/
|
|
@@ -409,14 +143,24 @@ function buildRequestParamsSignature(node, resolver, options = {}) {
|
|
|
409
143
|
groups
|
|
410
144
|
};
|
|
411
145
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
146
|
+
const operationParameterGroupsByNode = /* @__PURE__ */ new WeakMap();
|
|
147
|
+
/**
|
|
148
|
+
* Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each
|
|
149
|
+
* group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance
|
|
150
|
+
* (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the
|
|
151
|
+
* same parameters once per plugin.
|
|
152
|
+
*/
|
|
153
|
+
function getOperationParameters(node) {
|
|
154
|
+
const cached = operationParameterGroupsByNode.get(node);
|
|
155
|
+
if (cached) return cached;
|
|
156
|
+
const groups = {
|
|
157
|
+
path: dedupeParams(node.parameters.filter((param) => param.in === "path")),
|
|
158
|
+
query: dedupeParams(node.parameters.filter((param) => param.in === "query")),
|
|
159
|
+
header: dedupeParams(node.parameters.filter((param) => param.in === "header")),
|
|
160
|
+
cookie: dedupeParams(node.parameters.filter((param) => param.in === "cookie"))
|
|
419
161
|
};
|
|
162
|
+
operationParameterGroupsByNode.set(node, groups);
|
|
163
|
+
return groups;
|
|
420
164
|
}
|
|
421
165
|
function getStatusCodeNumber(statusCode) {
|
|
422
166
|
const code = Number(statusCode);
|
|
@@ -447,7 +191,7 @@ function resolveStatusCodeNames(node, resolver) {
|
|
|
447
191
|
}
|
|
448
192
|
const typeNamesByResolver = /* @__PURE__ */ new WeakMap();
|
|
449
193
|
function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
450
|
-
const cacheKey = `${node.operationId}\0${options.
|
|
194
|
+
const cacheKey = `${node.operationId}\0${options.order ?? ""}\0${options.responseStatusNames ?? ""}\0${options.includeParams === false ? "noparams" : ""}\0${(options.exclude ?? []).join(",")}`;
|
|
451
195
|
let byResolver = typeNamesByResolver.get(resolver);
|
|
452
196
|
if (byResolver) {
|
|
453
197
|
const cached = byResolver.get(cacheKey);
|
|
@@ -456,7 +200,7 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
456
200
|
byResolver = /* @__PURE__ */ new Map();
|
|
457
201
|
typeNamesByResolver.set(resolver, byResolver);
|
|
458
202
|
}
|
|
459
|
-
const { path, query, header } = getOperationParameters(node
|
|
203
|
+
const { path, query, header } = getOperationParameters(node);
|
|
460
204
|
const responseStatusNames = options.responseStatusNames === "error" ? resolveErrorNames(node, resolver) : options.responseStatusNames === false ? [] : resolveStatusCodeNames(node, resolver);
|
|
461
205
|
const exclude = new Set(options.exclude ?? []);
|
|
462
206
|
const paramNames = options.includeParams === false ? [] : [
|
|
@@ -478,6 +222,33 @@ function resolveOperationTypeNames(node, resolver, options = {}) {
|
|
|
478
222
|
return result;
|
|
479
223
|
}
|
|
480
224
|
//#endregion
|
|
225
|
+
//#region ../../internals/utils/src/casing.ts
|
|
226
|
+
/**
|
|
227
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
228
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
229
|
+
* and capitalizes each word according to `pascal`.
|
|
230
|
+
*
|
|
231
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
232
|
+
*/
|
|
233
|
+
function toCamelOrPascal(text, pascal) {
|
|
234
|
+
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) => {
|
|
235
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
236
|
+
return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
|
|
237
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Converts `text` to camelCase.
|
|
241
|
+
*
|
|
242
|
+
* @example Word boundaries
|
|
243
|
+
* `camelCase('hello-world') // 'helloWorld'`
|
|
244
|
+
*
|
|
245
|
+
* @example With a prefix
|
|
246
|
+
* `camelCase('tag', { prefix: 'create' }) // 'createTag'`
|
|
247
|
+
*/
|
|
248
|
+
function camelCase(text, { prefix = "", suffix = "" } = {}) {
|
|
249
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
481
252
|
//#region ../../internals/shared/src/group.ts
|
|
482
253
|
/**
|
|
483
254
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -512,24 +283,14 @@ function createGroupConfig(group) {
|
|
|
512
283
|
//#region src/components/Request.tsx
|
|
513
284
|
function Request({ baseURL = "", name, resolver, node }) {
|
|
514
285
|
if (!ast.isHttpOperationNode(node)) return null;
|
|
515
|
-
const { query: originalQueryParams, header: originalHeaderParams } = getOperationParameters(node, { paramsCasing: "original" });
|
|
516
|
-
const { query: casedQueryParams, header: casedHeaderParams } = getOperationParameters(node);
|
|
517
|
-
const queryParamsMapping = buildParamsMapping(originalQueryParams, casedQueryParams);
|
|
518
|
-
const headerParamsMapping = buildParamsMapping(originalHeaderParams, casedHeaderParams);
|
|
519
286
|
const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false });
|
|
520
287
|
const paramsSignature = [signature, "options: Partial<Cypress.RequestOptions> = {}"].filter(Boolean).join(", ");
|
|
521
288
|
const responseType = resolver.response.response(node);
|
|
522
289
|
const returnType = `Cypress.Chainable<${responseType}>`;
|
|
523
290
|
const urlTemplate = Url.toGroupedTemplateString(node.path, { prefix: baseURL });
|
|
524
291
|
const requestOptions = [`method: '${node.method}'`, `url: ${urlTemplate}`];
|
|
525
|
-
if (groups.query) requestOptions.push(
|
|
526
|
-
|
|
527
|
-
mapping: queryParamsMapping
|
|
528
|
-
})}` : "qs: query");
|
|
529
|
-
if (groups.headers) requestOptions.push(headerParamsMapping ? `headers: ${buildParamsRemapExpression({
|
|
530
|
-
source: "headers",
|
|
531
|
-
mapping: headerParamsMapping
|
|
532
|
-
})}` : "headers");
|
|
292
|
+
if (groups.query) requestOptions.push("qs: query");
|
|
293
|
+
if (groups.headers) requestOptions.push("headers");
|
|
533
294
|
if (groups.body) requestOptions.push("body");
|
|
534
295
|
requestOptions.push("...options");
|
|
535
296
|
const requestCall = `return cy.request<${responseType}>({
|
|
@@ -577,14 +338,13 @@ const cypressGenerator = defineGenerator({
|
|
|
577
338
|
output,
|
|
578
339
|
group: group ?? void 0
|
|
579
340
|
}),
|
|
580
|
-
fileTs:
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
path: node.path,
|
|
341
|
+
fileTs: resolveDependencyOperationFile({
|
|
342
|
+
cache: ctx.cache,
|
|
343
|
+
node,
|
|
344
|
+
resolver: tsResolver,
|
|
585
345
|
root,
|
|
586
346
|
output: pluginTs.options?.output ?? output,
|
|
587
|
-
group: pluginTs.options?.group
|
|
347
|
+
group: pluginTs.options?.group
|
|
588
348
|
})
|
|
589
349
|
};
|
|
590
350
|
return /* @__PURE__ */ jsxs(File, {
|