@storybook-astro/framework 0.1.0-beta.9 → 1.0.0

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 (92) hide show
  1. package/README.md +38 -0
  2. package/dist/base-IRZo3zgK.d.ts +23 -0
  3. package/dist/chunk-4SWPVM6R.js +96 -0
  4. package/dist/chunk-4SWPVM6R.js.map +1 -0
  5. package/dist/chunk-5EF25G5S.js +69 -0
  6. package/dist/chunk-5EF25G5S.js.map +1 -0
  7. package/dist/chunk-7GHEQUPV.js +439 -0
  8. package/dist/chunk-7GHEQUPV.js.map +1 -0
  9. package/dist/chunk-C5OH4VBR.js +492 -0
  10. package/dist/chunk-C5OH4VBR.js.map +1 -0
  11. package/dist/chunk-DNGQBPT7.js +15 -0
  12. package/dist/chunk-DNGQBPT7.js.map +1 -0
  13. package/dist/chunk-E4LB75JN.js +89 -0
  14. package/dist/chunk-E4LB75JN.js.map +1 -0
  15. package/dist/chunk-PJEDXZVN.js +240 -0
  16. package/dist/chunk-PJEDXZVN.js.map +1 -0
  17. package/dist/chunk-UK43WNEA.js +657 -0
  18. package/dist/chunk-UK43WNEA.js.map +1 -0
  19. package/dist/dist-HJOEPVRQ.js +15574 -0
  20. package/dist/dist-HJOEPVRQ.js.map +1 -0
  21. package/dist/index.d.ts +42 -0
  22. package/dist/index.js +13 -64
  23. package/dist/index.js.map +1 -1
  24. package/dist/integrations/index.d.ts +138 -0
  25. package/dist/integrations/index.js +8 -196
  26. package/dist/integrations/index.js.map +1 -1
  27. package/dist/middleware.d.ts +26 -0
  28. package/dist/middleware.js +179 -0
  29. package/dist/middleware.js.map +1 -0
  30. package/dist/portable-stories-BvdaQigq.d.ts +83 -0
  31. package/dist/preset.d.ts +14 -0
  32. package/dist/preset.js +5 -1
  33. package/dist/testing.d.ts +27 -0
  34. package/dist/testing.js +324 -15539
  35. package/dist/testing.js.map +1 -1
  36. package/dist/types-CHTsRtA7.d.ts +42 -0
  37. package/dist/viteStorybookAstroMiddlewarePlugin-NP2E52IC.js +11 -0
  38. package/dist/viteStorybookAstroMiddlewarePlugin-NP2E52IC.js.map +1 -0
  39. package/dist/vitest/index.d.ts +19 -0
  40. package/dist/vitest/index.js +229 -0
  41. package/dist/vitest/index.js.map +1 -0
  42. package/package.json +31 -17
  43. package/src/importAstroConfig.ts +11 -0
  44. package/src/index.ts +20 -6
  45. package/src/integrations/alpine.ts +5 -2
  46. package/src/integrations/base.ts +2 -2
  47. package/src/integrations/moduleResolver.ts +43 -0
  48. package/src/integrations/preact.ts +5 -2
  49. package/src/integrations/react.ts +5 -2
  50. package/src/integrations/solid.ts +5 -2
  51. package/src/integrations/svelte.ts +5 -2
  52. package/src/integrations/vue.ts +5 -2
  53. package/src/lib/sanitization.test.ts +232 -0
  54. package/src/lib/sanitization.ts +338 -0
  55. package/src/lib/ssr-load-module-with-fs-fallback.ts +29 -0
  56. package/src/middleware.test.ts +48 -0
  57. package/src/middleware.ts +204 -96
  58. package/src/module-mocks.ts +16 -0
  59. package/src/msw-helpers.ts +1 -0
  60. package/src/msw.ts +58 -0
  61. package/src/preset.ts +38 -3
  62. package/src/rules-options.test.ts +71 -0
  63. package/src/rules-options.ts +87 -0
  64. package/src/rules.test.ts +183 -0
  65. package/src/rules.ts +314 -0
  66. package/src/testing/astro-runtime.ts +219 -0
  67. package/src/testing/component-utils.ts +32 -0
  68. package/src/testing/index.ts +2 -0
  69. package/src/testing/integration-config.ts +121 -0
  70. package/src/testing/project-root.ts +185 -0
  71. package/src/testing/renderer-daemon.ts +269 -0
  72. package/src/testing/story-composition.ts +33 -0
  73. package/src/testing/types.ts +14 -0
  74. package/src/testing/working-directory.ts +28 -0
  75. package/src/testing.ts +1 -254
  76. package/src/types.ts +16 -4
  77. package/src/virtual.d.ts +2 -1
  78. package/src/vite/createVirtualModulePlugin.test.ts +80 -0
  79. package/src/vite/createVirtualModulePlugin.ts +25 -0
  80. package/src/viteAstroContainerRenderersPlugin.ts +60 -26
  81. package/src/vitePluginAstro.ts +12 -5
  82. package/src/vitePluginAstroBuildPrerender.ts +665 -204
  83. package/src/vitePluginAstroRoutesFallback.ts +37 -0
  84. package/src/vitePluginAstroVueFallback.ts +47 -0
  85. package/src/viteStorybookAstroMiddlewarePlugin.ts +88 -12
  86. package/src/viteStorybookRendererFallbackPlugin.ts +13 -23
  87. package/src/vitest/config.ts +95 -0
  88. package/src/vitest/global-setup.ts +16 -0
  89. package/src/vitest/index.ts +2 -0
  90. package/src/vitest/vite-plugins.ts +187 -0
  91. package/dist/chunk-KTGNRGDJ.js +0 -561
  92. package/dist/chunk-KTGNRGDJ.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @storybook-astro/framework
