@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
@@ -16,24 +16,64 @@ async function selectStoryRules(input) {
16
16
  if (typeof use !== "function") {
17
17
  throw new Error('Each story rule "use" entry must be a function.');
18
18
  }
19
- await use({
20
- mode: input.mode,
19
+ const cleanup = await use({
21
20
  story,
22
- msw: {
23
- use: (...handlers) => {
24
- selection.mswHandlers.push(...handlers);
25
- }
26
- },
27
21
  mock: (specifier, replacement) => {
28
22
  const normalizedSpecifier = normalizeMockSpecifier(specifier);
29
23
  const normalizedReplacement = normalizeMockReplacement(replacement, input.configFilePath);
30
24
  selection.moduleMocks.set(normalizedSpecifier, normalizedReplacement);
31
25
  }
32
26
  });
27
+ if (cleanup !== void 0) {
28
+ if (typeof cleanup !== "function") {
29
+ throw new Error('Story rule "use" must return either nothing or a cleanup function.');
30
+ }
31
+ selection.cleanups.push(cleanup);
32
+ }
33
33
  }
34
34
  }
35
35
  return selection;
36
36
  }
37
+ async function withStoryRuleCleanups(cleanups, callback) {
38
+ let result;
39
+ let callbackError;
40
+ try {
41
+ result = await callback();
42
+ } catch (error) {
43
+ callbackError = error;
44
+ }
45
+ try {
46
+ await runStoryRuleCleanups(cleanups);
47
+ } catch (cleanupError) {
48
+ if (callbackError) {
49
+ throw new AggregateError(
50
+ [callbackError, cleanupError],
51
+ "Story rule execution and cleanup both failed."
52
+ );
53
+ }
54
+ throw cleanupError;
55
+ }
56
+ if (callbackError) {
57
+ throw callbackError;
58
+ }
59
+ return result;
60
+ }
61
+ async function runStoryRuleCleanups(cleanups) {
62
+ const errors = [];
63
+ for (let index = cleanups.length - 1; index >= 0; index -= 1) {
64
+ try {
65
+ await cleanups[index]();
66
+ } catch (error) {
67
+ errors.push(error);
68
+ }
69
+ }
70
+ if (errors.length === 1) {
71
+ throw errors[0];
72
+ }
73
+ if (errors.length > 1) {
74
+ throw new AggregateError(errors, "Story rule cleanup failed.");
75
+ }
76
+ }
37
77
  function normalizeRulesConfig(configModule) {
38
78
  const configExport = getRulesConfigExport(configModule);
39
79
  if (configExport === void 0 || configExport === null) {
@@ -176,7 +216,7 @@ function slugify(input) {
176
216
  function createEmptySelection() {
177
217
  return {
178
218
  moduleMocks: /* @__PURE__ */ new Map(),
179
- mswHandlers: []
219
+ cleanups: []
180
220
  };
181
221
  }
182
222
  function toPosixPath(input) {
@@ -314,6 +354,16 @@ function sanitizeRenderPayload(payload, options) {
314
354
  slots: sanitizedSlots
315
355
  };
316
356
  }
357
+ function serializeSanitizationOptions(options) {
358
+ if (!options) {
359
+ return "undefined";
360
+ }
361
+ assertNoFunctions(options.sanitizeHtml, "framework.options.sanitization.sanitizeHtml");
362
+ const state = {
363
+ seen: /* @__PURE__ */ new WeakSet()
364
+ };
365
+ return serializeValue(options, "framework.options.sanitization", state);
366
+ }
317
367
  function mergeSanitizeHtmlOptions(userOptions) {
318
368
  const merged = {
319
369
  ...DEFAULT_SANITIZE_HTML_OPTIONS,
@@ -397,6 +447,68 @@ function matchesPathPattern(path, pattern) {
397
447
  const patternSegments = pattern.split(".");
398
448
  return matchSegments(pathSegments, patternSegments);
399
449
  }
450
+ function serializeValue(value, path, state) {
451
+ if (value === null) {
452
+ return "null";
453
+ }
454
+ if (value === void 0) {
455
+ return "undefined";
456
+ }
457
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
458
+ return JSON.stringify(value);
459
+ }
460
+ if (value instanceof RegExp) {
461
+ return value.toString();
462
+ }
463
+ if (Array.isArray(value)) {
464
+ const serializedItems = value.map(
465
+ (item, index) => serializeValue(item, `${path}[${index}]`, state)
466
+ );
467
+ return `[${serializedItems.join(", ")}]`;
468
+ }
469
+ if (isRecord2(value)) {
470
+ if (state.seen.has(value)) {
471
+ throw new Error(`${path} contains a circular reference.`);
472
+ }
473
+ state.seen.add(value);
474
+ const serializedEntries = Object.entries(value).filter(([, nestedValue]) => nestedValue !== void 0).map(([key, nestedValue]) => {
475
+ const serializedNestedValue = serializeValue(nestedValue, `${path}.${key}`, state);
476
+ return `${JSON.stringify(key)}: ${serializedNestedValue}`;
477
+ });
478
+ return `{ ${serializedEntries.join(", ")} }`;
479
+ }
480
+ throw new Error(
481
+ `${path} contains an unsupported value of type ${typeof value}. Only plain objects, arrays, primitives, and regular expressions are supported.`
482
+ );
483
+ }
484
+ function assertNoFunctions(value, path) {
485
+ const state = {
486
+ seen: /* @__PURE__ */ new WeakSet()
487
+ };
488
+ assertNoFunctionsRecursive(value, path, state);
489
+ }
490
+ function assertNoFunctionsRecursive(value, path, state) {
491
+ if (typeof value === "function") {
492
+ throw new Error(
493
+ `${path} cannot contain functions. Function-valued sanitization hooks are not supported in framework options.`
494
+ );
495
+ }
496
+ if (Array.isArray(value)) {
497
+ value.forEach((item, index) => {
498
+ assertNoFunctionsRecursive(item, `${path}[${index}]`, state);
499
+ });
500
+ return;
501
+ }
502
+ if (isRecord2(value)) {
503
+ if (state.seen.has(value)) {
504
+ return;
505
+ }
506
+ state.seen.add(value);
507
+ Object.entries(value).forEach(([key, nestedValue]) => {
508
+ assertNoFunctionsRecursive(nestedValue, `${path}.${key}`, state);
509
+ });
510
+ }
511
+ }
400
512
  function matchSegments(pathSegments, patternSegments) {
401
513
  if (patternSegments.length === 0) {
402
514
  return pathSegments.length === 0;
@@ -444,49 +556,14 @@ function resolveStoryModuleMock(specifier) {
444
556
  return moduleMockStorage.getStore()?.get(specifier);
445
557
  }
446
558
 
447
- // src/msw.ts
448
- import { setupServer } from "msw/node";
449
- var defaultListenOptions = {
450
- onUnhandledRequest: "bypass"
451
- };
452
- async function applyMswHandlers(handlers) {
453
- const state = getMswState();
454
- if (state.pendingUpdate) {
455
- await state.pendingUpdate;
456
- }
457
- const updatePromise = syncMswHandlers(handlers, state);
458
- state.pendingUpdate = updatePromise;
459
- try {
460
- await updatePromise;
461
- } finally {
462
- state.pendingUpdate = void 0;
463
- }
464
- }
465
- async function syncMswHandlers(handlers, state) {
466
- if (!state.server) {
467
- state.server = setupServer();
468
- state.server.listen(defaultListenOptions);
469
- }
470
- state.server.resetHandlers(...handlers);
471
- }
472
- function getMswState() {
473
- const globalState = globalThis;
474
- if (!globalState.__storybookAstroMswState__) {
475
- globalState.__storybookAstroMswState__ = {
476
- server: void 0,
477
- pendingUpdate: void 0
478
- };
479
- }
480
- return globalState.__storybookAstroMswState__;
481
- }
482
-
483
559
  export {
484
560
  defineStoryRules,
485
561
  selectStoryRules,
562
+ withStoryRuleCleanups,
486
563
  resolveSanitizationOptions,
487
564
  sanitizeRenderPayload,
565
+ serializeSanitizationOptions,
488
566
  withStoryModuleMocks,
489
- resolveStoryModuleMock,
490
- applyMswHandlers
567
+ resolveStoryModuleMock
491
568
  };
492
- //# sourceMappingURL=chunk-C5OH4VBR.js.map
569
+ //# sourceMappingURL=chunk-V76WSNSP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rules.ts","../src/lib/sanitization.ts","../src/module-mocks.ts"],"sourcesContent":["import { dirname, isAbsolute, resolve } from 'node:path';\nimport type { RenderStoryInput } from './types.ts';\n\nexport type StoryRuleCleanup = () => void | Promise<void>;\ntype StoryRuleUseResult = void | StoryRuleCleanup | Promise<void | StoryRuleCleanup>;\n\nexport type StoryRuleUseContext = {\n story: StoryRuleStory;\n mock: (specifier: string, replacement: string) => void;\n};\n\nexport type StoryRuleUse = (context: StoryRuleUseContext) => StoryRuleUseResult;\n\nexport type StoryRule = {\n match: string | string[];\n use: StoryRuleUse | StoryRuleUse[];\n};\n\nexport type StoryRulesConfig = {\n rules: StoryRule[];\n};\n\nexport type StoryRuleStory = {\n id: string;\n title?: string;\n name?: string;\n keys: string[];\n};\n\nexport type StoryRuleSelectionInput = {\n configModule: unknown;\n configFilePath?: string;\n story?: RenderStoryInput;\n};\n\nexport type StoryRuleSelection = {\n moduleMocks: Map<string, string>;\n cleanups: StoryRuleCleanup[];\n};\n\ntype MutableStoryRuleSelection = {\n moduleMocks: Map<string, string>;\n cleanups: StoryRuleCleanup[];\n};\n\nexport function defineStoryRules(config: StoryRulesConfig): StoryRulesConfig {\n return config;\n}\n\nexport async function selectStoryRules(\n input: StoryRuleSelectionInput\n): Promise<StoryRuleSelection> {\n const config = normalizeRulesConfig(input.configModule);\n const story = normalizeStory(input.story);\n const selection = createEmptySelection();\n\n for (const rule of config.rules) {\n if (!isStoryRuleMatch(rule.match, story)) {\n continue;\n }\n\n const uses = Array.isArray(rule.use) ? rule.use : [rule.use];\n\n for (const use of uses) {\n if (typeof use !== 'function') {\n throw new Error('Each story rule \"use\" entry must be a function.');\n }\n\n const cleanup = await use({\n story,\n mock: (specifier, replacement) => {\n const normalizedSpecifier = normalizeMockSpecifier(specifier);\n const normalizedReplacement = normalizeMockReplacement(replacement, input.configFilePath);\n\n selection.moduleMocks.set(normalizedSpecifier, normalizedReplacement);\n }\n });\n\n if (cleanup !== undefined) {\n if (typeof cleanup !== 'function') {\n throw new Error('Story rule \"use\" must return either nothing or a cleanup function.');\n }\n\n selection.cleanups.push(cleanup);\n }\n }\n }\n\n return selection;\n}\n\nexport async function withStoryRuleCleanups<T>(\n cleanups: StoryRuleCleanup[],\n callback: () => Promise<T>\n): Promise<T> {\n let result: T | undefined;\n let callbackError: unknown;\n\n try {\n result = await callback();\n } catch (error) {\n callbackError = error;\n }\n\n try {\n await runStoryRuleCleanups(cleanups);\n } catch (cleanupError) {\n if (callbackError) {\n throw new AggregateError(\n [callbackError, cleanupError],\n 'Story rule execution and cleanup both failed.'\n );\n }\n\n throw cleanupError;\n }\n\n if (callbackError) {\n throw callbackError;\n }\n\n return result as T;\n}\n\nexport async function runStoryRuleCleanups(cleanups: StoryRuleCleanup[]): Promise<void> {\n const errors: unknown[] = [];\n\n for (let index = cleanups.length - 1; index >= 0; index -= 1) {\n try {\n await cleanups[index]();\n } catch (error) {\n errors.push(error);\n }\n }\n\n if (errors.length === 1) {\n throw errors[0];\n }\n\n if (errors.length > 1) {\n throw new AggregateError(errors, 'Story rule cleanup failed.');\n }\n}\n\nfunction normalizeRulesConfig(configModule: unknown): StoryRulesConfig {\n const configExport = getRulesConfigExport(configModule);\n\n if (configExport === undefined || configExport === null) {\n return {\n rules: []\n };\n }\n\n if (!isRecord(configExport)) {\n throw new Error(\n 'Story rules config must export an object with a \"rules\" array via a default export or named export.'\n );\n }\n\n const rules = configExport.rules;\n\n if (rules === undefined) {\n return {\n rules: []\n };\n }\n\n if (!Array.isArray(rules)) {\n throw new Error('Story rules config \"rules\" must be an array.');\n }\n\n return {\n rules: rules as StoryRule[]\n };\n}\n\nfunction getRulesConfigExport(configModule: unknown): unknown {\n if (!isRecord(configModule)) {\n return configModule;\n }\n\n if ('default' in configModule && configModule.default !== undefined) {\n return configModule.default;\n }\n\n if ('rules' in configModule) {\n return {\n rules: configModule.rules\n };\n }\n\n return undefined;\n}\n\nfunction normalizeStory(story?: RenderStoryInput): StoryRuleStory {\n const id = normalizeStoryId(story?.id);\n const title = normalizeOptionalString(story?.title);\n const name = normalizeOptionalString(story?.name);\n const keys = Array.from(resolveStoryKeys({ id, title, name }));\n\n return {\n id,\n title,\n name,\n keys\n };\n}\n\nfunction resolveStoryKeys(story: { id: string; title?: string; name?: string }) {\n const keys = new Set<string>();\n\n keys.add('');\n\n const storyId = story.id;\n const idPath = storyId ? storyId.replaceAll('--', '/') : '';\n\n if (storyId) {\n keys.add(storyId);\n keys.add(`/story/${storyId}`);\n }\n\n if (idPath) {\n keys.add(idPath);\n keys.add(`/story/${idPath}`);\n }\n\n const titlePath = story.title\n ? story.title\n .split('/')\n .map((segment) => slugify(segment))\n .filter(Boolean)\n .join('/')\n : '';\n\n const storyNamePath = story.name ? slugify(story.name) : '';\n\n if (titlePath && storyNamePath) {\n const composedPath = `${titlePath}/${storyNamePath}`;\n\n keys.add(composedPath);\n keys.add(`/story/${composedPath}`);\n }\n\n return keys;\n}\n\nfunction isStoryRuleMatch(match: string | string[], story: StoryRuleStory): boolean {\n const patterns = Array.isArray(match) ? match : [match];\n\n return patterns.some((pattern) => {\n if (typeof pattern !== 'string') {\n throw new Error('Story rule \"match\" must be a string or an array of strings.');\n }\n\n const normalizedPattern = pattern.trim();\n\n if (!normalizedPattern) {\n throw new Error('Story rule \"match\" cannot be empty.');\n }\n\n return story.keys.some((key) => isWildcardMatch(normalizedPattern, key));\n });\n}\n\nfunction isWildcardMatch(pattern: string, candidate: string): boolean {\n const escapedPattern = escapeRegExp(pattern).replaceAll('*', '.*');\n const regex = new RegExp(`^${escapedPattern}$`);\n\n return regex.test(candidate);\n}\n\nfunction normalizeStoryId(id?: string): string {\n const value = normalizeOptionalString(id) ?? '';\n\n if (!value) {\n return '';\n }\n\n return value.startsWith('/story/') ? value.slice('/story/'.length) : value;\n}\n\nfunction normalizeOptionalString(value: unknown): string | undefined {\n if (typeof value !== 'string') {\n return undefined;\n }\n\n const normalizedValue = value.trim();\n\n return normalizedValue || undefined;\n}\n\nfunction normalizeMockSpecifier(value: unknown): string {\n if (typeof value !== 'string') {\n throw new Error('Story rule mock specifier must be a string.');\n }\n\n const normalizedValue = value.trim();\n\n if (!normalizedValue) {\n throw new Error('Story rule mock specifier cannot be empty.');\n }\n\n return normalizedValue;\n}\n\nfunction normalizeMockReplacement(value: unknown, configFilePath?: string): string {\n if (typeof value !== 'string') {\n throw new Error('Story rule mock replacement must be a string.');\n }\n\n const normalizedValue = value.trim();\n\n if (!normalizedValue) {\n throw new Error('Story rule mock replacement cannot be empty.');\n }\n\n if (isAbsolute(normalizedValue)) {\n return toPosixPath(normalizedValue);\n }\n\n if (normalizedValue.startsWith('.')) {\n if (!configFilePath) {\n throw new Error(\n 'Story rule mock replacement uses a relative path, but rules config path is unavailable.'\n );\n }\n\n return toPosixPath(resolve(dirname(configFilePath), normalizedValue));\n }\n\n return normalizedValue;\n}\n\nfunction slugify(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction createEmptySelection(): MutableStoryRuleSelection {\n return {\n moduleMocks: new Map(),\n cleanups: []\n };\n}\n\nfunction toPosixPath(input: string): string {\n return input.replaceAll('\\\\', '/');\n}\n\nfunction escapeRegExp(input: string) {\n return input.replace(/[|\\\\{}()[\\]^$+?.]/g, '\\\\$&');\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n return !Array.isArray(value);\n}\n","import sanitizeHtml from 'sanitize-html';\nimport type { IOptions } from 'sanitize-html';\n\ntype SanitizationPayload = {\n args: Record<string, unknown>;\n slots: Record<string, unknown>;\n};\n\nexport type SanitizationOptions = {\n enabled?: boolean;\n args?: string[];\n slots?: string[];\n sanitizeHtml?: IOptions;\n};\n\nexport type ResolvedSanitizationOptions = {\n enabled: boolean;\n args: string[];\n slots: string[];\n sanitizeHtml: IOptions;\n};\n\nconst DEFAULT_SANITIZE_HTML_OPTIONS: IOptions = {\n allowedTags: [\n 'a',\n 'abbr',\n 'b',\n 'blockquote',\n 'br',\n 'caption',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'dd',\n 'details',\n 'dfn',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'figcaption',\n 'figure',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'i',\n 'img',\n 'kbd',\n 'li',\n 'mark',\n 'ol',\n 'p',\n 'pre',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'u',\n 'ul',\n 'var',\n 'wbr'\n ],\n allowedAttributes: {\n '*': [\n 'aria-describedby',\n 'aria-hidden',\n 'aria-label',\n 'aria-labelledby',\n 'class',\n 'id',\n 'lang',\n 'role',\n 'title'\n ],\n a: ['href', 'name', 'target', 'rel'],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height', 'loading', 'decoding'],\n td: ['colspan', 'rowspan'],\n th: ['colspan', 'rowspan', 'scope'],\n time: ['datetime']\n },\n allowedSchemes: ['http', 'https', 'mailto', 'tel', 'data'],\n allowedSchemesByTag: {\n a: ['http', 'https', 'mailto', 'tel'],\n img: ['http', 'https', 'data']\n },\n allowedSchemesAppliedToAttributes: ['href', 'src', 'cite', 'srcset'],\n allowProtocolRelative: false,\n disallowedTagsMode: 'discard',\n enforceHtmlBoundary: true,\n parseStyleAttributes: false\n};\n\nexport function resolveSanitizationOptions(options?: SanitizationOptions): ResolvedSanitizationOptions {\n if (!options) {\n return {\n enabled: true,\n args: [],\n slots: ['**'],\n sanitizeHtml: mergeSanitizeHtmlOptions()\n };\n }\n\n const enabled = options.enabled ?? true;\n const args = normalizePathList(options.args, 'framework.options.sanitization.args');\n const slots =\n options.slots === undefined\n ? ['**']\n : normalizePathList(options.slots, 'framework.options.sanitization.slots');\n\n return {\n enabled,\n args,\n slots,\n sanitizeHtml: mergeSanitizeHtmlOptions(options.sanitizeHtml)\n };\n}\n\nexport function sanitizeRenderPayload(\n payload: SanitizationPayload,\n options: ResolvedSanitizationOptions\n): SanitizationPayload {\n if (!options.enabled) {\n return payload;\n }\n\n const sanitizedArgs =\n options.args.length > 0\n ? sanitizeRecord(payload.args, options.args, options.sanitizeHtml)\n : payload.args;\n\n const sanitizedSlots =\n options.slots.length > 0\n ? sanitizeRecord(payload.slots, options.slots, options.sanitizeHtml)\n : payload.slots;\n\n return {\n args: sanitizedArgs,\n slots: sanitizedSlots\n };\n}\n\nexport function serializeSanitizationOptions(options?: SanitizationOptions): string {\n if (!options) {\n return 'undefined';\n }\n\n assertNoFunctions(options.sanitizeHtml, 'framework.options.sanitization.sanitizeHtml');\n\n const state = {\n seen: new WeakSet<object>()\n };\n\n return serializeValue(options, 'framework.options.sanitization', state);\n}\n\nfunction mergeSanitizeHtmlOptions(userOptions?: IOptions): IOptions {\n const merged: IOptions = {\n ...DEFAULT_SANITIZE_HTML_OPTIONS,\n ...userOptions\n };\n\n if (\n isRecord(DEFAULT_SANITIZE_HTML_OPTIONS.allowedAttributes) &&\n isRecord(userOptions?.allowedAttributes)\n ) {\n merged.allowedAttributes = {\n ...DEFAULT_SANITIZE_HTML_OPTIONS.allowedAttributes,\n ...userOptions.allowedAttributes\n };\n }\n\n if (isRecord(userOptions?.allowedClasses)) {\n merged.allowedClasses = {\n ...(isRecord(DEFAULT_SANITIZE_HTML_OPTIONS.allowedClasses)\n ? DEFAULT_SANITIZE_HTML_OPTIONS.allowedClasses\n : {}),\n ...userOptions.allowedClasses\n };\n }\n\n if (isRecord(userOptions?.allowedStyles)) {\n merged.allowedStyles = {\n ...(isRecord(DEFAULT_SANITIZE_HTML_OPTIONS.allowedStyles)\n ? DEFAULT_SANITIZE_HTML_OPTIONS.allowedStyles\n : {}),\n ...userOptions.allowedStyles\n };\n }\n\n return merged;\n}\n\nfunction normalizePathList(value: unknown, path: string): string[] {\n if (value === undefined) {\n return [];\n }\n\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array of dot-path patterns.`);\n }\n\n const unique = new Set<string>();\n\n value.forEach((entry, index) => {\n if (typeof entry !== 'string') {\n throw new Error(`${path}[${index}] must be a string.`);\n }\n\n const normalized = entry.trim();\n\n if (!normalized) {\n throw new Error(`${path}[${index}] cannot be an empty string.`);\n }\n\n unique.add(normalized);\n });\n\n return Array.from(unique);\n}\n\nfunction sanitizeRecord(\n record: Record<string, unknown>,\n patterns: string[],\n options: IOptions\n): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n\n Object.entries(record).forEach(([key, value]) => {\n sanitized[key] = sanitizeValue(value, key, patterns, options);\n });\n\n return sanitized;\n}\n\nfunction sanitizeValue(\n value: unknown,\n currentPath: string,\n patterns: string[],\n options: IOptions\n): unknown {\n if (typeof value === 'string') {\n if (shouldSanitizePath(currentPath, patterns)) {\n return sanitizeHtml(value, options);\n }\n\n return value;\n }\n\n if (Array.isArray(value)) {\n return value.map((item, index) => {\n const nextPath = `${currentPath}.${index}`;\n\n return sanitizeValue(item, nextPath, patterns, options);\n });\n }\n\n if (isRecord(value)) {\n const sanitized: Record<string, unknown> = {};\n\n Object.entries(value).forEach(([key, nestedValue]) => {\n const nextPath = `${currentPath}.${key}`;\n\n sanitized[key] = sanitizeValue(nestedValue, nextPath, patterns, options);\n });\n\n return sanitized;\n }\n\n return value;\n}\n\nfunction shouldSanitizePath(path: string, patterns: string[]): boolean {\n return patterns.some((pattern) => matchesPathPattern(path, pattern));\n}\n\nfunction matchesPathPattern(path: string, pattern: string): boolean {\n const pathSegments = path.split('.');\n const patternSegments = pattern.split('.');\n\n return matchSegments(pathSegments, patternSegments);\n}\n\nfunction serializeValue(value: unknown, path: string, state: { seen: WeakSet<object> }): string {\n if (value === null) {\n return 'null';\n }\n\n if (value === undefined) {\n return 'undefined';\n }\n\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return JSON.stringify(value);\n }\n\n if (value instanceof RegExp) {\n return value.toString();\n }\n\n if (Array.isArray(value)) {\n const serializedItems = value.map((item, index) =>\n serializeValue(item, `${path}[${index}]`, state)\n );\n\n return `[${serializedItems.join(', ')}]`;\n }\n\n if (isRecord(value)) {\n if (state.seen.has(value)) {\n throw new Error(`${path} contains a circular reference.`);\n }\n\n state.seen.add(value);\n\n const serializedEntries = Object.entries(value)\n .filter(([, nestedValue]) => nestedValue !== undefined)\n .map(([key, nestedValue]) => {\n const serializedNestedValue = serializeValue(nestedValue, `${path}.${key}`, state);\n\n return `${JSON.stringify(key)}: ${serializedNestedValue}`;\n });\n\n return `{ ${serializedEntries.join(', ')} }`;\n }\n\n throw new Error(\n `${path} contains an unsupported value of type ${typeof value}. ` +\n 'Only plain objects, arrays, primitives, and regular expressions are supported.'\n );\n}\n\nfunction assertNoFunctions(value: unknown, path: string): void {\n const state = {\n seen: new WeakSet<object>()\n };\n\n assertNoFunctionsRecursive(value, path, state);\n}\n\nfunction assertNoFunctionsRecursive(\n value: unknown,\n path: string,\n state: { seen: WeakSet<object> }\n): void {\n if (typeof value === 'function') {\n throw new Error(\n `${path} cannot contain functions. ` +\n 'Function-valued sanitization hooks are not supported in framework options.'\n );\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n assertNoFunctionsRecursive(item, `${path}[${index}]`, state);\n });\n\n return;\n }\n\n if (isRecord(value)) {\n if (state.seen.has(value)) {\n return;\n }\n\n state.seen.add(value);\n\n Object.entries(value).forEach(([key, nestedValue]) => {\n assertNoFunctionsRecursive(nestedValue, `${path}.${key}`, state);\n });\n }\n}\n\nfunction matchSegments(pathSegments: string[], patternSegments: string[]): boolean {\n if (patternSegments.length === 0) {\n return pathSegments.length === 0;\n }\n\n const [patternHead, ...patternTail] = patternSegments;\n\n if (patternHead === '**') {\n if (patternTail.length === 0) {\n return true;\n }\n\n for (let index = 0; index <= pathSegments.length; index += 1) {\n const remainingPath = pathSegments.slice(index);\n\n if (matchSegments(remainingPath, patternTail)) {\n return true;\n }\n }\n\n return false;\n }\n\n if (pathSegments.length === 0) {\n return false;\n }\n\n const [pathHead, ...pathTail] = pathSegments;\n\n if (patternHead === '*' || patternHead === pathHead) {\n return matchSegments(pathTail, patternTail);\n }\n\n return false;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n if (Array.isArray(value) || value instanceof RegExp) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\n\nexport type StoryModuleMocks = Map<string, string>;\n\nconst moduleMockStorage = new AsyncLocalStorage<StoryModuleMocks>();\n\nexport async function withStoryModuleMocks<T>(\n moduleMocks: StoryModuleMocks,\n callback: () => Promise<T>\n): Promise<T> {\n return moduleMockStorage.run(moduleMocks, callback);\n}\n\nexport function resolveStoryModuleMock(specifier: string): string | undefined {\n return moduleMockStorage.getStore()?.get(specifier);\n}\n"],"mappings":"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","names":["isRecord"]}
package/dist/index.d.ts CHANGED
@@ -1,23 +1,20 @@
1
1
  import { ProjectAnnotations } from 'storybook/internal/types';
2
2
  export { ArgTypes, Args, Parameters, ProjectAnnotations, StrictArgs } from 'storybook/internal/types';
3
+ import { PreviewAddon, Preview as Preview$1, InferTypes } from 'storybook/internal/csf';
3
4
  import { A as AstroRenderer } from './portable-stories-BvdaQigq.js';
4
5
  export { c as composeStories, a as composeStory, s as setProjectAnnotations } from './portable-stories-BvdaQigq.js';
5
- export { F as FrameworkOptions, S as SanitizationOptions, a as StoryRulesOptions, b as StorybookConfig } from './types-CHTsRtA7.js';
6
- import { RequestHandler } from 'msw';
6
+ import { R as RenderStoryInput } from './types-Cvor6Tyi.js';
7
+ export { F as FrameworkOptions, a as RenderMode, S as SanitizationOptions, b as ServerBuildOptions, c as StoryRulesOptions, d as StorybookConfig } from './types-Cvor6Tyi.js';
7
8
  export { core, viteFinal } from './preset.js';
8
9
  import 'vite';
9
10
  import './base-IRZo3zgK.js';
10
11
  import 'astro';
11
12
  import 'sanitize-html';
12
13
 
13
- type StoryMode = 'development' | 'production';
14
- type StoryRuleUseResult = void | Promise<void>;
14
+ type StoryRuleCleanup = () => void | Promise<void>;
15
+ type StoryRuleUseResult = void | StoryRuleCleanup | Promise<void | StoryRuleCleanup>;
15
16
  type StoryRuleUseContext = {
16
- mode: StoryMode;
17
17
  story: StoryRuleStory;
18
- msw: {
19
- use: (...handlers: RequestHandler[]) => void;
20
- };
21
18
  mock: (specifier: string, replacement: string) => void;
22
19
  };
23
20
  type StoryRuleUse = (context: StoryRuleUseContext) => StoryRuleUseResult;
@@ -34,9 +31,22 @@ type StoryRuleStory = {
34
31
  name?: string;
35
32
  keys: string[];
36
33
  };
34
+ type StoryRuleSelectionInput = {
35
+ configModule: unknown;
36
+ configFilePath?: string;
37
+ story?: RenderStoryInput;
38
+ };
39
+ type StoryRuleSelection = {
40
+ moduleMocks: Map<string, string>;
41
+ cleanups: StoryRuleCleanup[];
42
+ };
37
43
  declare function defineStoryRules(config: StoryRulesConfig): StoryRulesConfig;
38
44
 
39
45
  /** Preview configuration type for `.storybook/preview.ts` in Astro projects. */
40
46
  type Preview = ProjectAnnotations<AstroRenderer>;
41
47
 
42
- export { AstroRenderer, type Preview, type StoryRule, type StoryRuleUse, type StoryRuleUseContext, type StoryRulesConfig, defineStoryRules };
48
+ declare function definePreview<Addons extends PreviewAddon<never>[] = []>(input: ProjectAnnotations<AstroRenderer> & {
49
+ addons?: Addons;
50
+ }): Preview$1<AstroRenderer & InferTypes<Addons>>;
51
+
52
+ export { AstroRenderer, type Preview, RenderStoryInput, type StoryRule, type StoryRuleCleanup, type StoryRuleSelection, type StoryRuleSelectionInput, type StoryRuleStory, type StoryRuleUse, type StoryRuleUseContext, type StoryRulesConfig, definePreview, defineStoryRules };
package/dist/index.js CHANGED
@@ -1,23 +1,30 @@
1
1
  import {
2
2
  core,
3
3
  viteFinal
4
- } from "./chunk-KSDXET2L.js";
4
+ } from "./chunk-4HECE7IW.js";
5
5
  import {
6
6
  defineStoryRules
7
- } from "./chunk-C5OH4VBR.js";
7
+ } from "./chunk-V76WSNSP.js";
8
8
  import {
9
9
  composeStories,
10
10
  composeStory,
11
11
  setProjectAnnotations
12
12
  } from "./chunk-5EF25G5S.js";
13
+ import "./chunk-POHTFYST.js";
13
14
  import "./chunk-E4LB75JN.js";
14
- import "./chunk-7GHEQUPV.js";
15
15
  import "./chunk-DNGQBPT7.js";
16
16
  import "./chunk-G3PMV62Z.js";
17
+
18
+ // src/index.ts
19
+ import { definePreview as definePreviewBase } from "storybook/internal/csf";
20
+ function definePreview(input) {
21
+ return definePreviewBase(input);
22
+ }
17
23
  export {
18
24
  composeStories,
19
25
  composeStory,
20
26
  core,
27
+ definePreview,
21
28
  defineStoryRules,
22
29
  setProjectAnnotations,
23
30
  viteFinal
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Re-export types from storybook internal\nexport type {\n Args,\n ArgTypes,\n Parameters,\n ProjectAnnotations,\n StrictArgs\n} from 'storybook/internal/types';\n\nimport { definePreview as definePreviewBase, type PreviewAddon, type InferTypes, type Preview as CsfPreview } from 'storybook/internal/csf';\nimport type { ProjectAnnotations } from 'storybook/internal/types';\nimport type { AstroRenderer } from './portable-stories.ts';\n\n/** Preview configuration type for `.storybook/preview.ts` in Astro projects. */\nexport type Preview = ProjectAnnotations<AstroRenderer>;\n\n// Export portable stories functionality\nexport {\n composeStories,\n composeStory,\n setProjectAnnotations,\n type AstroRenderer\n} from './portable-stories.ts';\n\n// Export framework types\nexport type {\n FrameworkOptions,\n RenderMode,\n RenderStoryInput,\n ServerBuildOptions,\n SanitizationOptions,\n StoryRulesOptions,\n StorybookConfig\n} from './types.ts';\nexport type {\n StoryRuleCleanup,\n StoryRule,\n StoryRulesConfig,\n StoryRuleSelection,\n StoryRuleSelectionInput,\n StoryRuleStory,\n StoryRuleUse,\n StoryRuleUseContext\n} from './rules.ts';\nexport { defineStoryRules } from './rules.ts';\n\n// Re-export preset functionality for framework usage\nexport { core, viteFinal } from './preset.ts';\n\n// Preview configuration helper\nexport function definePreview<Addons extends PreviewAddon<never>[] = []>(\n input: ProjectAnnotations<AstroRenderer> & { addons?: Addons }\n): CsfPreview<AstroRenderer & InferTypes<Addons>> {\n return definePreviewBase<AstroRenderer, Addons>(input);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AASA,SAAS,iBAAiB,yBAAyF;AAyC5G,SAAS,cACd,OACgD;AAChD,SAAO,kBAAyC,KAAK;AACvD;","names":[]}
@@ -1,11 +1,11 @@
1
1
  import {
2
- applyMswHandlers,
3
2
  resolveSanitizationOptions,
4
3
  resolveStoryModuleMock,
5
4
  sanitizeRenderPayload,
6
5
  selectStoryRules,
7
- withStoryModuleMocks
8
- } from "./chunk-C5OH4VBR.js";
6
+ withStoryModuleMocks,
7
+ withStoryRuleCleanups
8
+ } from "./chunk-V76WSNSP.js";
9
9
  import "./chunk-G3PMV62Z.js";
10
10
 
11
11
  // src/middleware.ts
@@ -13,7 +13,36 @@ import { pathToFileURL } from "url";
13
13
  import { experimental_AstroContainer as AstroContainer } from "astro/container";
14
14
  import { addRenderers, resolveClientModules } from "virtual:astro-container-renderers";
15
15
  async function handlerFactory(_integrations, options) {
16
- const mode = options?.mode ?? "development";
16
+ if (!globalThis.astroAsset) {
17
+ globalThis.astroAsset = {};
18
+ }
19
+ globalThis.astroAsset.imageService = {
20
+ propertiesToHash: ["src"],
21
+ validateOptions(options2) {
22
+ return options2;
23
+ },
24
+ getURL(options2) {
25
+ const src = options2.src;
26
+ if (src != null && typeof src === "object" && "src" in src && typeof src.src === "string") {
27
+ return src.src;
28
+ }
29
+ return typeof src === "string" ? src : "";
30
+ },
31
+ getHTMLAttributes(options2) {
32
+ const { src, width, height, format, quality, densities, widths, formats, layout, priority, fit, position, background, ...attrs } = options2;
33
+ const srcObj = src != null && typeof src === "object" ? src : null;
34
+ return {
35
+ ...attrs,
36
+ width: width ?? srcObj?.width,
37
+ height: height ?? srcObj?.height,
38
+ loading: attrs.loading ?? "lazy",
39
+ decoding: attrs.decoding ?? "async"
40
+ };
41
+ },
42
+ getSrcSet() {
43
+ return [];
44
+ }
45
+ };
17
46
  const container = await AstroContainer.create({
18
47
  // Somewhat hacky way to force client-side Storybook's Vite to resolve modules properly
19
48
  resolve: async (specifier) => {
@@ -70,30 +99,30 @@ async function handlerFactory(_integrations, options) {
70
99
  const selectedRules = await selectStoryRules({
71
100
  configModule: rulesConfigModule,
72
101
  configFilePath: options?.rulesConfigFilePath,
73
- mode,
74
102
  story: data.story
75
103
  });
76
- await applyMswHandlers(selectedRules.mswHandlers);
77
- return withStoryModuleMocks(selectedRules.moduleMocks, async () => {
78
- const patchedComponent = await loadPatchedComponent(
79
- data.component,
80
- selectedRules.moduleMocks.size === 0
81
- );
82
- const processedArgs = await processImageMetadata(data.args ?? {});
83
- const sanitizedPayload = sanitizeRenderPayload(
84
- {
85
- args: processedArgs,
86
- slots: data.slots ?? {}
87
- },
88
- sanitizationOptions
89
- );
90
- return container.renderToString(
91
- patchedComponent,
92
- {
93
- props: sanitizedPayload.args,
94
- slots: sanitizedPayload.slots
95
- }
96
- );
104
+ return withStoryRuleCleanups(selectedRules.cleanups, async () => {
105
+ return withStoryModuleMocks(selectedRules.moduleMocks, async () => {
106
+ const patchedComponent = await loadPatchedComponent(
107
+ data.component,
108
+ selectedRules.moduleMocks.size === 0
109
+ );
110
+ const processedArgs = await processImageMetadata(data.args ?? {});
111
+ const sanitizedPayload = sanitizeRenderPayload(
112
+ {
113
+ args: processedArgs,
114
+ slots: data.slots ?? {}
115
+ },
116
+ sanitizationOptions
117
+ );
118
+ return container.renderToString(
119
+ patchedComponent,
120
+ {
121
+ props: sanitizedPayload.args,
122
+ slots: sanitizedPayload.slots
123
+ }
124
+ );
125
+ });
97
126
  });
98
127
  };
99
128
  const resultPromise = renderQueue.then(executeRender, executeRender);
@@ -131,14 +160,14 @@ async function processImageMetadata(args) {
131
160
  const processed = {};
132
161
  for (const [key, value] of Object.entries(args)) {
133
162
  if (isImageMetadata(value)) {
134
- processed[key] = convertImageMetadataToUrl(value);
163
+ processed[key] = value;
135
164
  continue;
136
165
  }
137
166
  if (Array.isArray(value)) {
138
167
  processed[key] = await Promise.all(
139
168
  value.map(async (item) => {
140
169
  if (isImageMetadata(item)) {
141
- return convertImageMetadataToUrl(item);
170
+ return item;
142
171
  }
143
172
  if (isRecord(item)) {
144
173
  return processImageMetadata(item);
@@ -159,17 +188,6 @@ async function processImageMetadata(args) {
159
188
  function isImageMetadata(value) {
160
189
  return isRecord(value) && typeof value.src === "string" && ("width" in value || "height" in value || "format" in value);
161
190
  }
162
- function convertImageMetadataToUrl(imageMetadata) {
163
- const src = imageMetadata.src;
164
- const fsPath = imageMetadata.fsPath;
165
- if (typeof src === "string") {
166
- return src;
167
- }
168
- if (typeof fsPath === "string") {
169
- return fsPath;
170
- }
171
- return String(imageMetadata);
172
- }
173
191
  function isRecord(value) {
174
192
  return typeof value === "object" && value !== null;
175
193
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url';\nimport { experimental_AstroContainer as AstroContainer } from 'astro/container';\nimport type { Integration } from './integrations/index.ts';\nimport type { SanitizationOptions } from './lib/sanitization.ts';\nimport { resolveSanitizationOptions, sanitizeRenderPayload } from './lib/sanitization.ts';\nimport { resolveStoryModuleMock, withStoryModuleMocks } from './module-mocks.ts';\nimport { applyMswHandlers } from './msw.ts';\nimport { selectStoryRules } from './rules.ts';\nimport type { RenderStoryInput } from './types.ts';\nimport { addRenderers, resolveClientModules } from 'virtual:astro-container-renderers';\n\ntype ResolveRulesConfigModule = () => unknown | Promise<unknown>;\n\ntype AstroCreateResult = {\n createAstro?: (...args: unknown[]) => unknown;\n};\n\ntype AstroComponentFactory = ((\n result: AstroCreateResult,\n props: unknown,\n slots: unknown\n) => unknown) & {\n isAstroComponentFactory?: boolean;\n moduleId?: string;\n propagation?: unknown;\n};\n\nexport type HandlerProps = {\n component: string;\n args?: Record<string, unknown>;\n slots?: Record<string, unknown>;\n story?: RenderStoryInput;\n};\n\ntype HandlerFactoryOptions = {\n mode?: 'development' | 'production';\n sanitization?: SanitizationOptions;\n rulesConfigFilePath?: string;\n resolveRulesConfigModule?: ResolveRulesConfigModule;\n loadModule?: (id: string) => Promise<{ default: unknown }>;\n};\n\nexport async function handlerFactory(_integrations: Integration[], options?: HandlerFactoryOptions) {\n const mode = options?.mode ?? 'development';\n const container = await AstroContainer.create({\n // Somewhat hacky way to force client-side Storybook's Vite to resolve modules properly\n resolve: async (specifier) => {\n const mockedModule = resolveStoryModuleMock(specifier);\n\n if (mockedModule) {\n return mockedModule;\n }\n\n if (specifier.startsWith('astro:scripts')) {\n return `/@id/${specifier}`;\n }\n\n const resolution = resolveClientModules(specifier);\n\n if (resolution) {\n return resolution;\n }\n\n return specifier;\n }\n });\n\n addRenderers(container);\n const sanitizationOptions = resolveSanitizationOptions(options?.sanitization);\n const loadModule =\n options?.loadModule ??\n ((id: string) => {\n const normalizedId = /^[a-zA-Z]:[/\\\\]/.test(id) ? pathToFileURL(id).href : id;\n\n return import(/* @vite-ignore */ normalizedId);\n });\n const componentCache = new Map<string, Promise<AstroComponentFactory>>();\n let renderQueue = Promise.resolve<void>(undefined);\n\n async function loadPatchedComponent(componentId: string, useCache = true) {\n if (!useCache) {\n const { default: component } = await loadModule(componentId);\n\n return patchCreateAstroCompat(component);\n }\n\n if (!componentCache.has(componentId)) {\n componentCache.set(componentId, (async () => {\n const { default: component } = await loadModule(componentId);\n\n return patchCreateAstroCompat(component);\n })());\n }\n\n const cachedComponent = componentCache.get(componentId);\n\n if (!cachedComponent) {\n throw new Error(`Failed to load Astro component: ${componentId}`);\n }\n\n try {\n return await cachedComponent;\n } catch (error) {\n // Drop failed entries so transient/module errors can recover on the next request.\n componentCache.delete(componentId);\n throw error;\n }\n }\n\n return async function handler(data: HandlerProps) {\n const executeRender = async () => {\n const rulesConfigModule = options?.resolveRulesConfigModule\n ? await options.resolveRulesConfigModule()\n : undefined;\n\n const selectedRules = await selectStoryRules({\n configModule: rulesConfigModule,\n configFilePath: options?.rulesConfigFilePath,\n mode,\n story: data.story\n });\n\n await applyMswHandlers(selectedRules.mswHandlers);\n\n return withStoryModuleMocks(selectedRules.moduleMocks, async () => {\n const patchedComponent = await loadPatchedComponent(\n data.component,\n selectedRules.moduleMocks.size === 0\n );\n const processedArgs = await processImageMetadata(data.args ?? {});\n const sanitizedPayload = sanitizeRenderPayload(\n {\n args: processedArgs,\n slots: data.slots ?? {}\n },\n sanitizationOptions\n );\n\n return container.renderToString(\n patchedComponent as Parameters<typeof container.renderToString>[0],\n {\n props: sanitizedPayload.args,\n slots: sanitizedPayload.slots\n }\n );\n });\n };\n\n const resultPromise = renderQueue.then(executeRender, executeRender);\n\n renderQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n\n return resultPromise;\n };\n}\n\nfunction patchCreateAstroCompat(component: unknown): AstroComponentFactory {\n if (typeof component !== 'function') {\n throw new Error('Expected Astro component factory to be a function.');\n }\n\n const originalComponent = component as AstroComponentFactory;\n const wrapped = ((result: AstroCreateResult, props: unknown, slots: unknown) => {\n if (result && typeof result.createAstro === 'function') {\n const originalCreateAstro = result.createAstro;\n const runtimeExpectsAstroGlobal = originalCreateAstro.length >= 3;\n\n result.createAstro = (...args: unknown[]) => {\n if (args.length === 3 && !runtimeExpectsAstroGlobal) {\n return originalCreateAstro(args[1], args[2]);\n }\n\n return originalCreateAstro(...args);\n };\n }\n\n return originalComponent(result, props, slots);\n }) as AstroComponentFactory;\n\n wrapped.isAstroComponentFactory = originalComponent.isAstroComponentFactory;\n wrapped.moduleId = originalComponent.moduleId;\n wrapped.propagation = originalComponent.propagation;\n\n return wrapped;\n}\n\nasync function processImageMetadata(\n args: Record<string, unknown>\n): Promise<Record<string, unknown>> {\n const processed: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(args)) {\n if (isImageMetadata(value)) {\n processed[key] = convertImageMetadataToUrl(value);\n\n continue;\n }\n\n if (Array.isArray(value)) {\n processed[key] = await Promise.all(\n value.map(async (item) => {\n if (isImageMetadata(item)) {\n return convertImageMetadataToUrl(item);\n }\n\n if (isRecord(item)) {\n return processImageMetadata(item);\n }\n\n return item;\n })\n );\n\n continue;\n }\n\n if (isRecord(value)) {\n processed[key] = await processImageMetadata(value);\n\n continue;\n }\n\n processed[key] = value;\n }\n\n return processed;\n}\n\nfunction isImageMetadata(value: unknown): value is Record<string, unknown> {\n return (\n isRecord(value) &&\n typeof value.src === 'string' &&\n ('width' in value || 'height' in value || 'format' in value)\n );\n}\n\nfunction convertImageMetadataToUrl(imageMetadata: Record<string, unknown>): string {\n const src = imageMetadata.src;\n const fsPath = imageMetadata.fsPath;\n\n if (typeof src === 'string') {\n return src;\n }\n\n if (typeof fsPath === 'string') {\n return fsPath;\n }\n\n return String(imageMetadata);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B,sBAAsB;AAQ9D,SAAS,cAAc,4BAA4B;AAiCnD,eAAsB,eAAe,eAA8B,SAAiC;AAClG,QAAM,OAAO,SAAS,QAAQ;AAC9B,QAAM,YAAY,MAAM,eAAe,OAAO;AAAA;AAAA,IAE5C,SAAS,OAAO,cAAc;AAC5B,YAAM,eAAe,uBAAuB,SAAS;AAErD,UAAI,cAAc;AAChB,eAAO;AAAA,MACT;AAEA,UAAI,UAAU,WAAW,eAAe,GAAG;AACzC,eAAO,QAAQ,SAAS;AAAA,MAC1B;AAEA,YAAM,aAAa,qBAAqB,SAAS;AAEjD,UAAI,YAAY;AACd,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,eAAa,SAAS;AACtB,QAAM,sBAAsB,2BAA2B,SAAS,YAAY;AAC5E,QAAM,aACJ,SAAS,eACR,CAAC,OAAe;AACf,UAAM,eAAe,kBAAkB,KAAK,EAAE,IAAI,cAAc,EAAE,EAAE,OAAO;AAE3E,WAAO;AAAA;AAAA,MAA0B;AAAA;AAAA,EACnC;AACF,QAAM,iBAAiB,oBAAI,IAA4C;AACvE,MAAI,cAAc,QAAQ,QAAc,MAAS;AAEjD,iBAAe,qBAAqB,aAAqB,WAAW,MAAM;AACxE,QAAI,CAAC,UAAU;AACb,YAAM,EAAE,SAAS,UAAU,IAAI,MAAM,WAAW,WAAW;AAE3D,aAAO,uBAAuB,SAAS;AAAA,IACzC;AAEA,QAAI,CAAC,eAAe,IAAI,WAAW,GAAG;AACpC,qBAAe,IAAI,cAAc,YAAY;AAC3C,cAAM,EAAE,SAAS,UAAU,IAAI,MAAM,WAAW,WAAW;AAE3D,eAAO,uBAAuB,SAAS;AAAA,MACzC,GAAG,CAAC;AAAA,IACN;AAEA,UAAM,kBAAkB,eAAe,IAAI,WAAW;AAEtD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,mCAAmC,WAAW,EAAE;AAAA,IAClE;AAEA,QAAI;AACF,aAAO,MAAM;AAAA,IACf,SAAS,OAAO;AAEd,qBAAe,OAAO,WAAW;AACjC,YAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO,eAAe,QAAQ,MAAoB;AAChD,UAAM,gBAAgB,YAAY;AAChC,YAAM,oBAAoB,SAAS,2BAC/B,MAAM,QAAQ,yBAAyB,IACvC;AAEJ,YAAM,gBAAgB,MAAM,iBAAiB;AAAA,QAC3C,cAAc;AAAA,QACd,gBAAgB,SAAS;AAAA,QACzB;AAAA,QACA,OAAO,KAAK;AAAA,MACd,CAAC;AAED,YAAM,iBAAiB,cAAc,WAAW;AAEhD,aAAO,qBAAqB,cAAc,aAAa,YAAY;AACjE,cAAM,mBAAmB,MAAM;AAAA,UAC7B,KAAK;AAAA,UACL,cAAc,YAAY,SAAS;AAAA,QACrC;AACA,cAAM,gBAAgB,MAAM,qBAAqB,KAAK,QAAQ,CAAC,CAAC;AAChE,cAAM,mBAAmB;AAAA,UACvB;AAAA,YACE,MAAM;AAAA,YACN,OAAO,KAAK,SAAS,CAAC;AAAA,UACxB;AAAA,UACA;AAAA,QACF;AAEA,eAAO,UAAU;AAAA,UACf;AAAA,UACA;AAAA,YACE,OAAO,iBAAiB;AAAA,YACxB,OAAO,iBAAiB;AAAA,UAC1B;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,gBAAgB,YAAY,KAAK,eAAe,aAAa;AAEnE,kBAAc,cAAc;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,uBAAuB,WAA2C;AACzE,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,QAAM,oBAAoB;AAC1B,QAAM,WAAW,CAAC,QAA2B,OAAgB,UAAmB;AAC9E,QAAI,UAAU,OAAO,OAAO,gBAAgB,YAAY;AACtD,YAAM,sBAAsB,OAAO;AACnC,YAAM,4BAA4B,oBAAoB,UAAU;AAEhE,aAAO,cAAc,IAAI,SAAoB;AAC3C,YAAI,KAAK,WAAW,KAAK,CAAC,2BAA2B;AACnD,iBAAO,oBAAoB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAAA,QAC7C;AAEA,eAAO,oBAAoB,GAAG,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,WAAO,kBAAkB,QAAQ,OAAO,KAAK;AAAA,EAC/C;AAEA,UAAQ,0BAA0B,kBAAkB;AACpD,UAAQ,WAAW,kBAAkB;AACrC,UAAQ,cAAc,kBAAkB;AAExC,SAAO;AACT;AAEA,eAAe,qBACb,MACkC;AAClC,QAAM,YAAqC,CAAC;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,gBAAgB,KAAK,GAAG;AAC1B,gBAAU,GAAG,IAAI,0BAA0B,KAAK;AAEhD;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,gBAAU,GAAG,IAAI,MAAM,QAAQ;AAAA,QAC7B,MAAM,IAAI,OAAO,SAAS;AACxB,cAAI,gBAAgB,IAAI,GAAG;AACzB,mBAAO,0BAA0B,IAAI;AAAA,UACvC;AAEA,cAAI,SAAS,IAAI,GAAG;AAClB,mBAAO,qBAAqB,IAAI;AAAA,UAClC;AAEA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA;AAAA,IACF;AAEA,QAAI,SAAS,KAAK,GAAG;AACnB,gBAAU,GAAG,IAAI,MAAM,qBAAqB,KAAK;AAEjD;AAAA,IACF;AAEA,cAAU,GAAG,IAAI;AAAA,EACnB;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAkD;AACzE,SACE,SAAS,KAAK,KACd,OAAO,MAAM,QAAQ,aACpB,WAAW,SAAS,YAAY,SAAS,YAAY;AAE1D;AAEA,SAAS,0BAA0B,eAAgD;AACjF,QAAM,MAAM,cAAc;AAC1B,QAAM,SAAS,cAAc;AAE7B,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,aAAa;AAC7B;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;","names":[]}
1
+ {"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url';\nimport { experimental_AstroContainer as AstroContainer } from 'astro/container';\nimport type { Integration } from './integrations/index.ts';\nimport type { SanitizationOptions } from './lib/sanitization.ts';\nimport { resolveSanitizationOptions, sanitizeRenderPayload } from './lib/sanitization.ts';\nimport { resolveStoryModuleMock, withStoryModuleMocks } from './module-mocks.ts';\nimport { selectStoryRules, withStoryRuleCleanups } from './rules.ts';\nimport type { RenderStoryInput } from './types.ts';\nimport { addRenderers, resolveClientModules } from 'virtual:astro-container-renderers';\n\ntype ResolveRulesConfigModule = () => unknown | Promise<unknown>;\n\ntype AstroCreateResult = {\n createAstro?: (...args: unknown[]) => unknown;\n};\n\ntype AstroComponentFactory = ((\n result: AstroCreateResult,\n props: unknown,\n slots: unknown\n) => unknown) & {\n isAstroComponentFactory?: boolean;\n moduleId?: string;\n propagation?: unknown;\n};\n\nexport type HandlerProps = {\n component: string;\n args?: Record<string, unknown>;\n slots?: Record<string, unknown>;\n story?: RenderStoryInput;\n};\n\ntype HandlerFactoryOptions = {\n sanitization?: SanitizationOptions;\n rulesConfigFilePath?: string;\n resolveRulesConfigModule?: ResolveRulesConfigModule;\n loadModule?: (id: string) => Promise<{ default: unknown }>;\n};\n\nexport async function handlerFactory(_integrations: Integration[], options?: HandlerFactoryOptions) {\n // Inject a passthrough image service before any component renders.\n //\n // AstroContainer has no image service configuration API, and the default\n // getConfiguredImageService() tries to dynamically import \"virtual:image-service\"\n // which fails in astro6/Vite 7's module runner. Even when it succeeds (astro5),\n // the noop service still routes through /_image?href=... URLs that the Storybook\n // dev server cannot serve.\n //\n // Pre-populating globalThis.astroAsset.imageService bypasses the dynamic import\n // entirely. Our service returns the direct /@fs/... Vite URL from the ImageMetadata\n // object, which Vite can serve as a static asset in the browser.\n if (!globalThis.astroAsset) {\n (globalThis as Record<string, unknown>).astroAsset = {};\n }\n (globalThis.astroAsset as Record<string, unknown>).imageService = {\n propertiesToHash: ['src'],\n validateOptions(options: Record<string, unknown>) {\n return options;\n },\n getURL(options: { src: unknown }) {\n const src = options.src;\n\n if (src != null && typeof src === 'object' && 'src' in src && typeof (src as Record<string, unknown>).src === 'string') {\n // ImageMetadata object — return the /@fs/... Vite URL directly\n return (src as Record<string, unknown>).src as string;\n }\n\n return typeof src === 'string' ? src : '';\n },\n getHTMLAttributes(options: Record<string, unknown>) {\n const { src, width, height, format, quality, densities, widths, formats, layout, priority, fit, position, background, ...attrs } = options;\n const srcObj = src != null && typeof src === 'object' ? src as Record<string, unknown> : null;\n\n return {\n ...attrs,\n width: width ?? srcObj?.width,\n height: height ?? srcObj?.height,\n loading: (attrs.loading as string | undefined) ?? 'lazy',\n decoding: (attrs.decoding as string | undefined) ?? 'async',\n };\n },\n getSrcSet() {\n return [];\n }\n };\n\n const container = await AstroContainer.create({\n // Somewhat hacky way to force client-side Storybook's Vite to resolve modules properly\n resolve: async (specifier) => {\n const mockedModule = resolveStoryModuleMock(specifier);\n\n if (mockedModule) {\n return mockedModule;\n }\n\n if (specifier.startsWith('astro:scripts')) {\n return `/@id/${specifier}`;\n }\n\n const resolution = resolveClientModules(specifier);\n\n if (resolution) {\n return resolution;\n }\n\n return specifier;\n }\n });\n\n addRenderers(container);\n const sanitizationOptions = resolveSanitizationOptions(options?.sanitization);\n const loadModule =\n options?.loadModule ??\n ((id: string) => {\n const normalizedId = /^[a-zA-Z]:[/\\\\]/.test(id) ? pathToFileURL(id).href : id;\n\n return import(/* @vite-ignore */ normalizedId);\n });\n const componentCache = new Map<string, Promise<AstroComponentFactory>>();\n let renderQueue = Promise.resolve<void>(undefined);\n\n async function loadPatchedComponent(componentId: string, useCache = true) {\n if (!useCache) {\n const { default: component } = await loadModule(componentId);\n\n return patchCreateAstroCompat(component);\n }\n\n if (!componentCache.has(componentId)) {\n componentCache.set(componentId, (async () => {\n const { default: component } = await loadModule(componentId);\n\n return patchCreateAstroCompat(component);\n })());\n }\n\n const cachedComponent = componentCache.get(componentId);\n\n if (!cachedComponent) {\n throw new Error(`Failed to load Astro component: ${componentId}`);\n }\n\n try {\n return await cachedComponent;\n } catch (error) {\n // Drop failed entries so transient/module errors can recover on the next request.\n componentCache.delete(componentId);\n throw error;\n }\n }\n\n return async function handler(data: HandlerProps) {\n const executeRender = async () => {\n const rulesConfigModule = options?.resolveRulesConfigModule\n ? await options.resolveRulesConfigModule()\n : undefined;\n\n const selectedRules = await selectStoryRules({\n configModule: rulesConfigModule,\n configFilePath: options?.rulesConfigFilePath,\n story: data.story\n });\n\n return withStoryRuleCleanups(selectedRules.cleanups, async () => {\n return withStoryModuleMocks(selectedRules.moduleMocks, async () => {\n const patchedComponent = await loadPatchedComponent(\n data.component,\n selectedRules.moduleMocks.size === 0\n );\n const processedArgs = await processImageMetadata(data.args ?? {});\n const sanitizedPayload = sanitizeRenderPayload(\n {\n args: processedArgs,\n slots: data.slots ?? {}\n },\n sanitizationOptions\n );\n\n return container.renderToString(\n patchedComponent as Parameters<typeof container.renderToString>[0],\n {\n props: sanitizedPayload.args,\n slots: sanitizedPayload.slots\n }\n );\n });\n });\n };\n\n const resultPromise = renderQueue.then(executeRender, executeRender);\n\n renderQueue = resultPromise.then(\n () => undefined,\n () => undefined\n );\n\n return resultPromise;\n };\n}\n\nfunction patchCreateAstroCompat(component: unknown): AstroComponentFactory {\n if (typeof component !== 'function') {\n throw new Error('Expected Astro component factory to be a function.');\n }\n\n const originalComponent = component as AstroComponentFactory;\n const wrapped = ((result: AstroCreateResult, props: unknown, slots: unknown) => {\n if (result && typeof result.createAstro === 'function') {\n const originalCreateAstro = result.createAstro;\n const runtimeExpectsAstroGlobal = originalCreateAstro.length >= 3;\n\n result.createAstro = (...args: unknown[]) => {\n if (args.length === 3 && !runtimeExpectsAstroGlobal) {\n return originalCreateAstro(args[1], args[2]);\n }\n\n return originalCreateAstro(...args);\n };\n }\n\n return originalComponent(result, props, slots);\n }) as AstroComponentFactory;\n\n wrapped.isAstroComponentFactory = originalComponent.isAstroComponentFactory;\n wrapped.moduleId = originalComponent.moduleId;\n wrapped.propagation = originalComponent.propagation;\n\n return wrapped;\n}\n\nasync function processImageMetadata(\n args: Record<string, unknown>\n): Promise<Record<string, unknown>> {\n const processed: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(args)) {\n if (isImageMetadata(value)) {\n // Keep ImageMetadata as a plain object — Astro's image service checks\n // isESMImportedImage (typeof src === 'object') and skips the /@fs/ string\n // validation that throws LocalImageUsedWrongly. Converting to a URL string\n // causes that error when the string starts with /@fs/.\n processed[key] = value;\n\n continue;\n }\n\n if (Array.isArray(value)) {\n processed[key] = await Promise.all(\n value.map(async (item) => {\n if (isImageMetadata(item)) {\n return item;\n }\n\n if (isRecord(item)) {\n return processImageMetadata(item);\n }\n\n return item;\n })\n );\n\n continue;\n }\n\n if (isRecord(value)) {\n processed[key] = await processImageMetadata(value);\n\n continue;\n }\n\n processed[key] = value;\n }\n\n return processed;\n}\n\nfunction isImageMetadata(value: unknown): value is Record<string, unknown> {\n return (\n isRecord(value) &&\n typeof value.src === 'string' &&\n ('width' in value || 'height' in value || 'format' in value)\n );\n}\n\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B,sBAAsB;AAO9D,SAAS,cAAc,4BAA4B;AAgCnD,eAAsB,eAAe,eAA8B,SAAiC;AAYlG,MAAI,CAAC,WAAW,YAAY;AAC1B,IAAC,WAAuC,aAAa,CAAC;AAAA,EACxD;AACA,EAAC,WAAW,WAAuC,eAAe;AAAA,IAChE,kBAAkB,CAAC,KAAK;AAAA,IACxB,gBAAgBA,UAAkC;AAChD,aAAOA;AAAA,IACT;AAAA,IACA,OAAOA,UAA2B;AAChC,YAAM,MAAMA,SAAQ;AAEpB,UAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,SAAS,OAAO,OAAQ,IAAgC,QAAQ,UAAU;AAEtH,eAAQ,IAAgC;AAAA,MAC1C;AAEA,aAAO,OAAO,QAAQ,WAAW,MAAM;AAAA,IACzC;AAAA,IACA,kBAAkBA,UAAkC;AAClD,YAAM,EAAE,KAAK,OAAO,QAAQ,QAAQ,SAAS,WAAW,QAAQ,SAAS,QAAQ,UAAU,KAAK,UAAU,YAAY,GAAG,MAAM,IAAIA;AACnI,YAAM,SAAS,OAAO,QAAQ,OAAO,QAAQ,WAAW,MAAiC;AAEzF,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO,SAAS,QAAQ;AAAA,QACxB,QAAQ,UAAU,QAAQ;AAAA,QAC1B,SAAU,MAAM,WAAkC;AAAA,QAClD,UAAW,MAAM,YAAmC;AAAA,MACtD;AAAA,IACF;AAAA,IACA,YAAY;AACV,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,eAAe,OAAO;AAAA;AAAA,IAE5C,SAAS,OAAO,cAAc;AAC5B,YAAM,eAAe,uBAAuB,SAAS;AAErD,UAAI,cAAc;AAChB,eAAO;AAAA,MACT;AAEA,UAAI,UAAU,WAAW,eAAe,GAAG;AACzC,eAAO,QAAQ,SAAS;AAAA,MAC1B;AAEA,YAAM,aAAa,qBAAqB,SAAS;AAEjD,UAAI,YAAY;AACd,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,eAAa,SAAS;AACtB,QAAM,sBAAsB,2BAA2B,SAAS,YAAY;AAC5E,QAAM,aACJ,SAAS,eACR,CAAC,OAAe;AACf,UAAM,eAAe,kBAAkB,KAAK,EAAE,IAAI,cAAc,EAAE,EAAE,OAAO;AAE3E,WAAO;AAAA;AAAA,MAA0B;AAAA;AAAA,EACnC;AACF,QAAM,iBAAiB,oBAAI,IAA4C;AACvE,MAAI,cAAc,QAAQ,QAAc,MAAS;AAEjD,iBAAe,qBAAqB,aAAqB,WAAW,MAAM;AACxE,QAAI,CAAC,UAAU;AACb,YAAM,EAAE,SAAS,UAAU,IAAI,MAAM,WAAW,WAAW;AAE3D,aAAO,uBAAuB,SAAS;AAAA,IACzC;AAEA,QAAI,CAAC,eAAe,IAAI,WAAW,GAAG;AACpC,qBAAe,IAAI,cAAc,YAAY;AAC3C,cAAM,EAAE,SAAS,UAAU,IAAI,MAAM,WAAW,WAAW;AAE3D,eAAO,uBAAuB,SAAS;AAAA,MACzC,GAAG,CAAC;AAAA,IACN;AAEA,UAAM,kBAAkB,eAAe,IAAI,WAAW;AAEtD,QAAI,CAAC,iBAAiB;AACpB,YAAM,IAAI,MAAM,mCAAmC,WAAW,EAAE;AAAA,IAClE;AAEA,QAAI;AACF,aAAO,MAAM;AAAA,IACf,SAAS,OAAO;AAEd,qBAAe,OAAO,WAAW;AACjC,YAAM;AAAA,IACR;AAAA,EACF;AAEA,SAAO,eAAe,QAAQ,MAAoB;AAChD,UAAM,gBAAgB,YAAY;AAChC,YAAM,oBAAoB,SAAS,2BAC/B,MAAM,QAAQ,yBAAyB,IACvC;AAEJ,YAAM,gBAAgB,MAAM,iBAAiB;AAAA,QAC3C,cAAc;AAAA,QACd,gBAAgB,SAAS;AAAA,QACzB,OAAO,KAAK;AAAA,MACd,CAAC;AAED,aAAO,sBAAsB,cAAc,UAAU,YAAY;AAC/D,eAAO,qBAAqB,cAAc,aAAa,YAAY;AACjE,gBAAM,mBAAmB,MAAM;AAAA,YAC7B,KAAK;AAAA,YACL,cAAc,YAAY,SAAS;AAAA,UACrC;AACA,gBAAM,gBAAgB,MAAM,qBAAqB,KAAK,QAAQ,CAAC,CAAC;AAChE,gBAAM,mBAAmB;AAAA,YACvB;AAAA,cACE,MAAM;AAAA,cACN,OAAO,KAAK,SAAS,CAAC;AAAA,YACxB;AAAA,YACA;AAAA,UACF;AAEA,iBAAO,UAAU;AAAA,YACf;AAAA,YACA;AAAA,cACE,OAAO,iBAAiB;AAAA,cACxB,OAAO,iBAAiB;AAAA,YAC1B;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,UAAM,gBAAgB,YAAY,KAAK,eAAe,aAAa;AAEnE,kBAAc,cAAc;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,uBAAuB,WAA2C;AACzE,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,QAAM,oBAAoB;AAC1B,QAAM,WAAW,CAAC,QAA2B,OAAgB,UAAmB;AAC9E,QAAI,UAAU,OAAO,OAAO,gBAAgB,YAAY;AACtD,YAAM,sBAAsB,OAAO;AACnC,YAAM,4BAA4B,oBAAoB,UAAU;AAEhE,aAAO,cAAc,IAAI,SAAoB;AAC3C,YAAI,KAAK,WAAW,KAAK,CAAC,2BAA2B;AACnD,iBAAO,oBAAoB,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;AAAA,QAC7C;AAEA,eAAO,oBAAoB,GAAG,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,WAAO,kBAAkB,QAAQ,OAAO,KAAK;AAAA,EAC/C;AAEA,UAAQ,0BAA0B,kBAAkB;AACpD,UAAQ,WAAW,kBAAkB;AACrC,UAAQ,cAAc,kBAAkB;AAExC,SAAO;AACT;AAEA,eAAe,qBACb,MACkC;AAClC,QAAM,YAAqC,CAAC;AAE5C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,gBAAgB,KAAK,GAAG;AAK1B,gBAAU,GAAG,IAAI;AAEjB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,gBAAU,GAAG,IAAI,MAAM,QAAQ;AAAA,QAC7B,MAAM,IAAI,OAAO,SAAS;AACxB,cAAI,gBAAgB,IAAI,GAAG;AACzB,mBAAO;AAAA,UACT;AAEA,cAAI,SAAS,IAAI,GAAG;AAClB,mBAAO,qBAAqB,IAAI;AAAA,UAClC;AAEA,iBAAO;AAAA,QACT,CAAC;AAAA,MACH;AAEA;AAAA,IACF;AAEA,QAAI,SAAS,KAAK,GAAG;AACnB,gBAAU,GAAG,IAAI,MAAM,qBAAqB,KAAK;AAEjD;AAAA,IACF;AAEA,cAAU,GAAG,IAAI;AAAA,EACnB;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,OAAkD;AACzE,SACE,SAAS,KAAK,KACd,OAAO,MAAM,QAAQ,aACpB,WAAW,SAAS,YAAY,SAAS,YAAY;AAE1D;AAGA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;","names":["options"]}
@@ -0,0 +1,10 @@
1
+ import { d as StorybookConfig } from '../types-Cvor6Tyi.js';
2
+ import 'storybook/internal/types';
3
+ import 'vite';
4
+ import '../base-IRZo3zgK.js';
5
+ import 'astro';
6
+ import 'sanitize-html';
7
+
8
+ declare function defineMain(config: StorybookConfig): StorybookConfig;
9
+
10
+ export { StorybookConfig, defineMain };
@@ -0,0 +1,10 @@
1
+ import "../chunk-G3PMV62Z.js";
2
+
3
+ // src/node/index.ts
4
+ function defineMain(config) {
5
+ return config;
6
+ }
7
+ export {
8
+ defineMain
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/node/index.ts"],"sourcesContent":["import type { StorybookConfig } from '../types.ts';\n\nexport function defineMain(config: StorybookConfig): StorybookConfig {\n return config;\n}\n\nexport type { StorybookConfig };\n"],"mappings":";;;AAEO,SAAS,WAAW,QAA0C;AACnE,SAAO;AACT;","names":[]}
package/dist/preset.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { c as StorybookConfigVite } from './types-CHTsRtA7.js';
1
+ import { e as StorybookConfigVite } from './types-Cvor6Tyi.js';
2
2
  import 'storybook/internal/types';
3
3
  import 'vite';
4
4
  import './base-IRZo3zgK.js';
package/dist/preset.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  core,
3
3
  viteFinal
4
- } from "./chunk-KSDXET2L.js";
5
- import "./chunk-C5OH4VBR.js";
4
+ } from "./chunk-4HECE7IW.js";
5
+ import "./chunk-V76WSNSP.js";
6
+ import "./chunk-POHTFYST.js";
6
7
  import "./chunk-E4LB75JN.js";
7
- import "./chunk-7GHEQUPV.js";
8
8
  import "./chunk-DNGQBPT7.js";
9
9
  import "./chunk-G3PMV62Z.js";
10
10
  export {