@storybook-astro/framework 1.0.3 → 1.1.1

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.
Files changed (63) hide show
  1. package/dist/{chunk-KSDXET2L.js → chunk-4HECE7IW.js} +477 -61
  2. package/dist/chunk-4HECE7IW.js.map +1 -0
  3. package/dist/{chunk-7GHEQUPV.js → chunk-POHTFYST.js} +46 -8
  4. package/dist/chunk-POHTFYST.js.map +1 -0
  5. package/dist/chunk-T7NWIO5S.js +220 -0
  6. package/dist/chunk-T7NWIO5S.js.map +1 -0
  7. package/dist/{chunk-C5OH4VBR.js → chunk-V76WSNSP.js} +124 -47
  8. package/dist/chunk-V76WSNSP.js.map +1 -0
  9. package/dist/index.d.ts +19 -9
  10. package/dist/index.js +10 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/middleware.js +57 -39
  13. package/dist/middleware.js.map +1 -1
  14. package/dist/node/index.d.ts +10 -0
  15. package/dist/node/index.js +10 -0
  16. package/dist/node/index.js.map +1 -0
  17. package/dist/preset.d.ts +1 -1
  18. package/dist/preset.js +3 -3
  19. package/dist/testing.js +12 -64
  20. package/dist/testing.js.map +1 -1
  21. package/dist/{types-CHTsRtA7.d.ts → types-Cvor6Tyi.d.ts} +21 -5
  22. package/dist/{viteStorybookAstroMiddlewarePlugin-NP2E52IC.js → viteStorybookAstroMiddlewarePlugin-2EFKTECT.js} +2 -2
  23. package/dist/vitest/global-setup.js +42 -0
  24. package/dist/vitest/global-setup.js.map +1 -0
  25. package/dist/vitest/index.js +20 -3
  26. package/dist/vitest/index.js.map +1 -1
  27. package/package.json +11 -3
  28. package/src/index.ts +21 -1
  29. package/src/lib/sanitization.ts +104 -0
  30. package/src/middleware.ts +76 -44
  31. package/src/node/index.ts +7 -0
  32. package/src/preset.ts +86 -16
  33. package/src/renderer/renderer-dev.ts +82 -0
  34. package/src/renderer/renderer-server.test.ts +101 -0
  35. package/src/renderer/renderer-server.ts +135 -0
  36. package/src/renderer/renderer-static.ts +62 -0
  37. package/src/rules.test.ts +89 -18
  38. package/src/rules.ts +67 -18
  39. package/src/server/index.ts +111 -0
  40. package/src/testing/renderer-daemon.ts +10 -1
  41. package/src/types.ts +25 -5
  42. package/src/virtual.d.ts +37 -0
  43. package/src/vite/astroFilesVirtualModulePlugin.ts +36 -0
  44. package/src/vite/createVirtualModulePlugin.ts +3 -3
  45. package/src/vite/storybookAstroRulesConfigVirtualModulePlugin.ts +37 -0
  46. package/src/vite/storybookAstroSanitizationConfigVirtualModulePlugin.ts +21 -0
  47. package/src/vite/storybookAstroServerAuthConfigVirtualModulePlugin.test.ts +71 -0
  48. package/src/vite/storybookAstroServerAuthConfigVirtualModulePlugin.ts +42 -0
  49. package/src/vitePluginAstroBuildPrerender.ts +50 -51
  50. package/src/vitePluginAstroBuildServer.ts +289 -0
  51. package/src/vitePluginAstroIntegrationOptsFallback.ts +25 -0
  52. package/src/vitePluginAstroToolbarFallback.ts +38 -0
  53. package/src/viteStorybookAstroMiddlewarePlugin.ts +40 -8
  54. package/src/viteStorybookAstroRendererPlugin.ts +45 -0
  55. package/src/vitest/config.ts +45 -4
  56. package/src/vitest/global-setup.ts +45 -0
  57. package/dist/chunk-7GHEQUPV.js.map +0 -1
  58. package/dist/chunk-C5OH4VBR.js.map +0 -1
  59. package/dist/chunk-KSDXET2L.js.map +0 -1
  60. package/dist/middleware.d.ts +0 -26
  61. package/src/msw-helpers.ts +0 -1
  62. package/src/msw.ts +0 -58
  63. /package/dist/{viteStorybookAstroMiddlewarePlugin-NP2E52IC.js.map → viteStorybookAstroMiddlewarePlugin-2EFKTECT.js.map} +0 -0
package/dist/testing.js CHANGED
@@ -4,13 +4,17 @@ import {
4
4
  setProjectAnnotations
5
5
  } from "./chunk-5EF25G5S.js";
6
6
  import {
7
- resolveTestingIntegrationsForRoot
8
- } from "./chunk-4SWPVM6R.js";
9
- import "./chunk-PJEDXZVN.js";
7
+ renderViaTestingRendererDaemon,
8
+ runWithWorkingDirectory
9
+ } from "./chunk-T7NWIO5S.js";
10
10
  import {
11
11
  ssrLoadModuleWithFsFallback
12
- } from "./chunk-7GHEQUPV.js";
12
+ } from "./chunk-POHTFYST.js";
13
+ import {
14
+ resolveTestingIntegrationsForRoot
15
+ } from "./chunk-4SWPVM6R.js";
13
16
  import "./chunk-DNGQBPT7.js";
17
+ import "./chunk-PJEDXZVN.js";
14
18
  import "./chunk-G3PMV62Z.js";
15
19
 
16
20
  // src/testing/story-composition.ts
@@ -29,7 +33,7 @@ var composeStory2 = composeStory;
29
33
  var setProjectAnnotations2 = setProjectAnnotations;
30
34
 
31
35
  // src/testing/astro-runtime.ts
32
- import { fileURLToPath as fileURLToPath3 } from "url";
36
+ import { fileURLToPath as fileURLToPath2 } from "url";
33
37
 
34
38
  // src/testing/project-root.ts
35
39
  import { existsSync, readFileSync } from "fs";
@@ -188,62 +192,6 @@ async function resolveTestingProjectRoot(component) {
188
192
  return process.cwd();
189
193
  }
190
194
 
191
- // src/testing/working-directory.ts
192
- var workingDirectoryLock = Promise.resolve();
193
- async function runWithWorkingDirectory(dir, fn) {
194
- const previousLock = workingDirectoryLock;
195
- let releaseLock;
196
- workingDirectoryLock = new Promise((resolve2) => {
197
- releaseLock = resolve2;
198
- });
199
- await previousLock;
200
- const previousCwd = process.cwd();
201
- try {
202
- if (previousCwd !== dir) {
203
- process.chdir(dir);
204
- }
205
- return await fn();
206
- } finally {
207
- if (process.cwd() !== previousCwd) {
208
- process.chdir(previousCwd);
209
- }
210
- releaseLock();
211
- }
212
- }
213
-
214
- // src/testing/renderer-daemon.ts
215
- import { createServer as createHttpServer } from "http";
216
- import { fileURLToPath as fileURLToPath2 } from "url";
217
- var TESTING_RENDERER_DAEMON_URL_ENV = "STORYBOOK_ASTRO_TESTING_RENDERER_DAEMON_URL";
218
- function getTestingRendererDaemonUrl() {
219
- const value = process.env[TESTING_RENDERER_DAEMON_URL_ENV];
220
- if (!value || value.length === 0) {
221
- return null;
222
- }
223
- return value;
224
- }
225
- async function renderViaTestingRendererDaemon(payload) {
226
- const daemonUrl = getTestingRendererDaemonUrl();
227
- if (!daemonUrl) {
228
- return null;
229
- }
230
- const response = await fetch(daemonUrl, {
231
- method: "POST",
232
- headers: {
233
- "content-type": "application/json"
234
- },
235
- body: JSON.stringify(payload)
236
- });
237
- const parsed = await response.json();
238
- if (!response.ok) {
239
- throw new Error(parsed.error ?? `Renderer daemon returned ${response.status}.`);
240
- }
241
- if (typeof parsed.html !== "string") {
242
- throw new Error("Renderer daemon returned an invalid payload.");
243
- }
244
- return parsed.html;
245
- }
246
-
247
195
  // src/testing/astro-runtime.ts
248
196
  var astroContainerPromise = null;
249
197
  var astroSsrViteServerPromises = /* @__PURE__ */ new Map();
@@ -264,11 +212,11 @@ async function getAstroContainer() {
264
212
  }