2
+
3
+ The community-supported [Storybook](https://storybook.js.org/) framework for [Astro](https://astro.build/).
4
+
5
+ > Astro 5 & 6 + Storybook 10
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -D storybook @storybook/builder-vite @storybook-astro/framework
11
+ ```
12
+
13
+ ## Setup
14
+
15
+ ```javascript
16
+ // .storybook/main.js
17
+ export default {
18
+ stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
19
+ framework: {
20
+ name: '@storybook-astro/framework',
21
+ options: {},
22
+ },
23
+ };
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ Node.js 20.16+, Storybook 10, Astro 5.5.3+ or 6.0.0+, Vite 6+
29
+
30
+ ## Links
31
+
32
+ - [Getting Started](https://storybook-astro.org/getting-started)
33
+ - [Live Demo](https://demo.storybook-astro.org)
34
+ - [GitHub](https://github.com/storybook-astro/storybook-astro)
35
+
36
+ ## License
37
+
38
+ MIT
@@ -0,0 +1,23 @@
1
+ import { AstroIntegration } from 'astro';
2
+
3
+ type RendererDeclaration = {
4
+ server?: {
5
+ name: string;
6
+ entrypoint: string;
7
+ };
8
+ client?: {
9
+ name: string;
10
+ entrypoint: string;
11
+ };
12
+ };
13
+ declare abstract class Integration {
14
+ abstract readonly name: string;
15
+ abstract readonly dependencies: string[];
16
+ abstract readonly options: Record<string | number | symbol, unknown>;
17
+ abstract readonly renderer: RendererDeclaration;
18
+ abstract readonly storybookEntryPreview?: string;
19
+ abstract resolveClient(moduleName: string): string | undefined;
20
+ abstract loadIntegration(resolveFrom?: string): Promise<AstroIntegration>;
21
+ }
22
+
23
+ export { Integration as I };
@@ -0,0 +1,96 @@
1
+ import {
2
+ alpinejs,
3
+ preact,
4
+ react,
5
+ solid,
6
+ svelte,
7
+ vue
8
+ } from "./chunk-PJEDXZVN.js";
9
+
10
+ // src/testing/integration-config.ts
11
+ import { resolve as resolvePath } from "path";
12
+ var TESTING_INTEGRATIONS_ENV = "STORYBOOK_ASTRO_TESTING_INTEGRATIONS";
13
+ var REGEXP_TAG = "__storybookAstroRegExp";
14
+ function replacer(_key, value) {
15
+ if (value instanceof RegExp) {
16
+ return {
17
+ [REGEXP_TAG]: true,
18
+ source: value.source,
19
+ flags: value.flags
20
+ };
21
+ }
22
+ return value;
23
+ }
24
+ function reviver(_key, value) {
25
+ if (value && typeof value === "object" && REGEXP_TAG in value && value[REGEXP_TAG] === true) {
26
+ const source = value.source;
27
+ const flags = value.flags;
28
+ if (typeof source === "string" && typeof flags === "string") {
29
+ return new RegExp(source, flags);
30
+ }
31
+ }
32
+ return value;
33
+ }
34
+ function readIntegrationMapFromEnv() {
35
+ const raw = process.env[TESTING_INTEGRATIONS_ENV];
36
+ if (!raw) {
37
+ return {};
38
+ }
39
+ try {
40
+ const parsed = JSON.parse(raw, reviver);
41
+ if (!parsed || typeof parsed !== "object") {
42
+ return {};
43
+ }
44
+ return parsed;
45
+ } catch {
46
+ return {};
47
+ }
48
+ }
49
+ function writeIntegrationMapToEnv(value) {
50
+ process.env[TESTING_INTEGRATIONS_ENV] = JSON.stringify(value, replacer);
51
+ }
52
+ function serializeIntegration(integration) {
53
+ return {
54
+ name: integration.name,
55
+ options: integration.options
56
+ };
57
+ }
58
+ function deserializeIntegration(integration) {
59
+ switch (integration.name) {
60
+ case "react":
61
+ return react(integration.options);
62
+ case "solid":
63
+ return solid(integration.options);
64
+ case "preact":
65
+ return preact(integration.options);
66
+ case "vue":
67
+ return vue(integration.options);
68
+ case "svelte":
69
+ return svelte(integration.options);
70
+ case "alpine":
71
+ return alpinejs(integration.options);
72
+ default:
73
+ throw new Error(`Unknown testing integration: ${integration.name}`);
74
+ }
75
+ }
76
+ function registerTestingIntegrationsForRoot(root, integrations) {
77
+ const normalizedRoot = resolvePath(root);
78
+ const integrationMap = readIntegrationMapFromEnv();
79
+ integrationMap[normalizedRoot] = integrations.map(serializeIntegration);
80
+ writeIntegrationMapToEnv(integrationMap);
81
+ }
82
+ function resolveTestingIntegrationsForRoot(root) {
83
+ const normalizedRoot = resolvePath(root);
84
+ const integrationMap = readIntegrationMapFromEnv();
85
+ const integrations = integrationMap[normalizedRoot];
86
+ if (!integrations) {
87
+ return [];
88
+ }
89
+ return integrations.map(deserializeIntegration);
90
+ }
91
+
92
+ export {
93
+ registerTestingIntegrationsForRoot,
94
+ resolveTestingIntegrationsForRoot
95
+ };
96
+ //# sourceMappingURL=chunk-4SWPVM6R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/integration-config.ts"],"sourcesContent":["import { resolve as resolvePath } from 'node:path';\nimport type { Integration } from '../integrations/base.ts';\nimport {\n alpinejs,\n preact,\n react,\n solid,\n svelte,\n vue,\n} from '../integrations/index.ts';\n\nconst TESTING_INTEGRATIONS_ENV = 'STORYBOOK_ASTRO_TESTING_INTEGRATIONS';\n\ntype SerializedIntegration = {\n name: string;\n options: unknown;\n};\n\ntype SerializedIntegrationMap = Record<string, SerializedIntegration[]>;\n\nconst REGEXP_TAG = '__storybookAstroRegExp';\n\nfunction replacer(_key: string, value: unknown): unknown {\n if (value instanceof RegExp) {\n return {\n [REGEXP_TAG]: true,\n source: value.source,\n flags: value.flags\n };\n }\n\n return value;\n}\n\nfunction reviver(_key: string, value: unknown): unknown {\n if (\n value &&\n typeof value === 'object' &&\n REGEXP_TAG in value &&\n (value as Record<string, unknown>)[REGEXP_TAG] === true\n ) {\n const source = (value as Record<string, unknown>).source;\n const flags = (value as Record<string, unknown>).flags;\n\n if (typeof source === 'string' && typeof flags === 'string') {\n return new RegExp(source, flags);\n }\n }\n\n return value;\n}\n\nfunction readIntegrationMapFromEnv(): SerializedIntegrationMap {\n const raw = process.env[TESTING_INTEGRATIONS_ENV];\n\n if (!raw) {\n return {};\n }\n\n try {\n const parsed = JSON.parse(raw, reviver);\n\n if (!parsed || typeof parsed !== 'object') {\n return {};\n }\n\n return parsed as SerializedIntegrationMap;\n } catch {\n return {};\n }\n}\n\nfunction writeIntegrationMapToEnv(value: SerializedIntegrationMap) {\n process.env[TESTING_INTEGRATIONS_ENV] = JSON.stringify(value, replacer);\n}\n\nfunction serializeIntegration(integration: Integration): SerializedIntegration {\n return {\n name: integration.name,\n options: integration.options\n };\n}\n\nfunction deserializeIntegration(integration: SerializedIntegration): Integration {\n switch (integration.name) {\n case 'react':\n return react(integration.options as Parameters<typeof react>[0]);\n case 'solid':\n return solid(integration.options as Parameters<typeof solid>[0]);\n case 'preact':\n return preact(integration.options as Parameters<typeof preact>[0]);\n case 'vue':\n return vue(integration.options as Parameters<typeof vue>[0]);\n case 'svelte':\n return svelte(integration.options as Parameters<typeof svelte>[0]);\n case 'alpine':\n return alpinejs(integration.options as Parameters<typeof alpinejs>[0]);\n default:\n throw new Error(`Unknown testing integration: ${integration.name}`);\n }\n}\n\nexport function registerTestingIntegrationsForRoot(root: string, integrations: Integration[]) {\n const normalizedRoot = resolvePath(root);\n const integrationMap = readIntegrationMapFromEnv();\n\n integrationMap[normalizedRoot] = integrations.map(serializeIntegration);\n writeIntegrationMapToEnv(integrationMap);\n}\n\nexport function resolveTestingIntegrationsForRoot(root: string): Integration[] {\n const normalizedRoot = resolvePath(root);\n const integrationMap = readIntegrationMapFromEnv();\n const integrations = integrationMap[normalizedRoot];\n\n if (!integrations) {\n return [];\n }\n\n return integrations.map(deserializeIntegration);\n}\n"],"mappings":";;;;;;;;;;AAAA,SAAS,WAAW,mBAAmB;AAWvC,IAAM,2BAA2B;AASjC,IAAM,aAAa;AAEnB,SAAS,SAAS,MAAc,OAAyB;AACvD,MAAI,iBAAiB,QAAQ;AAC3B,WAAO;AAAA,MACL,CAAC,UAAU,GAAG;AAAA,MACd,QAAQ,MAAM;AAAA,MACd,OAAO,MAAM;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,QAAQ,MAAc,OAAyB;AACtD,MACE,SACA,OAAO,UAAU,YACjB,cAAc,SACb,MAAkC,UAAU,MAAM,MACnD;AACA,UAAM,SAAU,MAAkC;AAClD,UAAM,QAAS,MAAkC;AAEjD,QAAI,OAAO,WAAW,YAAY,OAAO,UAAU,UAAU;AAC3D,aAAO,IAAI,OAAO,QAAQ,KAAK;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,4BAAsD;AAC7D,QAAM,MAAM,QAAQ,IAAI,wBAAwB;AAEhD,MAAI,CAAC,KAAK;AACR,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK,OAAO;AAEtC,QAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,aAAO,CAAC;AAAA,IACV;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,yBAAyB,OAAiC;AACjE,UAAQ,IAAI,wBAAwB,IAAI,KAAK,UAAU,OAAO,QAAQ;AACxE;AAEA,SAAS,qBAAqB,aAAiD;AAC7E,SAAO;AAAA,IACL,MAAM,YAAY;AAAA,IAClB,SAAS,YAAY;AAAA,EACvB;AACF;AAEA,SAAS,uBAAuB,aAAiD;AAC/E,UAAQ,YAAY,MAAM;AAAA,IACxB,KAAK;AACH,aAAO,MAAM,YAAY,OAAsC;AAAA,IACjE,KAAK;AACH,aAAO,MAAM,YAAY,OAAsC;AAAA,IACjE,KAAK;AACH,aAAO,OAAO,YAAY,OAAuC;AAAA,IACnE,KAAK;AACH,aAAO,IAAI,YAAY,OAAoC;AAAA,IAC7D,KAAK;AACH,aAAO,OAAO,YAAY,OAAuC;AAAA,IACnE,KAAK;AACH,aAAO,SAAS,YAAY,OAAyC;AAAA,IACvE;AACE,YAAM,IAAI,MAAM,gCAAgC,YAAY,IAAI,EAAE;AAAA,EACtE;AACF;AAEO,SAAS,mCAAmC,MAAc,cAA6B;AAC5F,QAAM,iBAAiB,YAAY,IAAI;AACvC,QAAM,iBAAiB,0BAA0B;AAEjD,iBAAe,cAAc,IAAI,aAAa,IAAI,oBAAoB;AACtE,2BAAyB,cAAc;AACzC;AAEO,SAAS,kCAAkC,MAA6B;AAC7E,QAAM,iBAAiB,YAAY,IAAI;AACvC,QAAM,iBAAiB,0BAA0B;AACjD,QAAM,eAAe,eAAe,cAAc;AAElD,MAAI,CAAC,cAAc;AACjB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,aAAa,IAAI,sBAAsB;AAChD;","names":[]}
@@ -0,0 +1,69 @@
1
+ // src/portable-stories.ts
2
+ import {
3
+ composeStory as originalComposeStory,
4
+ composeStories as originalComposeStories,
5
+ setProjectAnnotations as originalSetProjectAnnotations
6
+ } from "storybook/internal/preview-api";
7
+ var render = (args, context) => {
8
+ const Component = context?.component;
9
+ const renderer = context?.parameters?.renderer;
10
+ const id = context?.id || "test-story";
11
+ const brokenRenderers = [];
12
+ if (renderer && brokenRenderers.includes(renderer)) {
13
+ throw new Error(`Renderer '${renderer}' not found. Available renderers: react, vue, svelte, solid, preact`);
14
+ }
15
+ if (!Component) {
16
+ throw new Error(`Unable to render story ${id} as the component annotation is missing from the default export`);
17
+ }
18
+ if (typeof Component === "function" && Component.isAstroComponentFactory) {
19
+ return Component;
20
+ }
21
+ if (typeof Component === "function") {
22
+ if (renderer && !brokenRenderers.includes(renderer)) {
23
+ return Component;
24
+ }
25
+ if (!renderer) {
26
+ throw new Error(
27
+ `Component appears to be a framework component but no renderer is specified. Add 'parameters: { renderer: "framework-name" }' to your story configuration.`
28
+ );
29
+ }
30
+ }
31
+ return {
32
+ component: Component,
33
+ args,
34
+ renderer: renderer || "astro"
35
+ };
36
+ };
37
+ function setProjectAnnotations(projectAnnotations) {
38
+ return originalSetProjectAnnotations(projectAnnotations);
39
+ }
40
+ function composeStory(story, componentAnnotations, projectAnnotations, exportsName) {
41
+ const mergedProjectAnnotations = projectAnnotations ? {
42
+ ...projectAnnotations,
43
+ render: projectAnnotations.render || render
44
+ } : {
45
+ render
46
+ };
47
+ return originalComposeStory(
48
+ story,
49
+ componentAnnotations,
50
+ mergedProjectAnnotations,
51
+ exportsName
52
+ );
53
+ }
54
+ function composeStories(storiesImport, projectAnnotations) {
55
+ const mergedProjectAnnotations = projectAnnotations ? {
56
+ ...projectAnnotations,
57
+ render: projectAnnotations.render || render
58
+ } : {
59
+ render
60
+ };
61
+ return originalComposeStories(storiesImport, mergedProjectAnnotations);
62
+ }
63
+
64
+ export {
65
+ setProjectAnnotations,
66
+ composeStory,
67
+ composeStories
68
+ };
69
+ //# sourceMappingURL=chunk-5EF25G5S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portable-stories.ts"],"sourcesContent":["// @ts-ignore - Storybook internal modules have complex module resolution\nimport type {\n Args,\n ComponentAnnotations,\n NamedOrDefaultProjectAnnotations,\n NormalizedProjectAnnotations,\n ProjectAnnotations,\n StoryAnnotationsOrFn,\n WebRenderer,\n} from 'storybook/internal/types';\n// @ts-ignore - Storybook internal modules have complex module resolution\nimport {\n composeStory as originalComposeStory,\n composeStories as originalComposeStories,\n setProjectAnnotations as originalSetProjectAnnotations,\n} from 'storybook/internal/preview-api';\n\n// Define the AstroRenderer type to match other frameworks\nexport interface AstroRenderer extends WebRenderer {\n component: any;\n storyResult: any;\n}\n\n// Create a render function for testing that mimics Storybook's render behavior\nconst render = (args: Args, context?: any) => {\n const Component = context?.component;\n const renderer = context?.parameters?.renderer;\n const id = context?.id || 'test-story';\n \n // Renderers that are known to not work in the current integration\n const brokenRenderers: string[] = [];\n \n // Mimic the renderer detection logic from the main renderer\n if (renderer && brokenRenderers.includes(renderer)) {\n throw new Error(`Renderer '${renderer}' not found. Available renderers: react, vue, svelte, solid, preact`);\n }\n \n // For Astro components and working integrations, return a renderable object\n if (!Component) {\n throw new Error(`Unable to render story ${id} as the component annotation is missing from the default export`);\n }\n \n // Astro components can be identified by isAstroComponentFactory\n if (typeof Component === 'function' && (Component as any).isAstroComponentFactory) {\n // This is an Astro component - return it for server-side rendering\n return Component;\n }\n \n // For framework components that have working integrations\n if (typeof Component === 'function') {\n if (renderer && !brokenRenderers.includes(renderer)) {\n // This would delegate to working framework renderer\n return Component;\n }\n \n // If no renderer specified for function component\n if (!renderer) {\n throw new Error(\n `Component appears to be a framework component but no renderer is specified. ` +\n `Add 'parameters: { renderer: \"framework-name\" }' to your story configuration.`\n );\n }\n }\n \n // Return a basic representation for testing\n return {\n component: Component,\n args: args,\n renderer: renderer || 'astro'\n };\n};\n\n/**\n * Function that sets the globalConfig of your storybook. The global config is the preview module of\n * your .storybook folder.\n *\n * It should be run a single time, so that your global config (e.g. decorators) is applied to your\n * stories when using `composeStories` or `composeStory`.\n *\n * Example:\n *\n * ```jsx\n * // setup-file.js\n * import { setProjectAnnotations } from '@storybook-astro/framework';\n * import projectAnnotations from './.storybook/preview';\n *\n * setProjectAnnotations(projectAnnotations);\n * ```\n *\n * @param projectAnnotations - E.g. (import projectAnnotations from '../.storybook/preview')\n */\nexport function setProjectAnnotations(\n projectAnnotations:\n | NamedOrDefaultProjectAnnotations<AstroRenderer>\n | NamedOrDefaultProjectAnnotations<AstroRenderer>[]\n): NormalizedProjectAnnotations<AstroRenderer> {\n return originalSetProjectAnnotations<AstroRenderer>(projectAnnotations);\n}\n\n/**\n * Function that will receive a story along with meta (e.g. a default export from a .stories file)\n * and optionally projectAnnotations e.g. (import * as projectAnnotations from '../.storybook/preview')\n * and will return a composed component that has all args/parameters/decorators/etc combined and applied to it.\n *\n * It's very useful for reusing a story in scenarios outside of Storybook like unit testing.\n *\n * Example:\n * ```jsx\n * import { render } from '@testing-library/react';\n * import { composeStory } from '@storybook-astro/framework';\n * import meta, { Primary as PrimaryStory } from './Button.stories';\n *\n * const Primary = composeStory(PrimaryStory, meta);\n *\n * test('renders primary button', () => {\n * const { getByRole } = render(<Primary>Hello world</Primary>);\n * expect(getByRole('button')).toBeInTheDocument();\n * });\n * ```\n *\n * @param story - E.g. (import { Primary } from './Button.stories')\n * @param componentAnnotations - E.g. (import meta from './Button.stories')\n * @param projectAnnotations - E.g. (import * as projectAnnotations from '../.storybook/preview') this can be applied automatically if you use `setProjectAnnotations` in your setup files.\n * @param exportsName - In case your story does not contain a name and you want it to have a name.\n */\nexport function composeStory<TArgs extends Args = Args>(\n story: StoryAnnotationsOrFn<AstroRenderer, TArgs>,\n componentAnnotations: ComponentAnnotations<AstroRenderer, TArgs>,\n projectAnnotations?: ProjectAnnotations<AstroRenderer>,\n exportsName?: string\n) {\n // Merge project annotations with Astro renderer\n const mergedProjectAnnotations: any = projectAnnotations ? {\n ...projectAnnotations,\n render: projectAnnotations.render || render\n } : {\n render\n };\n \n return originalComposeStory<AstroRenderer, TArgs>(\n story as any,\n componentAnnotations,\n mergedProjectAnnotations as any,\n exportsName as any\n );\n}\n\n/**\n * Function that will receive a stories import (e.g. `import * as stories from './Button.stories'`)\n * and optionally a globalConfig (e.g. `import * from '../.storybook/preview`)\n * and will return an object containing all the stories passed, but now as a composed component that has all args/parameters/decorators/etc combined and applied to it.\n *\n * It's very useful for reusing stories in scenarios outside of Storybook like unit testing.\n *\n * Example:\n * ```jsx\n * import { render } from '@testing-library/react';\n * import { composeStories } from '@storybook-astro/framework';\n * import * as stories from './Button.stories';\n *\n * const { Primary, Secondary } = composeStories(stories);\n *\n * test('renders primary button', () => {\n * const { getByRole } = render(<Primary>Hello world</Primary>);\n * expect(getByRole('button')).toBeInTheDocument();\n * });\n * ```\n *\n * @param storiesImport - E.g. (import * as stories from './Button.stories')\n * @param projectAnnotations - E.g. (import * as globalConfig from '../.storybook/preview') this can be applied automatically if you use `setProjectAnnotations` in your setup files.\n */\nexport function composeStories<TModule extends Record<string, any>>(\n storiesImport: TModule,\n projectAnnotations?: ProjectAnnotations<AstroRenderer>\n): { [K in keyof Omit<TModule, 'default'>]: any } {\n // Merge project annotations with Astro renderer\n const mergedProjectAnnotations: any = projectAnnotations ? {\n ...projectAnnotations,\n render: projectAnnotations.render || render\n } : {\n render\n };\n \n return originalComposeStories(storiesImport as any, mergedProjectAnnotations as any) as { [K in keyof Omit<TModule, 'default'>]: any };\n}\n"],"mappings":";AAWA;AAAA,EACE,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,OACpB;AASP,IAAM,SAAS,CAAC,MAAY,YAAkB;AAC5C,QAAM,YAAY,SAAS;AAC3B,QAAM,WAAW,SAAS,YAAY;AACtC,QAAM,KAAK,SAAS,MAAM;AAG1B,QAAM,kBAA4B,CAAC;AAGnC,MAAI,YAAY,gBAAgB,SAAS,QAAQ,GAAG;AAClD,UAAM,IAAI,MAAM,aAAa,QAAQ,qEAAqE;AAAA,EAC5G;AAGA,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,0BAA0B,EAAE,iEAAiE;AAAA,EAC/G;AAGA,MAAI,OAAO,cAAc,cAAe,UAAkB,yBAAyB;AAEjF,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,cAAc,YAAY;AACnC,QAAI,YAAY,CAAC,gBAAgB,SAAS,QAAQ,GAAG;AAEnD,aAAO;AAAA,IACT;AAGA,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,WAAW;AAAA,IACX;AAAA,IACA,UAAU,YAAY;AAAA,EACxB;AACF;AAqBO,SAAS,sBACd,oBAG6C;AAC7C,SAAO,8BAA6C,kBAAkB;AACxE;AA4BO,SAAS,aACd,OACA,sBACA,oBACA,aACA;AAEA,QAAM,2BAAgC,qBAAqB;AAAA,IACzD,GAAG;AAAA,IACH,QAAQ,mBAAmB,UAAU;AAAA,EACvC,IAAI;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AA0BO,SAAS,eACd,eACA,oBACgD;AAEhD,QAAM,2BAAgC,qBAAqB;AAAA,IACzD,GAAG;AAAA,IACH,QAAQ,mBAAmB,UAAU;AAAA,EACvC,IAAI;AAAA,IACF;AAAA,EACF;AAEA,SAAO,uBAAuB,eAAsB,wBAA+B;AACrF;","names":[]}