@kubb/plugin-msw 5.0.0-beta.42 → 5.0.0-beta.56
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/{components--3aER8iM.js → components-Bi7cN-ws.js} +63 -152
- package/dist/components-Bi7cN-ws.js.map +1 -0
- package/dist/{components-BW5VCVSO.cjs → components-Bp69JYOt.cjs} +62 -157
- package/dist/components-Bp69JYOt.cjs.map +1 -0
- package/dist/components.cjs +1 -2
- package/dist/components.d.ts +1 -14
- package/dist/components.js +2 -2
- package/dist/{generators-CLKAZMic.js → generators-BnEvTy3q.js} +14 -12
- package/dist/generators-BnEvTy3q.js.map +1 -0
- package/dist/{generators-B6qnyBTW.cjs → generators-d22_s2UN.cjs} +13 -11
- package/dist/generators-d22_s2UN.cjs.map +1 -0
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +1 -1
- package/dist/generators.js +1 -1
- package/dist/index.cjs +34 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +34 -11
- package/dist/index.js.map +1 -1
- package/dist/{types-CwhQTrui.d.ts → types-B1yTWOfj.d.ts} +9 -13
- package/package.json +8 -16
- package/src/components/Mock.tsx +2 -2
- package/src/components/MockWithFaker.tsx +2 -2
- package/src/components/index.ts +0 -1
- package/src/generators/{handlersGenerator.tsx → handlersGenerator.ts} +20 -18
- package/src/generators/index.ts +1 -1
- package/src/generators/mswGenerator.tsx +2 -2
- package/src/plugin.ts +2 -2
- package/src/resolvers/resolverMsw.ts +2 -2
- package/src/types.ts +8 -12
- package/dist/components--3aER8iM.js.map +0 -1
- package/dist/components-BW5VCVSO.cjs.map +0 -1
- package/dist/generators-B6qnyBTW.cjs.map +0 -1
- package/dist/generators-CLKAZMic.js.map +0 -1
- package/extension.yaml +0 -752
- package/src/components/Handlers.tsx +0 -19
package/dist/generators.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_generators = require("./generators-
|
|
2
|
+
const require_generators = require("./generators-d22_s2UN.cjs");
|
|
3
3
|
exports.handlersGenerator = require_generators.handlersGenerator;
|
|
4
4
|
exports.mswGenerator = require_generators.mswGenerator;
|
package/dist/generators.d.ts
CHANGED
package/dist/generators.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as handlersGenerator, t as mswGenerator } from "./generators-
|
|
1
|
+
import { n as handlersGenerator, t as mswGenerator } from "./generators-BnEvTy3q.js";
|
|
2
2
|
export { handlersGenerator, mswGenerator };
|
package/dist/index.cjs
CHANGED
|
@@ -2,37 +2,60 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_components = require("./components-
|
|
6
|
-
const require_generators = require("./generators-
|
|
5
|
+
const require_components = require("./components-Bp69JYOt.cjs");
|
|
6
|
+
const require_generators = require("./generators-d22_s2UN.cjs");
|
|
7
7
|
let _kubb_core = require("@kubb/core");
|
|
8
8
|
let _kubb_plugin_faker = require("@kubb/plugin-faker");
|
|
9
9
|
let _kubb_plugin_ts = require("@kubb/plugin-ts");
|
|
10
|
+
//#region ../../internals/utils/src/fs.ts
|
|
11
|
+
/**
|
|
12
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
13
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
14
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
15
|
+
*
|
|
16
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
17
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
18
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
19
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
20
|
+
*
|
|
21
|
+
* @example Nested path from a dotted name
|
|
22
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
23
|
+
*
|
|
24
|
+
* @example PascalCase the final segment
|
|
25
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
26
|
+
*
|
|
27
|
+
* @example Suffix applied to the final segment only
|
|
28
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
29
|
+
*/
|
|
30
|
+
function toFilePath(name, caseLast = require_components.camelCase) {
|
|
31
|
+
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("/");
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
10
35
|
//#region ../../internals/shared/src/group.ts
|
|
11
36
|
/**
|
|
12
37
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
13
38
|
* shared default naming so every plugin groups output consistently:
|
|
14
39
|
*
|
|
15
40
|
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
16
|
-
* - other groups use
|
|
41
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
17
42
|
*
|
|
18
43
|
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
19
44
|
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
20
45
|
* per-plugin convention.
|
|
21
46
|
*
|
|
22
47
|
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
23
|
-
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
24
48
|
*
|
|
25
49
|
* @example
|
|
26
50
|
* ```ts
|
|
27
|
-
* createGroupConfig(group
|
|
28
|
-
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
51
|
+
* createGroupConfig(group) // shared across every plugin
|
|
29
52
|
* ```
|
|
30
53
|
*/
|
|
31
|
-
function createGroupConfig(group
|
|
54
|
+
function createGroupConfig(group) {
|
|
32
55
|
if (!group) return null;
|
|
33
56
|
const defaultName = (ctx) => {
|
|
34
57
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
35
|
-
return
|
|
58
|
+
return require_components.camelCase(ctx.group);
|
|
36
59
|
};
|
|
37
60
|
return {
|
|
38
61
|
...group,
|
|
@@ -57,7 +80,7 @@ const resolverMsw = (0, _kubb_core.defineResolver)(() => ({
|
|
|
57
80
|
name: "default",
|
|
58
81
|
pluginName: "plugin-msw",
|
|
59
82
|
default(name, type) {
|
|
60
|
-
return
|
|
83
|
+
return type === "file" ? toFilePath(name) : require_components.camelCase(name);
|
|
61
84
|
},
|
|
62
85
|
resolveName(name) {
|
|
63
86
|
return require_components.camelCase(name, { suffix: "handler" });
|
|
@@ -108,9 +131,9 @@ const pluginMswName = "plugin-msw";
|
|
|
108
131
|
const pluginMsw = (0, _kubb_core.definePlugin)((options) => {
|
|
109
132
|
const { output = {
|
|
110
133
|
path: "handlers",
|
|
111
|
-
|
|
134
|
+
barrel: { type: "named" }
|
|
112
135
|
}, group, exclude = [], include, override = [], handlers = false, parser = "data", baseURL, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
|
|
113
|
-
const groupConfig = createGroupConfig(group
|
|
136
|
+
const groupConfig = createGroupConfig(group);
|
|
114
137
|
return {
|
|
115
138
|
name: pluginMswName,
|
|
116
139
|
options,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["camelCase","camelCase","pluginTsName","pluginFakerName","mswGenerator","handlersGenerator"],"sources":["../../../internals/shared/src/group.ts","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["camelCase","camelCase","camelCase","pluginTsName","pluginFakerName","mswGenerator","handlersGenerator"],"sources":["../../../internals/utils/src/fs.ts","../../../internals/shared/src/group.ts","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["import { posix } from 'node:path'\nimport { camelCase } from './casing.ts'\n\nfunction toSlash(p: string): string {\n if (p.startsWith('\\\\\\\\?\\\\')) return p\n return p.replaceAll('\\\\', '/')\n}\n\n/**\n * Returns the relative path from `rootDir` to `filePath`, always using forward slashes\n * and prefixed with `./` when not already traversing upward.\n *\n * @example\n * ```ts\n * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'\n * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'\n * ```\n */\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = posix.relative(toSlash(rootDir), toSlash(filePath))\n\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Builds a nested file path from a dotted name. Splits on dots that precede a letter\n * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases\n * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.\n *\n * Empty segments are dropped before joining. They arise when the name starts with a dot\n * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to\n * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an\n * absolute path, letting generated files escape the configured output directory.\n *\n * @example Nested path from a dotted name\n * `toFilePath('pet.petId') // 'pet/petId'`\n *\n * @example PascalCase the final segment\n * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`\n *\n * @example Suffix applied to the final segment only\n * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`\n */\nexport function toFilePath(name: string, caseLast: (part: string) => string = camelCase): string {\n const parts = name.split(/\\.(?=[a-zA-Z])/)\n return parts\n .map((part, i) => (i === parts.length - 1 ? caseLast(part) : camelCase(part)))\n .filter(Boolean)\n .join('/')\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { camelCase, toFilePath } from '@internals/utils'\nimport { defineResolver } from '@kubb/core'\nimport type { PluginMsw } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-msw`. Decides the names and file\n * paths for every generated MSW handler. Function names get a `Handler`\n * suffix; the aggregate export is always `handlers`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMsw } from '@kubb/plugin-msw'\n *\n * resolverMsw.resolveName('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMsw = defineResolver<PluginMsw>(() => ({\n name: 'default',\n pluginName: 'plugin-msw',\n default(name, type) {\n return type === 'file' ? toFilePath(name) : camelCase(name)\n },\n resolveName(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n resolvePathName(name, type) {\n return this.default(name, type)\n },\n resolveHandlerName(node) {\n return this.resolveName(node.operationId)\n },\n resolveHandlersName() {\n return 'handlers'\n },\n}))\n","import { createGroupConfig } from '@internals/shared'\nimport { definePlugin } from '@kubb/core'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { handlersGenerator, mswGenerator } from './generators'\nimport { resolverMsw } from './resolvers/resolverMsw.ts'\nimport type { PluginMsw } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-msw`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']\n\n/**\n * Generates MSW request handlers from an OpenAPI spec. Drop them into your\n * test setup or service worker to mock the API end-to-end. Request path,\n * method, status, and response body all stay in sync with the spec. Combine\n * with `@kubb/plugin-faker` (via `parser: 'faker'`) to seed handlers with\n * realistic data.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginMsw } from '@kubb/plugin-msw'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginMsw({\n * output: { path: './handlers' },\n * handlers: true,\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMsw = definePlugin<PluginMsw>((options) => {\n const {\n output = { path: 'handlers', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n handlers = false,\n parser = 'data',\n baseURL,\n resolver: userResolver,\n transformer: userTransformer,\n generators: userGenerators = [],\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMswName,\n options,\n dependencies: [pluginTsName, parser === 'faker' ? pluginFakerName : null].filter((dependency): dependency is string => Boolean(dependency)),\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n const resolver = userResolver ? { ...resolverMsw, ...userResolver } : resolverMsw\n\n ctx.setOptions({\n output,\n parser,\n baseURL,\n group: groupConfig,\n exclude,\n include,\n override,\n handlers,\n resolver,\n })\n ctx.setResolver(resolver)\n if (userTransformer) {\n ctx.setTransformer(userTransformer)\n }\n\n ctx.addGenerator(mswGenerator)\n if (handlers) {\n ctx.addGenerator(handlersGenerator)\n }\n for (const gen of userGenerators) {\n ctx.addGenerator(gen)\n }\n },\n },\n }\n})\n\nexport default pluginMsw\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,WAAW,MAAc,WAAqCA,mBAAAA,WAAmB;CAC/F,MAAM,QAAQ,KAAK,MAAM,gBAAgB;CACzC,OAAO,MACJ,KAAK,MAAM,MAAO,MAAM,MAAM,SAAS,IAAI,SAAS,IAAI,IAAIA,mBAAAA,UAAU,IAAI,CAAE,CAAC,CAC7E,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;AACb;;;;;;;;;;;;;;;;;;;;;AChCA,SAAgB,kBAAkB,OAAwC;CACxE,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,eAAe,QAAmC;EACtD,IAAI,MAAM,SAAS,QACjB,OAAO,GAAG,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC;EAGjC,OAAOC,mBAAAA,UAAU,IAAI,KAAK;CAC5B;CAEA,OAAO;EACL,GAAG;EACH,MAAM,MAAM,OAAO,MAAM,OAAO;CAClC;AACF;;;;;;;;;;;;;;;ACtBA,MAAa,eAAA,GAAA,WAAA,eAAA,QAA+C;CAC1D,MAAM;CACN,YAAY;CACZ,QAAQ,MAAM,MAAM;EAClB,OAAO,SAAS,SAAS,WAAW,IAAI,IAAIC,mBAAAA,UAAU,IAAI;CAC5D;CACA,YAAY,MAAM;EAChB,OAAOA,mBAAAA,UAAU,MAAM,EAAE,QAAQ,UAAU,CAAC;CAC9C;CACA,gBAAgB,MAAM,MAAM;EAC1B,OAAO,KAAK,QAAQ,MAAM,IAAI;CAChC;CACA,mBAAmB,MAAM;EACvB,OAAO,KAAK,YAAY,KAAK,WAAW;CAC1C;CACA,sBAAsB;EACpB,OAAO;CACT;AACF,EAAE;;;;;;;ACtBF,MAAa,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B7B,MAAa,aAAA,GAAA,WAAA,aAAA,EAAqC,YAAY;CAC5D,MAAM,EACJ,SAAS;EAAE,MAAM;EAAY,QAAQ,EAAE,MAAM,QAAQ;CAAE,GACvD,OACA,UAAU,CAAC,GACX,SACA,WAAW,CAAC,GACZ,WAAW,OACX,SAAS,QACT,SACA,UAAU,cACV,aAAa,iBACb,YAAY,iBAAiB,CAAC,MAC5B;CAEJ,MAAM,cAAc,kBAAkB,KAAK;CAE3C,OAAO;EACL,MAAM;EACN;EACA,cAAc,CAACC,gBAAAA,cAAc,WAAW,UAAUC,mBAAAA,kBAAkB,IAAI,CAAC,CAAC,QAAQ,eAAqC,QAAQ,UAAU,CAAC;EAC1I,OAAO,EACL,oBAAoB,KAAK;GACvB,MAAM,WAAW,eAAe;IAAE,GAAG;IAAa,GAAG;GAAa,IAAI;GAEtE,IAAI,WAAW;IACb;IACA;IACA;IACA,OAAO;IACP;IACA;IACA;IACA;IACA;GACF,CAAC;GACD,IAAI,YAAY,QAAQ;GACxB,IAAI,iBACF,IAAI,eAAe,eAAe;GAGpC,IAAI,aAAaC,mBAAAA,YAAY;GAC7B,IAAI,UACF,IAAI,aAAaC,mBAAAA,iBAAiB;GAEpC,KAAK,MAAM,OAAO,gBAChB,IAAI,aAAa,GAAG;EAExB,EACF;CACF;AACF,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
1
|
import "./chunk-C0LytTxp.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as handlersGenerator, t as mswGenerator } from "./generators-
|
|
2
|
+
import { s as camelCase } from "./components-Bi7cN-ws.js";
|
|
3
|
+
import { n as handlersGenerator, t as mswGenerator } from "./generators-BnEvTy3q.js";
|
|
4
4
|
import { definePlugin, defineResolver } from "@kubb/core";
|
|
5
5
|
import { pluginFakerName } from "@kubb/plugin-faker";
|
|
6
6
|
import { pluginTsName } from "@kubb/plugin-ts";
|
|
7
|
+
//#region ../../internals/utils/src/fs.ts
|
|
8
|
+
/**
|
|
9
|
+
* Builds a nested file path from a dotted name. Splits on dots that precede a letter
|
|
10
|
+
* (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases
|
|
11
|
+
* every earlier segment, applies `caseLast` to the final segment, and joins with `/`.
|
|
12
|
+
*
|
|
13
|
+
* Empty segments are dropped before joining. They arise when the name starts with a dot
|
|
14
|
+
* followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to
|
|
15
|
+
* an empty string). Without this a leading `/` would form, which `path.resolve` reads as an
|
|
16
|
+
* absolute path, letting generated files escape the configured output directory.
|
|
17
|
+
*
|
|
18
|
+
* @example Nested path from a dotted name
|
|
19
|
+
* `toFilePath('pet.petId') // 'pet/petId'`
|
|
20
|
+
*
|
|
21
|
+
* @example PascalCase the final segment
|
|
22
|
+
* `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`
|
|
23
|
+
*
|
|
24
|
+
* @example Suffix applied to the final segment only
|
|
25
|
+
* `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`
|
|
26
|
+
*/
|
|
27
|
+
function toFilePath(name, caseLast = camelCase) {
|
|
28
|
+
const parts = name.split(/\.(?=[a-zA-Z])/);
|
|
29
|
+
return parts.map((part, i) => i === parts.length - 1 ? caseLast(part) : camelCase(part)).filter(Boolean).join("/");
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
7
32
|
//#region ../../internals/shared/src/group.ts
|
|
8
33
|
/**
|
|
9
34
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
10
35
|
* shared default naming so every plugin groups output consistently:
|
|
11
36
|
*
|
|
12
37
|
* - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).
|
|
13
|
-
* - other groups use
|
|
38
|
+
* - other groups use the camelCased group (`pet store` → `petStore`).
|
|
14
39
|
*
|
|
15
40
|
* A user-provided `group.name` always wins over the default namer, so callers stay in
|
|
16
41
|
* control of their output folders. Returns `null` when grouping is disabled, matching the
|
|
17
42
|
* per-plugin convention.
|
|
18
43
|
*
|
|
19
44
|
* @param group - The user-supplied group option, or `undefined` to disable grouping.
|
|
20
|
-
* @param options.suffix - Appended to non-`path` group names, e.g. `'Controller'` or `'Requests'`.
|
|
21
45
|
*
|
|
22
46
|
* @example
|
|
23
47
|
* ```ts
|
|
24
|
-
* createGroupConfig(group
|
|
25
|
-
* createGroupConfig(group, { suffix: 'Requests' }) // plugin-cypress, plugin-mcp
|
|
48
|
+
* createGroupConfig(group) // shared across every plugin
|
|
26
49
|
* ```
|
|
27
50
|
*/
|
|
28
|
-
function createGroupConfig(group
|
|
51
|
+
function createGroupConfig(group) {
|
|
29
52
|
if (!group) return null;
|
|
30
53
|
const defaultName = (ctx) => {
|
|
31
54
|
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
32
|
-
return
|
|
55
|
+
return camelCase(ctx.group);
|
|
33
56
|
};
|
|
34
57
|
return {
|
|
35
58
|
...group,
|
|
@@ -54,7 +77,7 @@ const resolverMsw = defineResolver(() => ({
|
|
|
54
77
|
name: "default",
|
|
55
78
|
pluginName: "plugin-msw",
|
|
56
79
|
default(name, type) {
|
|
57
|
-
return
|
|
80
|
+
return type === "file" ? toFilePath(name) : camelCase(name);
|
|
58
81
|
},
|
|
59
82
|
resolveName(name) {
|
|
60
83
|
return camelCase(name, { suffix: "handler" });
|
|
@@ -105,9 +128,9 @@ const pluginMswName = "plugin-msw";
|
|
|
105
128
|
const pluginMsw = definePlugin((options) => {
|
|
106
129
|
const { output = {
|
|
107
130
|
path: "handlers",
|
|
108
|
-
|
|
131
|
+
barrel: { type: "named" }
|
|
109
132
|
}, group, exclude = [], include, override = [], handlers = false, parser = "data", baseURL, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [] } = options;
|
|
110
|
-
const groupConfig = createGroupConfig(group
|
|
133
|
+
const groupConfig = createGroupConfig(group);
|
|
111
134
|
return {
|
|
112
135
|
name: pluginMswName,
|
|
113
136
|
options,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../internals/shared/src/group.ts","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../internals/utils/src/fs.ts","../../../internals/shared/src/group.ts","../src/resolvers/resolverMsw.ts","../src/plugin.ts"],"sourcesContent":["import { posix } from 'node:path'\nimport { camelCase } from './casing.ts'\n\nfunction toSlash(p: string): string {\n if (p.startsWith('\\\\\\\\?\\\\')) return p\n return p.replaceAll('\\\\', '/')\n}\n\n/**\n * Returns the relative path from `rootDir` to `filePath`, always using forward slashes\n * and prefixed with `./` when not already traversing upward.\n *\n * @example\n * ```ts\n * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'\n * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'\n * ```\n */\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = posix.relative(toSlash(rootDir), toSlash(filePath))\n\n return relativePath.startsWith('../') ? relativePath : `./${relativePath}`\n}\n\n/**\n * Builds a nested file path from a dotted name. Splits on dots that precede a letter\n * (so version numbers embedded in operationIds like `v2025.0` stay intact), camelCases\n * every earlier segment, applies `caseLast` to the final segment, and joins with `/`.\n *\n * Empty segments are dropped before joining. They arise when the name starts with a dot\n * followed by a letter (e.g. `..Schema` splits into `['..', 'Schema']` and `'..'` cases to\n * an empty string). Without this a leading `/` would form, which `path.resolve` reads as an\n * absolute path, letting generated files escape the configured output directory.\n *\n * @example Nested path from a dotted name\n * `toFilePath('pet.petId') // 'pet/petId'`\n *\n * @example PascalCase the final segment\n * `toFilePath('pet.Pet', pascalCase) // 'pet/Pet'`\n *\n * @example Suffix applied to the final segment only\n * `toFilePath('tag.tag', (part) => camelCase(part, { suffix: 'schema' })) // 'tag/tagSchema'`\n */\nexport function toFilePath(name: string, caseLast: (part: string) => string = camelCase): string {\n const parts = name.split(/\\.(?=[a-zA-Z])/)\n return parts\n .map((part, i) => (i === parts.length - 1 ? caseLast(part) : camelCase(part)))\n .filter(Boolean)\n .join('/')\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from '@kubb/core'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { camelCase, toFilePath } from '@internals/utils'\nimport { defineResolver } from '@kubb/core'\nimport type { PluginMsw } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-msw`. Decides the names and file\n * paths for every generated MSW handler. Function names get a `Handler`\n * suffix; the aggregate export is always `handlers`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMsw } from '@kubb/plugin-msw'\n *\n * resolverMsw.resolveName('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMsw = defineResolver<PluginMsw>(() => ({\n name: 'default',\n pluginName: 'plugin-msw',\n default(name, type) {\n return type === 'file' ? toFilePath(name) : camelCase(name)\n },\n resolveName(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n resolvePathName(name, type) {\n return this.default(name, type)\n },\n resolveHandlerName(node) {\n return this.resolveName(node.operationId)\n },\n resolveHandlersName() {\n return 'handlers'\n },\n}))\n","import { createGroupConfig } from '@internals/shared'\nimport { definePlugin } from '@kubb/core'\nimport { pluginFakerName } from '@kubb/plugin-faker'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { handlersGenerator, mswGenerator } from './generators'\nimport { resolverMsw } from './resolvers/resolverMsw.ts'\nimport type { PluginMsw } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-msw`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']\n\n/**\n * Generates MSW request handlers from an OpenAPI spec. Drop them into your\n * test setup or service worker to mock the API end-to-end. Request path,\n * method, status, and response body all stay in sync with the spec. Combine\n * with `@kubb/plugin-faker` (via `parser: 'faker'`) to seed handlers with\n * realistic data.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginMsw } from '@kubb/plugin-msw'\n *\n * export default defineConfig({\n * input: { path: './petStore.yaml' },\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginMsw({\n * output: { path: './handlers' },\n * handlers: true,\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMsw = definePlugin<PluginMsw>((options) => {\n const {\n output = { path: 'handlers', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n handlers = false,\n parser = 'data',\n baseURL,\n resolver: userResolver,\n transformer: userTransformer,\n generators: userGenerators = [],\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMswName,\n options,\n dependencies: [pluginTsName, parser === 'faker' ? pluginFakerName : null].filter((dependency): dependency is string => Boolean(dependency)),\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n const resolver = userResolver ? { ...resolverMsw, ...userResolver } : resolverMsw\n\n ctx.setOptions({\n output,\n parser,\n baseURL,\n group: groupConfig,\n exclude,\n include,\n override,\n handlers,\n resolver,\n })\n ctx.setResolver(resolver)\n if (userTransformer) {\n ctx.setTransformer(userTransformer)\n }\n\n ctx.addGenerator(mswGenerator)\n if (handlers) {\n ctx.addGenerator(handlersGenerator)\n }\n for (const gen of userGenerators) {\n ctx.addGenerator(gen)\n }\n },\n },\n }\n})\n\nexport default pluginMsw\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,WAAW,MAAc,WAAqC,WAAmB;CAC/F,MAAM,QAAQ,KAAK,MAAM,gBAAgB;CACzC,OAAO,MACJ,KAAK,MAAM,MAAO,MAAM,MAAM,SAAS,IAAI,SAAS,IAAI,IAAI,UAAU,IAAI,CAAE,CAAC,CAC7E,OAAO,OAAO,CAAC,CACf,KAAK,GAAG;AACb;;;;;;;;;;;;;;;;;;;;;AChCA,SAAgB,kBAAkB,OAAwC;CACxE,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,eAAe,QAAmC;EACtD,IAAI,MAAM,SAAS,QACjB,OAAO,GAAG,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC;EAGjC,OAAO,UAAU,IAAI,KAAK;CAC5B;CAEA,OAAO;EACL,GAAG;EACH,MAAM,MAAM,OAAO,MAAM,OAAO;CAClC;AACF;;;;;;;;;;;;;;;ACtBA,MAAa,cAAc,sBAAiC;CAC1D,MAAM;CACN,YAAY;CACZ,QAAQ,MAAM,MAAM;EAClB,OAAO,SAAS,SAAS,WAAW,IAAI,IAAI,UAAU,IAAI;CAC5D;CACA,YAAY,MAAM;EAChB,OAAO,UAAU,MAAM,EAAE,QAAQ,UAAU,CAAC;CAC9C;CACA,gBAAgB,MAAM,MAAM;EAC1B,OAAO,KAAK,QAAQ,MAAM,IAAI;CAChC;CACA,mBAAmB,MAAM;EACvB,OAAO,KAAK,YAAY,KAAK,WAAW;CAC1C;CACA,sBAAsB;EACpB,OAAO;CACT;AACF,EAAE;;;;;;;ACtBF,MAAa,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4B7B,MAAa,YAAY,cAAyB,YAAY;CAC5D,MAAM,EACJ,SAAS;EAAE,MAAM;EAAY,QAAQ,EAAE,MAAM,QAAQ;CAAE,GACvD,OACA,UAAU,CAAC,GACX,SACA,WAAW,CAAC,GACZ,WAAW,OACX,SAAS,QACT,SACA,UAAU,cACV,aAAa,iBACb,YAAY,iBAAiB,CAAC,MAC5B;CAEJ,MAAM,cAAc,kBAAkB,KAAK;CAE3C,OAAO;EACL,MAAM;EACN;EACA,cAAc,CAAC,cAAc,WAAW,UAAU,kBAAkB,IAAI,CAAC,CAAC,QAAQ,eAAqC,QAAQ,UAAU,CAAC;EAC1I,OAAO,EACL,oBAAoB,KAAK;GACvB,MAAM,WAAW,eAAe;IAAE,GAAG;IAAa,GAAG;GAAa,IAAI;GAEtE,IAAI,WAAW;IACb;IACA;IACA;IACA,OAAO;IACP;IACA;IACA;IACA;IACA;GACF,CAAC;GACD,IAAI,YAAY,QAAQ;GACxB,IAAI,iBACF,IAAI,eAAe,eAAe;GAGpC,IAAI,aAAa,YAAY;GAC7B,IAAI,UACF,IAAI,aAAa,iBAAiB;GAEpC,KAAK,MAAM,OAAO,gBAChB,IAAI,aAAa,GAAG;EAExB,EACF;CACF;AACF,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __name } from "./chunk-C0LytTxp.js";
|
|
2
|
-
import { Exclude, Generator, Group, Include, Output, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
|
|
2
|
+
import { Exclude, Generator, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ast } from "@kubb/core";
|
|
3
3
|
|
|
4
4
|
//#region src/types.d.ts
|
|
5
5
|
/**
|
|
@@ -23,22 +23,18 @@ type ResolverMsw = Resolver & {
|
|
|
23
23
|
*/
|
|
24
24
|
resolveHandlersName(this: ResolverMsw): string;
|
|
25
25
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Where the generated MSW handlers are written and how they are exported, plus the optional
|
|
28
|
+
* `group` strategy. The `group` option organizes `output.mode: 'directory'` output into per-tag or per-path subdirectories.
|
|
29
|
+
*
|
|
30
|
+
* @default { path: 'handlers', barrel: { type: 'named' } }
|
|
31
|
+
*/
|
|
32
|
+
type Options = OutputOptions & {
|
|
33
33
|
/**
|
|
34
34
|
* Base URL prepended to every handler's request URL. When omitted, falls back
|
|
35
35
|
* to the adapter's server URL (typically `servers[0].url`).
|
|
36
36
|
*/
|
|
37
37
|
baseURL?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Split generated files into subfolders based on the operation's tag.
|
|
40
|
-
*/
|
|
41
|
-
group?: Group;
|
|
42
38
|
/**
|
|
43
39
|
* Skip operations matching at least one entry in the list.
|
|
44
40
|
*/
|
|
@@ -100,4 +96,4 @@ declare global {
|
|
|
100
96
|
}
|
|
101
97
|
//#endregion
|
|
102
98
|
export { PluginMsw as n, Options as t };
|
|
103
|
-
//# sourceMappingURL=types-
|
|
99
|
+
//# sourceMappingURL=types-B1yTWOfj.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-msw",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.56",
|
|
4
4
|
"description": "Generate Mock Service Worker (MSW) request handlers from your OpenAPI specification. Intercept HTTP requests in the browser or Node.js for seamless frontend development and testing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api-mocking",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"files": [
|
|
27
27
|
"src",
|
|
28
28
|
"dist",
|
|
29
|
-
"extension.yaml",
|
|
30
29
|
"!/**/**.test.**",
|
|
31
30
|
"!/**/__tests__/**",
|
|
32
31
|
"!/**/__snapshots__/**"
|
|
@@ -72,31 +71,24 @@
|
|
|
72
71
|
"registry": "https://registry.npmjs.org/"
|
|
73
72
|
},
|
|
74
73
|
"dependencies": {
|
|
75
|
-
"@kubb/core": "5.0.0-beta.
|
|
76
|
-
"@kubb/renderer-jsx": "5.0.0-beta.
|
|
77
|
-
"@kubb/plugin-faker": "5.0.0-beta.
|
|
78
|
-
"@kubb/plugin-ts": "5.0.0-beta.
|
|
74
|
+
"@kubb/core": "5.0.0-beta.55",
|
|
75
|
+
"@kubb/renderer-jsx": "5.0.0-beta.55",
|
|
76
|
+
"@kubb/plugin-faker": "5.0.0-beta.56",
|
|
77
|
+
"@kubb/plugin-ts": "5.0.0-beta.56"
|
|
79
78
|
},
|
|
80
79
|
"devDependencies": {
|
|
81
80
|
"@internals/shared": "0.0.0",
|
|
82
81
|
"@internals/utils": "0.0.0"
|
|
83
82
|
},
|
|
84
83
|
"peerDependencies": {
|
|
85
|
-
"@kubb/renderer-jsx": "5.0.0-beta.
|
|
84
|
+
"@kubb/renderer-jsx": "5.0.0-beta.55"
|
|
86
85
|
},
|
|
87
|
-
"size-limit": [
|
|
88
|
-
{
|
|
89
|
-
"path": "./dist/*.js",
|
|
90
|
-
"limit": "510 KiB",
|
|
91
|
-
"gzip": true
|
|
92
|
-
}
|
|
93
|
-
],
|
|
94
86
|
"engines": {
|
|
95
87
|
"node": ">=22"
|
|
96
88
|
},
|
|
97
89
|
"scripts": {
|
|
98
|
-
"build": "tsdown
|
|
99
|
-
"clean": "
|
|
90
|
+
"build": "tsdown",
|
|
91
|
+
"clean": "node -e \"require('node:fs').rmSync('./dist', {recursive:true,force:true})\"",
|
|
100
92
|
"lint": "oxlint .",
|
|
101
93
|
"lint:fix": "oxlint --fix .",
|
|
102
94
|
"release": "pnpm publish --no-git-check",
|
package/src/components/Mock.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getPrimarySuccessResponse } from '@internals/shared'
|
|
2
|
-
import {
|
|
2
|
+
import { Url } from '@internals/utils'
|
|
3
3
|
import { ast } from '@kubb/core'
|
|
4
4
|
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
5
|
import { File, Function } from '@kubb/renderer-jsx'
|
|
@@ -21,7 +21,7 @@ export function Mock({ baseURL = '', name, typeName, requestTypeName, node }: Pr
|
|
|
21
21
|
const successResponse = getPrimarySuccessResponse(node)
|
|
22
22
|
const statusCode = successResponse ? Number(successResponse.statusCode) : 200
|
|
23
23
|
const contentType = getContentType(successResponse)
|
|
24
|
-
const url =
|
|
24
|
+
const url = Url.toPath(getMswUrl(node))
|
|
25
25
|
|
|
26
26
|
const headers = [contentType ? `'Content-Type': '${contentType}'` : null].filter(Boolean)
|
|
27
27
|
const responseHasSchema = hasResponseSchema(successResponse)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getPrimarySuccessResponse } from '@internals/shared'
|
|
2
|
-
import {
|
|
2
|
+
import { Url } from '@internals/utils'
|
|
3
3
|
import { ast } from '@kubb/core'
|
|
4
4
|
import { functionPrinter } from '@kubb/plugin-ts'
|
|
5
5
|
import { File, Function } from '@kubb/renderer-jsx'
|
|
@@ -22,7 +22,7 @@ export function MockWithFaker({ baseURL = '', name, fakerName, typeName, request
|
|
|
22
22
|
const successResponse = getPrimarySuccessResponse(node)
|
|
23
23
|
const statusCode = successResponse ? Number(successResponse.statusCode) : 200
|
|
24
24
|
const contentType = getContentType(successResponse)
|
|
25
|
-
const url =
|
|
25
|
+
const url = Url.toPath(getMswUrl(node))
|
|
26
26
|
|
|
27
27
|
const headers = [contentType ? `'Content-Type': '${contentType}'` : null].filter(Boolean)
|
|
28
28
|
|
package/src/components/index.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { defineGenerator } from '@kubb/core'
|
|
2
|
-
import { File, jsxRendererSync } from '@kubb/renderer-jsx'
|
|
3
|
-
import { Handlers } from '../components/Handlers.tsx'
|
|
1
|
+
import { ast, defineGenerator } from '@kubb/core'
|
|
4
2
|
import type { PluginMsw } from '../types'
|
|
5
3
|
|
|
6
4
|
/**
|
|
@@ -11,7 +9,6 @@ import type { PluginMsw } from '../types'
|
|
|
11
9
|
*/
|
|
12
10
|
export const handlersGenerator = defineGenerator<PluginMsw>({
|
|
13
11
|
name: 'plugin-msw',
|
|
14
|
-
renderer: jsxRendererSync,
|
|
15
12
|
operations(nodes, ctx) {
|
|
16
13
|
const { resolver, config, root } = ctx
|
|
17
14
|
const { output, group } = ctx.options
|
|
@@ -25,23 +22,28 @@ export const handlersGenerator = defineGenerator<PluginMsw>({
|
|
|
25
22
|
{ name: resolver.resolveName(node.operationId), extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path },
|
|
26
23
|
{ root, output, group: group ?? undefined },
|
|
27
24
|
)
|
|
28
|
-
|
|
29
|
-
return <File.Import key={operationFile.path} name={[operationName]} root={file.path} path={operationFile.path} />
|
|
25
|
+
return ast.createImport({ name: [operationName], root: file.path, path: operationFile.path })
|
|
30
26
|
})
|
|
31
27
|
|
|
32
28
|
const handlers = nodes.map((node) => `${resolver.resolveHandlerName(node)}()`)
|
|
33
29
|
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
baseName
|
|
37
|
-
path
|
|
38
|
-
meta
|
|
39
|
-
banner
|
|
40
|
-
footer
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
30
|
+
return [
|
|
31
|
+
ast.createFile({
|
|
32
|
+
baseName: file.baseName,
|
|
33
|
+
path: file.path,
|
|
34
|
+
meta: file.meta,
|
|
35
|
+
banner: resolver.resolveBanner(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),
|
|
36
|
+
footer: resolver.resolveFooter(ctx.meta, { output, config, file: { path: file.path, baseName: file.baseName } }),
|
|
37
|
+
imports,
|
|
38
|
+
sources: [
|
|
39
|
+
ast.createSource({
|
|
40
|
+
name: handlersName,
|
|
41
|
+
isIndexable: true,
|
|
42
|
+
isExportable: true,
|
|
43
|
+
nodes: [ast.createText(`export const ${handlersName} = ${JSON.stringify(handlers).replaceAll('"', '')} as const`)],
|
|
44
|
+
}),
|
|
45
|
+
],
|
|
46
|
+
}),
|
|
47
|
+
]
|
|
46
48
|
},
|
|
47
49
|
})
|
package/src/generators/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { handlersGenerator } from './handlersGenerator.
|
|
1
|
+
export { handlersGenerator } from './handlersGenerator.ts'
|
|
2
2
|
export { mswGenerator } from './mswGenerator.tsx'
|
|
@@ -2,7 +2,7 @@ import { getOperationSuccessResponses, resolveResponseTypes } from '@internals/s
|
|
|
2
2
|
import { ast, defineGenerator } from '@kubb/core'
|
|
3
3
|
import { pluginFakerName } from '@kubb/plugin-faker'
|
|
4
4
|
import { pluginTsName } from '@kubb/plugin-ts'
|
|
5
|
-
import { File,
|
|
5
|
+
import { File, jsxRenderer } from '@kubb/renderer-jsx'
|
|
6
6
|
import { Mock, MockWithFaker, Response } from '../components'
|
|
7
7
|
import type { PluginMsw } from '../types'
|
|
8
8
|
import { resolveFakerMeta } from '../utils.ts'
|
|
@@ -15,7 +15,7 @@ import { resolveFakerMeta } from '../utils.ts'
|
|
|
15
15
|
*/
|
|
16
16
|
export const mswGenerator = defineGenerator<PluginMsw>({
|
|
17
17
|
name: 'msw',
|
|
18
|
-
renderer:
|
|
18
|
+
renderer: jsxRenderer,
|
|
19
19
|
operation(node, ctx) {
|
|
20
20
|
if (!ast.isHttpOperationNode(node)) return null
|
|
21
21
|
const { driver, resolver, config, root } = ctx
|
package/src/plugin.ts
CHANGED
|
@@ -40,7 +40,7 @@ export const pluginMswName = 'plugin-msw' satisfies PluginMsw['name']
|
|
|
40
40
|
*/
|
|
41
41
|
export const pluginMsw = definePlugin<PluginMsw>((options) => {
|
|
42
42
|
const {
|
|
43
|
-
output = { path: 'handlers',
|
|
43
|
+
output = { path: 'handlers', barrel: { type: 'named' } },
|
|
44
44
|
group,
|
|
45
45
|
exclude = [],
|
|
46
46
|
include,
|
|
@@ -53,7 +53,7 @@ export const pluginMsw = definePlugin<PluginMsw>((options) => {
|
|
|
53
53
|
generators: userGenerators = [],
|
|
54
54
|
} = options
|
|
55
55
|
|
|
56
|
-
const groupConfig = createGroupConfig(group
|
|
56
|
+
const groupConfig = createGroupConfig(group)
|
|
57
57
|
|
|
58
58
|
return {
|
|
59
59
|
name: pluginMswName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { camelCase } from '@internals/utils'
|
|
1
|
+
import { camelCase, toFilePath } from '@internals/utils'
|
|
2
2
|
import { defineResolver } from '@kubb/core'
|
|
3
3
|
import type { PluginMsw } from '../types.ts'
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ export const resolverMsw = defineResolver<PluginMsw>(() => ({
|
|
|
18
18
|
name: 'default',
|
|
19
19
|
pluginName: 'plugin-msw',
|
|
20
20
|
default(name, type) {
|
|
21
|
-
return
|
|
21
|
+
return type === 'file' ? toFilePath(name) : camelCase(name)
|
|
22
22
|
},
|
|
23
23
|
resolveName(name) {
|
|
24
24
|
return camelCase(name, { suffix: 'handler' })
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ast, Exclude, Generator, Group, Include, Output, Override, PluginFactoryOptions, Resolver } from '@kubb/core'
|
|
1
|
+
import type { ast, Exclude, Generator, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver } from '@kubb/core'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Resolver for MSW that provides naming methods for handler functions.
|
|
@@ -22,22 +22,18 @@ export type ResolverMsw = Resolver & {
|
|
|
22
22
|
resolveHandlersName(this: ResolverMsw): string
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Where the generated MSW handlers are written and how they are exported, plus the optional
|
|
27
|
+
* `group` strategy. The `group` option organizes `output.mode: 'directory'` output into per-tag or per-path subdirectories.
|
|
28
|
+
*
|
|
29
|
+
* @default { path: 'handlers', barrel: { type: 'named' } }
|
|
30
|
+
*/
|
|
31
|
+
export type Options = OutputOptions & {
|
|
32
32
|
/**
|
|
33
33
|
* Base URL prepended to every handler's request URL. When omitted, falls back
|
|
34
34
|
* to the adapter's server URL (typically `servers[0].url`).
|
|
35
35
|
*/
|
|
36
36
|
baseURL?: string
|
|
37
|
-
/**
|
|
38
|
-
* Split generated files into subfolders based on the operation's tag.
|
|
39
|
-
*/
|
|
40
|
-
group?: Group
|
|
41
37
|
/**
|
|
42
38
|
* Skip operations matching at least one entry in the list.
|
|
43
39
|
*/
|