@storybook-astro/framework 1.2.0 → 1.3.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.
Files changed (87) hide show
  1. package/dist/{base-IRZo3zgK.d.ts → base-DT67T5pi.d.ts} +1 -0
  2. package/dist/{chunk-T7NWIO5S.js → chunk-2EABPTOY.js} +5 -5
  3. package/dist/{chunk-PJEDXZVN.js → chunk-7YBE4TTI.js} +2 -1
  4. package/dist/chunk-7YBE4TTI.js.map +1 -0
  5. package/dist/{chunk-POHTFYST.js → chunk-AYYMNFI6.js} +104 -6
  6. package/dist/chunk-AYYMNFI6.js.map +1 -0
  7. package/dist/{chunk-OUEDTRBO.js → chunk-B454DGX6.js} +259 -67
  8. package/dist/chunk-B454DGX6.js.map +1 -0
  9. package/dist/chunk-B5HHF6FC.js +116 -0
  10. package/dist/chunk-B5HHF6FC.js.map +1 -0
  11. package/dist/chunk-CU57AJUW.js +1402 -0
  12. package/dist/chunk-CU57AJUW.js.map +1 -0
  13. package/dist/{chunk-DNGQBPT7.js → chunk-PUTCAN6X.js} +5 -2
  14. package/dist/{chunk-DNGQBPT7.js.map → chunk-PUTCAN6X.js.map} +1 -1
  15. package/dist/{chunk-4SWPVM6R.js → chunk-WUTCMEF5.js} +2 -2
  16. package/dist/index.d.ts +17 -7
  17. package/dist/index.js +6 -5
  18. package/dist/index.js.map +1 -1
  19. package/dist/integrations/index.d.ts +2 -1
  20. package/dist/integrations/index.js +1 -1
  21. package/dist/middleware.js +18 -131
  22. package/dist/middleware.js.map +1 -1
  23. package/dist/{types-C-jan6Px.d.ts → preset-BvgHg2of.d.ts} +8 -11
  24. package/dist/preset.d.ts +2 -10
  25. package/dist/preset.js +5 -4
  26. package/dist/renderer/renderer-dev.js +62 -0
  27. package/dist/renderer/renderer-dev.js.map +1 -0
  28. package/dist/renderer/renderer-server.js +92 -0
  29. package/dist/renderer/renderer-server.js.map +1 -0
  30. package/dist/renderer/renderer-static.js +54 -0
  31. package/dist/renderer/renderer-static.js.map +1 -0
  32. package/dist/testing.js +12 -11
  33. package/dist/testing.js.map +1 -1
  34. package/dist/{viteStorybookAstroMiddlewarePlugin-2EFKTECT.js → viteStorybookAstroMiddlewarePlugin-UB6ZLJ4B.js} +4 -3
  35. package/dist/vitest/global-setup.js +6 -5
  36. package/dist/vitest/global-setup.js.map +1 -1
  37. package/dist/vitest/index.d.ts +1 -1
  38. package/dist/vitest/index.js +3 -3
  39. package/package.json +14 -43
  40. package/src/astroImageService.ts +57 -0
  41. package/src/astroRenderHandler.ts +205 -0
  42. package/src/importAstroConfig.ts +1 -1
  43. package/src/index.ts +2 -0
  44. package/src/integrations/alpine.ts +1 -0
  45. package/src/integrations/base.ts +6 -0
  46. package/src/lib/revive-dates.test.ts +106 -0
  47. package/src/lib/revive-dates.ts +51 -0
  48. package/src/middleware.ts +29 -200
  49. package/src/module-mocks.ts +153 -5
  50. package/src/preset.ts +38 -8
  51. package/src/productionRenderRuntime.ts +187 -0
  52. package/src/rules.test.ts +52 -4
  53. package/src/rules.ts +54 -7
  54. package/src/server/index.ts +101 -31
  55. package/src/storyRulesRuntime.ts +34 -0
  56. package/src/storySsrVite.ts +240 -0
  57. package/src/types.ts +0 -9
  58. package/src/virtual.d.ts +17 -3
  59. package/src/vite/{astroFilesVirtualModulePlugin.ts → astroFilesPlugin.ts} +4 -4
  60. package/src/vite/sanitizeConfigPlugin.ts +18 -0
  61. package/src/vite/{storybookAstroServerAuthConfigVirtualModulePlugin.test.ts → serverAuthPlugin.test.ts} +7 -10
  62. package/src/vite/{storybookAstroServerAuthConfigVirtualModulePlugin.ts → serverAuthPlugin.ts} +6 -9
  63. package/src/vite/serverRuntimePlugin.ts +109 -0
  64. package/src/vite/{storybookAstroRulesConfigVirtualModulePlugin.ts → storyRulesPlugin.ts} +6 -7
  65. package/src/vite/{createVirtualModulePlugin.test.ts → virtualModulePlugin.test.ts} +5 -5
  66. package/src/vite/{createVirtualModulePlugin.ts → virtualModulePlugin.ts} +2 -2
  67. package/src/viteAstroContainerRenderersPlugin.ts +72 -2
  68. package/src/vitePluginAstroBuildPrerender.ts +75 -646
  69. package/src/vitePluginAstroBuildServer.ts +217 -165
  70. package/src/vitePluginAstroBuildShared.test.ts +87 -0
  71. package/src/vitePluginAstroBuildShared.ts +465 -0
  72. package/src/vitePluginStoryModuleMocks.ts +29 -0
  73. package/src/viteStorybookAstroMiddlewarePlugin.ts +8 -0
  74. package/src/viteStorybookAstroRendererPlugin.ts +13 -6
  75. package/src/viteStorybookRendererFallbackPlugin.ts +2 -2
  76. package/dist/chunk-OUEDTRBO.js.map +0 -1
  77. package/dist/chunk-PBISP7PA.js +0 -1137
  78. package/dist/chunk-PBISP7PA.js.map +0 -1
  79. package/dist/chunk-PJEDXZVN.js.map +0 -1
  80. package/dist/chunk-POHTFYST.js.map +0 -1
  81. package/dist/node/index.d.ts +0 -10
  82. package/dist/node/index.js +0 -10
  83. package/dist/node/index.js.map +0 -1
  84. package/src/vite/storybookAstroSanitizationConfigVirtualModulePlugin.ts +0 -21
  85. /package/dist/{chunk-T7NWIO5S.js.map → chunk-2EABPTOY.js.map} +0 -0
  86. /package/dist/{chunk-4SWPVM6R.js.map → chunk-WUTCMEF5.js.map} +0 -0
  87. /package/dist/{viteStorybookAstroMiddlewarePlugin-2EFKTECT.js.map → viteStorybookAstroMiddlewarePlugin-UB6ZLJ4B.js.map} +0 -0
