@storybook-astro/framework 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/{chunk-KSDXET2L.js → chunk-4HECE7IW.js} +477 -61
  2. package/dist/chunk-4HECE7IW.js.map +1 -0
  3. package/dist/{chunk-7GHEQUPV.js → chunk-POHTFYST.js} +46 -8
  4. package/dist/chunk-POHTFYST.js.map +1 -0
  5. package/dist/chunk-T7NWIO5S.js +220 -0
  6. package/dist/chunk-T7NWIO5S.js.map +1 -0
  7. package/dist/{chunk-C5OH4VBR.js → chunk-V76WSNSP.js} +124 -47
  8. package/dist/chunk-V76WSNSP.js.map +1 -0
  9. package/dist/index.d.ts +19 -9
  10. package/dist/index.js +10 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/middleware.js +57 -39
  13. package/dist/middleware.js.map +1 -1
  14. package/dist/node/index.d.ts +10 -0
  15. package/dist/node/index.js +10 -0
  16. package/dist/node/index.js.map +1 -0
  17. package/dist/preset.d.ts +1 -1
  18. package/dist/preset.js +3 -3
  19. package/dist/testing.js +12 -64
  20. package/dist/testing.js.map +1 -1
  21. package/dist/{types-CHTsRtA7.d.ts → types-Cvor6Tyi.d.ts} +21 -5
  22. package/dist/{viteStorybookAstroMiddlewarePlugin-NP2E52IC.js → viteStorybookAstroMiddlewarePlugin-2EFKTECT.js} +2 -2
  23. package/dist/vitest/global-setup.js +42 -0
  24. package/dist/vitest/global-setup.js.map +1 -0
  25. package/dist/vitest/index.js +20 -3
  26. package/dist/vitest/index.js.map +1 -1
  27. package/package.json +11 -3
  28. package/src/index.ts +21 -1
  29. package/src/lib/sanitization.ts +104 -0
  30. package/src/middleware.ts +76 -44
  31. package/src/node/index.ts +7 -0
  32. package/src/preset.ts +86 -16
  33. package/src/renderer/renderer-dev.ts +82 -0
  34. package/src/renderer/renderer-server.test.ts +101 -0
  35. package/src/renderer/renderer-server.ts +135 -0
  36. package/src/renderer/renderer-static.ts +62 -0
  37. package/src/rules.test.ts +89 -18
  38. package/src/rules.ts +67 -18
  39. package/src/server/index.ts +111 -0
  40. package/src/testing/renderer-daemon.ts +10 -1
  41. package/src/types.ts +25 -5
  42. package/src/virtual.d.ts +37 -0
  43. package/src/vite/astroFilesVirtualModulePlugin.ts +36 -0
  44. package/src/vite/createVirtualModulePlugin.ts +3 -3
  45. package/src/vite/storybookAstroRulesConfigVirtualModulePlugin.ts +37 -0
  46. package/src/vite/storybookAstroSanitizationConfigVirtualModulePlugin.ts +21 -0
  47. package/src/vite/storybookAstroServerAuthConfigVirtualModulePlugin.test.ts +71 -0
  48. package/src/vite/storybookAstroServerAuthConfigVirtualModulePlugin.ts +42 -0
  49. package/src/vitePluginAstroBuildPrerender.ts +50 -51
  50. package/src/vitePluginAstroBuildServer.ts +289 -0
  51. package/src/vitePluginAstroIntegrationOptsFallback.ts +25 -0
  52. package/src/vitePluginAstroToolbarFallback.ts +38 -0
  53. package/src/viteStorybookAstroMiddlewarePlugin.ts +40 -8
  54. package/src/viteStorybookAstroRendererPlugin.ts +45 -0
  55. package/src/vitest/config.ts +45 -4
  56. package/src/vitest/global-setup.ts +45 -0
  57. package/dist/chunk-7GHEQUPV.js.map +0 -1
  58. package/dist/chunk-C5OH4VBR.js.map +0 -1
  59. package/dist/chunk-KSDXET2L.js.map +0 -1
  60. package/dist/middleware.d.ts +0 -26
  61. package/src/msw-helpers.ts +0 -1
  62. package/src/msw.ts +0 -58
  63. /package/dist/{viteStorybookAstroMiddlewarePlugin-NP2E52IC.js.map → viteStorybookAstroMiddlewarePlugin-2EFKTECT.js.map} +0 -0
