@kubb/plugin-msw 5.0.0-beta.56 → 5.0.0-beta.73

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 CHANGED
@@ -2,11 +2,39 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_components = require("./components-Bp69JYOt.cjs");
6
- const require_generators = require("./generators-d22_s2UN.cjs");
5
+ //#endregion
7
6
  let _kubb_core = require("@kubb/core");
8
7
  let _kubb_plugin_faker = require("@kubb/plugin-faker");
9
8
  let _kubb_plugin_ts = require("@kubb/plugin-ts");
9
+ let _kubb_renderer_jsx = require("@kubb/renderer-jsx");
10
+ let _kubb_renderer_jsx_jsx_runtime = require("@kubb/renderer-jsx/jsx-runtime");
11
+ //#region ../../internals/utils/src/casing.ts
12
+ /**
13
+ * Shared implementation for camelCase and PascalCase conversion.
14
+ * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
15
+ * and capitalizes each word according to `pascal`.
16
+ *
17
+ * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
18
+ */
19
+ function toCamelOrPascal(text, pascal) {
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) => {
21
+ if (word.length > 1 && word === word.toUpperCase()) return word;
22
+ return (i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()) + word.slice(1);
23
+ }).join("").replace(/[^a-zA-Z0-9]/g, "");
24
+ }
25
+ /**
26
+ * Converts `text` to camelCase.
27
+ *
28
+ * @example Word boundaries
29
+ * `camelCase('hello-world') // 'helloWorld'`
30
+ *
31
+ * @example With a prefix
32
+ * `camelCase('tag', { prefix: 'create' }) // 'createTag'`
33
+ */
34
+ function camelCase(text, { prefix = "", suffix = "" } = {}) {
35
+ return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
36
+ }
37
+ //#endregion
10
38
  //#region ../../internals/utils/src/fs.ts
11
39
  /**
12
40
  * Builds a nested file path from a dotted name. Splits on dots that precede a letter
@@ -27,9 +55,244 @@ let _kubb_plugin_ts = require("@kubb/plugin-ts");
27
55
  * @example Suffix applied to the final segment only
28
56
  * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
29
57
  */