265
213
  async function getAstroSsrViteServer(resolveFrom) {
266
214
  if (!astroSsrViteServerPromises.has(resolveFrom)) {
267
- const { createViteServer: createViteServer2 } = await import("./viteStorybookAstroMiddlewarePlugin-NP2E52IC.js");
215
+ const { createViteServer } = await import("./viteStorybookAstroMiddlewarePlugin-2EFKTECT.js");
268
216
  const integrations = getTestingIntegrations(resolveFrom);
269
217
  astroSsrViteServerPromises.set(
270
218
  resolveFrom,
271
- runWithWorkingDirectory(resolveFrom, () => createViteServer2(integrations, resolveFrom))
219
+ runWithWorkingDirectory(resolveFrom, () => createViteServer(integrations, resolveFrom))
272
220
  );
273
221
  }
274
222
  return astroSsrViteServerPromises.get(resolveFrom);
@@ -278,7 +226,7 @@ async function getAstroSsrHandler(resolveFrom) {
278
226
  astroSsrHandlerPromises.set(resolveFrom, (async () => {
279
227
  const integrations = getTestingIntegrations(resolveFrom);
280
228
  const viteServer = await getAstroSsrViteServer(resolveFrom);
281
- const middlewareModulePath = fileURLToPath3(new URL("../middleware", import.meta.url));
229
+ const middlewareModulePath = fileURLToPath2(new URL("../middleware", import.meta.url));
282
230
  const middleware = await runWithWorkingDirectory(
283
231
  resolveFrom,
284
232
  () => viteServer.ssrLoadModule(middlewareModulePath, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/story-composition.ts","../src/testing/astro-runtime.ts","../src/testing/project-root.ts","../src/testing/component-utils.ts","../src/testing/working-directory.ts","../src/testing/renderer-daemon.ts"],"sourcesContent":["import {\n composeStories as portableComposeStories,\n composeStory as portableComposeStory,\n setProjectAnnotations as portableSetProjectAnnotations,\n} from '../portable-stories.ts';\nimport type { ProjectAnnotations, Store_CSFExports as StoreCsfExports } from 'storybook/internal/types';\nimport type { AstroRenderer } from '../portable-stories.ts';\nimport type { ComposedStory, StoryMeta } from './types.ts';\n\nexport function composeStories<\n TModule extends StoreCsfExports<AstroRenderer> & Record<string, unknown>\n>(\n storiesImport: TModule,\n projectAnnotations?: ProjectAnnotations<AstroRenderer>\n) {\n const composed = portableComposeStories(storiesImport, projectAnnotations);\n\n for (const [storyExportName, story] of Object.entries(composed)) {\n if (typeof story === 'function') {\n const composedStory = story as ComposedStory;\n\n composedStory.__storybookAstroMeta = storiesImport.default as StoryMeta;\n composedStory.__storybookAstroStoryExport = storiesImport[\n storyExportName as keyof TModule\n ] as ComposedStory['__storybookAstroStoryExport'];\n }\n }\n\n return composed;\n}\n\nexport const composeStory = portableComposeStory;\nexport const setProjectAnnotations = portableSetProjectAnnotations;\n","import { fileURLToPath } from 'node:url';\nimport type { ViteDevServer } from 'vite';\nimport type { Integration as StorybookAstroIntegration } from '../integrations/base.ts';\nimport { resolveTestingIntegrationsForRoot } from './integration-config.ts';\nimport { resolveTestingProjectRoot } from './project-root.ts';\nimport { runWithWorkingDirectory } from './working-directory.ts';\nimport { getComponentModuleId, isAstroComponentFactory, isStorybookAstroClientStub } from './component-utils.ts';\nimport { ssrLoadModuleWithFsFallback } from '../lib/ssr-load-module-with-fs-fallback.ts';\nimport type { ComposedStory } from './types.ts';\nimport { renderViaTestingRendererDaemon } from './renderer-daemon.ts';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet astroContainerPromise: Promise<any> | null = null;\n\nconst astroSsrViteServerPromises = new Map<string, Promise<ViteDevServer>>();\n\nconst astroSsrHandlerPromises = new Map<\n string,\n Promise<(data: { component: string; args?: Record<string, unknown> }) => Promise<string>>\n>();\n\nconst testingIntegrationsCache = new Map<string, StorybookAstroIntegration[]>();\n\nfunction getTestingIntegrations(resolveFrom: string) {\n if (!testingIntegrationsCache.has(resolveFrom)) {\n testingIntegrationsCache.set(resolveFrom, resolveTestingIntegrationsForRoot(resolveFrom));\n }\n\n return testingIntegrationsCache.get(resolveFrom)!;\n}\n\nasync function getAstroContainer() {\n if (!astroContainerPromise) {\n const { experimental_AstroContainer: AstroContainer } = await import('astro/container');\n\n astroContainerPromise = AstroContainer.create();\n }\n\n return astroContainerPromise;\n}\n\nasync function getAstroSsrViteServer(resolveFrom: string) {\n if (!astroSsrViteServerPromises.has(resolveFrom)) {\n const { createViteServer } = await import('../viteStorybookAstroMiddlewarePlugin.ts');\n const integrations = getTestingIntegrations(resolveFrom);\n\n astroSsrViteServerPromises.set(\n resolveFrom,\n runWithWorkingDirectory(resolveFrom, () => createViteServer(integrations, resolveFrom))\n );\n }\n\n return astroSsrViteServerPromises.get(resolveFrom)!;\n}\n\nasync function getAstroSsrHandler(resolveFrom: string) {\n if (!astroSsrHandlerPromises.has(resolveFrom)) {\n astroSsrHandlerPromises.set(resolveFrom, (async () => {\n const integrations = getTestingIntegrations(resolveFrom);\n const viteServer = await getAstroSsrViteServer(resolveFrom);\n const middlewareModulePath = fileURLToPath(new URL('../middleware', import.meta.url));\n const middleware = await runWithWorkingDirectory(resolveFrom, () =>\n viteServer.ssrLoadModule(middlewareModulePath, {\n fixStacktrace: true\n })\n );\n\n return middleware.handlerFactory(integrations, {\n loadModule: (id: string) =>\n ssrLoadModuleWithFsFallback(viteServer, id, {\n fixStacktrace: true\n })\n });\n })());\n }\n\n return astroSsrHandlerPromises.get(resolveFrom)!;\n}\n\nasync function resolveAstroComponent(component: unknown, resolveFrom: string) {\n let resolvedComponent = component;\n\n if (!isAstroComponentFactory(resolvedComponent)) {\n throw new Error('Story meta.component must be an Astro component factory.');\n }\n\n if ('moduleId' in resolvedComponent && typeof resolvedComponent.moduleId === 'string') {\n const moduleId = resolvedComponent.moduleId;\n const normalizedModuleId = moduleId.split('?')[0].split('#')[0];\n\n try {\n const mod = await import(/* @vite-ignore */ normalizedModuleId) as Record<string, unknown>;\n\n if (isAstroComponentFactory(mod.default)) {\n resolvedComponent = mod.default;\n }\n } catch {\n // keep current component when direct module import is unavailable\n }\n\n if (isStorybookAstroClientStub(resolvedComponent)) {\n try {\n const viteServer = await getAstroSsrViteServer(resolveFrom);\n const mod = (await ssrLoadModuleWithFsFallback(viteServer, normalizedModuleId)) as Record<string, unknown>;\n\n if (isAstroComponentFactory(mod.default)) {\n resolvedComponent = mod.default;\n }\n } catch {\n // keep current component when SSR module loading is unavailable\n }\n }\n }\n\n return resolvedComponent;\n}\n\nasync function renderAstroComponentToDom(\n component: unknown,\n args: Record<string, unknown>,\n resolveFrom: string\n) {\n const moduleId = getComponentModuleId(component);\n\n if (moduleId) {\n try {\n // Fast path: reuse a single shared SSR daemon instead of spinning SSR in each worker.\n const html = await renderViaTestingRendererDaemon({\n resolveFrom,\n component: moduleId,\n args\n });\n\n if (typeof html === 'string') {\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n }\n } catch {\n // Fall back to in-worker rendering below when daemon render fails.\n }\n\n try {\n const handler = await getAstroSsrHandler(resolveFrom);\n const html = await handler({\n component: moduleId,\n args\n });\n\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n } catch {\n // Fall back to direct Container rendering below\n }\n }\n\n const resolvedComponent = await resolveAstroComponent(component, resolveFrom);\n const container = await getAstroContainer();\n \n if (!container) {\n throw new Error('Failed to initialize Astro container for rendering');\n }\n \n const html = await container.renderToString(resolvedComponent, {\n props: args\n });\n\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n}\n\nasync function renderComposedStory(story: ComposedStory) {\n const meta = story.__storybookAstroMeta;\n const storyExport = story.__storybookAstroStoryExport;\n let component = meta?.component ?? story.component;\n\n if (!isAstroComponentFactory(component)) {\n const maybeRendered = await story();\n\n if (isAstroComponentFactory(maybeRendered)) {\n component = maybeRendered;\n } else if (\n typeof maybeRendered === 'object' &&\n maybeRendered !== null &&\n 'component' in maybeRendered &&\n isAstroComponentFactory((maybeRendered as { component: unknown }).component)\n ) {\n component = (maybeRendered as { component: unknown }).component;\n }\n }\n\n if (!component) {\n throw new Error('Unable to resolve Astro component from composed story.');\n }\n\n const args = {\n ...(meta?.args ?? {}),\n ...(storyExport?.args ?? {}),\n ...(story.args ?? {})\n };\n\n const resolveFrom = await resolveTestingProjectRoot(component);\n\n return renderAstroComponentToDom(component, args, resolveFrom);\n}\n\nexport async function renderStory(story: ComposedStory) {\n return renderComposedStory(story);\n}\n\nexport const renderAstroStory = renderStory;\n","import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getComponentModuleFilePath } from './component-utils.ts';\n\nconst VITEST_CONFIG_FILES = [\n 'vitest.config.ts',\n 'vitest.config.mts',\n 'vitest.config.js',\n 'vitest.config.mjs',\n 'vitest.config.cjs'\n];\n\nfunction extractStackFilePath(line: string) {\n const trimmed = line.trim();\n\n const match = trimmed.match(/\\((.+):(\\d+):(\\d+)\\)$/) ?? trimmed.match(/^at\\s+(.+):(\\d+):(\\d+)$/);\n\n if (!match) {\n return null;\n }\n\n const rawPath = match[1];\n\n if (rawPath.startsWith('node:')) {\n return null;\n }\n\n if (rawPath.startsWith('file://')) {\n return fileURLToPath(rawPath);\n }\n\n if (rawPath.startsWith('/')) {\n return rawPath;\n }\n\n return null;\n}\n\nasync function getCurrentTestFilePath() {\n try {\n const { expect } = await import('vitest');\n const vitestState = expect.getState() as {\n testPath?: string;\n filepath?: string;\n filePath?: string;\n };\n\n const fromVitestState = vitestState.testPath ?? vitestState.filepath ?? vitestState.filePath;\n\n if (typeof fromVitestState === 'string') {\n const absolutePath = fromVitestState.startsWith('/')\n ? fromVitestState\n : resolve(process.cwd(), fromVitestState);\n\n if (existsSync(absolutePath)) {\n return absolutePath;\n }\n }\n } catch {\n // Fall through to stack-based lookup when Vitest state is unavailable.\n }\n\n const stack = new Error().stack;\n\n if (!stack) {\n return null;\n }\n\n const thisFilePath = fileURLToPath(import.meta.url);\n\n for (const line of stack.split('\\n')) {\n const filePath = extractStackFilePath(line);\n\n if (!filePath) {\n continue;\n }\n\n if (filePath === thisFilePath || filePath.includes('/node_modules/')) {\n continue;\n }\n\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n}\n\nfunction findNearestVitestConfigDir(startPath: string) {\n let dir = dirname(startPath);\n\n while (true) {\n if (VITEST_CONFIG_FILES.some((name) => existsSync(join(dir, name)))) {\n return dir;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nfunction packageJsonDeclaresAstro(packageJsonPath: string) {\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\n return ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'].some(\n (field) =>\n packageJson[field] &&\n typeof packageJson[field] === 'object' &&\n Object.prototype.hasOwnProperty.call(packageJson[field], 'astro')\n );\n } catch {\n return false;\n }\n}\n\nfunction findNearestAstroPackageDir(startPath: string) {\n let dir = dirname(startPath);\n\n while (true) {\n const packageJsonPath = join(dir, 'package.json');\n\n if (packageJsonDeclaresAstro(packageJsonPath)) {\n return dir;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nfunction canResolveAstroFrom(dir: string) {\n try {\n const require = createRequire(`${join(dir, '__storybook-astro-testing-resolve__.js')}`);\n\n require.resolve('astro/package.json');\n\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function resolveTestingProjectRoot(component: unknown) {\n const currentTestFilePath = await getCurrentTestFilePath();\n const componentModulePath = getComponentModuleFilePath(component);\n const candidates = [\n currentTestFilePath ? findNearestVitestConfigDir(currentTestFilePath) : null,\n currentTestFilePath ? findNearestAstroPackageDir(currentTestFilePath) : null,\n componentModulePath ? findNearestAstroPackageDir(componentModulePath) : null,\n packageJsonDeclaresAstro(join(process.cwd(), 'package.json')) ? process.cwd() : null,\n process.env.INIT_CWD && packageJsonDeclaresAstro(join(process.env.INIT_CWD, 'package.json'))\n ? process.env.INIT_CWD\n : null\n ].filter((value): value is string => Boolean(value));\n\n for (const candidate of candidates) {\n if (canResolveAstroFrom(candidate)) {\n return candidate;\n }\n }\n\n return process.cwd();\n}\n","export function isStorybookAstroClientStub(component: unknown) {\n return (\n typeof component === 'function' &&\n String(component).includes('Astro components are rendered server-side by Storybook')\n );\n}\n\nexport function isAstroComponentFactory(component: unknown) {\n return typeof component === 'function' && 'isAstroComponentFactory' in component;\n}\n\nexport function getComponentModuleId(component: unknown) {\n if (typeof component !== 'function' || !('moduleId' in component)) {\n return null;\n }\n\n if (typeof component.moduleId !== 'string') {\n return null;\n }\n\n return component.moduleId.split('?')[0].split('#')[0];\n}\n\nexport function getComponentModuleFilePath(component: unknown) {\n const moduleId = getComponentModuleId(component);\n\n if (!moduleId || !moduleId.startsWith('/')) {\n return null;\n }\n\n return moduleId;\n}\n","let workingDirectoryLock: Promise<void> = Promise.resolve();\n\nexport async function runWithWorkingDirectory<T>(dir: string, fn: () => Promise<T>) {\n const previousLock = workingDirectoryLock;\n let releaseLock!: () => void;\n\n workingDirectoryLock = new Promise<void>((resolve) => {\n releaseLock = resolve;\n });\n\n await previousLock;\n\n const previousCwd = process.cwd();\n\n try {\n if (previousCwd !== dir) {\n process.chdir(dir);\n }\n\n return await fn();\n } finally {\n if (process.cwd() !== previousCwd) {\n process.chdir(previousCwd);\n }\n\n releaseLock();\n }\n}\n","import { createServer as createHttpServer } from 'node:http';\nimport type { IncomingMessage } from 'node:http';\nimport { fileURLToPath } from 'node:url';\nimport type { ViteDevServer } from 'vite';\nimport { createViteServer } from '../viteStorybookAstroMiddlewarePlugin.ts';\nimport { resolveTestingIntegrationsForRoot } from './integration-config.ts';\nimport { runWithWorkingDirectory } from './working-directory.ts';\nimport { ssrLoadModuleWithFsFallback } from '../lib/ssr-load-module-with-fs-fallback.ts';\n\nconst RENDER_PATH = '/render';\n\nexport const TESTING_RENDERER_DAEMON_URL_ENV = 'STORYBOOK_ASTRO_TESTING_RENDERER_DAEMON_URL';\n\ntype RenderPayload = {\n resolveFrom: string;\n component: string;\n args?: Record<string, unknown>;\n slots?: Record<string, unknown>;\n};\n\ntype RenderHandler = (data: {\n component: string;\n args?: Record<string, unknown>;\n slots?: Record<string, unknown>;\n}) => Promise<string>;\n\ntype RunningDaemon = {\n url: string;\n close: () => Promise<void>;\n};\n\nasync function readJsonBody(request: IncomingMessage) {\n const chunks: Buffer[] = [];\n\n for await (const chunk of request) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n if (chunks.length === 0) {\n return null;\n }\n\n return JSON.parse(Buffer.concat(chunks).toString('utf-8')) as unknown;\n}\n\nfunction createBadRequest(message: string) {\n const error = new Error(message);\n\n (error as Error & { statusCode?: number }).statusCode = 400;\n\n return error;\n}\n\nfunction assertRenderPayload(payload: unknown): asserts payload is RenderPayload {\n if (!payload || typeof payload !== 'object') {\n throw createBadRequest('Invalid render payload.');\n }\n\n const record = payload as Record<string, unknown>;\n\n if (typeof record.resolveFrom !== 'string' || record.resolveFrom.length === 0) {\n throw createBadRequest('Missing render payload field: resolveFrom.');\n }\n\n if (typeof record.component !== 'string' || record.component.length === 0) {\n throw createBadRequest('Missing render payload field: component.');\n }\n\n if (\n 'args' in record &&\n typeof record.args !== 'undefined' &&\n (typeof record.args !== 'object' || record.args === null || Array.isArray(record.args))\n ) {\n throw createBadRequest('Render payload field args must be an object when provided.');\n }\n\n if (\n 'slots' in record &&\n typeof record.slots !== 'undefined' &&\n (typeof record.slots !== 'object' || record.slots === null || Array.isArray(record.slots))\n ) {\n throw createBadRequest('Render payload field slots must be an object when provided.');\n }\n}\n\nfunction getErrorStatusCode(error: unknown) {\n if (error && typeof error === 'object' && 'statusCode' in error) {\n const statusCode = (error as { statusCode?: unknown }).statusCode;\n\n if (typeof statusCode === 'number' && Number.isInteger(statusCode) && statusCode >= 400) {\n return statusCode;\n }\n }\n\n return 500;\n}\n\nexport async function startTestingRendererDaemon(): Promise<RunningDaemon> {\n // One daemon process serves all Vitest workers; cache is keyed by project root.\n const viteServerPromises = new Map<string, Promise<ViteDevServer>>();\n const renderHandlerPromises = new Map<string, Promise<RenderHandler>>();\n\n async function getViteServer(resolveFrom: string) {\n if (!viteServerPromises.has(resolveFrom)) {\n const integrations = resolveTestingIntegrationsForRoot(resolveFrom);\n\n viteServerPromises.set(\n resolveFrom,\n runWithWorkingDirectory(resolveFrom, () => createViteServer(integrations, resolveFrom))\n );\n }\n\n return viteServerPromises.get(resolveFrom)!;\n }\n\n async function getRenderHandler(resolveFrom: string) {\n if (!renderHandlerPromises.has(resolveFrom)) {\n renderHandlerPromises.set(resolveFrom, (async () => {\n const integrations = resolveTestingIntegrationsForRoot(resolveFrom);\n const viteServer = await getViteServer(resolveFrom);\n const middlewareModulePath = fileURLToPath(new URL('../middleware', import.meta.url));\n const middleware = await runWithWorkingDirectory(resolveFrom, () =>\n viteServer.ssrLoadModule(middlewareModulePath, {\n fixStacktrace: true\n })\n );\n\n return middleware.handlerFactory(integrations, {\n loadModule: (id: string) =>\n ssrLoadModuleWithFsFallback(viteServer, id, {\n fixStacktrace: true\n })\n }) as Promise<RenderHandler>;\n })());\n }\n\n return renderHandlerPromises.get(resolveFrom)!;\n }\n\n const server = createHttpServer(async (request, response) => {\n // Allow cross-origin requests from browser-like test environments (e.g. happy-dom).\n response.setHeader('Access-Control-Allow-Origin', '*');\n response.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');\n response.setHeader('Access-Control-Allow-Headers', 'content-type');\n\n if (request.method === 'OPTIONS') {\n response.statusCode = 204;\n response.end();\n\n return;\n }\n\n if (request.method !== 'POST' || request.url !== RENDER_PATH) {\n response.statusCode = 404;\n response.end();\n\n return;\n }\n\n try {\n const payload = await readJsonBody(request);\n\n assertRenderPayload(payload);\n\n const handler = await getRenderHandler(payload.resolveFrom);\n const html = await handler({\n component: payload.component,\n args: payload.args,\n slots: payload.slots\n });\n\n response.statusCode = 200;\n response.setHeader('content-type', 'application/json');\n response.end(JSON.stringify({ html }));\n } catch (error) {\n const statusCode = getErrorStatusCode(error);\n\n response.statusCode = statusCode;\n response.setHeader('content-type', 'application/json');\n response.end(JSON.stringify({\n error: error instanceof Error ? error.message : String(error)\n }));\n }\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(0, '127.0.0.1', () => {\n server.off('error', reject);\n resolve();\n });\n });\n\n const address = server.address();\n\n if (!address || typeof address === 'string') {\n throw new Error('Failed to start Storybook Astro testing renderer daemon.');\n }\n\n const url = `http://127.0.0.1:${address.port}${RENDER_PATH}`;\n\n return {\n url,\n close: async () => {\n await Promise.all(\n [...viteServerPromises.values()].map(async (viteServerPromise) => {\n const viteServer = await viteServerPromise;\n\n await viteServer.close();\n })\n );\n\n await new Promise<void>((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n\n return;\n }\n\n resolve();\n });\n });\n }\n };\n}\n\nexport function getTestingRendererDaemonUrl() {\n const value = process.env[TESTING_RENDERER_DAEMON_URL_ENV];\n\n if (!value || value.length === 0) {\n return null;\n }\n\n return value;\n}\n\nexport async function renderViaTestingRendererDaemon(payload: RenderPayload) {\n const daemonUrl = getTestingRendererDaemonUrl();\n\n if (!daemonUrl) {\n // Daemon is optional so local in-worker rendering can still be used as fallback.\n return null;\n }\n\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n const response = await fetch(daemonUrl, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json'\n },\n body: JSON.stringify(payload)\n });\n\n const parsed = (await response.json()) as {\n html?: string;\n error?: string;\n };\n\n if (!response.ok) {\n throw new Error(parsed.error ?? `Renderer daemon returned ${response.status}.`);\n }\n\n if (typeof parsed.html !== 'string') {\n throw new Error('Renderer daemon returned an invalid payload.');\n }\n\n return parsed.html;\n}\n"],"mappings":"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","names":["composeStories","composeStory","setProjectAnnotations","fileURLToPath","require","resolve","fileURLToPath","createViteServer","fileURLToPath","html"]}
1
+ {"version":3,"sources":["../src/testing/story-composition.ts","../src/testing/astro-runtime.ts","../src/testing/project-root.ts","../src/testing/component-utils.ts"],"sourcesContent":["import {\n composeStories as portableComposeStories,\n composeStory as portableComposeStory,\n setProjectAnnotations as portableSetProjectAnnotations,\n} from '../portable-stories.ts';\nimport type { ProjectAnnotations, Store_CSFExports as StoreCsfExports } from 'storybook/internal/types';\nimport type { AstroRenderer } from '../portable-stories.ts';\nimport type { ComposedStory, StoryMeta } from './types.ts';\n\nexport function composeStories<\n TModule extends StoreCsfExports<AstroRenderer> & Record<string, unknown>\n>(\n storiesImport: TModule,\n projectAnnotations?: ProjectAnnotations<AstroRenderer>\n) {\n const composed = portableComposeStories(storiesImport, projectAnnotations);\n\n for (const [storyExportName, story] of Object.entries(composed)) {\n if (typeof story === 'function') {\n const composedStory = story as ComposedStory;\n\n composedStory.__storybookAstroMeta = storiesImport.default as StoryMeta;\n composedStory.__storybookAstroStoryExport = storiesImport[\n storyExportName as keyof TModule\n ] as ComposedStory['__storybookAstroStoryExport'];\n }\n }\n\n return composed;\n}\n\nexport const composeStory = portableComposeStory;\nexport const setProjectAnnotations = portableSetProjectAnnotations;\n","import { fileURLToPath } from 'node:url';\nimport type { ViteDevServer } from 'vite';\nimport type { Integration as StorybookAstroIntegration } from '../integrations/base.ts';\nimport { resolveTestingIntegrationsForRoot } from './integration-config.ts';\nimport { resolveTestingProjectRoot } from './project-root.ts';\nimport { runWithWorkingDirectory } from './working-directory.ts';\nimport { getComponentModuleId, isAstroComponentFactory, isStorybookAstroClientStub } from './component-utils.ts';\nimport { ssrLoadModuleWithFsFallback } from '../lib/ssr-load-module-with-fs-fallback.ts';\nimport type { ComposedStory } from './types.ts';\nimport { renderViaTestingRendererDaemon } from './renderer-daemon.ts';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet astroContainerPromise: Promise<any> | null = null;\n\nconst astroSsrViteServerPromises = new Map<string, Promise<ViteDevServer>>();\n\nconst astroSsrHandlerPromises = new Map<\n string,\n Promise<(data: { component: string; args?: Record<string, unknown> }) => Promise<string>>\n>();\n\nconst testingIntegrationsCache = new Map<string, StorybookAstroIntegration[]>();\n\nfunction getTestingIntegrations(resolveFrom: string) {\n if (!testingIntegrationsCache.has(resolveFrom)) {\n testingIntegrationsCache.set(resolveFrom, resolveTestingIntegrationsForRoot(resolveFrom));\n }\n\n return testingIntegrationsCache.get(resolveFrom)!;\n}\n\nasync function getAstroContainer() {\n if (!astroContainerPromise) {\n const { experimental_AstroContainer: AstroContainer } = await import('astro/container');\n\n astroContainerPromise = AstroContainer.create();\n }\n\n return astroContainerPromise;\n}\n\nasync function getAstroSsrViteServer(resolveFrom: string) {\n if (!astroSsrViteServerPromises.has(resolveFrom)) {\n const { createViteServer } = await import('../viteStorybookAstroMiddlewarePlugin.ts');\n const integrations = getTestingIntegrations(resolveFrom);\n\n astroSsrViteServerPromises.set(\n resolveFrom,\n runWithWorkingDirectory(resolveFrom, () => createViteServer(integrations, resolveFrom))\n );\n }\n\n return astroSsrViteServerPromises.get(resolveFrom)!;\n}\n\nasync function getAstroSsrHandler(resolveFrom: string) {\n if (!astroSsrHandlerPromises.has(resolveFrom)) {\n astroSsrHandlerPromises.set(resolveFrom, (async () => {\n const integrations = getTestingIntegrations(resolveFrom);\n const viteServer = await getAstroSsrViteServer(resolveFrom);\n const middlewareModulePath = fileURLToPath(new URL('../middleware', import.meta.url));\n const middleware = await runWithWorkingDirectory(resolveFrom, () =>\n viteServer.ssrLoadModule(middlewareModulePath, {\n fixStacktrace: true\n })\n );\n\n return middleware.handlerFactory(integrations, {\n loadModule: (id: string) =>\n ssrLoadModuleWithFsFallback(viteServer, id, {\n fixStacktrace: true\n })\n });\n })());\n }\n\n return astroSsrHandlerPromises.get(resolveFrom)!;\n}\n\nasync function resolveAstroComponent(component: unknown, resolveFrom: string) {\n let resolvedComponent = component;\n\n if (!isAstroComponentFactory(resolvedComponent)) {\n throw new Error('Story meta.component must be an Astro component factory.');\n }\n\n if ('moduleId' in resolvedComponent && typeof resolvedComponent.moduleId === 'string') {\n const moduleId = resolvedComponent.moduleId;\n const normalizedModuleId = moduleId.split('?')[0].split('#')[0];\n\n try {\n const mod = await import(/* @vite-ignore */ normalizedModuleId) as Record<string, unknown>;\n\n if (isAstroComponentFactory(mod.default)) {\n resolvedComponent = mod.default;\n }\n } catch {\n // keep current component when direct module import is unavailable\n }\n\n if (isStorybookAstroClientStub(resolvedComponent)) {\n try {\n const viteServer = await getAstroSsrViteServer(resolveFrom);\n const mod = (await ssrLoadModuleWithFsFallback(viteServer, normalizedModuleId)) as Record<string, unknown>;\n\n if (isAstroComponentFactory(mod.default)) {\n resolvedComponent = mod.default;\n }\n } catch {\n // keep current component when SSR module loading is unavailable\n }\n }\n }\n\n return resolvedComponent;\n}\n\nasync function renderAstroComponentToDom(\n component: unknown,\n args: Record<string, unknown>,\n resolveFrom: string\n) {\n const moduleId = getComponentModuleId(component);\n\n if (moduleId) {\n try {\n // Fast path: reuse a single shared SSR daemon instead of spinning SSR in each worker.\n const html = await renderViaTestingRendererDaemon({\n resolveFrom,\n component: moduleId,\n args\n });\n\n if (typeof html === 'string') {\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n }\n } catch {\n // Fall back to in-worker rendering below when daemon render fails.\n }\n\n try {\n const handler = await getAstroSsrHandler(resolveFrom);\n const html = await handler({\n component: moduleId,\n args\n });\n\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n } catch {\n // Fall back to direct Container rendering below\n }\n }\n\n const resolvedComponent = await resolveAstroComponent(component, resolveFrom);\n const container = await getAstroContainer();\n \n if (!container) {\n throw new Error('Failed to initialize Astro container for rendering');\n }\n \n const html = await container.renderToString(resolvedComponent, {\n props: args\n });\n\n if (typeof document !== 'undefined') {\n document.body.innerHTML = html;\n }\n\n return html;\n}\n\nasync function renderComposedStory(story: ComposedStory) {\n const meta = story.__storybookAstroMeta;\n const storyExport = story.__storybookAstroStoryExport;\n let component = meta?.component ?? story.component;\n\n if (!isAstroComponentFactory(component)) {\n const maybeRendered = await story();\n\n if (isAstroComponentFactory(maybeRendered)) {\n component = maybeRendered;\n } else if (\n typeof maybeRendered === 'object' &&\n maybeRendered !== null &&\n 'component' in maybeRendered &&\n isAstroComponentFactory((maybeRendered as { component: unknown }).component)\n ) {\n component = (maybeRendered as { component: unknown }).component;\n }\n }\n\n if (!component) {\n throw new Error('Unable to resolve Astro component from composed story.');\n }\n\n const args = {\n ...(meta?.args ?? {}),\n ...(storyExport?.args ?? {}),\n ...(story.args ?? {})\n };\n\n const resolveFrom = await resolveTestingProjectRoot(component);\n\n return renderAstroComponentToDom(component, args, resolveFrom);\n}\n\nexport async function renderStory(story: ComposedStory) {\n return renderComposedStory(story);\n}\n\nexport const renderAstroStory = renderStory;\n","import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { getComponentModuleFilePath } from './component-utils.ts';\n\nconst VITEST_CONFIG_FILES = [\n 'vitest.config.ts',\n 'vitest.config.mts',\n 'vitest.config.js',\n 'vitest.config.mjs',\n 'vitest.config.cjs'\n];\n\nfunction extractStackFilePath(line: string) {\n const trimmed = line.trim();\n\n const match = trimmed.match(/\\((.+):(\\d+):(\\d+)\\)$/) ?? trimmed.match(/^at\\s+(.+):(\\d+):(\\d+)$/);\n\n if (!match) {\n return null;\n }\n\n const rawPath = match[1];\n\n if (rawPath.startsWith('node:')) {\n return null;\n }\n\n if (rawPath.startsWith('file://')) {\n return fileURLToPath(rawPath);\n }\n\n if (rawPath.startsWith('/')) {\n return rawPath;\n }\n\n return null;\n}\n\nasync function getCurrentTestFilePath() {\n try {\n const { expect } = await import('vitest');\n const vitestState = expect.getState() as {\n testPath?: string;\n filepath?: string;\n filePath?: string;\n };\n\n const fromVitestState = vitestState.testPath ?? vitestState.filepath ?? vitestState.filePath;\n\n if (typeof fromVitestState === 'string') {\n const absolutePath = fromVitestState.startsWith('/')\n ? fromVitestState\n : resolve(process.cwd(), fromVitestState);\n\n if (existsSync(absolutePath)) {\n return absolutePath;\n }\n }\n } catch {\n // Fall through to stack-based lookup when Vitest state is unavailable.\n }\n\n const stack = new Error().stack;\n\n if (!stack) {\n return null;\n }\n\n const thisFilePath = fileURLToPath(import.meta.url);\n\n for (const line of stack.split('\\n')) {\n const filePath = extractStackFilePath(line);\n\n if (!filePath) {\n continue;\n }\n\n if (filePath === thisFilePath || filePath.includes('/node_modules/')) {\n continue;\n }\n\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n return null;\n}\n\nfunction findNearestVitestConfigDir(startPath: string) {\n let dir = dirname(startPath);\n\n while (true) {\n if (VITEST_CONFIG_FILES.some((name) => existsSync(join(dir, name)))) {\n return dir;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nfunction packageJsonDeclaresAstro(packageJsonPath: string) {\n if (!existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n\n return ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies'].some(\n (field) =>\n packageJson[field] &&\n typeof packageJson[field] === 'object' &&\n Object.prototype.hasOwnProperty.call(packageJson[field], 'astro')\n );\n } catch {\n return false;\n }\n}\n\nfunction findNearestAstroPackageDir(startPath: string) {\n let dir = dirname(startPath);\n\n while (true) {\n const packageJsonPath = join(dir, 'package.json');\n\n if (packageJsonDeclaresAstro(packageJsonPath)) {\n return dir;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nfunction canResolveAstroFrom(dir: string) {\n try {\n const require = createRequire(`${join(dir, '__storybook-astro-testing-resolve__.js')}`);\n\n require.resolve('astro/package.json');\n\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function resolveTestingProjectRoot(component: unknown) {\n const currentTestFilePath = await getCurrentTestFilePath();\n const componentModulePath = getComponentModuleFilePath(component);\n const candidates = [\n currentTestFilePath ? findNearestVitestConfigDir(currentTestFilePath) : null,\n currentTestFilePath ? findNearestAstroPackageDir(currentTestFilePath) : null,\n componentModulePath ? findNearestAstroPackageDir(componentModulePath) : null,\n packageJsonDeclaresAstro(join(process.cwd(), 'package.json')) ? process.cwd() : null,\n process.env.INIT_CWD && packageJsonDeclaresAstro(join(process.env.INIT_CWD, 'package.json'))\n ? process.env.INIT_CWD\n : null\n ].filter((value): value is string => Boolean(value));\n\n for (const candidate of candidates) {\n if (canResolveAstroFrom(candidate)) {\n return candidate;\n }\n }\n\n return process.cwd();\n}\n","export function isStorybookAstroClientStub(component: unknown) {\n return (\n typeof component === 'function' &&\n String(component).includes('Astro components are rendered server-side by Storybook')\n );\n}\n\nexport function isAstroComponentFactory(component: unknown) {\n return typeof component === 'function' && 'isAstroComponentFactory' in component;\n}\n\nexport function getComponentModuleId(component: unknown) {\n if (typeof component !== 'function' || !('moduleId' in component)) {\n return null;\n }\n\n if (typeof component.moduleId !== 'string') {\n return null;\n }\n\n return component.moduleId.split('?')[0].split('#')[0];\n}\n\nexport function getComponentModuleFilePath(component: unknown) {\n const moduleId = getComponentModuleId(component);\n\n if (!moduleId || !moduleId.startsWith('/')) {\n return null;\n }\n\n return moduleId;\n}\n"],"mappings":"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","names":["composeStories","composeStory","setProjectAnnotations","fileURLToPath","require","fileURLToPath","html"]}
@@ -1,4 +1,4 @@
1
- import { CompatibleString, Options } from 'storybook/internal/types';
1
+ import { StorybookConfig as StorybookConfig$1, CompatibleString, Options } from 'storybook/internal/types';
2
2
  import { InlineConfig } from 'vite';
3
3
  import { I as Integration } from './base-IRZo3zgK.js';
4
4
  import { IOptions } from 'sanitize-html';
@@ -16,27 +16,43 @@ type StoryRulesOptions = string | {
16
16
 
17
17
  type FrameworkName = CompatibleString<'@storybook-astro/framework'>;
18
18
 
19
+ type RenderMode = 'server' | 'static';
20
+ type ServerBuildOptions = {
21
+ serverUrl?: string;
22
+ authToken?: string;
23
+ authHeader?: string;
24
+ };
19
25
  type RenderStoryInput = {
20
26
  id: string;
21
27
  title?: string;
22
28
  name?: string;
23
29
  };
24
- type FrameworkOptions = {
30
+ type BaseFrameworkOptions = {
25
31
  integrations?: Integration[];
26
32
  sanitization?: SanitizationOptions;
27
- storyRules?: StoryRulesOptions;
28
33
  resolveFrom?: string;
29
34
  };
35
+ type ServerFrameworkOptions = BaseFrameworkOptions & {
36
+ renderMode?: 'server';
37
+ storyRules?: StoryRulesOptions;
38
+ server?: ServerBuildOptions;
39
+ };
40
+ type StaticFrameworkOptions = BaseFrameworkOptions & {
41
+ renderMode: 'static';
42
+ storyRules?: StoryRulesOptions;
43
+ server?: never;
44
+ };
45
+ type FrameworkOptions = ServerFrameworkOptions | StaticFrameworkOptions;
30
46
  type StorybookConfigFramework = {
31
47
  framework: {
32
48
  name: FrameworkName;
33
49
  options?: FrameworkOptions;
34
50
  };
35
51
  };
36
- type StorybookConfig = StorybookConfigFramework;
37
52
  type ViteFinal = (config: InlineConfig, options: Options) => InlineConfig | Promise<InlineConfig>;
38
53
  type StorybookConfigVite = {
39
54
  viteFinal?: ViteFinal;
40
55
  };
56
+ type StorybookConfig = Omit<StorybookConfig$1, 'framework'> & StorybookConfigFramework & StorybookConfigVite;
41
57
 
42
- export type { FrameworkOptions as F, RenderStoryInput as R, SanitizationOptions as S, StoryRulesOptions as a, StorybookConfig as b, StorybookConfigVite as c };
58
+ export type { FrameworkOptions as F, RenderStoryInput as R, SanitizationOptions as S, RenderMode as a, ServerBuildOptions as b, StoryRulesOptions as c, StorybookConfig as d, StorybookConfigVite as e };
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createViteServer,
3
3
  vitePluginStorybookAstroMiddleware
4
- } from "./chunk-7GHEQUPV.js";
4
+ } from "./chunk-POHTFYST.js";
5
5
  import "./chunk-DNGQBPT7.js";
6
6
  import "./chunk-G3PMV62Z.js";
7
7
  export {
8
8
  createViteServer,
9
9
  vitePluginStorybookAstroMiddleware
10
10
  };
11
- //# sourceMappingURL=viteStorybookAstroMiddlewarePlugin-NP2E52IC.js.map
11
+ //# sourceMappingURL=viteStorybookAstroMiddlewarePlugin-2EFKTECT.js.map
@@ -0,0 +1,42 @@
1
+ import {
2
+ TESTING_RENDERER_DAEMON_URL_ENV,
3
+ startTestingRendererDaemon
4
+ } from "../chunk-T7NWIO5S.js";
5
+ import "../chunk-POHTFYST.js";
6
+ import "../chunk-4SWPVM6R.js";
7
+ import "../chunk-DNGQBPT7.js";
8
+ import "../chunk-PJEDXZVN.js";
9
+ import "../chunk-G3PMV62Z.js";
10
+
11
+ // src/vitest/global-setup.ts
12
+ var SUPPRESSED_WARNING_PATTERNS = [
13
+ "Missing pages directory",
14
+ "points to missing source files",
15
+ "Failed to load source map for"
16
+ ];
17
+ function shouldSuppress(chunk) {
18
+ const msg = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
19
+ return SUPPRESSED_WARNING_PATTERNS.some((pattern) => msg.includes(pattern));
20
+ }
21
+ async function globalSetup() {
22
+ const originalWrite = process.stderr.write.bind(process.stderr);
23
+ process.stderr.write = function(chunk, encodingOrCb, cb) {
24
+ if (shouldSuppress(chunk)) {
25
+ const done = typeof encodingOrCb === "function" ? encodingOrCb : cb;
26
+ done?.();
27
+ return true;
28
+ }
29
+ return originalWrite(chunk, encodingOrCb, cb);
30
+ };
31
+ const daemon = await startTestingRendererDaemon();
32
+ process.env[TESTING_RENDERER_DAEMON_URL_ENV] = daemon.url;
33
+ return async () => {
34
+ await daemon.close();
35
+ delete process.env[TESTING_RENDERER_DAEMON_URL_ENV];
36
+ process.stderr.write = originalWrite;
37
+ };
38
+ }
39
+ export {
40
+ globalSetup as default
41
+ };
42
+ //# sourceMappingURL=global-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/vitest/global-setup.ts"],"sourcesContent":["import {\n TESTING_RENDERER_DAEMON_URL_ENV,\n startTestingRendererDaemon\n} from '../testing/renderer-daemon.ts';\n\n/**\n * Patterns for warnings that are always benign in the test context and should\n * be silenced so they don't pollute test output.\n *\n * - \"Missing pages directory\" — Astro emits this when the project root has no\n * src/pages directory. Component tests never have pages.\n * - \"points to missing source files\" — Sourcemap gaps in the `entities` package;\n * a third-party packaging issue, not actionable.\n */\nconst SUPPRESSED_WARNING_PATTERNS = [\n 'Missing pages directory',\n 'points to missing source files',\n 'Failed to load source map for'\n];\n\nfunction shouldSuppress(chunk: Buffer | string): boolean {\n const msg = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);\n\n return SUPPRESSED_WARNING_PATTERNS.some((pattern) => msg.includes(pattern));\n}\n\nexport default async function globalSetup() {\n // Intercept stderr before starting the daemon so that Astro's own logger\n // (which bypasses Vite's customLogger) doesn't leak benign noise into output.\n const originalWrite = process.stderr.write.bind(process.stderr);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (process.stderr as any).write = function (\n chunk: Buffer | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void\n ): boolean {\n if (shouldSuppress(chunk)) {\n const done = typeof encodingOrCb === 'function' ? encodingOrCb : cb;\n\n done?.();\n\n return true;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (originalWrite as any)(chunk, encodingOrCb, cb);\n };\n\n const daemon = await startTestingRendererDaemon();\n\n // Workers discover the shared renderer via env instead of creating their own SSR stack.\n process.env[TESTING_RENDERER_DAEMON_URL_ENV] = daemon.url;\n\n return async () => {\n await daemon.close();\n delete process.env[TESTING_RENDERER_DAEMON_URL_ENV];\n // Restore stderr so post-teardown output is unaffected.\n process.stderr.write = originalWrite;\n };\n}\n"],"mappings":";;;;;;;;;;;AAcA,IAAM,8BAA8B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,eAAe,OAAiC;AACvD,QAAM,MAAM,OAAO,SAAS,KAAK,IAAI,MAAM,SAAS,MAAM,IAAI,OAAO,KAAK;AAE1E,SAAO,4BAA4B,KAAK,CAAC,YAAY,IAAI,SAAS,OAAO,CAAC;AAC5E;AAEA,eAAO,cAAqC;AAG1C,QAAM,gBAAgB,QAAQ,OAAO,MAAM,KAAK,QAAQ,MAAM;AAG9D,EAAC,QAAQ,OAAe,QAAQ,SAC9B,OACA,cACA,IACS;AACT,QAAI,eAAe,KAAK,GAAG;AACzB,YAAM,OAAO,OAAO,iBAAiB,aAAa,eAAe;AAEjE,aAAO;AAEP,aAAO;AAAA,IACT;AAGA,WAAQ,cAAsB,OAAO,cAAc,EAAE;AAAA,EACvD;AAEA,QAAM,SAAS,MAAM,2BAA2B;AAGhD,UAAQ,IAAI,+BAA+B,IAAI,OAAO;AAEtD,SAAO,YAAY;AACjB,UAAM,OAAO,MAAM;AACnB,WAAO,QAAQ,IAAI,+BAA+B;AAElD,YAAQ,OAAO,QAAQ;AAAA,EACzB;AACF;","names":[]}
@@ -4,10 +4,10 @@ import {
4
4
  import {
5
5
  registerTestingIntegrationsForRoot
6
6
  } from "../chunk-4SWPVM6R.js";
7
- import "../chunk-PJEDXZVN.js";
8
7
  import {
9
8
  importAstroConfig
10
9
  } from "../chunk-DNGQBPT7.js";
10
+ import "../chunk-PJEDXZVN.js";
11
11
  import "../chunk-G3PMV62Z.js";
12
12
 
13
13
  // ../../../node_modules/vitest/dist/config.js
@@ -18,6 +18,8 @@ function defineConfig(config) {
18
18
  }
19
19
 
20
20
  // src/vitest/config.ts
21
+ import { createLogger } from "vite";
22
+ import { existsSync as existsSync2 } from "fs";
21
23
  import { fileURLToPath } from "url";
22
24
 
23
25
  // src/vitest/vite-plugins.ts
@@ -161,6 +163,17 @@ function cjsInteropPlugin() {
161
163
  }
162
164
 
163
165
  // src/vitest/config.ts
166
+ function createTestLogger() {
167
+ const logger = createLogger();
168
+ const originalWarn = logger.warn.bind(logger);
169
+ logger.warn = (msg, options) => {
170
+ if (msg.includes("Missing pages directory") || msg.includes("points to missing source files") || msg.includes("Failed to load source map for")) {
171
+ return;
172
+ }
173
+ originalWarn(msg, options);
174
+ };
175
+ return logger;
176
+ }
164
177
  function normalizeGlobalSetup(globalSetup, value) {
165
178
  if (!globalSetup) {
166
179
  return [value];
@@ -186,7 +199,8 @@ function defineConfig2(options) {
186
199
  ...rest
187
200
  } = options;
188
201
  registerTestingIntegrationsForRoot(root, integrations);
189
- const globalSetupFilePath = fileURLToPath(new URL("./global-setup.ts", import.meta.url));
202
+ const globalSetupTsPath = fileURLToPath(new URL("./global-setup.ts", import.meta.url));
203
+ const globalSetupFilePath = existsSync2(globalSetupTsPath) ? globalSetupTsPath : fileURLToPath(new URL("./global-setup.js", import.meta.url));
190
204
  const testConfig = {
191
205
  ...rest.test,
192
206
  globalSetup: normalizeGlobalSetup(rest.test?.globalSetup, globalSetupFilePath)
@@ -216,9 +230,12 @@ function defineConfig2(options) {
216
230
  })
217
231
  )
218
232
  );
233
+ const testLogger = createTestLogger();
219
234
  return async ({ mode: viteMode, command }) => {
220
235
  const astroConfigFactory = await astroConfigFactoryPromise;
221
- return astroConfigFactory({ mode: viteMode, command });
236
+ const config = await astroConfigFactory({ mode: viteMode, command });
237
+ config.customLogger = testLogger;
238
+ return config;
222
239
  };
223
240
  }
224
241
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../node_modules/vitest/dist/config.js","../../src/vitest/config.ts","../../src/vitest/vite-plugins.ts"],"sourcesContent":["export { c as configDefaults, a as coverageConfigDefaults, d as defaultExclude, b as defaultInclude } from './chunks/defaults.BOqNVLsY.js';\nexport { mergeConfig } from 'vite';\nexport { d as defaultBrowserPort } from './chunks/constants.D_Q9UYh-.js';\nimport 'node:os';\nimport './chunks/env.D4Lgay0q.js';\nimport 'std-env';\n\nfunction defineConfig(config) {\n\treturn config;\n}\nfunction defineProject(config) {\n\treturn config;\n}\n\nexport { defineConfig, defineProject };\n","import { defineConfig as defineVitestConfig } from 'vitest/config';\nimport { fileURLToPath } from 'node:url';\nimport type { InlineConfig, PluginOption } from 'vite';\nimport type { Integration } from '../integrations/base.ts';\nimport { importAstroConfig } from '../importAstroConfig.ts';\nimport { vitePluginAstroComponentMarker } from '../vitePluginAstroComponentMarker.ts';\nimport { registerTestingIntegrationsForRoot } from '../testing/integration-config.ts';\nimport { cjsInteropPlugin, vitestPatchForSolidJs } from './vite-plugins.ts';\n\n// Type definition omits 'test' to allow Vitest-specific config options\n// Vite 8 type definitions conflict with Vitest config when used in monorepo\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Vitest config requires any type for test option\nexport type TestingDefineConfig = Omit<InlineConfig, 'plugins' | 'test'> & {\n integrations?: Integration[];\n plugins?: PluginOption[];\n astroConfigFile?: false | string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n test?: any;\n};\n\nfunction normalizeGlobalSetup(globalSetup: string | string[] | undefined, value: string) {\n // Inject our setup without clobbering any user-provided global setup hooks.\n if (!globalSetup) {\n return [value];\n }\n\n if (Array.isArray(globalSetup)) {\n if (globalSetup.includes(value)) {\n return globalSetup;\n }\n\n return [...globalSetup, value];\n }\n\n if (globalSetup === value) {\n return [globalSetup];\n }\n\n return [globalSetup, value];\n}\n\nexport function defineConfig(options: TestingDefineConfig) {\n const {\n integrations = [],\n plugins = [],\n root = process.cwd(),\n mode = 'test',\n astroConfigFile = false,\n ...rest\n } = options;\n\n registerTestingIntegrationsForRoot(root, integrations);\n\n const globalSetupFilePath = fileURLToPath(new URL('./global-setup.ts', import.meta.url));\n const testConfig = {\n ...rest.test,\n globalSetup: normalizeGlobalSetup(rest.test?.globalSetup, globalSetupFilePath)\n };\n\n // Cast to any to work around Vite 8 type conflicts in monorepo environments\n // where multiple Vite versions exist in node_modules\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Type conflict with Vite 8 in monorepo\n const vitestConfig = defineVitestConfig({\n ...rest,\n root,\n mode,\n test: testConfig,\n plugins: [\n cjsInteropPlugin(),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vitePluginAstroComponentMarker() as any,\n ...plugins\n ]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n\n const astroConfigFactoryPromise = Promise\n .all([\n importAstroConfig(root),\n Promise.all(integrations.map((integration) => integration.loadIntegration(root)))\n ])\n .then(([astroConfigModule, resolvedIntegrations]) =>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n astroConfigModule.getViteConfig(vitestConfig as any, {\n configFile: astroConfigFile,\n integrations: [...resolvedIntegrations, vitestPatchForSolidJs()]\n })\n );\n\n return async ({ mode: viteMode, command }: { mode: string; command: 'build' | 'serve' }) => {\n const astroConfigFactory = await astroConfigFactoryPromise;\n\n return astroConfigFactory({ mode: viteMode, command });\n };\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { AstroIntegration } from 'astro';\nimport type { Plugin } from 'vite';\n\ntype ResolveConfig = { resolve?: { alias?: Record<string, string> | Array<{ find: string | RegExp; replacement: string }> } };\n\nfunction findPackageDir(pkgName: string): string | null {\n let dir = process.cwd();\n\n while (true) {\n const candidate = join(dir, 'node_modules', pkgName);\n\n if (existsSync(join(candidate, 'package.json'))) {\n return candidate;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nexport function vitestPatchForSolidJs(): AstroIntegration {\n return {\n name: 'fix-solid',\n hooks: {\n 'astro:config:done': ({ config }) => {\n const solidPlugin = config.vite.plugins?.find(\n (plugin) => plugin && 'name' in plugin && plugin.name === 'solid'\n ) as Plugin | undefined;\n\n if (!solidPlugin) {\n return;\n }\n\n const originalConfigEnvironment = solidPlugin.configEnvironment;\n\n if (typeof originalConfigEnvironment !== 'function') {\n return;\n }\n\n // Use bracket notation to avoid type assignment issues\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (solidPlugin as any).configEnvironment = async (name: unknown, resolvedConfig: unknown, opts: unknown): Promise<void> => {\n await (originalConfigEnvironment as (name: unknown, config: unknown, opts: unknown) => Promise<void>)(name, resolvedConfig, opts);\n\n const config = resolvedConfig as ResolveConfig;\n\n config.resolve ??= {};\n const alias = config.resolve.alias;\n const replacement = 'solid-js/web/dist/web.js';\n\n if (Array.isArray(alias)) {\n const hasAlias = alias.some((entry) => {\n if (!entry || typeof entry !== 'object' || !('find' in entry)) {\n return false;\n }\n\n return entry.find === 'solid-js/web' || String(entry.find) === '/^solid-js\\\\/web$/';\n });\n\n if (!hasAlias) {\n alias.unshift({ find: /^solid-js\\/web$/, replacement });\n }\n\n return;\n }\n\n config.resolve!.alias = {\n ...(alias ?? {}),\n 'solid-js/web': replacement\n };\n };\n }\n }\n };\n}\n\nexport function cjsInteropPlugin(): Plugin {\n return {\n name: 'cjs-esm-interop',\n enforce: 'pre',\n resolveId(id) {\n if (id.startsWith('.') || id.startsWith('/') || id.startsWith('\\0') || id.includes('node_modules')) {\n return;\n }\n\n const parts = id.split('/');\n const pkgName = id.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];\n const subpath = parts.slice(pkgName.split('/').length).join('/');\n\n if (subpath && !['server-renderer', 'server', 'client'].includes(subpath)) {\n return;\n }\n\n try {\n const nmDir = findPackageDir(pkgName);\n\n if (!nmDir) {\n return;\n }\n\n const pkgJsonPath = join(nmDir, 'package.json');\n\n if (!existsSync(pkgJsonPath)) {\n return;\n }\n\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));\n\n const exportKey = subpath ? `./${subpath}` : '.';\n const exportEntry = pkgJson.exports?.[exportKey];\n\n if (exportEntry) {\n const importEntry = exportEntry.import;\n\n if (importEntry) {\n const esmPath =\n typeof importEntry === 'string'\n ? importEntry\n : importEntry.default || importEntry.node;\n\n if (esmPath) {\n const resolved = join(nmDir, esmPath);\n\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n }\n }\n\n if (!subpath && pkgJson.module) {\n const resolved = join(nmDir, pkgJson.module);\n\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n } catch {\n // Ignore resolution errors\n }\n },\n transform(code, id) {\n if (!id.includes('node_modules')) {\n return;\n }\n\n if (id.startsWith('\\0')) {\n return;\n }\n\n if (/\\bexport\\s+(default|const|let|var|function|class|\\{|\\*)/.test(code)) {\n return;\n }\n\n if (!code.includes('module.exports') && !code.includes('exports.')) {\n return;\n }\n\n const dirPath = id.substring(0, id.lastIndexOf('/'));\n const fileName = id;\n\n return {\n code: [\n 'import { createRequire as __createRequire } from \"module\";',\n `var __require = __createRequire(\"file://${dirPath}/\");`,\n 'var module = { exports: {} };',\n 'var exports = module.exports;',\n 'function require(id) { return __require(id); }',\n `var __dirname = ${JSON.stringify(dirPath)};`,\n `var __filename = ${JSON.stringify(fileName)};`,\n code,\n 'export default module.exports;'\n ].join('\\n'),\n map: null\n };\n }\n };\n}\n"],"mappings":"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","names":["config","defineConfig"]}
1
+ {"version":3,"sources":["../../../../../node_modules/vitest/dist/config.js","../../src/vitest/config.ts","../../src/vitest/vite-plugins.ts"],"sourcesContent":["export { c as configDefaults, a as coverageConfigDefaults, d as defaultExclude, b as defaultInclude } from './chunks/defaults.BOqNVLsY.js';\nexport { mergeConfig } from 'vite';\nexport { d as defaultBrowserPort } from './chunks/constants.D_Q9UYh-.js';\nimport 'node:os';\nimport './chunks/env.D4Lgay0q.js';\nimport 'std-env';\n\nfunction defineConfig(config) {\n\treturn config;\n}\nfunction defineProject(config) {\n\treturn config;\n}\n\nexport { defineConfig, defineProject };\n","import { defineConfig as defineVitestConfig } from 'vitest/config';\nimport { createLogger } from 'vite';\nimport { existsSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport type { InlineConfig, PluginOption } from 'vite';\nimport type { Integration } from '../integrations/base.ts';\nimport { importAstroConfig } from '../importAstroConfig.ts';\nimport { vitePluginAstroComponentMarker } from '../vitePluginAstroComponentMarker.ts';\nimport { registerTestingIntegrationsForRoot } from '../testing/integration-config.ts';\nimport { cjsInteropPlugin, vitestPatchForSolidJs } from './vite-plugins.ts';\n\n/**\n * Creates a Vite logger that suppresses known benign warnings in the test context:\n * - \"Missing pages directory\" — Astro warns when no src/pages exists, but component\n * tests don't use pages so this is always safe to ignore.\n * - \"points to missing source files\" — Sourcemap warnings from the `entities` package\n * which ships without source files. Not actionable.\n */\nfunction createTestLogger() {\n const logger = createLogger();\n const originalWarn = logger.warn.bind(logger);\n\n logger.warn = (msg, options) => {\n if (\n msg.includes('Missing pages directory') ||\n msg.includes('points to missing source files') ||\n msg.includes('Failed to load source map for')\n ) {\n return;\n }\n\n originalWarn(msg, options);\n };\n\n return logger;\n}\n\n// Type definition omits 'test' to allow Vitest-specific config options\n// Vite 8 type definitions conflict with Vitest config when used in monorepo\n \nexport type TestingDefineConfig = Omit<InlineConfig, 'plugins' | 'test'> & {\n integrations?: Integration[];\n plugins?: PluginOption[];\n astroConfigFile?: false | string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n test?: any;\n};\n\nfunction normalizeGlobalSetup(globalSetup: string | string[] | undefined, value: string) {\n // Inject our setup without clobbering any user-provided global setup hooks.\n if (!globalSetup) {\n return [value];\n }\n\n if (Array.isArray(globalSetup)) {\n if (globalSetup.includes(value)) {\n return globalSetup;\n }\n\n return [...globalSetup, value];\n }\n\n if (globalSetup === value) {\n return [globalSetup];\n }\n\n return [globalSetup, value];\n}\n\nexport function defineConfig(options: TestingDefineConfig) {\n const {\n integrations = [],\n plugins = [],\n root = process.cwd(),\n mode = 'test',\n astroConfigFile = false,\n ...rest\n } = options;\n\n registerTestingIntegrationsForRoot(root, integrations);\n\n // In the workspace, import.meta.url points to src/vitest/config.ts so global-setup.ts exists.\n // In a compiled tarball install, import.meta.url points to dist/vitest/config.js so we fall\n // back to global-setup.js which is the tsup-compiled output.\n const globalSetupTsPath = fileURLToPath(new URL('./global-setup.ts', import.meta.url));\n const globalSetupFilePath = existsSync(globalSetupTsPath)\n ? globalSetupTsPath\n : fileURLToPath(new URL('./global-setup.js', import.meta.url));\n const testConfig = {\n ...rest.test,\n globalSetup: normalizeGlobalSetup(rest.test?.globalSetup, globalSetupFilePath)\n };\n\n // Cast to any to work around Vite 8 type conflicts in monorepo environments\n // where multiple Vite versions exist in node_modules\n \n const vitestConfig = defineVitestConfig({\n ...rest,\n root,\n mode,\n test: testConfig,\n plugins: [\n cjsInteropPlugin(),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n vitePluginAstroComponentMarker() as any,\n ...plugins\n ]\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any);\n\n const astroConfigFactoryPromise = Promise\n .all([\n importAstroConfig(root),\n Promise.all(integrations.map((integration) => integration.loadIntegration(root)))\n ])\n .then(([astroConfigModule, resolvedIntegrations]) =>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n astroConfigModule.getViteConfig(vitestConfig as any, {\n configFile: astroConfigFile,\n integrations: [...resolvedIntegrations, vitestPatchForSolidJs()]\n })\n );\n\n const testLogger = createTestLogger();\n\n return async ({ mode: viteMode, command }: { mode: string; command: 'build' | 'serve' }) => {\n const astroConfigFactory = await astroConfigFactoryPromise;\n const config = await astroConfigFactory({ mode: viteMode, command });\n\n // Inject the logger — this overrides any logger Astro may have set,\n // which is intentional since we only filter benign test-context noise.\n config.customLogger = testLogger;\n\n return config;\n };\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { AstroIntegration } from 'astro';\nimport type { Plugin } from 'vite';\n\ntype ResolveConfig = { resolve?: { alias?: Record<string, string> | Array<{ find: string | RegExp; replacement: string }> } };\n\nfunction findPackageDir(pkgName: string): string | null {\n let dir = process.cwd();\n\n while (true) {\n const candidate = join(dir, 'node_modules', pkgName);\n\n if (existsSync(join(candidate, 'package.json'))) {\n return candidate;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n break;\n }\n\n dir = parent;\n }\n\n return null;\n}\n\nexport function vitestPatchForSolidJs(): AstroIntegration {\n return {\n name: 'fix-solid',\n hooks: {\n 'astro:config:done': ({ config }) => {\n const solidPlugin = config.vite.plugins?.find(\n (plugin) => plugin && 'name' in plugin && plugin.name === 'solid'\n ) as Plugin | undefined;\n\n if (!solidPlugin) {\n return;\n }\n\n const originalConfigEnvironment = solidPlugin.configEnvironment;\n\n if (typeof originalConfigEnvironment !== 'function') {\n return;\n }\n\n // Use bracket notation to avoid type assignment issues\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (solidPlugin as any).configEnvironment = async (name: unknown, resolvedConfig: unknown, opts: unknown): Promise<void> => {\n await (originalConfigEnvironment as (name: unknown, config: unknown, opts: unknown) => Promise<void>)(name, resolvedConfig, opts);\n\n const config = resolvedConfig as ResolveConfig;\n\n config.resolve ??= {};\n const alias = config.resolve.alias;\n const replacement = 'solid-js/web/dist/web.js';\n\n if (Array.isArray(alias)) {\n const hasAlias = alias.some((entry) => {\n if (!entry || typeof entry !== 'object' || !('find' in entry)) {\n return false;\n }\n\n return entry.find === 'solid-js/web' || String(entry.find) === '/^solid-js\\\\/web$/';\n });\n\n if (!hasAlias) {\n alias.unshift({ find: /^solid-js\\/web$/, replacement });\n }\n\n return;\n }\n\n config.resolve!.alias = {\n ...(alias ?? {}),\n 'solid-js/web': replacement\n };\n };\n }\n }\n };\n}\n\nexport function cjsInteropPlugin(): Plugin {\n return {\n name: 'cjs-esm-interop',\n enforce: 'pre',\n resolveId(id) {\n if (id.startsWith('.') || id.startsWith('/') || id.startsWith('\\0') || id.includes('node_modules')) {\n return;\n }\n\n const parts = id.split('/');\n const pkgName = id.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];\n const subpath = parts.slice(pkgName.split('/').length).join('/');\n\n if (subpath && !['server-renderer', 'server', 'client'].includes(subpath)) {\n return;\n }\n\n try {\n const nmDir = findPackageDir(pkgName);\n\n if (!nmDir) {\n return;\n }\n\n const pkgJsonPath = join(nmDir, 'package.json');\n\n if (!existsSync(pkgJsonPath)) {\n return;\n }\n\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));\n\n const exportKey = subpath ? `./${subpath}` : '.';\n const exportEntry = pkgJson.exports?.[exportKey];\n\n if (exportEntry) {\n const importEntry = exportEntry.import;\n\n if (importEntry) {\n const esmPath =\n typeof importEntry === 'string'\n ? importEntry\n : importEntry.default || importEntry.node;\n\n if (esmPath) {\n const resolved = join(nmDir, esmPath);\n\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n }\n }\n\n if (!subpath && pkgJson.module) {\n const resolved = join(nmDir, pkgJson.module);\n\n if (existsSync(resolved)) {\n return resolved;\n }\n }\n } catch {\n // Ignore resolution errors\n }\n },\n transform(code, id) {\n if (!id.includes('node_modules')) {\n return;\n }\n\n if (id.startsWith('\\0')) {\n return;\n }\n\n if (/\\bexport\\s+(default|const|let|var|function|class|\\{|\\*)/.test(code)) {\n return;\n }\n\n if (!code.includes('module.exports') && !code.includes('exports.')) {\n return;\n }\n\n const dirPath = id.substring(0, id.lastIndexOf('/'));\n const fileName = id;\n\n return {\n code: [\n 'import { createRequire as __createRequire } from \"module\";',\n `var __require = __createRequire(\"file://${dirPath}/\");`,\n 'var module = { exports: {} };',\n 'var exports = module.exports;',\n 'function require(id) { return __require(id); }',\n `var __dirname = ${JSON.stringify(dirPath)};`,\n `var __filename = ${JSON.stringify(fileName)};`,\n code,\n 'export default module.exports;'\n ].join('\\n'),\n map: null\n };\n }\n };\n}\n"],"mappings":"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","names":["existsSync","config","defineConfig","existsSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook-astro/framework",
3
- "version": "1.0.3",
3
+ "version": "1.1.1",
4
4
  "description": "Community-supported Storybook framework for Astro 5 & 6 components",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,6 +40,10 @@
40
40
  "types": "./src/vitest/index.ts",
41
41
  "import": "./dist/vitest/index.js"
42
42
  },
43
+ "./node": {
44
+ "types": "./src/node/index.ts",
45
+ "import": "./dist/node/index.js"
46
+ },
43
47
  "./preset": {
44
48
  "types": "./preset.ts",
45
49
  "import": "./dist/preset.js"
@@ -65,6 +69,10 @@
65
69
  "types": "./src/vitest/index.ts",
66
70
  "import": "./dist/vitest/index.js"
67
71
  },
72
+ "./node": {
73
+ "types": "./src/node/index.ts",
74
+ "import": "./dist/node/index.js"
75
+ },
68
76
  "./preset": {
69
77
  "types": "./preset.ts",
70
78
  "import": "./dist/preset.js"
@@ -159,8 +167,8 @@
159
167
  }
160
168
  },
161
169
  "dependencies": {
162
- "@storybook-astro/renderer": "1.0.3",
163
- "msw": "^2.12.10",
170
+ "@storybook-astro/renderer": "1.1.1",
171
+ "hono": "^4.11.12",
164
172
  "sanitize-html": "^2.17.0",
165
173
  "vite": "^6.4.1 || ^7.0.0 || ^8.0.0"
166
174
  }
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export type {
7
7
  StrictArgs
8
8
  } from 'storybook/internal/types';
9
9
 
10
+ import { definePreview as definePreviewBase, type PreviewAddon, type InferTypes, type Preview as CsfPreview } from 'storybook/internal/csf';
10
11
  import type { ProjectAnnotations } from 'storybook/internal/types';
11
12
  import type { AstroRenderer } from './portable-stories.ts';
12
13
 
@@ -24,12 +25,31 @@ export {
24
25
  // Export framework types
25
26
  export type {
26
27
  FrameworkOptions,
28
+ RenderMode,
29
+ RenderStoryInput,
30
+ ServerBuildOptions,
27
31
  SanitizationOptions,
28
32
  StoryRulesOptions,
29
33
  StorybookConfig
30
34
  } from './types.ts';
31
- export type { StoryRule, StoryRulesConfig, StoryRuleUse, StoryRuleUseContext } from './rules.ts';
35
+ export type {
36
+ StoryRuleCleanup,
37
+ StoryRule,
38
+ StoryRulesConfig,
39
+ StoryRuleSelection,
40
+ StoryRuleSelectionInput,
41
+ StoryRuleStory,
42
+ StoryRuleUse,
43
+ StoryRuleUseContext
44
+ } from './rules.ts';
32
45
  export { defineStoryRules } from './rules.ts';
33
46
 
34
47
  // Re-export preset functionality for framework usage
35
48
  export { core, viteFinal } from './preset.ts';
49
+
50
+ // Preview configuration helper
51
+ export function definePreview<Addons extends PreviewAddon<never>[] = []>(
52
+ input: ProjectAnnotations<AstroRenderer> & { addons?: Addons }
53
+ ): CsfPreview<AstroRenderer & InferTypes<Addons>> {
54
+ return definePreviewBase<AstroRenderer, Addons>(input);
55
+ }