@@ -1,23 +1,26 @@
1
1
  import {
2
- applyMswHandlers,
3
2
  resolveSanitizationOptions,
4
3
  resolveStoryModuleMock,
5
4
  sanitizeRenderPayload,
6
5
  selectStoryRules,
7
- withStoryModuleMocks
8
- } from "./chunk-C5OH4VBR.js";
9
- import {
10
- vitePluginAstroComponentMarker
11
- } from "./chunk-E4LB75JN.js";
6
+ serializeSanitizationOptions,
7
+ withStoryModuleMocks,
8
+ withStoryRuleCleanups
9
+ } from "./chunk-V76WSNSP.js";
12
10
  import {
13
11
  createVirtualModulePlugin,
14
12
  resolveRulesConfigFilePath,
15
13
  ssrLoadModuleWithFsFallback,
14
+ viteAstroContainerRenderersPlugin,
16
15
  vitePluginAstroFontsFallback,
16
+ vitePluginAstroIntegrationOptsFallback,
17
17
  vitePluginAstroRoutesFallback,
18
18
  vitePluginAstroVueFallback,
19
19
  vitePluginStorybookAstroMiddleware
20
- } from "./chunk-7GHEQUPV.js";
20
+ } from "./chunk-POHTFYST.js";
21
+ import {
22
+ vitePluginAstroComponentMarker
23
+ } from "./chunk-E4LB75JN.js";
21
24
  import {
22
25
  importAstroConfig
23
26
  } from "./chunk-DNGQBPT7.js";
@@ -36,6 +39,42 @@ function viteStorybookRendererFallbackPlugin(integrations) {
36
39
  });
37
40
  }
38
41
 
42
+ // src/viteStorybookAstroRendererPlugin.ts
43
+ var packageName = "@storybook-astro/framework";
44
+ function viteStorybookAstroRendererPlugin(options) {
45
+ const pluginName = "storybook-astro:renderer-module";
46
+ const virtualModuleId = "virtual:storybook-astro-renderer";
47
+ const isProduction = options.mode === "production";
48
+ const isStaticMode = options.renderMode === "static";
49
+ return createVirtualModulePlugin({
50
+ pluginName,
51
+ virtualModuleId,
52
+ load() {
53
+ if (!isProduction) {
54
+ return `export * from '${packageName}/renderer/renderer-dev.ts';`;
55
+ }
56
+ if (isStaticMode) {
57
+ return `export * from '${packageName}/renderer/renderer-static.ts';`;
58
+ }
59
+ return [
60
+ `import { createServerRenderer } from '${packageName}/renderer/renderer-server.ts';`,
61
+ `const renderer = createServerRenderer(${JSON.stringify(
62
+ {
63
+ serverUrl: options.server?.serverUrl,
64
+ authToken: options.server?.authToken,
65
+ authHeader: options.server?.authHeader
66
+ },
67
+ null,
68
+ 2
69
+ )});`,
70
+ "export const render = renderer.render;",
71
+ "export const init = renderer.init;",
72
+ "export const applyStyles = renderer.applyStyles;"
73
+ ].join("\n");
74
+ }
75
+ });
76
+ }
77
+
39
78
  // src/vitePluginAstroBuildPrerender.ts
40
79
  import { createRequire } from "module";
41
80
  import { mkdir, readFile, readdir, writeFile } from "fs/promises";