30
- function toFilePath(name, caseLast = require_components.camelCase) {
58
+ function toFilePath(name, caseLast = camelCase) {
31
59
  const parts = name.split(/\.(?=[a-zA-Z])/);
32
- return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : require_components.camelCase(part)).filter(Boolean).join("/");
60
+ return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
61
+ }
62
+ //#endregion
63
+ //#region ../../internals/utils/src/reserved.ts
64
+ /**
65
+ * JavaScript and Java reserved words.
66
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
67
+ */
68
+ const reservedWords = new Set([
69
+ "abstract",
70
+ "arguments",
71
+ "boolean",
72
+ "break",
73
+ "byte",
74
+ "case",
75
+ "catch",
76
+ "char",
77
+ "class",
78
+ "const",
79
+ "continue",
80
+ "debugger",
81
+ "default",
82
+ "delete",
83
+ "do",
84
+ "double",
85
+ "else",
86
+ "enum",
87
+ "eval",
88
+ "export",
89
+ "extends",
90
+ "false",
91
+ "final",
92
+ "finally",
93
+ "float",
94
+ "for",
95
+ "function",
96
+ "goto",
97
+ "if",
98
+ "implements",
99
+ "import",
100
+ "in",
101
+ "instanceof",
102
+ "int",
103
+ "interface",
104
+ "let",
105
+ "long",
106
+ "native",
107
+ "new",
108
+ "null",
109
+ "package",
110
+ "private",
111
+ "protected",
112
+ "public",
113
+ "return",
114
+ "short",
115
+ "static",
116
+ "super",
117
+ "switch",
118
+ "synchronized",
119
+ "this",
120
+ "throw",
121
+ "throws",
122
+ "transient",
123
+ "true",
124
+ "try",
125
+ "typeof",
126
+ "var",
127
+ "void",
128
+ "volatile",
129
+ "while",
130
+ "with",
131
+ "yield",
132
+ "Array",
133
+ "Date",
134
+ "hasOwnProperty",
135
+ "Infinity",
136
+ "isFinite",
137
+ "isNaN",
138
+ "isPrototypeOf",
139
+ "length",
140
+ "Math",
141
+ "name",
142
+ "NaN",
143
+ "Number",
144
+ "Object",
145
+ "prototype",
146
+ "String",
147
+ "toString",
148
+ "undefined",
149
+ "valueOf"
150
+ ]);
151
+ /**
152
+ * Returns `true` when `name` is a syntactically valid JavaScript variable name.
153
+ *
154
+ * @example
155
+ * ```ts
156
+ * isValidVarName('status') // true
157
+ * isValidVarName('class') // false (reserved word)
158
+ * isValidVarName('42foo') // false (starts with digit)
159
+ * ```
160
+ */
161
+ function isValidVarName(name) {
162
+ if (!name || reservedWords.has(name)) return false;
163
+ return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
164
+ }
165
+ //#endregion
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
+ }
180
+ /**
181
+ * Helpers for OpenAPI/Swagger paths, plus a thin wrapper over the native `URL`.
182
+ */
183
+ var Url = class Url {
184
+ /**
185
+ * Reports whether `url` is a parseable absolute URL. Delegates to the native `URL.canParse`.
186
+ *
187
+ * @example
188
+ * Url.canParse('https://petstore.swagger.io/v2') // true
189
+ * Url.canParse('/pet/{petId}') // false
190
+ */
191
+ static canParse(url, base) {
192
+ return URL.canParse(url, base);
193
+ }
194
+ /**
195
+ * Converts an OpenAPI/Swagger path to Express-style colon syntax.
196
+ *
197
+ * @example
198
+ * Url.toPath('/pet/{petId}') // '/pet/:petId'
199
+ */
200
+ static toPath(path) {
201
+ return path.replace(/\{([^}]+)\}/g, ":$1");
202
+ }
203
+ /**
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.
207
+ *
208
+ * @example
209
+ * Url.toTemplateString('/pet/{petId}') // '`/pet/${petId}`'
210
+ *
211
+ * @example
212
+ * Url.toTemplateString('/pet/{petId}', { prefix: 'https://api' }) // '`https://api/pet/${petId}`'
213
+ */
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}\``;
221
+ }
222
+ /**
223
+ * Converts an OpenAPI/Swagger path to a template literal that reads each parameter off the
224
+ * grouped `path` request option, e.g. `/pet/{petId}` becomes `` `/pet/${path.petId}` ``. Parameter
225
+ * names are camelCased to match the generated `path` type, and `prefix` is prepended inside the
226
+ * literal. Shared by the client and cypress generators that pass a grouped `path` object.
227
+ *
228
+ * @example
229
+ * Url.toGroupedTemplateString('/pet/{petId}') // '`/pet/${path.petId}`'
230
+ */
231
+ static toGroupedTemplateString(path, { prefix } = {}) {
232
+ return Url.toTemplateString(path, {
233
+ prefix,
234
+ casing: "camelcase",
235
+ replacer: (name) => `path.${name}`
236
+ });
237
+ }
238
+ /**
239
+ * Returns the path and its extracted params as a structured `URLObject`, or as a stringified
240
+ * expression when `stringify` is set.
241
+ *
242
+ * @example
243
+ * Url.toObject('/pet/{petId}')
244
+ * // { url: '/pet/:petId', params: { petId: 'petId' } }
245
+ */
246
+ static toObject(path, { type = "path", replacer, stringify, casing } = {}) {
247
+ const object = {
248
+ url: type === "path" ? Url.toPath(path) : Url.toTemplateString(path, {
249
+ replacer,
250
+ casing
251
+ }),
252
+ params: toParamsObject(path, {
253
+ replacer,
254
+ casing
255
+ })
256
+ };
257
+ if (stringify) {
258
+ if (type === "template") return JSON.stringify(object).replaceAll("'", "").replaceAll(`"`, "");
259
+ if (object.params) return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", "").replaceAll(`"`, "")} }`;
260
+ return `{ url: '${object.url}' }`;
261
+ }
262
+ return object;
263
+ }
264
+ };
265
+ //#endregion
266
+ //#region ../../internals/shared/src/operation.ts
267
+ function getStatusCodeNumber(statusCode) {
268
+ const code = Number(statusCode);
269
+ return Number.isNaN(code) ? null : code;
270
+ }
271
+ function isSuccessStatusCode(statusCode) {
272
+ const code = getStatusCodeNumber(statusCode);
273
+ return code !== null && code >= 200 && code < 300;
274
+ }
275
+ function getSuccessResponses(responses) {
276
+ return responses.filter((response) => isSuccessStatusCode(response.statusCode));
277
+ }
278
+ function getOperationSuccessResponses(node) {
279
+ return getSuccessResponses(node.responses);
280
+ }
281
+ function getPrimarySuccessResponse(node) {
282
+ return getOperationSuccessResponses(node)[0] ?? null;
283
+ }
284
+ function resolveResponseTypes(node, resolver) {
285
+ const types = [];
286
+ for (const response of node.responses) {
287
+ if (response.statusCode === "default") {
288
+ types.push(["default", resolver.resolveResponseName(node)]);
289
+ continue;
290
+ }
291
+ const code = getStatusCodeNumber(response.statusCode);
292
+ if (code === null) continue;
293
+ types.push([code, isSuccessStatusCode(code) ? resolver.resolveResponseName(node) : resolver.resolveResponseStatusName(node, response.statusCode)]);
294
+ }
295
+ return types;
33
296
  }
