{"_id":"@akfm/vite-plugin-storybook-mock-server-functions","_rev":"2-ef2fef20e1ec7c03ab9bebe0faf63e16","name":"@akfm/vite-plugin-storybook-mock-server-functions","dist-tags":{"latest":"0.0.0"},"versions":{"0.0.0-beta0":{"name":"@akfm/vite-plugin-storybook-mock-server-functions","version":"0.0.0-beta0","keywords":["next.js","server-functions","storybook","vite-plugin"],"author":{"name":"akfm"},"license":"MIT","_id":"@akfm/vite-plugin-storybook-mock-server-functions@0.0.0-beta0","maintainers":[{"name":"akfm","email":"akfm.sato@gmail.com"}],"homepage":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions#readme","bugs":{"url":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions/issues"},"dist":{"shasum":"b8770fc61456d236d4c4671c24843ae585321326","tarball":"https://registry.npmjs.org/@akfm/vite-plugin-storybook-mock-server-functions/-/vite-plugin-storybook-mock-server-functions-0.0.0-beta0.tgz","fileCount":6,"integrity":"sha512-njxYkWSiO4CcHjEg/u1rNEHQ2BzocxtUN2Rl7QZxKghBgJetpB2BjlZGbTdCjgVpJVj//OD8WwkbaUo9jQDOBg==","signatures":[{"sig":"MEQCIGvYChUKX03MlpMriY4+AezG0OBTQzaY+5lZnLPh7ovjAiAfZjYc2hxrIcwZuUmDyC7L419/E3WcvF2WaAXgQCDD7w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":20191},"main":"./dist/index.mjs","type":"module","_from":"file:akfm-vite-plugin-storybook-mock-server-functions-0.0.0-beta0.tgz","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./runtime":{"types":"./dist/runtime/index.d.mts","import":"./dist/runtime/index.mjs"}},"scripts":{"dev":"tsdown --watch","lint":"oxlint .","test":"vitest run","build":"tsdown","format":"oxfmt --write .","typecheck":"tsc --noEmit","test:watch":"vitest","format:check":"oxfmt --check ."},"_npmUser":{"name":"akfm","email":"akfm.sato@gmail.com"},"_resolved":"/private/var/folders/r1/20d9kfjn2pl1xg7xc0jfzcqc0000gn/T/52c4963f9b328aaf1fb80082a8d993c0/akfm-vite-plugin-storybook-mock-server-functions-0.0.0-beta0.tgz","_integrity":"sha512-njxYkWSiO4CcHjEg/u1rNEHQ2BzocxtUN2Rl7QZxKghBgJetpB2BjlZGbTdCjgVpJVj//OD8WwkbaUo9jQDOBg==","repository":{"url":"git+https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions.git","type":"git"},"_npmVersion":"10.9.2","description":"Vite plugin that replaces Next.js Server Actions (\"use server\") with Storybook fn() mocks.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"oxc-parser":"0.141.0","magic-string":"1.1.0","estree-walker":"3.0.3","@rollup/pluginutils":"5.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"8.1.5","oxfmt":"0.60.0","unrun":"0.3.1","oxlint":"1.75.0","tsdown":"0.22.13","vitest":"4.1.10","storybook":"10.5.3","typescript":"7.0.2","@types/node":"26.1.1","@types/estree":"1.0.9"},"peerDependencies":{"vite":"^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0","storybook":"^9.0.0 || ^10.0.0"},"_npmOperationalInternal":{"tmp":"tmp/vite-plugin-storybook-mock-server-functions_0.0.0-beta0_1784904598386_0.9623873010774648","host":"s3://npm-registry-packages-npm-production"}},"0.0.0":{"name":"@akfm/vite-plugin-storybook-mock-server-functions","version":"0.0.0","description":"Vite plugin that replaces Next.js Server Actions (\"use server\") with Storybook fn() mocks.","keywords":["next.js","server-functions","storybook","vite-plugin"],"license":"MIT","author":{"name":"akfm"},"repository":{"type":"git","url":"git+https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions.git"},"type":"module","main":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./runtime":{"types":"./dist/runtime/index.d.mts","import":"./dist/runtime/index.mjs"}},"publishConfig":{"access":"public"},"scripts":{"build":"tsdown","dev":"tsdown --watch","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","lint":"oxlint .","format":"oxfmt --write .","format:check":"oxfmt --check ."},"dependencies":{"@rollup/pluginutils":"5.4.0","estree-walker":"3.0.3","magic-string":"1.1.0","oxc-parser":"0.141.0"},"devDependencies":{"@types/estree":"1.0.9","@types/node":"26.1.1","oxfmt":"0.60.0","oxlint":"1.75.0","storybook":"10.5.3","tsdown":"0.22.13","typescript":"7.0.2","unrun":"0.3.1","vite":"8.1.5","vitest":"4.1.10"},"peerDependencies":{"storybook":"^9.0.0 || ^10.0.0","vite":"^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"},"packageManager":"pnpm@10.34.1","_id":"@akfm/vite-plugin-storybook-mock-server-functions@0.0.0","gitHead":"944053118dea77657a08ffb874860cd21010bac5","bugs":{"url":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions/issues"},"homepage":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions#readme","_nodeVersion":"22.23.1","_npmVersion":"11.5.1","dist":{"integrity":"sha512-UtrX3IsaF4OLWRfbWedvQyF8UCTSSVBVbkDpkYCHtT9lDZTYqD+VY1RNuxq4xGb0N2k3zr3f7fzf6aFByq4KPw==","shasum":"065e5b02007c7f9bb4ac00f1e9b78c3d60f06a7a","tarball":"https://registry.npmjs.org/@akfm/vite-plugin-storybook-mock-server-functions/-/vite-plugin-storybook-mock-server-functions-0.0.0.tgz","fileCount":6,"unpackedSize":20222,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@akfm%2fvite-plugin-storybook-mock-server-functions@0.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC9jkec1RGkRAwQzGAAbLEjUUHYcClG3tHEIRpUL97YEgIgc3nqk9VoMOFL3w+J712LFyeg7iP05V6ikvjEGgbpFjk="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:2c0af6cf-0fca-4d8a-ba1c-46675d288ec5"}},"directories":{},"maintainers":[{"name":"akfm","email":"akfm.sato@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vite-plugin-storybook-mock-server-functions_0.0.0_1784905434005_0.15912479276813873"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-24T14:49:58.198Z","modified":"2026-07-24T15:03:55.019Z","0.0.0-beta0":"2026-07-24T14:49:58.522Z","0.0.0":"2026-07-24T15:03:54.168Z"},"bugs":{"url":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions/issues"},"author":{"name":"akfm"},"license":"MIT","homepage":"https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions#readme","keywords":["next.js","server-functions","storybook","vite-plugin"],"repository":{"type":"git","url":"git+https://github.com/AkifumiSato/vite-plugin-storybook-mock-server-functions.git"},"description":"Vite plugin that replaces Next.js Server Actions (\"use server\") with Storybook fn() mocks.","maintainers":[{"name":"akfm","email":"akfm.sato@gmail.com"}],"readme":"# @akfm/vite-plugin-storybook-mock-server-functions\n\n[![npm version](https://img.shields.io/npm/v/@akfm/vite-plugin-storybook-mock-server-functions.svg)](https://www.npmjs.com/package/@akfm/vite-plugin-storybook-mock-server-functions)\n[![license](https://img.shields.io/npm/l/@akfm/vite-plugin-storybook-mock-server-functions.svg)](#license)\n\nEnglish | [日本語](./README_ja.md)\n\nA Vite plugin that lets Next.js App Router Server Actions (`\"use server\"`) run standalone inside Storybook.\n\nNext.js Server Actions rely on Next.js's own bundler transform and server runtime at execution time, so loading them as-is in Storybook (which is Vite-based) results in build or runtime errors. This plugin detects functions carrying a `\"use server\"` directive and replaces them with [`storybook/test`](https://storybook.js.org/docs/writing-tests/interaction-testing)'s `fn()`-based mock functions, so components that use Server Actions can be rendered and tested in Storybook without a real server.\n\n## Features\n\n- Detects both module-level and function-level `\"use server\"` directives — no need to restructure existing action files.\n- Replaces only the directive-bearing functions with `fn()` mocks; everything else in the file (including non-action exports) is left untouched.\n- Lets each story inject its own mock implementation via `parameters.serverFunctions`, with mocks automatically reset between stories.\n- Ships as a single Vite plugin + one decorator — no extra Storybook addon to install.\n\n## Supported patterns\n\n- **Module-level directive**: `\"use server\"` at the top of a file. Every exported function in the file is treated as a Server Action.\n- **Function-level (inline) directive**: `\"use server\"` at the top of an individual function body, with no module-level directive required. This works on a standalone function declaration/expression just as well as on a property/method of an object or a field/method of a class — so a single directive-bearing function among otherwise-plain exports (e.g. only `api.create` is a Server Action, while `api.formatLabel` stays a regular function) is detected correctly either way.\n\n```ts\n// actions/todo.ts (module-level — every export in the file is a Server Action)\n\"use server\";\nexport async function createTodo(formData: FormData) {\n  /* real server-side work */\n}\n\n// actions/delete-todo.ts (function-level, no module-level directive — only this\n// function is a Server Action)\nexport async function deleteTodo(id: string) {\n  \"use server\";\n  /* real server-side work */\n}\n\n// actions/api.ts (function-level, only part of the object is a Server Action)\nexport const api = {\n  create: async (formData: FormData) => {\n    \"use server\";\n    /* real server-side work */\n  },\n  formatLabel: (todo: Todo) => todo.title.toUpperCase(), // regular function, left untouched\n};\n```\n\nEither way, at Storybook build time these functions are replaced with mock functions created via `storybook/test`'s `fn()`.\n\n## Installation\n\n```sh\nnpm install -D @akfm/vite-plugin-storybook-mock-server-functions\n```\n\n```sh\npnpm add -D @akfm/vite-plugin-storybook-mock-server-functions\n```\n\n```sh\nyarn add -D @akfm/vite-plugin-storybook-mock-server-functions\n```\n\nRequires `vite` and `storybook` as peer dependencies.\n\n## Setup\n\n### 1. Register the plugin\n\nAdd the plugin to `.storybook/main.ts`'s `viteFinal`.\n\n```ts\nimport { storybookMockServerFunctions } from \"@akfm/vite-plugin-storybook-mock-server-functions\";\n\nconst config = {\n  framework: \"@storybook/nextjs-vite\",\n  // ...\n  viteFinal: async (viteConfig) => {\n    viteConfig.plugins ??= [];\n    viteConfig.plugins.push(storybookMockServerFunctions());\n    return viteConfig;\n  },\n};\n\nexport default config;\n```\n\n### 2. Register the decorator\n\nAdd the decorator to `.storybook/preview.ts`. This resets all mocks before every story runs.\n\n```ts\nimport { withServerFunctionMocks } from \"@akfm/vite-plugin-storybook-mock-server-functions/runtime\";\n\nconst preview = {\n  decorators: [withServerFunctionMocks],\n};\n\nexport default preview;\n```\n\n## Injecting mock implementations from a story\n\nPass a `Map<mock function, implementation function>` via `parameters.serverFunctions` to inject any return value or behavior on a per-story basis. Since Vite's module graph is a singleton, the functions a story imports are the exact mock functions the plugin generated, so they can be used directly as Map keys.\n\n```tsx\nimport { createTodo } from \"../actions/todo\";\nimport { api } from \"../actions/api\";\n\nexport const Success: Story = {\n  parameters: {\n    serverFunctions: new Map([\n      [createTodo, async () => ({ ok: true, id: \"1\" })],\n      [api.create, async () => ({ ok: true })],\n    ]),\n  },\n};\n```\n\nIf `parameters.serverFunctions` is not set, each mock defaults to `async () => undefined`.\n\nNon-Server-Action functions like `api.formatLabel` are left untransformed and can be imported and used with their original implementation.\n\n## Options\n\n```ts\nstorybookMockServerFunctions({\n  include?: FilterPattern; // default: [/\\.[jt]sx?$/]\n  exclude?: FilterPattern; // default: [/node_modules/]\n})\n```\n\n`include` / `exclude` are passed straight through to [`@rollup/pluginutils`](https://github.com/rollup/plugins/tree/master/packages/pluginutils#createfilter)'s `createFilter`.\n\n## Example\n\n`example/` contains a verification Storybook app built with `@storybook/nextjs-vite`.\n\n```sh\npnpm install\npnpm build\npnpm --filter example storybook\n```\n\n## Known limitations\n\n- Re-exports of the form `export { x } from './y'` are not supported.\n- The function-level directive is only recognized on functions with a `BlockStatement` body (a single-expression arrow function like `() => \"use server\"` can't hold a directive in its body, matching Next.js's own constraint).\n- `parameters.serverFunctions` is designed around passing a `Map` of functions directly. If you rely on story serialization (e.g. Storybook's composed stories feature), be aware that functions cannot be serialized.\n- `oxc-parser` depends on a platform-specific native (napi) binary. This is normally resolved automatically via npm/pnpm optionalDependencies for your OS/architecture, but it may not work in unsupported runtime environments.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}