@storybook-astro/framework 1.5.0 → 1.6.0-canary.2

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/testing.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  renderViaTestingRendererDaemon,
3
3
  runWithWorkingDirectory
4
- } from "./chunk-XVVIGJV6.js";
4
+ } from "./chunk-EFR4J5QH.js";
5
5
  import {
6
6
  resolveTestingIntegrationsForRoot
7
7
  } from "./chunk-WUTCMEF5.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-KXAAX3GN.js";
13
13
  import {
14
14
  ssrLoadModuleWithFsFallback
15
- } from "./chunk-7UF6LK4Z.js";
15
+ } from "./chunk-BF3USGCF.js";
16
16
  import "./chunk-PUTCAN6X.js";
17
17
  import "./chunk-7YBE4TTI.js";
18
18
  import "./chunk-B5HHF6FC.js";
@@ -213,7 +213,7 @@ async function getAstroContainer() {
213
213
  }
214
214
  async function getAstroSsrViteServer(resolveFrom) {
215
215
  if (!astroSsrViteServerPromises.has(resolveFrom)) {
216
- const { createViteServer } = await import("./viteStorybookAstroMiddlewarePlugin-LUMKF7NG.js");
216
+ const { createViteServer } = await import("./viteStorybookAstroMiddlewarePlugin-QZV7LGWZ.js");
217
217
  const integrations = getTestingIntegrations(resolveFrom);
218
218
  astroSsrViteServerPromises.set(
219
219
  resolveFrom,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createViteServer,
3
3
  vitePluginStorybookAstroMiddleware
4
- } from "./chunk-7UF6LK4Z.js";
4
+ } from "./chunk-BF3USGCF.js";
5
5
  import "./chunk-PUTCAN6X.js";
6
6
  import "./chunk-B5HHF6FC.js";
7
7
  import "./chunk-G3PMV62Z.js";
@@ -9,4 +9,4 @@ export {
9
9
  createViteServer,
10
10
  vitePluginStorybookAstroMiddleware
11
11
  };
12
- //# sourceMappingURL=viteStorybookAstroMiddlewarePlugin-LUMKF7NG.js.map
12
+ //# sourceMappingURL=viteStorybookAstroMiddlewarePlugin-QZV7LGWZ.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  TESTING_RENDERER_DAEMON_URL_ENV,
3
3
  startTestingRendererDaemon
4
- } from "../chunk-XVVIGJV6.js";
4
+ } from "../chunk-EFR4J5QH.js";
5
5
  import "../chunk-WUTCMEF5.js";
6
- import "../chunk-7UF6LK4Z.js";
6
+ import "../chunk-BF3USGCF.js";
7
7
  import "../chunk-PUTCAN6X.js";
8
8
  import "../chunk-7YBE4TTI.js";
9
9
  import "../chunk-B5HHF6FC.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook-astro/framework",
3
- "version": "1.5.0",
3
+ "version": "1.6.0-canary.2",
4
4
  "description": "Community-supported Storybook framework for Astro 5 & 6 components",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -57,10 +57,10 @@
57
57
  "./package.json": "./package.json"
58
58
  },
59
59
  "scripts": {
60
- "build": "tsup",
60
+ "build": "tsup && node scripts/patch-shim-ref.mjs",
61
61
  "dev": "tsup --watch --no-clean",
62
62
  "lint": "eslint .",
63
- "prepublishOnly": "tsup"
63
+ "prepublishOnly": "tsup && node scripts/patch-shim-ref.mjs"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@storybook/preact": "^10.0.0",
@@ -145,7 +145,7 @@
145
145
  }
146
146
  },