@@ -0,0 +1,1402 @@
1
+ import {
2
+ vitePluginAstroComponentMarker
3
+ } from "./chunk-E4LB75JN.js";
4
+ import {
5
+ createAstroRenderHandler,
6
+ ensureAstroPassthroughImageService,
7
+ resolveSanitizationOptions,
8
+ serializeSanitizationOptions
9
+ } from "./chunk-B454DGX6.js";
10
+ import {
11
+ createVirtualModule,
12
+ resolveRulesConfigFilePath,
13
+ ssrLoadModuleWithFsFallback,
14
+ viteAstroContainerRenderersPlugin,
15
+ vitePluginAstroFontsFallback,
16
+ vitePluginAstroIntegrationOptsFallback,
17
+ vitePluginAstroRoutesFallback,
18
+ vitePluginAstroVueFallback,
19
+ vitePluginStoryModuleMocks,
20
+ vitePluginStorybookAstroMiddleware
21
+ } from "./chunk-AYYMNFI6.js";
22
+ import {
23
+ importAstroConfig
24
+ } from "./chunk-PUTCAN6X.js";
25
+ import {
26
+ resolveStoryModuleMock
27
+ } from "./chunk-B5HHF6FC.js";
28
+
29
+ // src/preset.ts
30
+ import { dirname as dirname3 } from "path";
31
+
32
+ // src/viteStorybookRendererFallbackPlugin.ts
33
+ function viteStorybookRendererFallbackPlugin(integrations) {
34
+ const safeIntegrations = integrations ?? [];
35
+ return createVirtualModule({
36
+ pluginName: "storybook-renderer-fallback",
37
+ virtualModuleId: "virtual:storybook-renderer-fallback",
38
+ load() {
39
+ return safeIntegrations.filter((integration) => integration.storybookEntryPreview).map(
40
+ (integration) => `export * as ${integration.name} from '${integration.storybookEntryPreview}';`
41
+ ).join("\n");
42
+ }
43
+ });
44
+ }
45
+
46
+ // src/viteStorybookAstroRendererPlugin.ts
47
+ import { fileURLToPath } from "url";
48
+ var rendererDevModulePath = fileURLToPath(new URL("./renderer/renderer-dev.js", import.meta.url));
49
+ var rendererStaticModulePath = fileURLToPath(new URL("./renderer/renderer-static.js", import.meta.url));
50
+ var rendererServerModulePath = fileURLToPath(new URL("./renderer/renderer-server.js", import.meta.url));
51
+ function viteStorybookAstroRendererPlugin(options) {
52
+ const pluginName = "storybook-astro:renderer-module";
53
+ const virtualModuleId = "virtual:storybook-astro-renderer";
54
+ const isProduction = options.mode === "production";
55
+ const isStaticMode = options.renderMode === "static";
56
+ return createVirtualModule({
57
+ pluginName,
58
+ virtualModuleId,
59
+ load() {
60
+ if (!isProduction) {
61
+ return `export * from ${JSON.stringify(normalizePath(rendererDevModulePath))};`;
62
+ }
63
+ if (isStaticMode) {
64
+ return `export * from ${JSON.stringify(normalizePath(rendererStaticModulePath))};`;
65
+ }
66
+ return [
67
+ `import { createServerRenderer } from ${JSON.stringify(normalizePath(rendererServerModulePath))};`,
68
+ `const renderer = createServerRenderer(${JSON.stringify(
69
+ {
70
+ serverUrl: options.server?.serverUrl,
71
+ authToken: options.server?.authToken,
72
+ authHeader: options.server?.authHeader
73
+ },
74
+ null,
75
+ 2
76
+ )});`,
77
+ "export const render = renderer.render;",
78
+ "export const init = renderer.init;",
79
+ "export const applyStyles = renderer.applyStyles;"
80
+ ].join("\n");
81
+ }
82
+ });
83
+ }
84
+ function normalizePath(value) {
85
+ return value.replace(/\\/g, "/");
86
+ }
87
+
88
+ // src/vitePluginAstroBuildPrerender.ts
89
+ import { mkdir as mkdir2, readFile as readFile2, writeFile } from "fs/promises";
90
+ import { resolve as resolve3 } from "path";
91
+
92
+ // src/vitePluginAstroBuildShared.ts
93
+ import { createHash } from "crypto";
94
+ import { access, copyFile, mkdir, readFile, readdir, stat } from "fs/promises";
95
+ import { dirname, resolve } from "path";
96
+ function resolveVirtualBuildModuleId(id) {
97
+ if (id.startsWith("virtual:astro-static-module/")) {
98
+ return `\0${id}`;
99
+ }
100
+ if (id.startsWith("virtual:astro-component-module/")) {
101
+ return `\0${id}`;
102
+ }
103
+ }
104
+ function loadVirtualBuildModule(id) {
105
+ if (id.startsWith("\0virtual:astro-static-module/")) {
106
+ const encodedSpecifier = id.replace("\0virtual:astro-static-module/", "");
107
+ const specifier = decodeURIComponent(encodedSpecifier);
108
+ if (isClientEntrypoint(specifier)) {
109
+ return [`export { default } from '${specifier}';`, `export * from '${specifier}';`].join(
110
+ "\n"
111
+ );
112
+ }
113
+ return [`import '${specifier}';`, "export default undefined;"].join("\n");
114
+ }
115
+ if (id.startsWith("\0virtual:astro-component-module/")) {
116
+ const withoutPrefix = id.replace("\0virtual:astro-component-module/", "");
117
+ const encodedSpecifier = withoutPrefix.replace(/\?.*$/, "");
118
+ const specifier = decodeURIComponent(encodedSpecifier);
119
+ return [`export { default } from '${specifier}';`, `export * from '${specifier}';`].join("\n");
120
+ }
121
+ }
122
+ async function emitBuildEntrypoints(options) {
123
+ const { pluginContext, integrations, resolveFrom } = options;
124
+ integrations.forEach((integration) => {
125
+ const entrypoint = integration.renderer.client?.entrypoint;
126
+ if (entrypoint) {
127
+ pluginContext.addWatchFile(entrypoint);
128
+ }
129
+ });
130
+ options.trackedSpecifiers.forEach((specifier) => {
131
+ const fileReferenceId = pluginContext.emitFile({
132
+ type: "chunk",
133
+ id: toStaticVirtualId(specifier),
134
+ name: createEntrypointName(resolveFrom, specifier)
135
+ });
136
+ options.staticEntrypointRefs.set(specifier, fileReferenceId);
137
+ });
138
+ }
139
+ async function emitHydratedComponentEntriesFromAstroFile(options) {
140
+ const hydratedComponentPaths = await collectHydratedComponentPaths(options.astroFilePath);
141
+ for (const resolvedImportPath of hydratedComponentPaths) {
142
+ if (options.componentEntrypointRefs.has(resolvedImportPath)) {
143
+ continue;
144
+ }
145
+ const fileReferenceId = options.pluginContext.emitFile({
146
+ type: "chunk",
147
+ id: toComponentChunkId(resolvedImportPath),
148
+ name: createEntrypointName(options.resolveFrom, resolvedImportPath)
149
+ });
150
+ options.componentEntrypointRefs.set(resolvedImportPath, fileReferenceId);
151
+ }
152
+ }
153
+ async function collectHydratedComponentPaths(astroFilePath) {
154
+ const localImportSpecifiers = await readLocalImportSpecifiers(astroFilePath);
155
+ const hydratedComponentPaths = [];
156
+ for (const specifier of localImportSpecifiers) {
157
+ const resolvedImportPath = await resolveLocalImportPath(astroFilePath, specifier);
158
+ if (!resolvedImportPath) {
159
+ continue;
160
+ }
161
+ if (!isHydratableSourceFile(resolvedImportPath) || isNonHydratableSourceFile(resolvedImportPath)) {
162
+ continue;
163
+ }
164
+ if (/\.(jsx|tsx)$/.test(resolvedImportPath) && !await hasDefaultExport(resolvedImportPath)) {
165
+ continue;
166
+ }
167
+ hydratedComponentPaths.push(resolvedImportPath);
168
+ }
169
+ return hydratedComponentPaths;
170
+ }
171
+ function collectTrackedSpecifiers(integrations) {
172
+ const specifiers = /* @__PURE__ */ new Set([
173
+ "astro:scripts/page.js",
174
+ "astro:scripts/before-hydration.js"
175
+ ]);
176
+ integrations.forEach((integration) => {
177
+ const entrypoint = integration.renderer.client?.entrypoint;
178
+ if (entrypoint) {
179
+ specifiers.add(entrypoint);
180
+ }
181
+ });
182
+ return specifiers;
183
+ }
184
+ function buildStaticModuleMap(pluginContext, staticEntrypointRefs, componentEntrypointRefs) {
185
+ const map = {};
186
+ staticEntrypointRefs.forEach((fileReferenceId, specifier) => {
187
+ const fileName = pluginContext.getFileName(fileReferenceId);
188
+ if (fileName) {
189
+ map[specifier] = toPublicPath(fileName);
190
+ }
191
+ });
192
+ componentEntrypointRefs.forEach((fileReferenceId, specifier) => {
193
+ const fileName = pluginContext.getFileName(fileReferenceId);
194
+ if (fileName) {
195
+ map[specifier] = toPublicPath(fileName);
196
+ }
197
+ });
198
+ return map;
199
+ }
200
+ function toPublicPath(fileName) {
201
+ return `./${fileName}`;
202
+ }
203
+ function stripQuery(input) {
204
+ return input?.replace(/\?.*$/, "");
205
+ }
206
+ function relativePathFromRoot(resolveFrom, filePath) {
207
+ return filePath.slice(resolveFrom.length).replace(/^[/\\]+/, "");
208
+ }
209
+ async function copyPath(sourcePath, targetPath) {
210
+ const sourceStats = await stat(sourcePath);
211
+ if (sourceStats.isDirectory()) {
212
+ await mkdir(targetPath, { recursive: true });
213
+ const entries = await readdir(sourcePath, { withFileTypes: true });
214
+ await Promise.all(
215
+ entries.map(
216
+ (entry) => copyPath(resolve(sourcePath, entry.name), resolve(targetPath, entry.name))
217
+ )
218
+ );
219
+ return;
220
+ }
221
+ await mkdir(dirname(targetPath), { recursive: true });
222
+ await copyFile(sourcePath, targetPath);
223
+ }
224
+ function buildSnapshotFilePath(resolveFrom, filePath, snapshotDirName) {
225
+ const normalizedResolveFrom = resolveFrom.replace(/\\/g, "/").replace(/\/$/, "");
226
+ const normalizedFilePath = filePath.replace(/\\/g, "/");
227
+ if (normalizedFilePath.startsWith(`${normalizedResolveFrom}/`)) {
228
+ return `${snapshotDirName}/${relativePathFromRoot(resolveFrom, filePath)}`.replace(/\\/g, "/");
229
+ }
230
+ return `${snapshotDirName}/__external/${normalizedFilePath.replace(/^[/\\]+/, "")}`.replace(
231
+ /\\/g,
232
+ "/"
233
+ );
234
+ }
235
+ async function copyRuntimeSnapshot(options) {
236
+ const runtimeInputFiles = /* @__PURE__ */ new Set([
237
+ ...options.astroComponents,
238
+ ...options.storyRulesConfigFilePath ? [options.storyRulesConfigFilePath] : [],
239
+ ...await listRuntimeConfigFiles(options.resolveFrom)
240
+ ]);
241
+ const copiedFiles = /* @__PURE__ */ new Set();
242
+ for (const runtimeInputFile of runtimeInputFiles) {
243
+ await copyLocalRuntimeDependencies(runtimeInputFile, options, copiedFiles);
244
+ }
245
+ }
246
+ async function hasDefaultExport(absPath) {
247
+ try {
248
+ const source = await readFile(absPath, "utf-8");
249
+ return /export\s+default\b/.test(source) || /export\s*\{[^}]*\bdefault\b/.test(source);
250
+ } catch {
251
+ return true;
252
+ }
253
+ }
254
+ function toStaticVirtualId(specifier) {
255
+ return `virtual:astro-static-module/${encodeURIComponent(specifier)}`;
256
+ }
257
+ function toComponentVirtualId(specifier) {
258
+ return `virtual:astro-component-module/${encodeURIComponent(specifier)}?component-wrapper`;
259
+ }
260
+ function toComponentChunkId(specifier) {
261
+ return /\.(svelte|vue)$/.test(specifier) ? specifier : toComponentVirtualId(specifier);
262
+ }
263
+ function createEntrypointName(resolveFrom, specifier) {
264
+ const normalizedResolveFrom = resolveFrom.replace(/\\/g, "/");
265
+ const normalizedSpecifier = specifier.replace(/\\/g, "/");
266
+ const relativeName = normalizedSpecifier.startsWith(`${normalizedResolveFrom}/`) ? normalizedSpecifier.slice(normalizedResolveFrom.length + 1) : normalizedSpecifier.split("/").slice(-2).join("/");
267
+ const sanitizedName = relativeName.replace(/[^a-zA-Z0-9/_-]/g, "_").replace(/_+/g, "_");
268
+ const hash = createHash("sha1").update(normalizedSpecifier).digest("hex").slice(0, 8);
269
+ return `${sanitizedName}-${hash}`;
270
+ }
271
+ function isClientEntrypoint(specifier) {
272
+ return specifier.startsWith("@astrojs/") && specifier.endsWith("/client.js");
273
+ }
274
+ function isHydratableSourceFile(input) {
275
+ return /\.(jsx|tsx|vue|svelte)$/.test(input);
276
+ }
277
+ function isNonHydratableSourceFile(input) {
278
+ return /\.stories\.[jt]sx?$|\.stories\.vue$|\.stories\.svelte$|\.(spec|test)\.[jt]sx?$/.test(
279
+ input
280
+ );
281
+ }
282
+ async function listRuntimeConfigFiles(resolveFrom) {
283
+ const candidates = [
284
+ "package.json",
285
+ "tsconfig.json",
286
+ "tsconfig.base.json",
287
+ "jsconfig.json",
288
+ "astro.config.mjs",
289
+ "astro.config.js",
290
+ "astro.config.ts",
291
+ "vite.config.js",
292
+ "vite.config.ts",
293
+ "svelte.config.js"
294
+ ];
295
+ const existing = [];
296
+ await Promise.all(
297
+ candidates.map(async (candidate) => {
298
+ const filePath = resolve(resolveFrom, candidate);
299
+ try {
300
+ await access(filePath);
301
+ existing.push(filePath);
302
+ } catch {
303
+ return;
304
+ }
305
+ })
306
+ );
307
+ return existing;
308
+ }
309
+ async function copyLocalRuntimeDependencies(sourcePath, options, copiedFiles) {
310
+ const normalizedSourcePath = sourcePath.replace(/\\/g, "/");
311
+ if (copiedFiles.has(normalizedSourcePath)) {
312
+ return;
313
+ }
314
+ copiedFiles.add(normalizedSourcePath);
315
+ const snapshotRelativePath = buildSnapshotFilePath(
316
+ options.resolveFrom,
317
+ normalizedSourcePath,
318
+ options.snapshotDirName
319
+ );
320
+ await copyPath(
321
+ normalizedSourcePath,
322
+ resolve(dirname(options.snapshotRoot), snapshotRelativePath)
323
+ );
324
+ const localImportSpecifiers = await readLocalImportSpecifiers(normalizedSourcePath);
325
+ for (const specifier of localImportSpecifiers) {
326
+ const resolvedDependency = await resolveLocalImportPath(normalizedSourcePath, specifier);
327
+ if (!resolvedDependency) {
328
+ continue;
329
+ }
330
+ await copyLocalRuntimeDependencies(resolvedDependency, options, copiedFiles);
331
+ }
332
+ }
333
+ async function readLocalImportSpecifiers(filePath) {
334
+ if (!/\.(astro|[cm]?[jt]sx?|vue|svelte)$/.test(filePath)) {
335
+ return [];
336
+ }
337
+ const source = await readFile(filePath, "utf-8");
338
+ const matches = source.matchAll(
339
+ /(?:import|export)\s+(?:[^'"`]*?\s+from\s+)?['"`]([^'"`]+)['"`]|import\(\s*['"`]([^'"`]+)['"`]\s*\)/g
340
+ );
341
+ return Array.from(matches, (match) => match[1] ?? match[2]).filter(
342
+ (specifier) => Boolean(specifier) && specifier.startsWith(".")
343
+ );
344
+ }
345
+ async function resolveLocalImportPath(importerPath, specifier) {
346
+ const basePath = resolve(dirname(importerPath), specifier);
347
+ const candidates = [
348
+ basePath,
349
+ `${basePath}.ts`,
350
+ `${basePath}.tsx`,
351
+ `${basePath}.js`,
352
+ `${basePath}.jsx`,
353
+ `${basePath}.mjs`,
354
+ `${basePath}.cjs`,
355
+ `${basePath}.astro`,
356
+ `${basePath}.vue`,
357
+ `${basePath}.svelte`,
358
+ resolve(basePath, "index.ts"),
359
+ resolve(basePath, "index.tsx"),
360
+ resolve(basePath, "index.js"),
361
+ resolve(basePath, "index.jsx"),
362
+ resolve(basePath, "index.mjs"),
363
+ resolve(basePath, "index.cjs"),
364
+ resolve(basePath, "index.astro"),
365
+ resolve(basePath, "index.vue"),
366
+ resolve(basePath, "index.svelte")
367
+ ];
368
+ for (const candidate of candidates) {
369
+ try {
370
+ const candidateStats = await stat(candidate);
371
+ if (candidateStats.isFile()) {
372
+ return candidate.replace(/\\/g, "/");
373
+ }
374
+ } catch {
375
+ continue;
376
+ }
377
+ }
378
+ return void 0;
379
+ }
380
+
381
+ // src/productionRenderRuntime.ts
382
+ import { resolve as resolve2 } from "path";
383
+
384
+ // src/storySsrVite.ts
385
+ import { createRequire } from "module";
386
+ import { createServer, mergeConfig } from "vite";
387
+ async function createStorySsrViteServer(options) {
388
+ const { getViteConfig, passthroughImageService } = await importAstroConfig(options.resolveFrom);
389
+ const astroConfig = await getViteConfig(
390
+ { root: options.resolveFrom },
391
+ {
392
+ configFile: false,
393
+ integrations: await Promise.all(
394
+ options.integrations.map((integration) => integration.loadIntegration(options.resolveFrom))
395
+ ),
396
+ image: { service: passthroughImageService() }
397
+ }
398
+ )({
399
+ mode: "production",
400
+ command: "serve"
401
+ });
402
+ const config = mergeConfig(astroConfig, {
403
+ appType: "custom",
404
+ server: {
405
+ middlewareMode: true
406
+ },
407
+ ssr: {
408
+ // Keep Astro runtime classes in the Vite SSR graph so containers and
409
+ // components share SlotString/HTMLString instances during prerendering.
410
+ noExternal: /^astro(\/.+)?$/
411
+ },
412
+ plugins: [
413
+ createProjectAstroResolutionPlugin(options.resolveFrom),
414
+ vitePluginAstroFontsFallback(),
415
+ vitePluginAstroIntegrationOptsFallback(),
416
+ vitePluginAstroVueFallback(),
417
+ vitePluginAstroRoutesFallback(),
418
+ vitePluginStoryModuleMocks(),
419
+ createTrackedSpecifierStubPlugin(options.trackedSpecifiers)
420
+ ]
421
+ });
422
+ const viteServer = await createServer(config);
423
+ await viteServer.pluginContainer.buildStart({});
424
+ return viteServer;
425
+ }
426
+ async function loadRulesConfigModule(viteServer, configFilePath) {
427
+ if (!configFilePath) {
428
+ return void 0;
429
+ }
430
+ try {
431
+ return await ssrLoadModuleWithFsFallback(viteServer, configFilePath, {
432
+ fixStacktrace: true
433
+ });
434
+ } catch (error) {
435
+ const reason = error instanceof Error ? error.message : String(error);
436
+ throw new Error(
437
+ `Unable to load framework.options.storyRules config module at ${configFilePath}: ${reason}`
438
+ );
439
+ }
440
+ }
441
+ function createClientModuleResolver(integrations, staticModuleMap) {
442
+ return function resolveClientModule(specifier) {
443
+ if (Object.hasOwn(staticModuleMap, specifier)) {
444
+ return staticModuleMap[specifier];
445
+ }
446
+ const normalizedSpecifier = specifier.replace(/\\/g, "/").replace(/\?.*$/, "");
447
+ if (Object.hasOwn(staticModuleMap, normalizedSpecifier)) {
448
+ return staticModuleMap[normalizedSpecifier];
449
+ }
450
+ for (const integration of integrations) {
451
+ const resolution = integration.resolveClient(specifier);
452
+ if (resolution) {
453
+ return resolution;
454
+ }
455
+ }
456
+ };
457
+ }
458
+ async function createProductionAstroContainer(options) {
459
+ ensureAstroPassthroughImageService();
460
+ const containerModule = await options.viteServer.ssrLoadModule("astro/container");
461
+ const ViteAstroContainer = containerModule.experimental_AstroContainer;
462
+ const container = await ViteAstroContainer.create({
463
+ resolve: async (specifier) => {
464
+ const mockedModule = resolveStoryModuleMock(specifier);
465
+ if (mockedModule) {
466
+ return mockedModule;
467
+ }
468
+ const resolution = options.resolveClientModule(specifier);
469
+ if (resolution) {
470
+ return resolution;
471
+ }
472
+ return specifier;
473
+ }
474
+ });
475
+ await addContainerRenderers(
476
+ container,
477
+ options.integrations,
478
+ options.resolveClientModule,
479
+ options.viteServer
480
+ );
481
+ return container;
482
+ }
483
+ async function addContainerRenderers(container, integrations, resolveClientModule, viteServer) {
484
+ for (const integration of integrations) {
485
+ const serverRenderer = integration.renderer.server;
486
+ if (serverRenderer) {
487
+ const serverRendererModule = await viteServer.ssrLoadModule(serverRenderer.entrypoint);
488
+ const renderer = serverRendererModule.default ?? serverRendererModule;
489
+ if (integration.name === "solid" && isRecord(renderer)) {
490
+ container.addServerRenderer({
491
+ name: serverRenderer.name,
492
+ renderer: {
493
+ ...renderer,
494
+ name: serverRenderer.name
495
+ }
496
+ });
497
+ } else {
498
+ container.addServerRenderer({
499
+ name: serverRenderer.name,
500
+ renderer
501
+ });
502
+ }
503
+ }
504
+ const clientRenderer = integration.renderer.client;
505
+ if (clientRenderer) {
506
+ const resolvedEntrypoint = resolveClientModule(clientRenderer.entrypoint) ?? clientRenderer.entrypoint;
507
+ container.addClientRenderer({
508
+ name: clientRenderer.name,
509
+ entrypoint: resolvedEntrypoint
510
+ });
511
+ }
512
+ }
513
+ }
514
+ function createProjectAstroResolutionPlugin(resolveFrom) {
515
+ const require2 = createRequire(import.meta.url);
516
+ return {
517
+ name: "storybook-astro:resolve-project-astro-shared",
518
+ enforce: "pre",
519
+ resolveId(id) {
520
+ if (id !== "astro" && !id.startsWith("astro/")) {
521
+ return null;
522
+ }
523
+ try {
524
+ return require2.resolve(id, {
525
+ paths: [resolveFrom]
526
+ });
527
+ } catch {
528
+ return null;
529
+ }
530
+ }
531
+ };
532
+ }
533
+ function createTrackedSpecifierStubPlugin(trackedSpecifiers) {
534
+ return {
535
+ name: "storybook-astro:shared-ssr-stubs",
536
+ resolveId(id) {
537
+ if (trackedSpecifiers.has(id)) {
538
+ return `\0storybook-astro-shared-ssr-stub:${encodeURIComponent(id)}`;
539
+ }
540
+ return null;
541
+ },
542
+ load(id) {
543
+ if (id.startsWith("\0storybook-astro-shared-ssr-stub:")) {
544
+ return "export default undefined;";
545
+ }
546
+ return null;
547
+ }
548
+ };
549
+ }
550
+ function isRecord(value) {
551
+ return typeof value === "object" && value !== null;
552
+ }
553
+
554
+ // src/productionRenderRuntime.ts
555
+ async function createProductionRenderRuntime(options) {
556
+ const viteServer = await createStorySsrViteServer({
557
+ integrations: options.integrations,
558
+ trackedSpecifiers: options.trackedSpecifiers,
559
+ resolveFrom: options.resolveFrom
560
+ });
561
+ try {
562
+ const rulesConfigModule = await loadRulesConfigModule(
563
+ viteServer,
564
+ options.storyRulesConfigFilePath
565
+ );
566
+ const resolveClientModule = createClientModuleResolver(
567
+ options.integrations,
568
+ options.staticModuleMap
569
+ );
570
+ const astroContainer = await createProductionAstroContainer({
571
+ integrations: options.integrations,
572
+ resolveClientModule,
573
+ viteServer
574
+ });
575
+ const loadModule = async (moduleId) => {
576
+ return await viteServer.ssrLoadModule(
577
+ options.resolveComponentId?.(moduleId) ?? moduleId
578
+ );
579
+ };
580
+ const renderAstroStory = createAstroRenderHandler({
581
+ container: astroContainer,
582
+ sanitization: options.sanitization,
583
+ rulesConfigFilePath: options.storyRulesConfigFilePath,
584
+ resolveRulesConfigModule: () => rulesConfigModule,
585
+ loadModule: async (moduleId) => {
586
+ const loadedModule = await loadModule(moduleId);
587
+ return {
588
+ default: loadedModule.default
589
+ };
590
+ },
591
+ invalidateModuleGraph: () => {
592
+ viteServer.moduleGraph.invalidateAll();
593
+ }
594
+ });
595
+ return {
596
+ loadModule,
597
+ renderAstroStory,
598
+ close: () => viteServer.close()
599
+ };
600
+ } catch (error) {
601
+ await viteServer.close();
602
+ throw error;
603
+ }
604
+ }
605
+ async function renderProductionStoryToHtml(options) {
606
+ const storyModulePath = resolveProjectImportPath(options.story.importPath, options.resolveFrom);
607
+ const componentPath = resolveProjectImportPath(options.story.componentPath, options.resolveFrom);
608
+ const storyModule = await options.runtime.loadModule(storyModulePath);
609
+ const defaultStoryMeta = isRecord2(storyModule.default) ? storyModule.default : {};
610
+ const selectedStoryExport = isRecord2(storyModule[options.story.exportName]) ? storyModule[options.story.exportName] : {};
611
+ if (typeof defaultStoryMeta.component !== "function") {
612
+ throw new Error(
613
+ `Unable to prerender story "${options.story.id}". Missing default export component in ${options.story.importPath}.`
614
+ );
615
+ }
616
+ if (selectedStoryExport.component && selectedStoryExport.component !== defaultStoryMeta.component) {
617
+ return void 0;
618
+ }
619
+ const storyArgs = mergeMetaArgsWithStoryArgs(
620
+ toRecord(defaultStoryMeta.args),
621
+ toRecord(selectedStoryExport.args)
622
+ );
623
+ const { componentArgs, storySlots } = separateStorySlots(storyArgs);
624
+ return options.runtime.renderAstroStory({
625
+ component: componentPath,
626
+ args: componentArgs,
627
+ slots: storySlots,
628
+ story: {
629
+ id: options.story.id,
630
+ title: options.story.title,
631
+ name: options.story.name
632
+ }
633
+ });
634
+ }
635
+ function resolveProjectImportPath(importPath, resolveFrom) {
636
+ if (importPath.startsWith("./") || importPath.startsWith("../")) {
637
+ return resolve2(resolveFrom, importPath);
638
+ }
639
+ return importPath;
640
+ }
641
+ function mergeMetaArgsWithStoryArgs(metaArgs, storyArgs) {
642
+ return {
643
+ ...metaArgs ?? {},
644
+ ...storyArgs ?? {}
645
+ };
646
+ }
647
+ function separateStorySlots(storyArgs) {
648
+ const componentArgs = { ...storyArgs };
649
+ const storySlots = componentArgs.slots;
650
+ delete componentArgs.slots;
651
+ if (!isRecord2(storySlots)) {
652
+ return {
653
+ componentArgs,
654
+ storySlots: {}
655
+ };
656
+ }
657
+ return {
658
+ componentArgs,
659
+ storySlots
660
+ };
661
+ }
662
+ function isRecord2(value) {
663
+ return typeof value === "object" && value !== null;
664
+ }
665
+ function toRecord(value) {
666
+ if (!isRecord2(value)) {
667
+ return void 0;
668
+ }
669
+ return value;
670
+ }
671
+
672
+ // src/vitePluginAstroBuildPrerender.ts
673
+ var PRERENDERED_STORIES_FILE = "astro-prerendered-stories.json";
674
+ function vitePluginAstroBuildPrerender(options) {
675
+ const integrations = options.integrations ?? [];
676
+ const resolveFrom = options.resolveFrom ?? process.cwd();
677
+ const storyRulesConfigFilePath = resolveRulesConfigFilePath(options.storyRules, resolveFrom);
678
+ const trackedSpecifiers = collectTrackedSpecifiers(integrations);
679
+ const staticEntrypointRefs = /* @__PURE__ */ new Map();
680
+ const componentEntrypointRefs = /* @__PURE__ */ new Map();
681
+ let outDir = resolve3(resolveFrom, "storybook-static");
682
+ return {
683
+ name: "storybook-astro:build-prerender",
684
+ apply: "build",
685
+ enforce: "post",
686
+ configResolved(config) {
687
+ outDir = resolve3(resolveFrom, config.build.outDir ?? "storybook-static");
688
+ },
689
+ async resolveId(id, importer) {
690
+ const importerPath = stripQuery(importer);
691
+ if (importerPath?.endsWith(".astro")) {
692
+ await emitHydratedComponentEntriesFromAstroFile({
693
+ pluginContext: this,
694
+ astroFilePath: importerPath,
695
+ resolveFrom,
696
+ componentEntrypointRefs
697
+ });
698
+ }
699
+ return resolveVirtualBuildModuleId(id);
700
+ },
701
+ load(id) {
702
+ return loadVirtualBuildModule(id);
703
+ },
704
+ async buildStart() {
705
+ await emitBuildEntrypoints({
706
+ pluginContext: this,
707
+ integrations,
708
+ resolveFrom,
709
+ trackedSpecifiers,
710
+ staticEntrypointRefs
711
+ });
712
+ },
713
+ async writeBundle(_outputOptions, bundle) {
714
+ const staticModuleMap = buildStaticModuleMap(
715
+ this,
716
+ staticEntrypointRefs,
717
+ componentEntrypointRefs
718
+ );
719
+ const astroStories = await collectAstroStories(outDir);
720
+ if (astroStories.length === 0) {
721
+ await writePrerenderedStoriesFile(outDir, {});
722
+ return;
723
+ }
724
+ const prerenderedStories = await prerenderAstroStories({
725
+ astroStories,
726
+ integrations,
727
+ sanitization: options.sanitization,
728
+ storyRulesConfigFilePath,
729
+ staticModuleMap,
730
+ trackedSpecifiers,
731
+ resolveFrom,
732
+ bundle
733
+ });
734
+ await writePrerenderedStoriesFile(outDir, prerenderedStories);
735
+ }
736
+ };
737
+ }
738
+ async function writePrerenderedStoriesFile(outDir, payload) {
739
+ await mkdir2(outDir, { recursive: true });
740
+ await writeFile(resolve3(outDir, PRERENDERED_STORIES_FILE), JSON.stringify(payload), "utf-8");
741
+ }
742
+ async function prerenderAstroStories(options) {
743
+ const runtime = await createProductionRenderRuntime({
744
+ integrations: options.integrations,
745
+ sanitization: options.sanitization,
746
+ storyRulesConfigFilePath: options.storyRulesConfigFilePath,
747
+ staticModuleMap: options.staticModuleMap,
748
+ trackedSpecifiers: options.trackedSpecifiers,
749
+ resolveFrom: options.resolveFrom
750
+ });
751
+ const assetPathMap = buildAssetPathMap(options.bundle);
752
+ try {
753
+ const output = {};
754
+ for (const story of options.astroStories) {
755
+ const html = await renderProductionStoryToHtml({
756
+ story,
757
+ runtime,
758
+ resolveFrom: options.resolveFrom
759
+ });
760
+ if (html !== void 0) {
761
+ output[story.id] = rewriteAssetPaths(html, assetPathMap);
762
+ }
763
+ }
764
+ return output;
765
+ } finally {
766
+ await runtime.close();
767
+ }
768
+ }
769
+ async function collectAstroStories(outDir) {
770
+ const indexFile = resolve3(outDir, "index.json");
771
+ const indexRaw = await readFile2(indexFile, "utf-8");
772
+ const indexJson = JSON.parse(indexRaw);
773
+ return Object.values(indexJson.entries ?? {}).filter((entry) => entry.type === "story" && entry.componentPath?.endsWith(".astro")).map((entry) => {
774
+ if (!entry.id || !entry.importPath || !entry.exportName || !entry.componentPath) {
775
+ throw new Error(`Encountered an invalid Storybook index entry in ${indexFile}.`);
776
+ }
777
+ return {
778
+ id: entry.id,
779
+ importPath: entry.importPath,
780
+ componentPath: entry.componentPath,
781
+ exportName: entry.exportName,
782
+ title: entry.title,
783
+ name: entry.name
784
+ };
785
+ });
786
+ }
787
+ function buildAssetPathMap(bundle) {
788
+ const exactMap = /* @__PURE__ */ new Map();
789
+ const stemMap = /* @__PURE__ */ new Map();
790
+ for (const chunk of Object.values(bundle)) {
791
+ if (chunk.type !== "asset") {
792
+ continue;
793
+ }
794
+ const asset = chunk;
795
+ if (asset.originalFileNames && asset.originalFileNames.length > 0) {
796
+ for (const originalPath of asset.originalFileNames) {
797
+ exactMap.set(originalPath, `/${asset.fileName}`);
798
+ }
799
+ }
800
+ const baseName = asset.fileName.split("/").pop() ?? "";
801
+ const stemMatch = baseName.match(/^(.+)-[A-Za-z0-9]{6,12}\.(png|jpe?g|gif|webp|svg|avif|ico)$/);
802
+ if (stemMatch) {
803
+ stemMap.set(`${stemMatch[1]}.${stemMatch[2]}`, `/${asset.fileName}`);
804
+ }
805
+ }
806
+ return { exactMap, stemMap };
807
+ }
808
+ function rewriteAssetPaths(html, assetPathMap) {
809
+ const { exactMap, stemMap } = assetPathMap;
810
+ if (exactMap.size === 0 && stemMap.size === 0) {
811
+ return html;
812
+ }
813
+ return html.replace(/\/@fs\/[^"']+/g, (match) => {
814
+ const pathOnly = match.replace(/\?.*$/, "");
815
+ const fsPath = pathOnly.slice("/@fs".length);
816
+ const absolutePath = fsPath.startsWith("//") ? fsPath.slice(1) : fsPath;
817
+ const exact = exactMap.get(absolutePath);
818
+ if (exact) {
819
+ return exact;
820
+ }
821
+ const baseName = absolutePath.split("/").pop() ?? "";
822
+ const stemHit = stemMap.get(baseName);
823
+ if (stemHit) {
824
+ return stemHit;
825
+ }
826
+ return match;
827
+ });
828
+ }
829
+
830
+ // src/vitePluginAstroBuildServer.ts
831
+ import { dirname as dirname2, resolve as resolve4 } from "path";
832
+ import { fileURLToPath as fileURLToPath2 } from "url";
833
+ import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
834
+ import { build } from "vite";
835
+
836
+ // src/vitePluginAstro.ts
837
+ import { mergeConfig as mergeConfig2 } from "vite";
838
+ var ASTRO_PLUGINS_THAT_ARE_SUPPOSEDLY_NOT_NEEDED_IN_STORYBOOK = [
839
+ "@astro/plugin-actions",
840
+ "@astrojs/vite-plugin-astro-ssr-manifest",
841
+ "astro-content-virtual-mod-plugin",
842
+ "astro:actions",
843
+ "astro:build:normal",
844
+ "astro:container",
845
+ "astro:content-asset-propagation",
846
+ "astro:content-imports",
847
+ "astro:content-listen",
848
+ "astro:dev-toolbar",
849
+ "astro:head-metadata",
850
+ "astro:html",
851
+ "astro:i18n",
852
+ "astro:integration-container",
853
+ "astro:jsx",
854
+ "astro:markdown",
855
+ "astro:postprocess",
856
+ "astro:prefetch",
857
+ "astro:scanner",
858
+ "astro:scripts:page-ssr",
859
+ "astro:server",
860
+ "astro:vite-plugin-env",
861
+ "astro:vite-plugin-file-url"
862
+ ];
863
+ async function mergeWithAstroConfig(config, integrations = [], resolveFrom = process.cwd(), mode = "development", command = "serve") {
864
+ const { getViteConfig } = await importAstroConfig(resolveFrom);
865
+ const safeIntegrations = integrations ?? [];
866
+ const astroConfig = await getViteConfig(
867
+ {},
868
+ {
869
+ configFile: false,
870
+ integrations: await Promise.all(
871
+ safeIntegrations.map((integration) => integration.loadIntegration(resolveFrom))
872
+ )
873
+ }
874
+ )({
875
+ mode,
876
+ command
877
+ });
878
+ const filteredPlugins = astroConfig.plugins.flat().filter(
879
+ (plugin) => plugin && "name" in plugin && !ASTRO_PLUGINS_THAT_ARE_SUPPOSEDLY_NOT_NEEDED_IN_STORYBOOK.includes(plugin.name)
880
+ );
881
+ return mergeConfig2(config, {
882
+ ...astroConfig,
883
+ plugins: filteredPlugins
884
+ });
885
+ }
886
+
887
+ // src/vite/sanitizeConfigPlugin.ts
888
+ var SANITIZE_CONFIG_MODULE_ID = "virtual:storybook-astro/sanitize-config";
889
+ function sanitizeConfigPlugin(options) {
890
+ return createVirtualModule({
891
+ pluginName: "storybook-astro:sanitize-config",
892
+ virtualModuleId: SANITIZE_CONFIG_MODULE_ID,
893
+ load() {
894
+ const serializedConfig = serializeSanitizationOptions(options);
895
+ return `export default ${serializedConfig};`;
896
+ }
897
+ });
898
+ }
899
+
900
+ // src/vite/serverAuthPlugin.ts
901
+ var SERVER_AUTH_MODULE_ID = "virtual:storybook-astro/server-auth";
902
+ function serverAuthPlugin(options) {
903
+ const authToken = normalizeOptionalString(options?.authToken);
904
+ const authHeader = normalizeAuthHeader(options?.authHeader);
905
+ return createVirtualModule({
906
+ pluginName: "storybook-astro:server-auth",
907
+ virtualModuleId: SERVER_AUTH_MODULE_ID,
908
+ load() {
909
+ return [
910
+ `export const storybookAstroServerAuthToken = ${authToken ? JSON.stringify(authToken) : "undefined"};`,
911
+ `export const storybookAstroServerAuthHeader = ${JSON.stringify(authHeader)};`
912
+ ].join("\n");
913
+ }
914
+ });
915
+ }
916
+ function normalizeOptionalString(value) {
917
+ if (!value) {
918
+ return void 0;
919
+ }
920
+ const normalizedValue = value.trim();
921
+ return normalizedValue || void 0;
922
+ }
923
+ function normalizeAuthHeader(value) {
924
+ const normalizedValue = normalizeOptionalString(value);
925
+ return (normalizedValue ?? "authorization").toLowerCase();
926
+ }
927
+
928
+ // src/vite/serverRuntimePlugin.ts
929
+ import { relative } from "path";
930
+ var SERVER_RUNTIME_MODULE_ID = "virtual:storybook-astro/server-runtime";
931
+ var integrationsModuleId = "@storybook-astro/framework/integrations";
932
+ function getIntegrationFactoryName(integration) {
933
+ return integration.factoryName ?? integration.name;
934
+ }
935
+ function serverRuntimePlugin(options) {
936
+ return createVirtualModule({
937
+ pluginName: "storybook-astro:server-runtime",
938
+ virtualModuleId: SERVER_RUNTIME_MODULE_ID,
939
+ load() {
940
+ const storyRulesConfigFilePath = resolveRulesConfigFilePath(options.storyRules, options.resolveFrom);
941
+ const storyRulesConfigRelativePath = storyRulesConfigFilePath ? relative(options.resolveFrom, storyRulesConfigFilePath).replace(/\\/g, "/") : void 0;
942
+ const integrations = options.integrations ?? [];
943
+ const runtimeConfig = {
944
+ snapshotDirName: options.snapshotDirName,
945
+ storyRulesConfigRelativePath,
946
+ componentPathMap: options.componentPathMap,
947
+ staticModuleMap: options.staticModuleMap,
948
+ staticCssMap: options.staticCssMap,
949
+ trackedSpecifiers: options.trackedSpecifiers
950
+ };
951
+ return [
952
+ createIntegrationImports(integrations),
953
+ `export const runtimeConfig = ${serializeValue(runtimeConfig)};`,
954
+ `export const integrations = [${createIntegrationFactoryCalls(integrations)}];`
955
+ ].join("\n");
956
+ }
957
+ });
958
+ }
959
+ function createIntegrationImports(integrations) {
960
+ const factoryNames = Array.from(new Set(integrations.map(getIntegrationFactoryName)));
961
+ if (factoryNames.length === 0) {
962
+ return "";
963
+ }
964
+ return `import { ${factoryNames.join(", ")} } from ${JSON.stringify(integrationsModuleId)};`;
965
+ }
966
+ function createIntegrationFactoryCalls(integrations) {
967
+ return integrations.map((integration) => `${getIntegrationFactoryName(integration)}(${serializeValue(integration.options)})`).join(", ");
968
+ }
969
+ function serializeValue(value) {
970
+ if (value === void 0) {
971
+ return "undefined";
972
+ }
973
+ if (value === null) {
974
+ return "null";
975
+ }
976
+ if (typeof value === "string") {
977
+ return JSON.stringify(value);
978
+ }
979
+ if (typeof value === "number" || typeof value === "boolean") {
980
+ return JSON.stringify(value);
981
+ }
982
+ if (value instanceof RegExp) {
983
+ return value.toString();
984
+ }
985
+ if (Array.isArray(value)) {
986
+ return `[${value.map((entry) => serializeValue(entry)).join(", ")}]`;
987
+ }
988
+ if (isRecord3(value)) {
989
+ return `{${Object.entries(value).map(([key, entryValue]) => `${JSON.stringify(key)}: ${serializeValue(entryValue)}`).join(", ")}}`;
990
+ }
991
+ throw new Error("Unable to serialize Storybook Astro server runtime configuration.");
992
+ }
993
+ function isRecord3(value) {
994
+ return typeof value === "object" && value !== null;
995
+ }
996
+
997
+ // src/vitePluginAstroBuildServer.ts
998
+ var moduleRoot = resolve4(dirname2(fileURLToPath2(import.meta.url)), ".");
999
+ var packageRoot = resolve4(moduleRoot, "..");
1000
+ function vitePluginAstroBuildServer(options) {
1001
+ const integrations = options.integrations ?? [];
1002
+ const resolveFrom = options.resolveFrom ?? process.cwd();
1003
+ const trackedSpecifiers = collectTrackedSpecifiers(integrations);
1004
+ const staticEntrypointRefs = /* @__PURE__ */ new Map();
1005
+ let storybookStaticOutDir = resolve4(resolveFrom, "storybook-static");
1006
+ return {
1007
+ name: "storybook-astro:build-server",
1008
+ apply: "build",
1009
+ enforce: "post",
1010
+ configResolved(config) {
1011
+ storybookStaticOutDir = resolve4(resolveFrom, config.build.outDir ?? "storybook-static");
1012
+ },
1013
+ resolveId(id) {
1014
+ return resolveVirtualBuildModuleId(id);
1015
+ },
1016
+ load(id) {
1017
+ return loadVirtualBuildModule(id);
1018
+ },
1019
+ async buildStart() {
1020
+ await emitBuildEntrypoints({
1021
+ pluginContext: this,
1022
+ integrations,
1023
+ resolveFrom,
1024
+ trackedSpecifiers,
1025
+ staticEntrypointRefs
1026
+ });
1027
+ },
1028
+ async writeBundle(_outputOptions) {
1029
+ const serverOutDir = resolve4(dirname2(storybookStaticOutDir), "storybook-server");
1030
+ const snapshotDirName = "project";
1031
+ const astroStories = await collectAstroStories2(storybookStaticOutDir, resolveFrom);
1032
+ const storyAstroComponentPaths = Array.from(new Set(astroStories.map((story) => story.componentPath)));
1033
+ const componentPathMap = buildComponentPathMap(storyAstroComponentPaths, resolveFrom, snapshotDirName);
1034
+ const storyRulesConfigFilePath = resolveRulesConfigFilePath(options.storyRules, resolveFrom);
1035
+ const trackedModuleMap = buildStaticModuleMap(this, staticEntrypointRefs, /* @__PURE__ */ new Map());
1036
+ const hydratedComponentAssets = await buildHydratedComponentAssets({
1037
+ componentPaths: storyAstroComponentPaths,
1038
+ integrations,
1039
+ resolveFrom,
1040
+ outDir: storybookStaticOutDir
1041
+ });
1042
+ const staticModuleMap = addSnapshotModuleAliases({
1043
+ ...trackedModuleMap,
1044
+ ...hydratedComponentAssets.staticModuleMap
1045
+ }, {
1046
+ resolveFrom,
1047
+ snapshotRoot: resolve4(serverOutDir, snapshotDirName),
1048
+ snapshotDirName
1049
+ });
1050
+ const staticCssMap = hydratedComponentAssets.staticCssMap;
1051
+ await buildAstroServer({
1052
+ integrations,
1053
+ sanitization: options.sanitization,
1054
+ storyRules: options.storyRules,
1055
+ server: options.server,
1056
+ outDir: serverOutDir,
1057
+ snapshotDirName,
1058
+ componentPathMap,
1059
+ staticModuleMap,
1060
+ staticCssMap,
1061
+ trackedSpecifiers: Array.from(trackedSpecifiers),
1062
+ resolveFrom
1063
+ });
1064
+ await copyRuntimeSnapshot({
1065
+ resolveFrom,
1066
+ snapshotRoot: resolve4(serverOutDir, snapshotDirName),
1067
+ snapshotDirName,
1068
+ astroComponents: storyAstroComponentPaths,
1069
+ storyRulesConfigFilePath
1070
+ });
1071
+ }
1072
+ };
1073
+ }
1074
+ async function buildAstroServer(options) {
1075
+ const buildConfig = {
1076
+ root: resolve4(packageRoot, "src/server"),
1077
+ ssr: {
1078
+ noExternal: /(@astrojs\/.+|react|react-dom)/
1079
+ },
1080
+ build: {
1081
+ ssr: true,
1082
+ outDir: options.outDir,
1083
+ emptyOutDir: true,
1084
+ sourcemap: true,
1085
+ manifest: false,
1086
+ rollupOptions: {
1087
+ input: resolve4(packageRoot, "src/server/index.ts"),
1088
+ treeshake: true
1089
+ }
1090
+ },
1091
+ plugins: [
1092
+ sanitizeConfigPlugin(options.sanitization),
1093
+ serverAuthPlugin(options.server),
1094
+ serverRuntimePlugin({
1095
+ integrations: options.integrations,
1096
+ storyRules: options.storyRules,
1097
+ resolveFrom: options.resolveFrom,
1098
+ snapshotDirName: options.snapshotDirName,
1099
+ componentPathMap: options.componentPathMap,
1100
+ staticModuleMap: options.staticModuleMap,
1101
+ staticCssMap: options.staticCssMap,
1102
+ trackedSpecifiers: options.trackedSpecifiers
1103
+ }),
1104
+ viteAstroContainerRenderersPlugin(options.integrations, {
1105
+ mode: "production",
1106
+ staticModuleMap: options.staticModuleMap
1107
+ })
1108
+ ]
1109
+ };
1110
+ const finalConfig = await mergeWithAstroConfig(
1111
+ buildConfig,
1112
+ options.integrations,
1113
+ options.resolveFrom,
1114
+ "production",
1115
+ "build"
1116
+ );
1117
+ await build(finalConfig);
1118
+ }
1119
+ function buildComponentPathMap(astroComponents, resolveFrom, snapshotDirName) {
1120
+ return Object.fromEntries(
1121
+ astroComponents.map((componentPath) => [
1122
+ componentPath,
1123
+ buildSnapshotFilePath(resolveFrom, componentPath, snapshotDirName).replace(
1124
+ new RegExp(`^${snapshotDirName}/`),
1125
+ ""
1126
+ )
1127
+ ])
1128
+ );
1129
+ }
1130
+ async function collectAstroStories2(outDir, resolveFrom) {
1131
+ const indexFile = resolve4(outDir, "index.json");
1132
+ const indexRaw = await import("fs/promises").then(({ readFile: readFile3 }) => readFile3(indexFile, "utf-8"));
1133
+ const indexJson = JSON.parse(indexRaw);
1134
+ return Object.values(indexJson.entries ?? []).filter((entry) => entry.type === "story" && entry.componentPath?.endsWith(".astro")).map((entry) => ({
1135
+ componentPath: entry.componentPath?.startsWith("./") || entry.componentPath?.startsWith("../") ? resolve4(resolveFrom, entry.componentPath) : entry.componentPath
1136
+ })).filter((entry) => Boolean(entry.componentPath));
1137
+ }
1138
+ async function buildHydratedComponentAssets(options) {
1139
+ const hydratedComponentPaths = Array.from(
1140
+ new Set((await Promise.all(options.componentPaths.map((componentPath) => collectHydratedComponentPaths(componentPath)))).flat())
1141
+ );
1142
+ if (hydratedComponentPaths.length === 0) {
1143
+ return {
1144
+ staticModuleMap: {},
1145
+ staticCssMap: {}
1146
+ };
1147
+ }
1148
+ const clientEntrypoints = Array.from(
1149
+ new Set(
1150
+ options.integrations.map((integration) => integration.renderer.client?.entrypoint).filter((entrypoint) => Boolean(entrypoint))
1151
+ )
1152
+ );
1153
+ const entryNames = Object.fromEntries(
1154
+ [
1155
+ ...hydratedComponentPaths.map((componentPath, index) => [`component-${index}`, componentPath]),
1156
+ ...clientEntrypoints.map((entrypoint, index) => [`renderer-${index}`, entrypoint])
1157
+ ]
1158
+ );
1159
+ const buildConfig = {
1160
+ root: options.resolveFrom,
1161
+ build: {
1162
+ write: false,
1163
+ outDir: options.outDir,
1164
+ emptyOutDir: false,
1165
+ manifest: false,
1166
+ rollupOptions: {
1167
+ input: entryNames,
1168
+ preserveEntrySignatures: "strict",
1169
+ output: {
1170
+ entryFileNames: "_astro/[name]-[hash].js",
1171
+ chunkFileNames: "_astro/[name]-[hash].js",
1172
+ assetFileNames: "_astro/[name]-[hash][extname]"
1173
+ }
1174
+ }
1175
+ }
1176
+ };
1177
+ const finalConfig = await mergeWithAstroConfig(
1178
+ buildConfig,
1179
+ options.integrations,
1180
+ options.resolveFrom,
1181
+ "production",
1182
+ "build"
1183
+ );
1184
+ const buildOutput = await build(finalConfig);
1185
+ const output = Array.isArray(buildOutput) ? buildOutput.flatMap((result) => result.output) : buildOutput.output;
1186
+ const staticModuleMap = {};
1187
+ const staticCssMap = {};
1188
+ for (const item of output) {
1189
+ await writeBuildOutputFile(options.outDir, item);
1190
+ if (item.type !== "chunk" || !item.facadeModuleId) {
1191
+ continue;
1192
+ }
1193
+ const normalizedFacadeId = item.facadeModuleId.replace(/\\/g, "/");
1194
+ const originalInputSpecifier = entryNames[item.name];
1195
+ staticModuleMap[normalizedFacadeId] = `./${item.fileName}`;
1196
+ if (originalInputSpecifier && originalInputSpecifier !== normalizedFacadeId) {
1197
+ staticModuleMap[originalInputSpecifier] = `./${item.fileName}`;
1198
+ }
1199
+ const importedCss = Array.from((item.viteMetadata?.importedCss ?? /* @__PURE__ */ new Set()).values());
1200
+ if (importedCss.length > 0) {
1201
+ staticCssMap[normalizedFacadeId] = importedCss.map((fileName) => `./${fileName}`);
1202
+ if (originalInputSpecifier && originalInputSpecifier !== normalizedFacadeId) {
1203
+ staticCssMap[originalInputSpecifier] = importedCss.map((fileName) => `./${fileName}`);
1204
+ }
1205
+ }
1206
+ }
1207
+ return {
1208
+ staticModuleMap,
1209
+ staticCssMap
1210
+ };
1211
+ }
1212
+ async function writeBuildOutputFile(outDir, item) {
1213
+ const outputPath = resolve4(outDir, item.fileName);
1214
+ await mkdir3(dirname2(outputPath), { recursive: true });
1215
+ if (item.type === "asset") {
1216
+ await writeFile2(outputPath, item.source);
1217
+ return;
1218
+ }
1219
+ await writeFile2(outputPath, item.code);
1220
+ }
1221
+ function addSnapshotModuleAliases(staticModuleMap, options) {
1222
+ const mapWithSnapshotPaths = { ...staticModuleMap };
1223
+ for (const [sourcePath, builtPath] of Object.entries(staticModuleMap)) {
1224
+ if (!sourcePath.startsWith("/")) {
1225
+ continue;
1226
+ }
1227
+ const snapshotPath = resolve4(
1228
+ dirname2(options.snapshotRoot),
1229
+ buildSnapshotFilePath(options.resolveFrom, sourcePath, options.snapshotDirName)
1230
+ ).replace(/\\/g, "/");
1231
+ mapWithSnapshotPaths[snapshotPath] = builtPath;
1232
+ }
1233
+ return mapWithSnapshotPaths;
1234
+ }
1235
+
1236
+ // src/vitePluginAstroToolbarFallback.ts
1237
+ var TOOLBAR_INTERNAL_STUB = `
1238
+ export const loadDevToolbarApps = async () => [];
1239
+ `;
1240
+ function vitePluginAstroToolbarFallback() {
1241
+ const VIRTUAL_ID = "astro:toolbar:internal";
1242
+ const RESOLVED_ID = "\0" + VIRTUAL_ID;
1243
+ return {
1244
+ name: "storybook-astro-toolbar-fallback",
1245
+ enforce: "pre",
1246
+ resolveId(id) {
1247
+ if (id === VIRTUAL_ID) {
1248
+ return RESOLVED_ID;
1249
+ }
1250
+ },
1251
+ load(id) {
1252
+ if (id === RESOLVED_ID) {
1253
+ return { code: TOOLBAR_INTERNAL_STUB };
1254
+ }
1255
+ }
1256
+ };
1257
+ }
1258
+
1259
+ // src/preset.ts
1260
+ var core = {
1261
+ builder: "@storybook/builder-vite",
1262
+ // Use import.meta.resolve so Storybook receives an absolute file:// URL
1263
+ // to the renderer preset rather than a bare package specifier. When
1264
+ // package managers like pnpm use strict node_modules isolation, bare
1265
+ // specifiers are resolved from the *project root*, where the renderer
1266
+ // (a dep of this framework, not the user's project) is not hoisted.
1267
+ // The absolute URL is resolved from *this* file's location where the
1268
+ // renderer is always accessible as a direct dependency.
1269
+ renderer: import.meta.resolve("@storybook-astro/renderer")
1270
+ };
1271
+ var viteFinal = async (config, storybookOptions) => {
1272
+ const { configType, presets, configDir } = storybookOptions;
1273
+ const frameworkOptions = await presets.apply("frameworkOptions");
1274
+ const options = {
1275
+ ...frameworkOptions,
1276
+ resolveFrom: frameworkOptions.resolveFrom ?? dirname3(configDir)
1277
+ };
1278
+ if (!config.plugins) {
1279
+ config.plugins = [];
1280
+ }
1281
+ const integrations = options.integrations ?? [];
1282
+ const renderMode = options.renderMode ?? "server";
1283
+ const mode = configType === "DEVELOPMENT" ? "development" : "production";
1284
+ const command = configType === "DEVELOPMENT" ? "serve" : "build";
1285
+ resolveSanitizationOptions(options.sanitization);
1286
+ config.envPrefix = mergeEnvPrefixes(config.envPrefix, "STORYBOOK_");
1287
+ const { vitePlugin: storybookAstroMiddlewarePlugin, viteConfig } = await vitePluginStorybookAstroMiddleware(options);
1288
+ config.plugins.push(
1289
+ viteStorybookRendererFallbackPlugin(integrations),
1290
+ viteStorybookAstroRendererPlugin({
1291
+ mode,
1292
+ renderMode,
1293
+ server: options.server
1294
+ }),
1295
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1296
+ vitePluginAstroComponentMarker(),
1297
+ vitePluginAstroIntegrationOptsFallback(),
1298
+ vitePluginAstroToolbarFallback(),
1299
+ vitePluginAstroVueFallback()
1300
+ );
1301
+ if (configType === "DEVELOPMENT") {
1302
+ config.plugins.push(storybookAstroMiddlewarePlugin, ...viteConfig.plugins);
1303
+ } else if (renderMode === "static") {
1304
+ config.plugins.push(vitePluginAstroBuildPrerender(options));
1305
+ } else {
1306
+ config.plugins.push(vitePluginAstroBuildServer(options));
1307
+ }
1308
+ if (configType !== "DEVELOPMENT") {
1309
+ config.build = {
1310
+ ...config.build ?? {},
1311
+ manifest: true
1312
+ };
1313
+ config.build.rollupOptions = {
1314
+ ...config.build.rollupOptions ?? {},
1315
+ preserveEntrySignatures: "strict"
1316
+ };
1317
+ }
1318
+ if (!config.resolve) {
1319
+ config.resolve = {};
1320
+ }
1321
+ if (!config.resolve.alias) {
1322
+ config.resolve.alias = {};
1323
+ }
1324
+ const aliases = config.resolve.alias;
1325
+ if (!aliases["react"]) {
1326
+ aliases["react"] = "react";
1327
+ }
1328
+ if (!aliases["react-dom"]) {
1329
+ aliases["react-dom"] = "react-dom";
1330
+ }
1331
+ const finalConfig = await mergeWithAstroConfig(
1332
+ config,
1333
+ integrations,
1334
+ options.resolveFrom,
1335
+ mode,
1336
+ command
1337
+ );
1338
+ if (!finalConfig.optimizeDeps) {
1339
+ finalConfig.optimizeDeps = {};
1340
+ }
1341
+ if (!finalConfig.optimizeDeps.exclude) {
1342
+ finalConfig.optimizeDeps.exclude = [];
1343
+ }
1344
+ for (const pkg of [
1345
+ "@astrojs/vue",
1346
+ "@astrojs/vue/client.js",
1347
+ "@astrojs/vue/server.js",
1348
+ "@astrojs/react",
1349
+ "@astrojs/react/client.js",
1350
+ "@astrojs/react/server.js",
1351
+ "@astrojs/preact",
1352
+ "@astrojs/preact/client.js",
1353
+ "@astrojs/preact/server.js"
1354
+ ]) {
1355
+ if (!finalConfig.optimizeDeps.exclude.includes(pkg)) {
1356
+ finalConfig.optimizeDeps.exclude.push(pkg);
1357
+ }
1358
+ }
1359
+ if (!finalConfig.optimizeDeps.exclude.includes("@storybook-astro/renderer")) {
1360
+ finalConfig.optimizeDeps.exclude.push("@storybook-astro/renderer");
1361
+ }
1362
+ for (const pkg of ["fsevents", "storybook/internal/preview-api"]) {
1363
+ if (!finalConfig.optimizeDeps.exclude.includes(pkg)) {
1364
+ finalConfig.optimizeDeps.exclude.push(pkg);
1365
+ }
1366
+ }
1367
+ const integrationVirtualModules = [
1368
+ "virtual:@astrojs/vue/app",
1369
+ "virtual:astro:vue-app",
1370
+ "astro:react:opts",
1371
+ "astro:preact:opts",
1372
+ "astro:toolbar:internal"
1373
+ ];
1374
+ if (!finalConfig.optimizeDeps.esbuildOptions) {
1375
+ finalConfig.optimizeDeps.esbuildOptions = {};
1376
+ }
1377
+ if (!finalConfig.optimizeDeps.esbuildOptions.external) {
1378
+ finalConfig.optimizeDeps.esbuildOptions.external = [];
1379
+ }
1380
+ for (const mod of integrationVirtualModules) {
1381
+ if (!finalConfig.optimizeDeps.esbuildOptions.external.includes(mod)) {
1382
+ finalConfig.optimizeDeps.esbuildOptions.external.push(mod);
1383
+ }
1384
+ }
1385
+ const optimizeDepsMut = finalConfig.optimizeDeps;
1386
+ const rolldownOpts = optimizeDepsMut.rolldownOptions ?? {};
1387
+ rolldownOpts.external = Array.from(
1388
+ /* @__PURE__ */ new Set([...rolldownOpts.external ?? [], ...integrationVirtualModules])
1389
+ );
1390
+ optimizeDepsMut.rolldownOptions = rolldownOpts;
1391
+ return finalConfig;
1392
+ };
1393
+ function mergeEnvPrefixes(existing, additionalPrefix) {
1394
+ const prefixes = Array.isArray(existing) ? existing : existing ? [existing] : [];
1395
+ return Array.from(/* @__PURE__ */ new Set([...prefixes, additionalPrefix]));
1396
+ }
1397
+
1398
+ export {
1399
+ core,
1400
+ viteFinal
1401
+ };
1402
+ //# sourceMappingURL=chunk-CU57AJUW.js.map