34
297
  //#endregion
35
298
  //#region ../../internals/shared/src/group.ts
@@ -55,7 +318,7 @@ function createGroupConfig(group) {
55
318
  if (!group) return null;
56
319
  const defaultName = (ctx) => {
57
320
  if (group.type === "path") return `${ctx.group.split("/")[1]}`;
58
- return require_components.camelCase(ctx.group);
321
+ return camelCase(ctx.group);
59
322
  };
60
323
  return {
61
324
  ...group,
@@ -63,6 +326,372 @@ function createGroupConfig(group) {
63
326
  };
64
327
  }
65
328
  //#endregion
329
+ //#region src/generators/handlersGenerator.ts
330
+ /**
331
+ * Aggregate generator enabled by `pluginMsw({ handlers: true })`. Emits a
332
+ * `handlers.ts` file that re-exports every generated handler grouped by HTTP
333
+ * method, ready to spread into `setupServer(...handlers)` or
334
+ * `setupWorker(...handlers)`.
335
+ */
336
+ const handlersGenerator = (0, _kubb_core.defineGenerator)({
337
+ name: "plugin-msw",
338
+ operations(nodes, ctx) {
339
+ const { resolver, config, root } = ctx;
340
+ const { output, group } = ctx.options;
341
+ const handlersName = resolver.resolveHandlersName();
342
+ const file = resolver.resolveFile({
343
+ name: resolver.resolvePathName(handlersName, "file"),
344
+ extname: ".ts"
345
+ }, {
346
+ root,
347
+ output,
348
+ group: group ?? void 0
349
+ });
350
+ const imports = nodes.map((node) => {
351
+ const operationName = resolver.resolveHandlerName(node);
352
+ const operationFile = resolver.resolveFile({
353
+ name: resolver.resolveName(node.operationId),
354
+ extname: ".ts",
355
+ tag: node.tags[0] ?? "default",
356
+ path: node.path
357
+ }, {
358
+ root,
359
+ output,
360
+ group: group ?? void 0
361
+ });
362
+ return _kubb_core.ast.factory.createImport({
363
+ name: [operationName],
364
+ root: file.path,
365
+ path: operationFile.path
366
+ });
367
+ });
368
+ const handlers = nodes.map((node) => `${resolver.resolveHandlerName(node)}()`);
369
+ return [_kubb_core.ast.factory.createFile({
370
+ baseName: file.baseName,
371
+ path: file.path,
372
+ meta: file.meta,
373
+ banner: resolver.resolveBanner(ctx.meta, {
374
+ output,
375
+ config,
376
+ file: {
377
+ path: file.path,
378
+ baseName: file.baseName
379
+ }
380
+ }),
381
+ footer: resolver.resolveFooter(ctx.meta, {
382
+ output,
383
+ config,
384
+ file: {
385
+ path: file.path,
386
+ baseName: file.baseName
387
+ }
388
+ }),
389
+ imports,
390
+ sources: [_kubb_core.ast.factory.createSource({
391
+ name: handlersName,
392
+ isIndexable: true,
393
+ isExportable: true,
394
+ nodes: [_kubb_core.ast.factory.createText(`export const ${handlersName} = ${JSON.stringify(handlers).replaceAll("\"", "")} as const`)]
395
+ })]
396
+ })];
397
+ }
398
+ });
399
+ //#endregion
400
+ //#region src/utils.ts
401
+ /**
402
+ * Gets the content type from a response, defaulting to 'application/json' if a schema exists.
403
+ */
404
+ function getContentType(response) {
405
+ if (!hasResponseSchema(response)) return null;
406
+ return getResponseContentType(response) ?? "application/json";
407
+ }
408
+ /**
409
+ * Determines if a response has a schema that is not void or any.
410
+ */
411
+ function hasResponseSchema(response) {
412
+ const schema = response?.content?.find((entry) => entry.schema)?.schema;
413
+ return !!schema && schema.type !== "void" && schema.type !== "any";
414
+ }
415
+ /**
416
+ * Picks the content type used for the mocked response header. When a response declares multiple
417
+ * content types, JSON is preferred (the faker mock body is JSON), otherwise the first declared type.
418
+ */
419
+ function getResponseContentType(response) {
420
+ const contents = response?.content ?? [];
421
+ const value = (contents.find((entry) => {
422
+ const baseType = entry.contentType?.split(";")[0]?.trim().toLowerCase();
423
+ return baseType === "application/json" || baseType?.endsWith("+json");
424
+ }) ?? contents[0])?.contentType;
425
+ return typeof value === "string" && value.length > 0 ? value : null;
426
+ }
427
+ /**
428
+ * Converts an HTTP method to its lowercase MSW equivalent (e.g., 'POST' → 'post').
429
+ */
430
+ function getMswMethod(node) {
431
+ return _kubb_core.ast.isHttpOperationNode(node) ? node.method.toLowerCase() : "";
432
+ }
433
+ /**
434
+ * Converts an OpenAPI-style path to an Express/MSW-style path by replacing `{param}` with `:param`.
435
+ */
436
+ function getMswUrl(node) {
437
+ return _kubb_core.ast.isHttpOperationNode(node) ? node.path.replaceAll("{", ":").replaceAll("}", "") : "";
438
+ }
439
+ /**
440
+ * Resolves faker metadata for an MSW operation, including response name and file path.
441
+ */
442
+ function resolveFakerMeta(node, options) {
443
+ const { root, fakerResolver, fakerOutput, fakerGroup } = options;
444
+ const tag = node.tags[0] ?? "default";
445
+ return {
446
+ name: fakerResolver.resolveResponseName(node),
447
+ file: fakerResolver.resolveFile({
448
+ name: node.operationId,
449
+ extname: ".ts",
450
+ tag,
451
+ path: node.path
452
+ }, {
453
+ root,
454
+ output: fakerOutput,
455
+ group: fakerGroup ?? void 0
456
+ })
457
+ };
458
+ }
459
+ //#endregion
460
+ //#region src/components/Mock.tsx
461
+ const declarationPrinter$2 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
462
+ function Mock({ baseURL = "", name, typeName, requestTypeName, node }) {
463
+ const method = getMswMethod(node);
464
+ const successResponse = getPrimarySuccessResponse(node);
465
+ const statusCode = successResponse ? Number(successResponse.statusCode) : 200;
466
+ const contentType = getContentType(successResponse);
467
+ const url = Url.toPath(getMswUrl(node));
468
+ const headers = [contentType ? `'Content-Type': '${contentType}'` : null].filter(Boolean);
469
+ const dataType = hasResponseSchema(successResponse) ? typeName : "string | number | boolean | null | object";
470
+ const callbackType = requestTypeName ? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>` : `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`;
471
+ const params = declarationPrinter$2.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
472
+ name: "data",
473
+ type: `${dataType} | ${callbackType}`,
474
+ optional: true
475
+ })] }));
476
+ const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`;
477
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
478
+ name,
479
+ isIndexable: true,
480
+ isExportable: true,
481
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
482
+ name,
483
+ export: true,
484
+ params: params ?? "",
485
+ children: `return ${httpCall}(\`${baseURL}${url.replace(/([^/]):/g, "$1\\\\:")}\`, function handler(info) {
486
+ if(typeof data === 'function') return data(info)
487
+
488
+ return new Response(JSON.stringify(data), {
489
+ status: ${statusCode},
490
+ ${headers.length ? ` headers: {
491
+ ${headers.join(", \n")}
492
+ },` : ""}
493
+ })
494
+ })`
495
+ })
496
+ });
497
+ }
498
+ //#endregion
499
+ //#region src/components/MockWithFaker.tsx
500
+ const declarationPrinter$1 = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
501
+ function MockWithFaker({ baseURL = "", name, fakerName, typeName, requestTypeName, node }) {
502
+ const method = getMswMethod(node);
503
+ const successResponse = getPrimarySuccessResponse(node);
504
+ const statusCode = successResponse ? Number(successResponse.statusCode) : 200;
505
+ const contentType = getContentType(successResponse);
506
+ const url = Url.toPath(getMswUrl(node));
507
+ const headers = [contentType ? `'Content-Type': '${contentType}'` : null].filter(Boolean);
508
+ const callbackType = requestTypeName ? `HttpResponseResolver<Record<string, string>, ${requestTypeName}, any>` : `((info: Parameters<Parameters<typeof http.${method}>[1]>[0]) => Response | Promise<Response>)`;
509
+ const params = declarationPrinter$1.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
510
+ name: "data",
511
+ type: `${typeName} | ${callbackType}`,
512
+ optional: true
513
+ })] }));
514
+ const httpCall = requestTypeName ? `http.${method}<Record<string, string>, ${requestTypeName}, any>` : `http.${method}`;
515
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
516
+ name,
517
+ isIndexable: true,
518
+ isExportable: true,
519
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
520
+ name,
521
+ export: true,
522
+ params: params ?? "",
523
+ children: `return ${httpCall}('${baseURL}${url.replace(/([^/]):/g, "$1\\\\:")}', function handler(info) {
524
+ if(typeof data === 'function') return data(info)
525
+
526
+ return new Response(JSON.stringify(data || ${fakerName}(data)), {
527
+ status: ${statusCode},
528
+ ${headers.length ? ` headers: {
529
+ ${headers.join(", \n")}
530
+ },` : ""}
531
+ })
532
+ })`
533
+ })
534
+ });
535
+ }
536
+ //#endregion
537
+ //#region src/components/Response.tsx
538
+ const declarationPrinter = (0, _kubb_plugin_ts.functionPrinter)({ mode: "declaration" });
539
+ function Response({ name, typeName, response }) {
540
+ const statusCode = Number(response.statusCode);
541
+ const contentType = getContentType(response);
542
+ const headers = [contentType ? `'Content-Type': '${contentType}'` : null].filter(Boolean);
543
+ const params = declarationPrinter.print((0, _kubb_plugin_ts.createFunctionParameters)({ params: [(0, _kubb_plugin_ts.createFunctionParameter)({
544
+ name: "data",
545
+ type: typeName,
546
+ optional: !hasResponseSchema(response)
547
+ })] }));
548
+ const responseName = `${name}Response${statusCode}`;
549
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Source, {
550
+ name: responseName,
551
+ isIndexable: true,
552
+ isExportable: true,
553
+ children: /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.Function, {
554
+ name: responseName,
555
+ export: true,
556
+ params: params ?? "",
557
+ children: `
558
+ return new Response(JSON.stringify(data), {
559
+ status: ${statusCode},
560
+ ${headers.length ? ` headers: {
561
+ ${headers.join(", \n")}
562
+ },` : ""}
563
+ })`
564
+ })
565
+ });
566
+ }
567
+ //#endregion
568
+ //#region src/generators/mswGenerator.tsx
569
+ /**
570
+ * Built-in operation generator for `@kubb/plugin-msw`. Emits one MSW handler
571
+ * per OpenAPI operation. With `parser: 'faker'` the handler returns a value
572
+ * from `@kubb/plugin-faker`; with `parser: 'data'` it returns a typed empty
573
+ * payload for tests to fill in.
574
+ */
575
+ const mswGenerator = (0, _kubb_core.defineGenerator)({
576
+ name: "msw",
577
+ renderer: _kubb_renderer_jsx.jsxRenderer,
578
+ operation(node, ctx) {
579
+ if (!_kubb_core.ast.isHttpOperationNode(node)) return null;
580
+ const { driver, resolver, config, root } = ctx;
581
+ const { output, parser, baseURL, group } = ctx.options;
582
+ const fileName = resolver.resolveName(node.operationId);
583
+ const mock = {
584
+ name: resolver.resolveHandlerName(node),
585
+ file: resolver.resolveFile({
586
+ name: fileName,
587
+ extname: ".ts",
588
+ tag: node.tags[0] ?? "default",
589
+ path: node.path
590
+ }, {
591
+ root,
592
+ output,
593
+ group: group ?? void 0
594
+ })
595
+ };
596
+ const fakerPlugin = parser === "faker" ? driver.getPlugin(_kubb_plugin_faker.pluginFakerName) : null;
597
+ const faker = parser === "faker" && fakerPlugin ? resolveFakerMeta(node, {
598
+ root,
599
+ fakerResolver: driver.getResolver(_kubb_plugin_faker.pluginFakerName),
600
+ fakerOutput: fakerPlugin.options?.output ?? output,
601
+ fakerGroup: fakerPlugin.options?.group ?? null
602
+ }) : null;
603
+ const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
604
+ if (!pluginTs) return null;
605
+ const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
606
+ const type = {
607
+ file: tsResolver.resolveFile({
608
+ name: node.operationId,
609
+ extname: ".ts",
610
+ tag: node.tags[0] ?? "default",
611
+ path: node.path
612
+ }, {
613
+ root,
614
+ output: pluginTs.options?.output ?? output,
615
+ group: pluginTs.options?.group ?? void 0
616
+ }),
617
+ responseName: tsResolver.resolveResponseName(node)
618
+ };
619
+ const types = resolveResponseTypes(node, tsResolver);
620
+ const hasSuccessSchema = getOperationSuccessResponses(node).some((response) => !!response.content?.[0]?.schema);
621
+ const requestName = node.requestBody?.content?.[0]?.schema ? tsResolver.resolveDataName(node) : null;
622
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsxs)(_kubb_renderer_jsx.File, {
623
+ baseName: mock.file.baseName,
624
+ path: mock.file.path,
625
+ meta: mock.file.meta,
626
+ banner: resolver.resolveBanner(ctx.meta, {
627
+ output,
628
+ config,
629
+ file: {
630
+ path: mock.file.path,
631
+ baseName: mock.file.baseName
632
+ }
633
+ }),
634
+ footer: resolver.resolveFooter(ctx.meta, {
635
+ output,
636
+ config,
637
+ file: {
638
+ path: mock.file.path,
639
+ baseName: mock.file.baseName
640
+ }
641
+ }),
642
+ children: [
643
+ /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
644
+ name: ["http"],
645
+ path: "msw"
646
+ }),
647
+ /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
648
+ name: ["HttpResponseResolver"],
649
+ isTypeOnly: true,
650
+ path: "msw"
651
+ }),
652
+ /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
653
+ name: Array.from(new Set([
654
+ type.responseName,
655
+ ...types.map((t) => t[1]),
656
+ ...requestName ? [requestName] : []
657
+ ])),
658
+ path: type.file.path,
659
+ root: mock.file.path,
660
+ isTypeOnly: true
661
+ }),
662
+ parser === "faker" && faker && /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(_kubb_renderer_jsx.File.Import, {
663
+ name: [faker.name],
664
+ root: mock.file.path,
665
+ path: faker.file.path
666
+ }),
667
+ types.filter(([code]) => code !== "default").map(([code, typeName]) => {
668
+ const response = node.responses.find((item) => item.statusCode === String(code));
669
+ if (!response) return null;
670
+ return /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Response, {
671
+ typeName,
672
+ response,
673
+ name: mock.name
674
+ }, typeName);
675
+ }),
676
+ parser === "faker" && faker && hasSuccessSchema ? /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(MockWithFaker, {
677
+ name: mock.name,
678
+ typeName: type.responseName,
679
+ requestTypeName: requestName,
680
+ fakerName: faker.name,
681
+ node,
682
+ baseURL
683
+ }) : /* @__PURE__ */ (0, _kubb_renderer_jsx_jsx_runtime.jsx)(Mock, {
684
+ name: mock.name,
685
+ typeName: type.responseName,
686
+ requestTypeName: requestName,
687
+ node,
688
+ baseURL
689
+ })
690
+ ]
691
+ });
692
+ }
693
+ });
694
+ //#endregion
66
695
  //#region src/resolvers/resolverMsw.ts