@@ -165,43 +204,46 @@ async function prerenderStories(options) {
165
204
  const selectedRules = await selectStoryRules({
166
205
  configModule: rulesConfigModule,
167
206
  configFilePath: options.storyRulesConfigFilePath,
168
- mode: "production",
169
207
  story: {
170
208
  id: story.id,
171
209
  title: story.title,
172
210
  name: story.name
173
211
  }
174
212
  });
175
- await applyMswHandlers(selectedRules.mswHandlers);
176
213
  if (selectedRules.moduleMocks.size > 0) {
177
214
  viteServer.moduleGraph.invalidateAll();
178
215
  }
179
- const html = await withStoryModuleMocks(selectedRules.moduleMocks, async () => {
180
- const modulePath = resolveImportPath(story.importPath, options.resolveFrom);
181
- const storyModule = await viteServer.ssrLoadModule(modulePath);
182
- const meta = isRecord(storyModule.default) ? storyModule.default : {};
183
- const storyExport = isRecord(storyModule[story.exportName]) ? storyModule[story.exportName] : {};
184
- if (typeof meta.component !== "function") {
185
- throw new Error(
186
- `Unable to prerender story "${story.id}". Missing default export component in ${story.importPath}.`
216
+ const html = await withStoryRuleCleanups(selectedRules.cleanups, async () => {
217
+ return withStoryModuleMocks(selectedRules.moduleMocks, async () => {
218
+ const modulePath = resolveImportPath(story.importPath, options.resolveFrom);
219
+ const storyModule = await viteServer.ssrLoadModule(modulePath);
220
+ const meta = isRecord(storyModule.default) ? storyModule.default : {};
221
+ const storyExport = isRecord(storyModule[story.exportName]) ? storyModule[story.exportName] : {};
222
+ if (typeof meta.component !== "function") {
223
+ throw new Error(
224
+ `Unable to prerender story "${story.id}". Missing default export component in ${story.importPath}.`
225
+ );
226
+ }
227
+ if (storyExport.component && storyExport.component !== meta.component) {
228
+ return void 0;
229
+ }
230
+ const mergedArgs = mergeStoryArgs(toRecord(meta.args), toRecord(storyExport.args));
231
+ const { args, slots } = separateSlots(mergedArgs);
232
+ const processedArgs = await processImageMetadata(args);
233
+ const sanitizedPayload = sanitizeRenderPayload(
234
+ {
235
+ args: processedArgs,
236
+ slots
237
+ },
238
+ sanitizationOptions
239
+ );
240
+ return container.renderToString(
241
+ patchCreateAstroCompat(meta.component),
242
+ {
243
+ props: sanitizedPayload.args,
244
+ slots: sanitizedPayload.slots
245
+ }
187
246
  );
188
- }
189
- if (storyExport.component && storyExport.component !== meta.component) {
190
- return void 0;
191
- }
192
- const mergedArgs = mergeStoryArgs(toRecord(meta.args), toRecord(storyExport.args));
193
- const { args, slots } = separateSlots(mergedArgs);
194
- const processedArgs = await processImageMetadata(args);
195
- const sanitizedPayload = sanitizeRenderPayload(
196
- {
197
- args: processedArgs,
198
- slots
199
- },
200
- sanitizationOptions
201
- );
202
- return container.renderToString(patchCreateAstroCompat(meta.component), {
203
- props: sanitizedPayload.args,
204
- slots: sanitizedPayload.slots
205
247
  });
206
248
  });
207
249
  if (html !== void 0) {
@@ -214,14 +256,18 @@ async function prerenderStories(options) {
214
256
  }
215
257
  }
216
258
  async function createStorySsrServer(integrations, trackedSpecifiers, resolveFrom) {
217
- const { getViteConfig } = await importAstroConfig(resolveFrom);
259
+ const { getViteConfig, passthroughImageService } = await importAstroConfig(resolveFrom);
218
260
  const astroConfig = await getViteConfig(
219
261
  { root: resolveFrom },
220
262
  {
221
263
  configFile: false,
222
264
  integrations: await Promise.all(
223
265
  integrations.map((integration) => integration.loadIntegration(resolveFrom))
224
- )
266
+ ),
267
+ // Use the passthrough image service so nested components that use <Image>
268
+ // from astro:assets render as plain <img> tags without triggering image
269
+ // optimization (which fails in the Storybook SSR context).
270
+ image: { service: passthroughImageService() }
225
271
  }
226
272
  )({
227
273
  mode: "production",
@@ -235,6 +281,7 @@ async function createStorySsrServer(integrations, trackedSpecifiers, resolveFrom
235
281
  plugins: [
236
282
  createProjectAstroResolutionPlugin(resolveFrom),
237
283
  vitePluginAstroFontsFallback(),
284
+ vitePluginAstroIntegrationOptsFallback(),
238
285
  vitePluginAstroVueFallback(),
239
286
  vitePluginAstroRoutesFallback(),
240
287
  {
@@ -476,14 +523,14 @@ async function processImageMetadata(args) {
476
523
  const processed = {};
477
524
  for (const [key, value] of Object.entries(args)) {
478
525
  if (isImageMetadata(value)) {
479
- processed[key] = convertImageMetadataToUrl(value);
526
+ processed[key] = value;
480
527
  continue;
481
528
  }
482
529
  if (Array.isArray(value)) {
483
530
  processed[key] = await Promise.all(
484
531
  value.map(async (item) => {
485
532
  if (isImageMetadata(item)) {
486
- return convertImageMetadataToUrl(item);
533
+ return item;
487
534
  }
488
535
  if (isRecord(item)) {
489
536
  return processImageMetadata(item);
@@ -504,17 +551,6 @@ async function processImageMetadata(args) {
504
551
  function isImageMetadata(value) {
505
552
  return isRecord(value) && typeof value.src === "string" && ("width" in value || "height" in value || "format" in value);
506
553
  }
507
- function convertImageMetadataToUrl(imageMetadata) {
508
- const src = imageMetadata.src;
509
- const fsPath = imageMetadata.fsPath;
510
- if (typeof src === "string") {
511
- return src;
512
- }
513
- if (typeof fsPath === "string") {
514
- return fsPath;
515
- }
516
- return String(imageMetadata);
517
- }
518
554
  function createProjectAstroResolutionPlugin(resolveFrom) {
519
555
  const require2 = createRequire(import.meta.url);
520
556
  return {
@@ -535,6 +571,12 @@ function createProjectAstroResolutionPlugin(resolveFrom) {
535
571
  };
536
572
  }
537
573
 
574
+ // src/vitePluginAstroBuildServer.ts
575
+ import { readdir as readdir2 } from "fs/promises";
576
+ import { dirname, resolve as resolve2 } from "path";
577
+ import { fileURLToPath } from "url";
578
+ import { build } from "vite";
579
+
538
580
  // src/vitePluginAstro.ts
539
581
  import { mergeConfig as mergeConfig2 } from "vite";
540
582
  var ASTRO_PLUGINS_THAT_ARE_SUPPOSEDLY_NOT_NEEDED_IN_STORYBOOK = [
@@ -586,32 +628,388 @@ async function mergeWithAstroConfig(config, integrations = [], resolveFrom = pro
586
628
  });
587
629
  }
588
630
 
631
+ // src/vite/astroFilesVirtualModulePlugin.ts
632
+ function astroFilesVirtualModulePlugin(astroComponents) {
633
+ return createVirtualModulePlugin({
634
+ pluginName: "storybook-astro:virtual-astro-files",
635
+ virtualModuleId: "virtual:astro-files",
636
+ load() {
637
+ const imports = astroComponents.reduce((records, file, index) => {
638
+ const moduleId = `_astroFile${index}`;
639
+ return [
640
+ ...records,
641
+ {
642
+ id: moduleId,
643
+ file,
644
+ importStatement: `import ${moduleId} from '${file}';`
645
+ }
646
+ ];
647
+ }, []);
648
+ return [
649
+ imports.map(({ importStatement }) => importStatement).join("\n"),
650
+ "export default {",
651
+ imports.map(({ file, id }) => `'${file}': ${id}`).join(",\n"),
652
+ "};"
653
+ ].join("\n");
654
+ }
655
+ });
656
+ }
657
+
658
+ // src/vite/storybookAstroRulesConfigVirtualModulePlugin.ts
659
+ var STORYBOOK_ASTRO_STORY_RULES_CONFIG_VIRTUAL_MODULE_ID = "virtual:storybook-astro-story-rules-config";
660
+ function storybookAstroStoryRulesConfigVirtualModulePlugin(options, resolveFrom = process.cwd()) {
661
+ return createVirtualModulePlugin({
662
+ pluginName: "storybook-astro:virtual-story-rules-config",
663
+ virtualModuleId: STORYBOOK_ASTRO_STORY_RULES_CONFIG_VIRTUAL_MODULE_ID,
664
+ load() {
665
+ const configFilePath = resolveRulesConfigFilePath(options, resolveFrom);
666
+ if (!configFilePath) {
667
+ return [
668
+ "const storybookAstroStoryRulesConfig = { rules: [] };",
669
+ "export default storybookAstroStoryRulesConfig;",
670
+ "export const storybookAstroStoryRulesConfigFilePath = undefined;"
671
+ ].join("\n");
672
+ }
673
+ const importPath = JSON.stringify(configFilePath.replace(/\\/g, "/"));
674
+ const configPath = JSON.stringify(configFilePath.replace(/\\/g, "/"));
675
+ return [
676
+ `import * as storybookAstroStoryRulesConfigModule from ${importPath};`,
677
+ "export default storybookAstroStoryRulesConfigModule;",
678
+ `export const storybookAstroStoryRulesConfigFilePath = ${configPath};`
679
+ ].join("\n");
680
+ }
681
+ });
682
+ }
683
+
684
+ // src/vite/storybookAstroSanitizationConfigVirtualModulePlugin.ts
685
+ var STORYBOOK_ASTRO_SANITIZATION_CONFIG_VIRTUAL_MODULE_ID = "virtual:storybook-astro-sanitization-config";
686
+ function storybookAstroSanitizationConfigVirtualModulePlugin(options) {
687
+ return createVirtualModulePlugin({
688
+ pluginName: "storybook-astro:virtual-sanitization-config",
689
+ virtualModuleId: STORYBOOK_ASTRO_SANITIZATION_CONFIG_VIRTUAL_MODULE_ID,
690
+ load() {
691
+ const serializedConfig = serializeSanitizationOptions(options);
692
+ return `export default ${serializedConfig};`;
693
+ }
694
+ });
695
+ }
696
+
697
+ // src/vite/storybookAstroServerAuthConfigVirtualModulePlugin.ts
698
+ var STORYBOOK_ASTRO_SERVER_AUTH_CONFIG_VIRTUAL_MODULE_ID = "virtual:storybook-astro-server-auth-config";
699
+ function storybookAstroServerAuthConfigVirtualModulePlugin(options) {
700
+ const authToken = normalizeOptionalString(options?.authToken);
701
+ const authHeader = normalizeAuthHeader(options?.authHeader);
702
+ return createVirtualModulePlugin({
703
+ pluginName: "storybook-astro:virtual-server-auth-config",
704
+ virtualModuleId: STORYBOOK_ASTRO_SERVER_AUTH_CONFIG_VIRTUAL_MODULE_ID,
705
+ load() {
706
+ return [
707
+ `export const storybookAstroServerAuthToken = ${authToken ? JSON.stringify(authToken) : "undefined"};`,
708
+ `export const storybookAstroServerAuthHeader = ${JSON.stringify(authHeader)};`
709
+ ].join("\n");
710
+ }
711
+ });
712
+ }
713
+ function normalizeOptionalString(value) {
714
+ if (!value) {
715
+ return void 0;
716
+ }
717
+ const normalizedValue = value.trim();
718
+ return normalizedValue || void 0;
719
+ }
720
+ function normalizeAuthHeader(value) {
721
+ const normalizedValue = normalizeOptionalString(value);
722
+ return (normalizedValue ?? "authorization").toLowerCase();
723
+ }
724
+
725
+ // src/vitePluginAstroBuildServer.ts
726
+ var moduleRoot = resolve2(dirname(fileURLToPath(import.meta.url)), ".");
727
+ var packageRoot = resolve2(moduleRoot, "..");
728
+ function vitePluginAstroBuildServer(options) {
729
+ const integrations = options.integrations ?? [];
730
+ const resolveFrom = options.resolveFrom ?? process.cwd();
731
+ const storiesMap = /* @__PURE__ */ new Map();
732
+ const trackedSpecifiers = collectTrackedSpecifiers2(integrations);
733
+ const staticEntrypointRefs = /* @__PURE__ */ new Map();
734
+ const componentEntrypointRefs = /* @__PURE__ */ new Map();
735
+ let storybookStaticOutDir = resolve2(resolveFrom, "storybook-static");
736
+ return {
737
+ name: "storybook-astro:build-server",
738
+ apply: "build",
739
+ enforce: "post",
740
+ configResolved(config) {
741
+ storybookStaticOutDir = resolve2(resolveFrom, config.build.outDir ?? "storybook-static");
742
+ },
743
+ resolveId(id, importer) {
744
+ if (id.endsWith(".astro") && importer) {
745
+ const absoluteAstroPath = resolve2(dirname(importer), id);
746
+ if (!storiesMap.has(absoluteAstroPath)) {
747
+ storiesMap.set(absoluteAstroPath, /* @__PURE__ */ new Set());
748
+ }
749
+ storiesMap.get(absoluteAstroPath)?.add(importer);
750
+ }
751
+ if (id.startsWith("virtual:astro-static-module/")) {
752
+ return `\0${id}`;
753
+ }
754
+ if (id.startsWith("virtual:astro-component-module/")) {
755
+ return `\0${id}`;
756
+ }
757
+ },
758
+ load(id) {
759
+ if (id.startsWith("\0virtual:astro-static-module/")) {
760
+ const encodedSpecifier = id.replace("\0virtual:astro-static-module/", "");
761
+ const specifier = decodeURIComponent(encodedSpecifier);
762
+ if (isClientEntrypoint2(specifier)) {
763
+ return [`export { default } from '${specifier}';`, `export * from '${specifier}';`].join("\n");
764
+ }
765
+ return [`import '${specifier}';`, "export default undefined;"].join("\n");
766
+ }
767
+ if (id.startsWith("\0virtual:astro-component-module/")) {
768
+ const encodedSpecifier = id.replace("\0virtual:astro-component-module/", "");
769
+ const specifier = decodeURIComponent(encodedSpecifier);
770
+ return [`export { default } from '${specifier}';`, `export * from '${specifier}';`].join("\n");
771
+ }
772
+ },
773
+ async buildStart() {
774
+ integrations.forEach((integration) => {
775
+ const entrypoint = integration.renderer.client?.entrypoint;
776
+ if (entrypoint) {
777
+ this.addWatchFile(entrypoint);
778
+ }
779
+ });
780
+ trackedSpecifiers.forEach((specifier) => {
781
+ const fileReferenceId = this.emitFile({
782
+ type: "chunk",
783
+ id: toStaticVirtualId2(specifier)
784
+ });
785
+ staticEntrypointRefs.set(specifier, fileReferenceId);
786
+ });
787
+ const srcRoot = resolve2(resolveFrom, "src/components");
788
+ const specifiers = await collectHydratableSourceModules2(srcRoot);
789
+ specifiers.forEach((specifier) => {
790
+ const fileReferenceId = this.emitFile({
791
+ type: "chunk",
792
+ id: toComponentVirtualId2(specifier)
793
+ });
794
+ componentEntrypointRefs.set(specifier, fileReferenceId);
795
+ });
796
+ },
797
+ async writeBundle() {
798
+ const astroComponents = Array.from(storiesMap.keys());
799
+ const staticModuleMap = buildStaticModuleMap2(
800
+ this,
801
+ staticEntrypointRefs,
802
+ componentEntrypointRefs
803
+ );
804
+ const serverOutDir = resolve2(dirname(storybookStaticOutDir), "storybook-server");
805
+ await buildAstroServer({
806
+ astroComponents,
807
+ integrations,
808
+ sanitization: options.sanitization,
809
+ storyRules: options.storyRules,
810
+ server: options.server,
811
+ outDir: serverOutDir,
812
+ staticModuleMap,
813
+ resolveFrom
814
+ });
815
+ }
816
+ };
817
+ }
818
+ async function buildAstroServer(options) {
819
+ const buildConfig = {
820
+ root: resolve2(packageRoot, "src/server"),
821
+ ssr: {
822
+ noExternal: /(@astrojs\/.+|react|react-dom)/
823
+ },
824
+ build: {
825
+ ssr: true,
826
+ outDir: options.outDir,
827
+ emptyOutDir: true,
828
+ sourcemap: true,
829
+ manifest: false,
830
+ rollupOptions: {
831
+ input: resolve2(packageRoot, "src/server/index.ts"),
832
+ treeshake: true
833
+ }
834
+ },
835
+ plugins: [
836
+ astroFilesVirtualModulePlugin(options.astroComponents),
837
+ storybookAstroSanitizationConfigVirtualModulePlugin(options.sanitization),
838
+ storybookAstroStoryRulesConfigVirtualModulePlugin(options.storyRules, options.resolveFrom),
839
+ storybookAstroServerAuthConfigVirtualModulePlugin(options.server),
840
+ viteAstroContainerRenderersPlugin(options.integrations, {
841
+ mode: "production",
842
+ staticModuleMap: options.staticModuleMap
843
+ })
844
+ ]
845
+ };
846
+ const finalConfig = await mergeWithAstroConfig(
847
+ buildConfig,
848
+ options.integrations,
849
+ options.resolveFrom,
850
+ "production",
851
+ "build"
852
+ );
853
+ await build(finalConfig);
854
+ }
855
+ function collectTrackedSpecifiers2(integrations) {
856
+ const specifiers = /* @__PURE__ */ new Set(["astro:scripts/page.js", "astro:scripts/before-hydration.js"]);
857
+ integrations.forEach((integration) => {
858
+ const entrypoint = integration.renderer.client?.entrypoint;
859
+ if (entrypoint) {
860
+ specifiers.add(entrypoint);
861
+ }
862
+ });
863
+ return specifiers;
864
+ }
865
+ function buildStaticModuleMap2(pluginContext, staticEntrypointRefs, componentEntrypointRefs) {
866
+ const map = {};
867
+ staticEntrypointRefs.forEach((fileReferenceId, specifier) => {
868
+ const fileName = pluginContext.getFileName(fileReferenceId);
869
+ if (fileName) {
870
+ map[specifier] = toPublicPath2(fileName);
871
+ }
872
+ });
873
+ componentEntrypointRefs.forEach((fileReferenceId, specifier) => {
874
+ const fileName = pluginContext.getFileName(fileReferenceId);
875
+ if (fileName) {
876
+ map[specifier] = toPublicPath2(fileName);
877
+ }
878
+ });
879
+ return map;
880
+ }
881
+ function toStaticVirtualId2(specifier) {
882
+ return `virtual:astro-static-module/${encodeURIComponent(specifier)}`;
883
+ }
884
+ function toComponentVirtualId2(specifier) {
885
+ return `virtual:astro-component-module/${encodeURIComponent(specifier)}`;
886
+ }
887
+ function isClientEntrypoint2(specifier) {
888
+ return specifier.startsWith("@astrojs/") && specifier.endsWith("/client.js");
889
+ }
890
+ function toPublicPath2(fileName) {
891
+ return `./${fileName}`;
892
+ }
893
+ async function collectHydratableSourceModules2(srcRoot) {
894
+ const modules = [];
895
+ async function walk(directory) {
896
+ let entries;
897
+ try {
898
+ entries = await readdir2(directory, { withFileTypes: true });
899
+ } catch {
900
+ return;
901
+ }
902
+ await Promise.all(
903
+ entries.map(async (entry) => {
904
+ const absolutePath = resolve2(directory, entry.name);
905
+ if (entry.isDirectory()) {
906
+ await walk(absolutePath);
907
+ return;
908
+ }
909
+ if (!entry.isFile()) {
910
+ return;
911
+ }
912
+ const normalizedPath = absolutePath.replace(/\\/g, "/");
913
+ if (!isHydratableSourceFile2(normalizedPath)) {
914
+ return;
915
+ }
916
+ if (isNonHydratableSourceFile2(normalizedPath)) {
917
+ return;
918
+ }
919
+ modules.push(normalizedPath);
920
+ })
921
+ );
922
+ }
923
+ await walk(srcRoot);
924
+ return modules;
925
+ }
926
+ function isHydratableSourceFile2(input) {
927
+ return /\.(jsx|tsx|vue|svelte|js|ts)$/.test(input);
928
+ }
929
+ function isNonHydratableSourceFile2(input) {
930
+ return /\.stories\.[jt]sx?$|\.stories\.vue$|\.stories\.svelte$|\.(spec|test)\.[jt]sx?$/.test(
931
+ input
932
+ );
933
+ }
934
+
935
+ // src/vitePluginAstroToolbarFallback.ts
936
+ var TOOLBAR_INTERNAL_STUB = `
937
+ export const loadDevToolbarApps = async () => [];
938
+ `;
939
+ function vitePluginAstroToolbarFallback() {
940
+ const VIRTUAL_ID = "astro:toolbar:internal";
941
+ const RESOLVED_ID = "\0" + VIRTUAL_ID;
942
+ return {
943
+ name: "storybook-astro-toolbar-fallback",
944
+ enforce: "pre",
945
+ resolveId(id) {
946
+ if (id === VIRTUAL_ID) {
947
+ return RESOLVED_ID;
948
+ }
949
+ },
950
+ load(id) {
951
+ if (id === RESOLVED_ID) {
952
+ return { code: TOOLBAR_INTERNAL_STUB };
953
+ }
954
+ }
955
+ };
956
+ }
957
+
589
958
  // src/preset.ts
590
959
  var core = {
591
960
  builder: "@storybook/builder-vite",
592
- renderer: "@storybook-astro/renderer"
961
+ // Use import.meta.resolve so Storybook receives an absolute file:// URL
962
+ // to the renderer preset rather than a bare package specifier. When
963
+ // package managers like pnpm use strict node_modules isolation, bare
964
+ // specifiers are resolved from the *project root*, where the renderer
965
+ // (a dep of this framework, not the user's project) is not hoisted.
966
+ // The absolute URL is resolved from *this* file's location where the
967
+ // renderer is always accessible as a direct dependency.
968
+ renderer: import.meta.resolve("@storybook-astro/renderer")
593
969
  };
594
970
  var viteFinal = async (config, { configType, presets }) => {
595
971
  const options = await presets.apply("frameworkOptions");
596
- const { vitePlugin: storybookAstroMiddlewarePlugin, viteConfig } = await vitePluginStorybookAstroMiddleware(options);
597
972
  if (!config.plugins) {
598
973
  config.plugins = [];
599
974
  }
600
975
  const integrations = options.integrations ?? [];
601
976
  const resolveFrom = options.resolveFrom ?? process.cwd();
977
+ const renderMode = options.renderMode ?? "server";
602
978
  const mode = configType === "DEVELOPMENT" ? "development" : "production";
603
979
  const command = configType === "DEVELOPMENT" ? "serve" : "build";
604
980
  resolveSanitizationOptions(options.sanitization);
981
+ config.envPrefix = mergeEnvPrefixes(config.envPrefix, "STORYBOOK_");
982
+ const { vitePlugin: storybookAstroMiddlewarePlugin, viteConfig } = await vitePluginStorybookAstroMiddleware(options);
605
983
  config.plugins.push(
606
- storybookAstroMiddlewarePlugin,
607
984
  viteStorybookRendererFallbackPlugin(integrations),
985
+ viteStorybookAstroRendererPlugin({
986
+ mode,
987
+ renderMode,
988
+ server: options.server
989
+ }),
608
990
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
609
991
  vitePluginAstroComponentMarker(),
610
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
611
- vitePluginAstroBuildPrerender(options),
612
- vitePluginAstroVueFallback(),
613
- ...viteConfig.plugins
992
+ vitePluginAstroIntegrationOptsFallback(),
993
+ vitePluginAstroToolbarFallback(),
994
+ vitePluginAstroVueFallback()
614
995
  );
996
+ if (configType === "DEVELOPMENT") {
997
+ config.plugins.push(storybookAstroMiddlewarePlugin, ...viteConfig.plugins);
998
+ } else if (renderMode === "static") {
999
+ config.plugins.push(vitePluginAstroBuildPrerender(options));
1000
+ } else {
1001
+ config.plugins.push(vitePluginAstroBuildServer(options));
1002
+ }
1003
+ if (configType !== "DEVELOPMENT") {
1004
+ config.build = {
1005
+ ...config.build ?? {},
1006
+ manifest: true
1007
+ };
1008
+ config.build.rollupOptions = {
1009
+ ...config.build.rollupOptions ?? {},
1010
+ preserveEntrySignatures: "strict"
1011
+ };
1012
+ }
615
1013
  if (!config.resolve) {
616
1014
  config.resolve = {};
617
1015
  }
@@ -632,29 +1030,47 @@ var viteFinal = async (config, { configType, presets }) => {
632
1030
  if (!finalConfig.optimizeDeps.exclude) {
633
1031
  finalConfig.optimizeDeps.exclude = [];
634
1032
  }
635
- if (!finalConfig.optimizeDeps.exclude.includes("@astrojs/vue")) {
636
- finalConfig.optimizeDeps.exclude.push("@astrojs/vue");
1033
+ for (const pkg of ["@astrojs/vue", "@astrojs/react", "@astrojs/preact"]) {
1034
+ if (!finalConfig.optimizeDeps.exclude.includes(pkg)) {
1035
+ finalConfig.optimizeDeps.exclude.push(pkg);
1036
+ }
637
1037
  }
638
1038
  if (!finalConfig.optimizeDeps.exclude.includes("@storybook-astro/renderer")) {
639
1039
  finalConfig.optimizeDeps.exclude.push("@storybook-astro/renderer");
640
1040
  }
1041
+ const integrationVirtualModules = [
1042
+ "virtual:@astrojs/vue/app",
1043
+ "virtual:astro:vue-app",
1044
+ "astro:react:opts",
1045
+ "astro:preact:opts",
1046
+ "astro:toolbar:internal"
1047
+ ];
641
1048
  if (!finalConfig.optimizeDeps.esbuildOptions) {
642
1049
  finalConfig.optimizeDeps.esbuildOptions = {};
643
1050
  }
644
1051
  if (!finalConfig.optimizeDeps.esbuildOptions.external) {
645
1052
  finalConfig.optimizeDeps.esbuildOptions.external = [];
646
1053
  }
647
- const vueVirtualModules = ["virtual:@astrojs/vue/app", "virtual:astro:vue-app"];
648
- for (const mod of vueVirtualModules) {
1054
+ for (const mod of integrationVirtualModules) {
649
1055
  if (!finalConfig.optimizeDeps.esbuildOptions.external.includes(mod)) {
650
1056
  finalConfig.optimizeDeps.esbuildOptions.external.push(mod);
651
1057
  }
652
1058
  }
1059
+ const optimizeDepsMut = finalConfig.optimizeDeps;
1060
+ const rolldownOpts = optimizeDepsMut.rolldownOptions ?? {};
1061
+ rolldownOpts.external = Array.from(
1062
+ /* @__PURE__ */ new Set([...rolldownOpts.external ?? [], ...integrationVirtualModules])
1063
+ );
1064
+ optimizeDepsMut.rolldownOptions = rolldownOpts;
653
1065
  return finalConfig;
654
1066
  };
1067
+ function mergeEnvPrefixes(existing, additionalPrefix) {
1068
+ const prefixes = Array.isArray(existing) ? existing : existing ? [existing] : [];
1069
+ return Array.from(/* @__PURE__ */ new Set([...prefixes, additionalPrefix]));
1070
+ }
655
1071
 
656
1072
  export {
657
1073
  core,
658
1074
  viteFinal
659
1075
  };
660
- //# sourceMappingURL=chunk-KSDXET2L.js.map
1076
+ //# sourceMappingURL=chunk-4HECE7IW.js.map