147
147
  "dependencies": {
148
- "@storybook-astro/renderer": "1.5.0",
148
+ "@storybook-astro/renderer": "1.6.0-canary.2",
149
149
  "hono": "^4.11.12",
150
150
  "sanitize-html": "^2.17.0",
151
151
  "tsconfck": "^3.1.6",
package/src/index.ts CHANGED
@@ -8,7 +8,9 @@ export type {
8
8
  } from 'storybook/internal/types';
9
9
 
10
10
  import { definePreview as definePreviewBase, type PreviewAddon, type InferTypes, type Preview as CsfPreview } from 'storybook/internal/csf';
11
+ import { combineParameters } from 'storybook/internal/preview-api';
11
12
  import type { ArgsStoryFn, ProjectAnnotations, RenderContext, Renderer } from 'storybook/internal/types';
13
+ import { defaultPreviewParameters } from '@storybook-astro/renderer/preview-defaults';
12
14
  import type { AstroRenderer } from './portable-stories.ts';
13
15
 
14
16
  // CSF4 consumers reach `definePreview` from the preview iframe; Node test setup
@@ -99,7 +101,14 @@ export function definePreview<Addons extends PreviewAddon<never>[] = []>(
99
101
 
100
102
  return definePreviewBase<AstroRenderer, Addons>({
101
103
  ...input,
102
- parameters: { renderer: 'astro' as const, ...input.parameters },
104
+ // CSF-factory stories compose only this `definePreview` chain — they never
105
+ // see the renderer's entry-preview annotation that carries our default
106
+ // parameters (e.g. the Docs story height). Merge those defaults here, under
107
+ // the user's parameters so their overrides still win.
108
+ parameters: combineParameters(defaultPreviewParameters, {
109
+ renderer: 'astro' as const,
110
+ ...input.parameters
111
+ }),
103
112
  render: input.render ?? composedRender,
104
113
  renderToCanvas: input.renderToCanvas ?? composedRenderToCanvas
105
114
  });
@@ -46,7 +46,7 @@ export async function buildHydratedComponentAssets(
46
46
  (
47
47
  await Promise.all(
48
48
  resolvedComponentPaths.map((componentPath) =>
49
- collectHydratedComponentPaths(componentPath)
49
+ collectHydratedComponentPaths(componentPath, options.resolveFrom)
50
50
  )
51
51
  )
52
52
  ).flat()
@@ -68,6 +68,10 @@ export async function buildHydratedComponentAssets(
68
68
  ...hydratedComponentPaths.map((componentPath, index) => [`component-${index}`, componentPath]),
69
69
  ...clientEntrypoints.map((entrypoint, index) => [`renderer-${index}`, entrypoint])
70
70
  ]);
71
+
72
+ // build.watch is not set, so result is always a build output, never a watcher.
73
+ type BuiltOutput = { output: (Rollup.OutputAsset | Rollup.OutputChunk)[] };
74
+
71
75
  const buildConfig = {
72
76
  root: options.resolveFrom,
73
77
  build: {
@@ -77,7 +81,7 @@ export async function buildHydratedComponentAssets(
77
81
  manifest: false,
78
82
  rollupOptions: {
79
83
  input: entryNames,
80
- preserveEntrySignatures: 'strict',
84
+ preserveEntrySignatures: 'strict' as const,
81
85
  output: {
82
86
  entryFileNames: '_astro/[name]-[hash].js',
83
87
  chunkFileNames: '_astro/[name]-[hash].js',
@@ -93,10 +97,10 @@ export async function buildHydratedComponentAssets(
93
97
  'production',
94
98
  'build'
95
99
  );
96
- const buildOutput = await build(finalConfig);
97
- const output = Array.isArray(buildOutput)
98
- ? buildOutput.flatMap((result) => result.output)
99
- : buildOutput.output;
100
+ const buildResult = (await build(finalConfig)) as BuiltOutput | BuiltOutput[];
101
+ const output = Array.isArray(buildResult)
102
+ ? buildResult.flatMap((result) => result.output)
103
+ : buildResult.output;
100
104
  const chunksByFileName = new Map<string, Rollup.OutputChunk>();
101
105
 
102
106
  for (const item of output) {
@@ -108,9 +108,8 @@ export async function renderProductionStoryToHtml(options: {
108
108
  const componentPath = resolveProjectImportPath(options.story.componentPath, options.resolveFrom);
109
109
  const storyModule = await options.runtime.loadModule(storyModulePath);
110
110
  const defaultStoryMeta = isRecord(storyModule.default) ? storyModule.default : {};
111
- const selectedStoryExport = isRecord(storyModule[options.story.exportName])
112
- ? storyModule[options.story.exportName]
113
- : {};
111
+ const rawStoryExport: unknown = storyModule[options.story.exportName];
112
+ const selectedStoryExport: Record<string, unknown> = isRecord(rawStoryExport) ? rawStoryExport : {};
114
113
 
115
114
  if (typeof defaultStoryMeta.component !== 'function') {
116
115
  throw new Error(
@@ -1,3 +1,4 @@
1
+ /// <reference types="vite/client" />
1
2
  import type {
2
3
  RenderComponentInput,
3
4
  RenderPromise,
@@ -52,7 +52,8 @@ export async function createStorySsrViteServer(options: {
52
52
  vitePluginAstroVueFallback(),
53
53
  vitePluginAstroRoutesFallback(),
54
54
  vitePluginStoryModuleMocks(),
55
- createTrackedSpecifierStubPlugin(options.trackedSpecifiers)
55
+ createTrackedSpecifierStubPlugin(options.trackedSpecifiers),
56
+ createStorybookBrowserStubPlugin()
56
57
  ]
57
58
  });
58
59
 
@@ -251,3 +252,29 @@ function createTrackedSpecifierStubPlugin(trackedSpecifiers: Set<string>): Plugi
251
252
  function isRecord(value: unknown): value is Record<string, unknown> {
252
253
  return typeof value === 'object' && value !== null;
253
254
  }
255
+
256
+ // Stubs Storybook's browser-only packages so story files that import docs
257
+ // blocks (e.g. `import { Controls } from '@storybook/blocks'`) don't
258
+ // trigger `document is not defined` during SSR prerendering. We only need
259
+ // component/args from story modules — docs block components are never called.
260
+ function createStorybookBrowserStubPlugin(): Plugin {
261
+ const STUB_ID = '\0storybook-astro-browser-stub';
262
+
263
+ return {
264
+ name: 'storybook-astro:storybook-browser-stubs',
265
+ resolveId(id: string) {
266
+ if (id === '@storybook/blocks') {
267
+ return STUB_ID;
268
+ }
269
+
270
+ return null;
271
+ },
272
+ load(id: string) {
273
+ if (id === STUB_ID) {
274
+ return 'export {};';
275
+ }
276
+
277
+ return null;
278
+ }
279
+ } satisfies Plugin;
280
+ }
@@ -1,8 +1,8 @@
1
- import type { PluginOption } from 'vite';
1
+ import type { Plugin, PluginOption } from 'vite';
2
2
  import { describe, expect, test } from 'vitest';
3
3
  import { SERVER_AUTH_MODULE_ID, serverAuthPlugin } from './serverAuthPlugin.ts';
4
4
 
5
- function getPlugin(pluginOption: PluginOption) {
5
+ function getPlugin(pluginOption: PluginOption): Plugin {
6
6
  if (Array.isArray(pluginOption)) {
7
7
  throw new Error('Expected a single plugin object, but got a plugin array.');
8
8
  }
@@ -11,10 +11,10 @@ function getPlugin(pluginOption: PluginOption) {
11
11
  throw new Error('Expected plugin option to be an object.');
12
12
  }
13
13
 
14
- return pluginOption;
14
+ return pluginOption as Plugin;
15
15
  }
16
16
 
17
- function getHookHandler<T extends (...args: unknown[]) => unknown>(hook: unknown): T {
17
+ function getHookHandler<T>(hook: unknown): T {
18
18
  if (typeof hook === 'function') {
19
19
  return hook as T;
20
20
  }
@@ -1,8 +1,8 @@
1
- import type { PluginOption } from 'vite';
1
+ import type { Plugin, PluginOption } from 'vite';
2
2
  import { describe, expect, test, vi } from 'vitest';
3
3
  import { createVirtualModule } from './virtualModulePlugin.ts';
4
4
 
5
- function getPlugin(pluginOption: PluginOption) {
5
+ function getPlugin(pluginOption: PluginOption): Plugin {
6
6
  if (Array.isArray(pluginOption)) {
7
7
  throw new Error('Expected a single plugin object, but got a plugin array.');
8
8
  }
@@ -11,10 +11,10 @@ function getPlugin(pluginOption: PluginOption) {
11
11
  throw new Error('Expected plugin option to be an object.');
12
12
  }
13
13
 
14
- return pluginOption;
14
+ return pluginOption as Plugin;
15
15
  }
16
16
 
17
- function getHookHandler<T extends (...args: unknown[]) => unknown>(hook: unknown): T {
17
+ function getHookHandler<T>(hook: unknown): T {
18
18
  if (typeof hook === 'function') {
19
19
  return hook as T;
20
20
  }
@@ -1,4 +1,4 @@
1
- import { mergeConfig, type InlineConfig } from 'vite';
1
+ import { mergeConfig, type InlineConfig, type Plugin } from 'vite';
2
2
  import type { Integration } from './integrations/index.ts';
3
3
  import { importAstroConfig } from './importAstroConfig.ts';
4
4
  import { loadUserAstroIntegrations } from './loadUserAstroConfig.ts';
@@ -58,13 +58,11 @@ export async function mergeWithAstroConfig(
58
58
  command
59
59
  });
60
60
 
61
- const filteredPlugins = astroConfig
62
- .plugins!.flat()
63
- .filter(
64
- (plugin) =>
65
- plugin &&
66
- 'name' in plugin &&
67
- !ASTRO_PLUGINS_THAT_ARE_SUPPOSEDLY_NOT_NEEDED_IN_STORYBOOK.includes(plugin.name)
61
+ const filteredPlugins = (astroConfig.plugins!.flat() as (Plugin | null | undefined | false)[])
62
+ .filter((plugin): plugin is Plugin =>
63
+ plugin != null &&
64
+ plugin !== false &&
65
+ !ASTRO_PLUGINS_THAT_ARE_SUPPOSEDLY_NOT_NEEDED_IN_STORYBOOK.includes(plugin.name)
68
66
  );
69
67
 
70
68
  return mergeConfig(config, {
@@ -163,6 +163,22 @@ export function vitePluginAstroFonts(
163
163
  };
164
164
  }
165
165
 
166
+ /**
167
+ * Resolves all font families and returns a single CSS string containing
168
+ * all @font-face declarations and :root CSS variable bindings. Used to
169
+ * inject font CSS into the browser via Storybook's render response.
170
+ */
171
+ export async function generateFontCss(families: StorybookFontFamily[], rootDir: string): Promise<string> {
172
+ if (families.length === 0) {
173
+ return '';
174
+ }
175
+
176
+ const root = pathToFileURL(rootDir.endsWith('/') ? rootDir : rootDir + '/');
177
+ const { componentEntries } = await resolveAllFamilies(families, root);
178
+
179
+ return componentEntries.map(([, { css }]) => css).join('\n');
180
+ }
181
+
166
182
  async function resolveAllFamilies(
167
183
  families: StorybookFontFamily[],
168
184
  root: URL
@@ -7,7 +7,7 @@ import type { FrameworkOptions } from './types.ts';
7
7
  import type { Integration } from './integrations/index.ts';
8
8
  import { importAstroConfig } from './importAstroConfig.ts';
9
9
  import { viteAstroContainerRenderersPlugin } from './viteAstroContainerRenderersPlugin.ts';
10
- import { vitePluginAstroFonts } from './vitePluginAstroFonts.ts';
10
+ import { vitePluginAstroFonts, generateFontCss } from './vitePluginAstroFonts.ts';
11
11
  import { vitePluginAstroIntegrationOptsFallback } from './vitePluginAstroIntegrationOptsFallback.ts';
12
12
  import { vitePluginAstroVueFallback } from './vitePluginAstroVueFallback.ts';
13
13
  import { vitePluginAstroRoutesFallback } from './vitePluginAstroRoutesFallback.ts';
@@ -26,6 +26,8 @@ export async function vitePluginStorybookAstroMiddleware(options: FrameworkOptio
26
26
  const vitePlugin = {
27
27
  name: 'storybook-astro-middleware-plugin',
28
28
  async configureServer(server) {
29
+ const fontCss = await generateFontCss(options.fonts ?? [], resolveFrom);
30
+
29
31
  viteServer = await createViteServer(options.integrations ?? [], resolveFrom, options.fonts);
30
32
  const storyRulesConfigFilePath = resolveRulesConfigFilePath(options.storyRules, resolveFrom);
31
33
 
@@ -65,7 +67,14 @@ export async function vitePluginStorybookAstroMiddleware(options: FrameworkOptio
65
67
  server.ws.on('astro:render:request', async (data: RenderRequestMessage['data']) => {
66
68
  try {
67
69
  const handler = await handlerPromise;
68
- const html = await handler(data);
70
+ const componentHtml = await handler(data);
71
+ // @font-face rules and :root CSS variable bindings must reach the
72
+ // browser. The Astro Container API renders a component fragment, not
73
+ // a full page, so Astro's font pipeline never gets to write them into
74
+ // a <head>. Prepending a <style> block to the fragment is the
75
+ // equivalent — @font-face and :root rules apply globally wherever
76
+ // the <style> element appears in the document.
77
+ const html = fontCss ? `<style>\n${fontCss}\n</style>${componentHtml}` : componentHtml;
69
78
 
70
79
  server.ws.send('astro:render:response', {
71
80
  html,
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/viteStorybookAstroMiddlewarePlugin.ts","../src/vite/virtualModulePlugin.ts","../src/viteAstroContainerRenderersPlugin.ts","../src/vitePluginAstroFonts.ts","../src/vitePluginAstroIntegrationOptsFallback.ts","../src/vitePluginAstroVueFallback.ts","../src/vitePluginAstroRoutesFallback.ts","../src/vitePluginStoryModuleMocks.ts","../src/lib/ssr-load-module-with-fs-fallback.ts","../src/rules-options.ts","../src/loadUserAstroConfig.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport { fileURLToPath } from 'node:url';\nimport type { ServerResponse } from 'node:http';\nimport { createServer, createLogger, type Connect, type PluginOption, type ViteDevServer } from 'vite';\nimport type { RenderRequestMessage, RenderResponseMessage } from '@storybook-astro/renderer/types';\nimport type { FrameworkOptions } from './types.ts';\nimport type { Integration } from './integrations/index.ts';\nimport { importAstroConfig } from './importAstroConfig.ts';\nimport { viteAstroContainerRenderersPlugin } from './viteAstroContainerRenderersPlugin.ts';\nimport { vitePluginAstroFonts } from './vitePluginAstroFonts.ts';\nimport { vitePluginAstroIntegrationOptsFallback } from './vitePluginAstroIntegrationOptsFallback.ts';\nimport { vitePluginAstroVueFallback } from './vitePluginAstroVueFallback.ts';\nimport { vitePluginAstroRoutesFallback } from './vitePluginAstroRoutesFallback.ts';\nimport { vitePluginStoryModuleMocks } from './vitePluginStoryModuleMocks.ts';\nimport { ssrLoadModuleWithFsFallback } from './lib/ssr-load-module-with-fs-fallback.ts';\nimport { resolveRulesConfigFilePath } from './rules-options.ts';\nimport { loadUserAstroIntegrations } from './loadUserAstroConfig.ts';\n\nexport async function vitePluginStorybookAstroMiddleware(options: FrameworkOptions) {\n // The internal Vite server is created lazily inside configureServer (dev-only).\n // During builds, configureServer never fires, so no server is created.\n let viteServer: ViteDevServer | null = null;\n\n const resolveFrom = options.resolveFrom ?? process.cwd();\n\n const vitePlugin = {\n name: 'storybook-astro-middleware-plugin',\n async configureServer(server) {\n viteServer = await createViteServer(options.integrations ?? [], resolveFrom, options.fonts);\n const storyRulesConfigFilePath = resolveRulesConfigFilePath(options.storyRules, resolveFrom);\n\n const filePath = fileURLToPath(new URL('./middleware', import.meta.url));\n const middleware = await viteServer.ssrLoadModule(filePath, {\n fixStacktrace: true\n });\n\n const createHandler = () => middleware.handlerFactory(options.integrations ?? [], {\n sanitization: options.sanitization,\n rulesConfigFilePath: storyRulesConfigFilePath,\n resolveRulesConfigModule: () =>\n loadRulesConfigModule(viteServer!, storyRulesConfigFilePath),\n invalidateModuleGraph: () => {\n viteServer?.moduleGraph.invalidateAll();\n },\n loadModule: (id: string) =>\n ssrLoadModuleWithFsFallback(viteServer!, id, {\n fixStacktrace: true\n }),\n resolveFrom\n });\n\n let handlerPromise = createHandler();\n\n const resetHandler = () => {\n handlerPromise = createHandler();\n };\n\n server.watcher.on('add', resetHandler);\n server.watcher.on('change', resetHandler);\n server.watcher.on('unlink', resetHandler);\n viteServer.watcher.on('add', resetHandler);\n viteServer.watcher.on('change', resetHandler);\n viteServer.watcher.on('unlink', resetHandler);\n\n server.ws.on('astro:render:request', async (data: RenderRequestMessage['data']) => {\n try {\n const handler = await handlerPromise;\n const html = await handler(data);\n\n server.ws.send('astro:render:response', {\n html,\n id: data.id\n } satisfies RenderResponseMessage['data']);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n const errorStack = err instanceof Error ? err.stack : '';\n\n console.error('[storybook-astro] Render error:', errorMessage);\n if (errorStack) {console.error(errorStack);}\n server.ws.send('astro:render:response', {\n id: data.id,\n html:\n '<div style=\"background: #d73838; padding: 12px; color: #f0f0f0; font-family: monospace; border-radius: 4px\">' +\n '<strong>Error rendering Astro component</strong><br/>' +\n '<pre style=\"white-space: pre-wrap; margin-top: 8px; font-size: 12px\">' +\n errorMessage.replace(/</g, '&lt;').replace(/>/g, '&gt;') +\n '</pre></div>'\n } satisfies RenderResponseMessage['data']);\n }\n });\n }\n } satisfies PluginOption;\n\n // Create asset serving plugin (only active in dev when viteServer exists)\n const assetServingPlugin = {\n name: 'storybook-astro-assets',\n configureServer(server: ViteDevServer) {\n server.middlewares.use('/_image', (req: Connect.IncomingMessage, res: ServerResponse, next: Connect.NextFunction) => {\n if (!viteServer) {\n next();\n\n return;\n }\n // Forward the request to the Astro vite server\n viteServer.middlewares.handle(req, res, (err?: unknown) => {\n if (err) {\n console.error('Asset serving error:', err);\n next();\n }\n });\n });\n }\n };\n\n // The extracted CSS plugins from Astro's internal Vite server cause Vue SFC\n // <style> blocks to be double-processed (once by these plugins, once by\n // Storybook's built-in CSS plugins), resulting in PostCSS errors.\n //\n // Solution: Don't extract Astro's CSS plugins. Storybook's built-in CSS\n // plugins handle both Vue styles AND Astro style sub-modules (which are\n // standard CSS imports like `Component.astro?astro&type=style&index=0&lang.css`).\n //\n // The Astro internal server's CSS plugins are only needed for SSR rendering\n // within that server - they don't need to be shared with Storybook's server.\n return {\n vitePlugin,\n viteConfig: {\n plugins: [\n assetServingPlugin\n ].filter(Boolean)\n }\n };\n}\n\n/**\n * Creates a Vite logger that silences known benign warnings emitted by Astro's\n * Vite plugin in the SSR server context:\n * - \"Missing pages directory\" — Storybook and test contexts have no src/pages.\n * - \"points to missing source files\" — Sourcemap gaps in the `entities` package.\n */\nfunction createSsrServerLogger() {\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\nexport async function createViteServer(\n integrations: Integration[],\n resolveFrom = process.cwd(),\n fonts?: FrameworkOptions['fonts']\n) {\n const { getViteConfig, passthroughImageService } = await importAstroConfig(resolveFrom);\n const safeIntegrations = integrations ?? [];\n const projectAstroResolutionPlugin = createProjectAstroResolutionPlugin(resolveFrom);\n\n const frameworkIntegrations = await Promise.all(\n safeIntegrations.map((integration) => integration.loadIntegration(resolveFrom))\n );\n\n const userIntegrations = await loadUserAstroIntegrations(resolveFrom);\n const frameworkNames = new Set(frameworkIntegrations.map(i => i.name));\n const extraIntegrations = userIntegrations.filter(i => !frameworkNames.has(i.name));\n\n const config = await getViteConfig(\n { root: resolveFrom },\n {\n configFile: false,\n integrations: [...frameworkIntegrations, ...extraIntegrations],\n // Use the passthrough image service so nested components that use <Image>\n // from astro:assets render as plain <img> tags without triggering image\n // optimization (which fails in the Storybook SSR context).\n image: { service: passthroughImageService() }\n }\n )({ mode: 'development', command: 'serve' });\n\n const viteServer = await createServer({\n configFile: false,\n ...config,\n customLogger: createSsrServerLogger(),\n plugins: [\n projectAstroResolutionPlugin,\n // Fallbacks must come first to intercept before Astro's plugins\n vitePluginAstroFonts({ fonts, root: resolveFrom }),\n vitePluginAstroIntegrationOptsFallback(),\n vitePluginAstroVueFallback(),\n vitePluginAstroRoutesFallback(),\n vitePluginStoryModuleMocks(),\n ...(config.plugins?.filter(Boolean) ?? []),\n viteAstroContainerRenderersPlugin(safeIntegrations)\n ]\n });\n\n // Initialize the server's plugin container to ensure all plugins are ready.\n // Without this, some plugins (like vite:css) may have uninitialized state\n // when ssrLoadModule is called.\n await viteServer.pluginContainer.buildStart({});\n\n return viteServer;\n}\n\nfunction createProjectAstroResolutionPlugin(resolveFrom: string): PluginOption {\n const require = createRequire(import.meta.url);\n\n return {\n name: 'storybook-astro:resolve-project-astro',\n enforce: 'pre',\n resolveId(id: string) {\n if (id !== 'astro' && !id.startsWith('astro/')) {\n return null;\n }\n\n try {\n return require.resolve(id, {\n paths: [resolveFrom]\n });\n } catch {\n return null;\n }\n }\n } satisfies PluginOption;\n}\n\nasync function loadRulesConfigModule(viteServer: ViteDevServer, configFilePath?: string) {\n if (!configFilePath) {\n return undefined;\n }\n\n try {\n return await ssrLoadModuleWithFsFallback(viteServer, configFilePath, {\n fixStacktrace: true\n });\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n\n throw new Error(\n `Unable to load framework.options.storyRules config module at ${configFilePath}: ${reason}`\n );\n }\n}\n","import type { Plugin } from 'vite';\n\ntype CreateVirtualModuleOptions = {\n pluginName: string;\n virtualModuleId: string;\n load: (id: string) => string | Promise<string> | undefined;\n};\n\nexport function createVirtualModule(options: CreateVirtualModuleOptions): Plugin {\n const resolvedVirtualModuleId = `\\0${options.virtualModuleId}`;\n\n return {\n name: options.pluginName,\n resolveId(id) {\n if (id === options.virtualModuleId) {\n return resolvedVirtualModuleId;\n }\n },\n async load(id) {\n if (id === resolvedVirtualModuleId) {\n return options.load(id);\n }\n }\n } satisfies Plugin;\n}\n","import type { Integration } from './integrations/index.ts';\nimport { createVirtualModule } from './vite/virtualModulePlugin.ts';\n\ntype PluginOptions = {\n mode?: 'development' | 'production';\n staticModuleMap?: Record<string, string>;\n};\n\nexport function viteAstroContainerRenderersPlugin(\n integrations: Integration[],\n options: PluginOptions = {}\n) {\n const safeIntegrations = integrations ?? [];\n const mode = options.mode ?? 'development';\n const staticModuleMap = options.staticModuleMap ?? {};\n\n return createVirtualModule({\n pluginName: 'storybook-astro:container-renderers',\n virtualModuleId: 'virtual:astro-container-renderers',\n load() {\n const importStatements = buildImportStatements(safeIntegrations);\n const browserModuleResolverHelpers =\n mode === 'development' ? buildBrowserModuleResolverHelpers() : '';\n const clientModuleEntrypoints =\n mode === 'development' ? buildClientModuleEntrypoints(safeIntegrations) : '[]';\n const clientResolvers =\n mode === 'development'\n ? safeIntegrations\n .filter((integration) => typeof integration.resolveClient === 'function')\n .map((integration) =>\n integration.resolveClient.toString().replace(/^resolveClient/, 'function')\n )\n .join(',\\n')\n : '';\n\n return `\n ${importStatements}\n ${browserModuleResolverHelpers}\n\n export function addRenderers(container) {\n ${safeIntegrations.map((integration) => buildServerRenderer(integration) + '\\n' + buildClientRenderer(integration)).join('\\n')}\n }\n\n const staticClientModules = ${JSON.stringify(staticModuleMap, null, 2)};\n const clientModuleEntrypoints = ${clientModuleEntrypoints};\n\n const clientModulesResolvers = [\n ${clientResolvers}\n ];\n\n export function resolveClientModules(specifier) {\n if (Object.hasOwn(staticClientModules, specifier)) {\n return staticClientModules[specifier];\n }\n\n const normalizedSpecifier = specifier.replace(/\\\\\\\\/g, '/').replace(/\\\\?.*$/, '');\n\n if (Object.hasOwn(staticClientModules, normalizedSpecifier)) {\n return staticClientModules[normalizedSpecifier];\n }\n\n for (const entrypoint of clientModuleEntrypoints) {\n if (normalizedSpecifier === entrypoint || normalizedSpecifier.startsWith(entrypoint)) {\n return storybookAstroResolveBrowserModulePath(normalizedSpecifier);\n }\n }\n\n for (const resolver of clientModulesResolvers) {\n const resolution = resolver(specifier);\n\n if (resolution) {\n return resolution;\n }\n }\n }\n `;\n }\n });\n}\n\nfunction buildClientModuleEntrypoints(integrations: Integration[]) {\n return JSON.stringify(\n Array.from(\n new Set(\n integrations\n .map((integration) => integration.renderer.client?.entrypoint)\n .filter((entrypoint): entrypoint is string => Boolean(entrypoint))\n )\n )\n );\n}\n\nfunction buildBrowserModuleResolverHelpers() {\n return `\n import path from 'node:path';\n import { createRequire } from 'node:module';\n import { pathToFileURL } from 'node:url';\n\n function storybookAstroToFileHref(filePath) {\n return pathToFileURL(filePath).href;\n }\n\n function storybookAstroResolveFrom(moduleName, fromDirectory) {\n const fromFile = path.join(fromDirectory, '__storybook_astro_resolve__.js');\n\n return createRequire(storybookAstroToFileHref(fromFile)).resolve(moduleName);\n }\n\n function storybookAstroResolveFromCandidates(moduleName, primaryDirectory) {\n const directories = [primaryDirectory, process.env.INIT_CWD].filter(Boolean);\n const visited = new Set();\n let lastError;\n\n for (const directory of directories) {\n if (visited.has(directory)) {\n continue;\n }\n\n visited.add(directory);\n\n try {\n return storybookAstroResolveFrom(moduleName, directory);\n } catch (error) {\n lastError = error;\n }\n }\n\n throw lastError;\n }\n\n function storybookAstroResolveBrowserModulePath(moduleName, resolveFrom = process.cwd()) {\n const resolvedPath = storybookAstroResolveFromCandidates(moduleName, resolveFrom).replace(/\\\\\\\\/g, '/');\n\n return '/@fs/' + resolvedPath;\n }\n `;\n}\n\nfunction buildImportStatements(integrations: Integration[]) {\n return integrations\n .filter((integration) => integration.renderer.server)\n .map(\n (integration) =>\n `import ${integration.name}Renderer from '${integration.renderer.server?.entrypoint}';`\n )\n .join('\\n');\n}\n\nfunction buildServerRenderer(integration: Integration) {\n const serverRenderer = integration.renderer.server;\n\n if (!serverRenderer) {\n return '';\n }\n\n if (integration.name === 'solid') {\n return `\n container.addServerRenderer({\n name: '${serverRenderer.name}',\n renderer: {\n ...${integration.name}Renderer,\n name: '${serverRenderer.name}'\n }\n });\n `;\n }\n\n return `\n container.addServerRenderer({\n name: '${serverRenderer.name}',\n renderer: ${integration.name}Renderer\n });\n `;\n}\n\nfunction buildClientRenderer(integration: Integration) {\n const clientRenderer = integration.renderer.client;\n\n if (clientRenderer) {\n return `\n container.addClientRenderer({\n name: '${clientRenderer.name}',\n entrypoint: '${clientRenderer.entrypoint}'\n });\n `;\n }\n\n return '';\n}\n","import { pathToFileURL } from 'node:url';\nimport type { Plugin } from 'vite';\n\n// We avoid a hard import of `astro/assets/fonts/types` here because consumers\n// using older Astro versions without the new fonts API would fail to install.\n// The provider interface we rely on is small and stable enough to type locally.\nexport interface StorybookFontProvider {\n name: string;\n init?: (context: { storage: FontStorage; root: URL }) => Promise<void> | void;\n resolveFont: (options: {\n familyName: string;\n weights: string[];\n styles: string[];\n subsets: string[];\n formats: string[];\n }) => Promise<{ fonts: FontFaceData[] } | undefined> | { fonts: FontFaceData[] } | undefined;\n}\n\nexport interface FontFaceData {\n src: Array<{ url?: string; name?: string; format?: string; tech?: string }>;\n weight?: string | number | [number, number];\n style?: string;\n display?: string;\n unicodeRange?: string[];\n featureSettings?: string;\n variationSettings?: string;\n}\n\nexport interface StorybookFontFamily {\n name: string;\n cssVariable: string;\n provider: StorybookFontProvider;\n weights?: Array<string | number>;\n styles?: string[];\n subsets?: string[];\n formats?: string[];\n fallbacks?: string[];\n display?: string;\n}\n\ninterface FontStorage {\n getItem: <T = unknown>(key: string, init?: () => Promise<T> | T) => Promise<T | null>;\n setItem: (key: string, value: unknown) => Promise<void> | void;\n}\n\ninterface ResolvedFontData {\n componentEntries: Array<[string, { css: string; preloads: never[] }]>;\n fontDataByCssVariable: Record<\n string,\n Array<{\n src: Array<{ url: string; format?: string; tech?: string }>;\n weight?: string;\n style?: string;\n }>\n >;\n}\n\nconst DEFAULTS = {\n weights: ['400'],\n styles: ['normal', 'italic'],\n subsets: ['latin'],\n formats: ['woff2'],\n fallbacks: ['sans-serif']\n} as const;\n\nconst VIRTUAL_INTERNAL_ID = 'virtual:astro:assets/fonts/internal';\nconst VIRTUAL_RUNTIME_ID = 'virtual:astro:assets/fonts/runtime';\nconst VIRTUAL_RUNTIME_RESOLVER_ID = 'virtual:astro:assets/fonts/runtime/font-file-url-resolver';\nconst PACKAGE_RUNTIME_IDS = ['astro/assets/fonts/runtime', 'astro/assets/fonts/runtime.js'];\n\nconst RUNTIME_STUB = `\nexport const fontData = {};\nexport function createGetFontData(fontsMod) {\n return fontsMod?.fontDataByCssVariable ?? {};\n}\nexport const experimental_getFontFileURL = () => undefined;\n`;\n\nconst RESOLVER_STUB = `\nexport const runtimeFontFileUrlResolver = { resolve: () => undefined };\n`;\n\n/**\n * Resolves Astro's font Provider API for Storybook by reading the user's\n * configured font families, calling each provider to produce @font-face data,\n * and emitting CSS through Astro's font virtual modules.\n *\n * Lightweight first cut: generates @font-face declarations and a CSS variable\n * binding to the family name plus fallbacks. Does not handle preload links,\n * Capsize-optimized fallback metrics, or build-time font file emission — those\n * paths fall back to remote URLs returned by the provider directly.\n *\n * If no families are provided, the plugin emits no-op stubs so Astro's\n * font virtual modules still resolve in projects that don't configure fonts.\n */\nexport function vitePluginAstroFonts(\n options: {\n fonts?: StorybookFontFamily[];\n root?: string;\n } = {}\n): Plugin {\n const families = options.fonts ?? [];\n const rootDir = options.root ?? process.cwd();\n const root = pathToFileURL(rootDir.endsWith('/') ? rootDir : rootDir + '/');\n\n let resolved: ResolvedFontData | null = null;\n let resolvePromise: Promise<ResolvedFontData> | null = null;\n\n const ensureResolved = async () => {\n if (!resolvePromise) {\n resolvePromise = resolveAllFamilies(families, root);\n }\n\n resolved = await resolvePromise;\n\n return resolved;\n };\n\n return {\n name: 'storybook-astro-fonts',\n enforce: 'pre',\n\n async buildStart() {\n await ensureResolved();\n },\n\n resolveId(id) {\n if (id === VIRTUAL_INTERNAL_ID) {\n return '\\0' + VIRTUAL_INTERNAL_ID;\n }\n if (id === VIRTUAL_RUNTIME_ID) {\n return '\\0' + VIRTUAL_RUNTIME_ID;\n }\n if (id === VIRTUAL_RUNTIME_RESOLVER_ID) {\n return '\\0' + VIRTUAL_RUNTIME_RESOLVER_ID;\n }\n if (PACKAGE_RUNTIME_IDS.includes(id)) {\n return '\\0storybook:astro-fonts-runtime';\n }\n\n return undefined;\n },\n\n async load(id) {\n if (id === '\\0' + VIRTUAL_INTERNAL_ID) {\n const data = resolved ?? (await ensureResolved());\n\n return {\n code:\n `export const componentDataByCssVariable = new Map(${JSON.stringify(data.componentEntries)});\\n` +\n `export const fontDataByCssVariable = ${JSON.stringify(data.fontDataByCssVariable)};\\n`\n };\n }\n if (id === '\\0' + VIRTUAL_RUNTIME_ID || id === '\\0storybook:astro-fonts-runtime') {\n return { code: RUNTIME_STUB };\n }\n if (id === '\\0' + VIRTUAL_RUNTIME_RESOLVER_ID) {\n return { code: RESOLVER_STUB };\n }\n\n return undefined;\n }\n };\n}\n\nasync function resolveAllFamilies(\n families: StorybookFontFamily[],\n root: URL\n): Promise<ResolvedFontData> {\n const componentEntries: ResolvedFontData['componentEntries'] = [];\n const fontDataByCssVariable: ResolvedFontData['fontDataByCssVariable'] = {};\n const storage = createMemoryStorage();\n\n for (const family of families) {\n try {\n if (family.provider.init) {\n await family.provider.init({ storage, root });\n }\n const result = await family.provider.resolveFont({\n familyName: family.name,\n weights: (family.weights ?? DEFAULTS.weights).map(String),\n styles: family.styles ?? [...DEFAULTS.styles],\n subsets: family.subsets ?? [...DEFAULTS.subsets],\n formats: family.formats ?? [...DEFAULTS.formats]\n });\n const faces = result?.fonts ?? [];\n\n if (faces.length === 0) {\n continue;\n }\n\n componentEntries.push([\n family.cssVariable,\n { css: buildFamilyCss(family, faces), preloads: [] }\n ]);\n fontDataByCssVariable[family.cssVariable] = faces.map(toFontData);\n } catch (err) {\n // Swallow per-family errors so one bad family doesn't break the rest.\n // Errors surface as the family simply not rendering, matching Astro's\n // behavior when a provider can't resolve a font.\n console.warn(\n `[storybook-astro-fonts] Failed to resolve font family \"${family.name}\":`,\n err instanceof Error ? err.message : err\n );\n }\n }\n\n return { componentEntries, fontDataByCssVariable };\n}\n\nexport function buildFamilyCss(family: StorybookFontFamily, faces: FontFaceData[]): string {\n const fallbacks = family.fallbacks ?? [...DEFAULTS.fallbacks];\n const familyList = [JSON.stringify(family.name), ...fallbacks].join(', ');\n const faceBlocks = faces.map((face) => buildFontFaceBlock(family, face)).join('\\n');\n const rootRule = `:root { ${family.cssVariable}: ${familyList}; }`;\n\n return `${faceBlocks}\\n${rootRule}`;\n}\n\nfunction buildFontFaceBlock(family: StorybookFontFamily, face: FontFaceData): string {\n const src = face.src\n .map((source) => {\n if (source.url) {\n const format = source.format ? ` format(${JSON.stringify(source.format)})` : '';\n const tech = source.tech ? ` tech(${source.tech})` : '';\n\n return `url(${JSON.stringify(source.url)})${format}${tech}`;\n }\n if (source.name) {\n return `local(${JSON.stringify(source.name)})`;\n }\n\n return '';\n })\n .filter(Boolean)\n .join(', ');\n\n const descriptors: string[] = [\n `font-family: ${JSON.stringify(family.name)};`,\n `src: ${src};`,\n `font-display: ${family.display ?? 'swap'};`\n ];\n\n if (face.weight !== undefined) {\n const weight = Array.isArray(face.weight) ? face.weight.join(' ') : String(face.weight);\n\n descriptors.push(`font-weight: ${weight};`);\n }\n if (face.style) {\n descriptors.push(`font-style: ${face.style};`);\n }\n if (face.unicodeRange?.length) {\n descriptors.push(`unicode-range: ${face.unicodeRange.join(', ')};`);\n }\n if (face.featureSettings) {\n descriptors.push(`font-feature-settings: ${face.featureSettings};`);\n }\n if (face.variationSettings) {\n descriptors.push(`font-variation-settings: ${face.variationSettings};`);\n }\n\n return `@font-face { ${descriptors.join(' ')} }`;\n}\n\nfunction toFontData(face: FontFaceData) {\n return {\n src: face.src\n .filter((source) => source.url)\n .map((source) => ({ url: source.url!, format: source.format, tech: source.tech })),\n weight:\n face.weight !== undefined\n ? Array.isArray(face.weight)\n ? face.weight.join(' ')\n : String(face.weight)\n : undefined,\n style: face.style\n };\n}\n\nfunction createMemoryStorage(): FontStorage {\n const store = new Map<string, unknown>();\n\n return {\n async getItem(key, init) {\n if (store.has(key)) {\n return store.get(key) as never;\n }\n if (init) {\n const value = await init();\n\n store.set(key, value);\n\n return value as never;\n }\n\n return null;\n },\n async setItem(key, value) {\n store.set(key, value);\n }\n };\n}\n","import type { Plugin } from 'vite';\n\nconst OPTS_STUB = 'export default {}';\n\nconst VIRTUAL_IDS = ['astro:react:opts', 'astro:preact:opts'];\n\nexport function vitePluginAstroIntegrationOptsFallback(): Plugin {\n const resolvedIds = new Map(VIRTUAL_IDS.map((id) => [id, `\\0${id}`]));\n const resolvedIdSet = new Set(resolvedIds.values());\n\n return {\n name: 'storybook-astro-integration-opts-fallback',\n enforce: 'pre',\n\n resolveId(id) {\n return resolvedIds.get(id);\n },\n\n load(id) {\n if (resolvedIdSet.has(id)) {\n return { code: OPTS_STUB };\n }\n }\n };\n}\n","import type { Plugin } from 'vite';\n\nconst VUE_APP_STUB = `\nexport const setup = () => {};\n`;\n\n// Different versions of @astrojs/vue use different virtual module names\nconst VIRTUAL_IDS = ['virtual:astro:vue-app', 'virtual:@astrojs/vue/app'];\n\n/**\n * Provides fallback resolution for @astrojs/vue's virtual module\n * in Storybook's SSR Vite server.\n *\n * @astrojs/vue's server.js imports a virtual module to get a setup function\n * for configuring the Vue app instance. The virtual module name varies by version:\n * - v6.0.0-beta.1: \"virtual:astro:vue-app\"\n * - Later versions: \"virtual:@astrojs/vue/app\"\n *\n * The Vite plugin that normally creates this virtual module may not run in\n * Storybook's SSR context, so this plugin stubs it with a no-op setup function\n * (the default behavior when no appEntrypoint is configured).\n */\nexport function vitePluginAstroVueFallback(): Plugin {\n const resolvedIds = new Map(VIRTUAL_IDS.map((id) => [id, '\\0' + id]));\n const resolvedIdSet = new Set(resolvedIds.values());\n\n return {\n name: 'storybook-astro-vue-fallback',\n // Must run before vite:resolve to intercept virtual modules\n // before Vite tries to resolve them as Node package imports\n enforce: 'pre',\n\n resolveId(id) {\n const resolved = resolvedIds.get(id);\n\n if (resolved) {\n return resolved;\n }\n },\n\n load(id) {\n if (resolvedIdSet.has(id)) {\n return { code: VUE_APP_STUB };\n }\n }\n };\n}\n","import type { Plugin } from 'vite';\n\nconst ROUTES_STUB = `\nexport const routes = [];\n`;\n\n/**\n * Provides fallback resolution for Astro's routes virtual module\n * in Storybook's SSR Vite server.\n *\n * In Astro 6, the manifest and app entrypoints import from \"virtual:astro:routes\"\n * to get route data. In Storybook's context, there are no routes, so this plugin\n * stubs the virtual module with an empty routes array.\n */\nexport function vitePluginAstroRoutesFallback(): Plugin {\n const VIRTUAL_ID = 'virtual:astro:routes';\n const RESOLVED_VIRTUAL_ID = '\\0' + VIRTUAL_ID;\n\n return {\n name: 'storybook-astro-routes-fallback',\n // Must run before vite:resolve to intercept virtual modules\n // before Vite tries to resolve them as Node package imports\n enforce: 'pre',\n\n resolveId(id) {\n if (id === VIRTUAL_ID) {\n return RESOLVED_VIRTUAL_ID;\n }\n },\n\n load(id) {\n if (id === RESOLVED_VIRTUAL_ID) {\n return { code: ROUTES_STUB };\n }\n }\n };\n}\n","import type { PluginOption } from 'vite';\nimport {\n loadStoryInlineModule,\n resolveStoryModuleMock,\n STORYBOOK_ASTRO_INLINE_MODULE_PREFIX\n} from './module-mocks.ts';\n\nexport function vitePluginStoryModuleMocks(): PluginOption {\n return {\n name: 'storybook-astro:story-module-mocks',\n enforce: 'pre',\n resolveId(id) {\n if (id.startsWith(STORYBOOK_ASTRO_INLINE_MODULE_PREFIX)) {\n return `\\0${id}`;\n }\n\n const mockedModule = resolveStoryModuleMock(id);\n\n if (mockedModule) {\n return mockedModule;\n }\n\n return null;\n },\n load(id) {\n return loadStoryInlineModule(id);\n }\n } satisfies PluginOption;\n}\n","import type { ViteDevServer } from 'vite';\n\ntype SsrLoadModuleOptions = {\n fixStacktrace?: boolean;\n};\n\nexport async function ssrLoadModuleWithFsFallback<TModule = unknown>(\n viteServer: Pick<ViteDevServer, 'ssrLoadModule'>,\n id: string,\n options?: SsrLoadModuleOptions\n) {\n const ids = [id];\n\n if (id.startsWith('/') && !id.startsWith('/@fs/')) {\n ids.push(`/@fs${id}`);\n }\n\n let lastError: unknown;\n\n for (const candidate of ids) {\n try {\n return await viteServer.ssrLoadModule(candidate, options) as TModule;\n } catch (error) {\n lastError = error;\n }\n }\n\n throw lastError;\n}\n","import { existsSync, statSync } from 'node:fs';\nimport { extname, resolve } from 'node:path';\n\nexport type StoryRulesOptions =\n | string\n | {\n configFile: string;\n };\n\nexport function resolveRulesConfigFilePath(\n options?: StoryRulesOptions,\n resolveFrom = process.cwd()\n): string | undefined {\n if (options === undefined) {\n return undefined;\n }\n\n const configFile = normalizeConfigFileOption(options);\n const resolvedConfigFilePath = resolve(resolveFrom, configFile);\n const normalizedConfigFilePath = resolveConfigFilePath(resolvedConfigFilePath);\n\n if (!normalizedConfigFilePath) {\n throw new Error(\n `framework.options.storyRules config file was not found: ${resolvedConfigFilePath}. ` +\n 'Provide an existing path in framework.options.storyRules.'\n );\n }\n\n return normalizedConfigFilePath;\n}\n\nfunction normalizeConfigFileOption(options: StoryRulesOptions): string {\n const configFile =\n typeof options === 'string'\n ? options\n : typeof options === 'object' && options !== null\n ? options.configFile\n : undefined;\n\n if (typeof configFile !== 'string') {\n throw new Error(\n 'framework.options.storyRules must be either a string path or an object with a string configFile.'\n );\n }\n\n const normalizedConfigFile = configFile.trim();\n\n if (!normalizedConfigFile) {\n throw new Error('framework.options.storyRules config file path cannot be empty.');\n }\n\n return normalizedConfigFile;\n}\n\nfunction resolveConfigFilePath(filePath: string): string | undefined {\n if (existsSync(filePath)) {\n const fileStats = statSync(filePath);\n\n if (fileStats.isFile()) {\n return filePath;\n }\n }\n\n if (extname(filePath)) {\n return undefined;\n }\n\n const extensions = ['.ts', '.mts', '.cts', '.js', '.mjs', '.cjs'];\n\n for (const extension of extensions) {\n const candidateFilePath = `${filePath}${extension}`;\n\n if (existsSync(candidateFilePath)) {\n return candidateFilePath;\n }\n }\n\n for (const extension of extensions) {\n const candidateFilePath = resolve(filePath, `index${extension}`);\n\n if (existsSync(candidateFilePath)) {\n return candidateFilePath;\n }\n }\n\n return undefined;\n}\n","import { loadConfigFromFile, type Plugin } from 'vite';\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { AstroIntegration } from 'astro';\nimport type { StorybookFontFamily } from './vitePluginAstroFonts.ts';\n\nconst CONFIG_FILENAMES = [\n 'astro.config.ts',\n 'astro.config.mjs',\n 'astro.config.js',\n 'astro.config.cjs',\n];\n\ninterface UserAstroConfigData {\n integrations: AstroIntegration[];\n fonts: StorybookFontFamily[];\n vitePlugins: Plugin[];\n}\n\nconst EMPTY: UserAstroConfigData = {\n integrations: [],\n fonts: [],\n vitePlugins: []\n};\n\n// Cache by resolveFrom — config rarely changes during a Storybook session and\n// several call sites read the same data. Each entry stores the in-flight\n// promise so concurrent callers share the same load.\nconst configCache = new Map<string, Promise<UserAstroConfigData>>();\n\nasync function loadUserAstroConfigData(resolveFrom: string): Promise<UserAstroConfigData> {\n let cached = configCache.get(resolveFrom);\n\n if (!cached) {\n cached = readUserAstroConfig(resolveFrom);\n configCache.set(resolveFrom, cached);\n }\n\n return cached;\n}\n\nasync function readUserAstroConfig(resolveFrom: string): Promise<UserAstroConfigData> {\n // Vite's loadConfigFromFile resolves a relative configFile against\n // process.cwd(), not the configRoot argument, so we always hand it an\n // absolute path to make the lookup deterministic regardless of where\n // Storybook is invoked from.\n const configFile = CONFIG_FILENAMES\n .map((name) => resolve(resolveFrom, name))\n .find((path) => existsSync(path));\n\n if (!configFile) {\n return EMPTY;\n }\n\n try {\n const result = await loadConfigFromFile(\n { command: 'serve', mode: 'development' },\n configFile,\n resolveFrom\n );\n\n if (!result?.config) {\n return EMPTY;\n }\n\n const config = result.config as {\n integrations?: unknown;\n fonts?: unknown;\n vite?: { plugins?: unknown };\n };\n\n return {\n integrations: extractIntegrations(config.integrations),\n fonts: extractFonts(config.fonts),\n vitePlugins: extractVitePlugins(config.vite?.plugins)\n };\n } catch (err) {\n console.warn(\n '[storybook-astro] Could not load astro.config to discover integrations / fonts / vite plugins:',\n err instanceof Error ? err.message : String(err)\n );\n\n return EMPTY;\n }\n}\n\nfunction extractIntegrations(raw: unknown): AstroIntegration[] {\n if (!raw) {\n return [];\n }\n\n // Astro allows nested arrays from conditional spreads (e.g. ...whenX(() => mdx()))\n const flat = (Array.isArray(raw) ? raw : [raw]).flat(Infinity);\n\n return flat.filter(\n (i): i is AstroIntegration =>\n Boolean(i) && typeof i === 'object' && 'name' in i && 'hooks' in i\n );\n}\n\nfunction extractFonts(raw: unknown): StorybookFontFamily[] {\n if (!Array.isArray(raw)) {\n return [];\n }\n\n return raw.filter(\n (f): f is StorybookFontFamily =>\n Boolean(f) &&\n typeof f === 'object' &&\n typeof (f as { name?: unknown }).name === 'string' &&\n typeof (f as { cssVariable?: unknown }).cssVariable === 'string' &&\n typeof (f as { provider?: unknown }).provider === 'object'\n );\n}\n\nfunction extractVitePlugins(raw: unknown): Plugin[] {\n if (!raw) {\n return [];\n }\n\n // vite.plugins accepts Plugin | Plugin[] | (Plugin | false | null | undefined)[][] etc.\n const flat = (Array.isArray(raw) ? raw : [raw]).flat(Infinity);\n\n return flat.filter(\n (p): p is Plugin =>\n Boolean(p) && typeof p === 'object' && 'name' in p && typeof (p as Plugin).name === 'string'\n );\n}\n\n/**\n * Loads integrations declared in the user's astro.config.* so that any Vite\n * plugins they register (e.g. astro-icon's virtual:astro-icon resolver) are\n * present in both the main Storybook Vite server and the internal Astro SSR\n * server. Returns an empty array on any failure so the calling code can\n * continue with only the framework-level integrations.\n */\nexport async function loadUserAstroIntegrations(resolveFrom: string): Promise<AstroIntegration[]> {\n return (await loadUserAstroConfigData(resolveFrom)).integrations;\n}\n\n/**\n * Loads the `fonts:` array from the user's astro.config.* so the Astro 6\n * Font Provider API works in Storybook without duplicating the array into\n * `framework.options.fonts`. Returns [] if the project has no fonts\n * configured or the config can't be read.\n */\nexport async function loadUserAstroFonts(resolveFrom: string): Promise<StorybookFontFamily[]> {\n return (await loadUserAstroConfigData(resolveFrom)).fonts;\n}\n\n/**\n * Loads raw Vite plugins declared at `vite.plugins` in the user's\n * astro.config.* (e.g. `@tailwindcss/vite`, `unocss/vite`). These are not\n * registered through Astro's integration API so `loadUserAstroIntegrations`\n * does not pick them up; this loader fills the gap so CSS frameworks added\n * as raw Vite plugins work in Storybook without `viteFinal`.\n */\nexport async function loadUserAstroVitePlugins(resolveFrom: string): Promise<Plugin[]> {\n return (await loadUserAstroConfigData(resolveFrom)).vitePlugins;\n}\n"],"mappings":"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","names":["VIRTUAL_IDS","existsSync","resolve","require"]}