67
696
  /**
68
697
  * Default resolver used by `@kubb/plugin-msw`. Decides the names and file
@@ -80,10 +709,10 @@ const resolverMsw = (0, _kubb_core.defineResolver)(() => ({
80
709
  name: "default",
81
710
  pluginName: "plugin-msw",
82
711
  default(name, type) {
83
- return type === "file" ? toFilePath(name) : require_components.camelCase(name);
712
+ return type === "file" ? toFilePath(name) : camelCase(name);
84
713
  },
85
714
  resolveName(name) {
86
- return require_components.camelCase(name, { suffix: "handler" });
715
+ return camelCase(name, { suffix: "handler" });
87
716
  },
88
717
  resolvePathName(name, type) {
89
718
  return this.default(name, type);
@@ -132,7 +761,7 @@ const pluginMsw = (0, _kubb_core.definePlugin)((options) => {
132
761
  const { output = {
133
762
  path: "handlers",
134
763
  barrel: { type: "named" }
135
- }, group, exclude = [], include, override = [], handlers = false, parser = "data", baseURL, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
764
+ }, group, exclude = [], include, override = [], handlers = false, parser = "data", baseURL, resolver: userResolver, macros: userMacros } = options;
136
765
  const groupConfig = createGroupConfig(group);
137
766
  return {
138
767
  name: pluginMswName,
@@ -155,10 +784,9 @@ const pluginMsw = (0, _kubb_core.definePlugin)((options) => {
155
784
  resolver
156
785
  });
157
786
  ctx.setResolver(resolver);
158
- if (userTransformer) ctx.setTransformer(userTransformer);
159
- ctx.addGenerator(require_generators.mswGenerator);
160
- if (handlers) ctx.addGenerator(require_generators.handlersGenerator);
161
- for (const gen of userGenerators) ctx.addGenerator(gen);
787
+ if (userMacros?.length) ctx.setMacros(userMacros);
788
+ ctx.addGenerator(mswGenerator);
789
+ if (handlers) ctx.addGenerator(handlersGenerator);
162
790
  } }
163
791
  };
164
792
  });