storybook 10.2.0-alpha.16 → 10.2.0-alpha.17

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 (65) hide show
  1. package/dist/_node-chunks/{builder-manager-DQ6DNDHX.js → builder-manager-Q4F5VX5J.js} +14 -12
  2. package/dist/_node-chunks/{camelcase-ILOVTISA.js → camelcase-FL6OBJRZ.js} +7 -7
  3. package/dist/_node-chunks/{chunk-3PMH6BEP.js → chunk-25OWI2RR.js} +6 -6
  4. package/dist/_node-chunks/{chunk-ZN5DGHF3.js → chunk-2XSHQN7K.js} +10 -10
  5. package/dist/_node-chunks/{chunk-RIEIAV32.js → chunk-3D4SLKEE.js} +7 -7
  6. package/dist/_node-chunks/{chunk-XWGABQX7.js → chunk-5Q5JEISY.js} +6 -6
  7. package/dist/_node-chunks/{chunk-JXU4P6K3.js → chunk-C3FPVGL4.js} +6 -6
  8. package/dist/_node-chunks/chunk-CBPOKBOR.js +18 -0
  9. package/dist/_node-chunks/{chunk-KAAWGCHX.js → chunk-CCJGKJ27.js} +12 -12
  10. package/dist/_node-chunks/{chunk-6QEWR44T.js → chunk-DJ3RRSJ7.js} +7 -7
  11. package/dist/_node-chunks/chunk-EG3WZ464.js +23 -0
  12. package/dist/_node-chunks/{chunk-TDBTCAEB.js → chunk-EYPTVKFI.js} +123 -72
  13. package/dist/_node-chunks/{chunk-K6FMM5LS.js → chunk-FAARRTOD.js} +6 -6
  14. package/dist/_node-chunks/{chunk-YFUVKP3W.js → chunk-G7P42ZEY.js} +7 -7
  15. package/dist/_node-chunks/chunk-GYJ7LPFJ.js +144 -0
  16. package/dist/_node-chunks/{chunk-PGYIGHRK.js → chunk-IRMNO3QS.js} +9 -9
  17. package/dist/_node-chunks/{chunk-CFXIZS6A.js → chunk-IWM3WHZE.js} +7 -7
  18. package/dist/_node-chunks/{chunk-47ZRY4XW.js → chunk-JBRILZWU.js} +6 -6
  19. package/dist/_node-chunks/{chunk-SWN4HCJE.js → chunk-KKNWPXMS.js} +6 -6
  20. package/dist/_node-chunks/{chunk-WVXPIXUS.js → chunk-MU4E5UBA.js} +7 -7
  21. package/dist/_node-chunks/{chunk-M6AUSQA3.js → chunk-PWI3ORDV.js} +22 -22
  22. package/dist/_node-chunks/chunk-RGEHGZS6.js +61 -0
  23. package/dist/_node-chunks/{chunk-IVYTDHSW.js → chunk-V3SFCYKQ.js} +7 -7
  24. package/dist/_node-chunks/{chunk-LOJ73E6E.js → chunk-VK4OWRKU.js} +9 -9
  25. package/dist/_node-chunks/{chunk-WIOSV6HC.js → chunk-VT2FICF4.js} +6 -6
  26. package/dist/_node-chunks/{chunk-TLGG6YAX.js → chunk-VTBZVEBF.js} +511 -127
  27. package/dist/_node-chunks/{chunk-FNQ5WLS5.js → chunk-XI7HDOMY.js} +7 -7
  28. package/dist/_node-chunks/{chunk-XJMJA2L4.js → chunk-XTIFAWOB.js} +250 -14
  29. package/dist/_node-chunks/{chunk-TTACLBSG.js → chunk-XYONORVT.js} +7 -7
  30. package/dist/_node-chunks/{chunk-OKUHCLLJ.js → chunk-ZOUBYBCH.js} +9 -9
  31. package/dist/_node-chunks/{globby-A35XB3PP.js → globby-4BDMCAAD.js} +9 -9
  32. package/dist/_node-chunks/{lib-D5I6ETBH.js → lib-XS2XQMOO.js} +7 -7
  33. package/dist/_node-chunks/{mdx-N42X6CFJ-DZ4EAFAE.js → mdx-N42X6CFJ-JFERGMQH.js} +8 -8
  34. package/dist/_node-chunks/{p-limit-2CRKZRXN.js → p-limit-I4CLTHWH.js} +7 -7
  35. package/dist/babel/index.js +10 -10
  36. package/dist/bin/core.js +12 -12
  37. package/dist/bin/dispatcher.js +11 -11
  38. package/dist/bin/loader.js +9 -9
  39. package/dist/cli/index.js +18 -18
  40. package/dist/common/index.js +19 -19
  41. package/dist/core-events/index.d.ts +19 -3
  42. package/dist/core-events/index.js +5 -1
  43. package/dist/core-server/index.d.ts +64 -2
  44. package/dist/core-server/index.js +37 -34
  45. package/dist/core-server/presets/common-override-preset.js +11 -11
  46. package/dist/core-server/presets/common-preset.js +532 -234
  47. package/dist/csf/index.d.ts +15 -3
  48. package/dist/csf/index.js +37 -13
  49. package/dist/csf-tools/index.d.ts +19 -1
  50. package/dist/csf-tools/index.js +11 -10
  51. package/dist/manager/globals-runtime.js +6 -2
  52. package/dist/manager/runtime.js +17 -98
  53. package/dist/manager-api/index.js +1 -1
  54. package/dist/mocking-utils/index.js +8 -8
  55. package/dist/node-logger/index.js +9 -9
  56. package/dist/preview/runtime.js +33 -6
  57. package/dist/preview-api/index.d.ts +68 -67
  58. package/dist/server-errors.js +11 -11
  59. package/dist/telemetry/index.d.ts +13 -2
  60. package/dist/telemetry/index.js +23 -22
  61. package/package.json +1 -1
  62. package/dist/_node-chunks/chunk-5E2HAJXY.js +0 -35
  63. package/dist/_node-chunks/chunk-DGLVYUKY.js +0 -61
  64. package/dist/_node-chunks/chunk-MSK3YTQT.js +0 -23
  65. package/dist/_node-chunks/chunk-SPPXK6CQ.js +0 -18
@@ -1,54 +1,63 @@
1
- import CJS_COMPAT_NODE_URL_4zwbyhk64wx from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_4zwbyhk64wx from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_4zwbyhk64wx from "node:module";
1
+ import CJS_COMPAT_NODE_URL_w8tq4vh9mzk from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_w8tq4vh9mzk from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_w8tq4vh9mzk from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_4zwbyhk64wx.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_4zwbyhk64wx.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_4zwbyhk64wx.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_w8tq4vh9mzk.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_w8tq4vh9mzk.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_w8tq4vh9mzk.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
11
11
  // ------------------------------------------------------------
12
- import "../../_node-chunks/chunk-KAAWGCHX.js";
12
+ import "../../_node-chunks/chunk-CCJGKJ27.js";
13
13
  import {
14
+ doesStoryFileExist,
15
+ generateStoryFile,
16
+ getStoryMetadata,
14
17
  parseStaticDir,
15
18
  sendTelemetryError,
16
19
  throttle
17
- } from "../../_node-chunks/chunk-XJMJA2L4.js";
18
- import "../../_node-chunks/chunk-MSK3YTQT.js";
19
- import "../../_node-chunks/chunk-CFXIZS6A.js";
20
- import "../../_node-chunks/chunk-K6FMM5LS.js";
20
+ } from "../../_node-chunks/chunk-XTIFAWOB.js";
21
+ import "../../_node-chunks/chunk-EG3WZ464.js";
22
+ import "../../_node-chunks/chunk-IWM3WHZE.js";
23
+ import "../../_node-chunks/chunk-FAARRTOD.js";
24
+ import {
25
+ isI18nPackage,
26
+ isRouterPackage,
27
+ isStateManagementPackage,
28
+ isStylingPackage
29
+ } from "../../_node-chunks/chunk-GYJ7LPFJ.js";
21
30
  import {
22
31
  globalSettings
23
- } from "../../_node-chunks/chunk-LOJ73E6E.js";
32
+ } from "../../_node-chunks/chunk-VK4OWRKU.js";
24
33
  import {
25
34
  invariant
26
- } from "../../_node-chunks/chunk-JXU4P6K3.js";
27
- import "../../_node-chunks/chunk-SWN4HCJE.js";
35
+ } from "../../_node-chunks/chunk-C3FPVGL4.js";
36
+ import "../../_node-chunks/chunk-KKNWPXMS.js";
28
37
  import {
29
38
  resolvePackageDir
30
- } from "../../_node-chunks/chunk-RIEIAV32.js";
39
+ } from "../../_node-chunks/chunk-3D4SLKEE.js";
31
40
  import {
32
41
  isAbsolute,
33
42
  join
34
- } from "../../_node-chunks/chunk-XWGABQX7.js";
43
+ } from "../../_node-chunks/chunk-5Q5JEISY.js";
35
44
  import {
36
- loadConfig
37
- } from "../../_node-chunks/chunk-TLGG6YAX.js";
38
- import "../../_node-chunks/chunk-5E2HAJXY.js";
45
+ glob
46
+ } from "../../_node-chunks/chunk-DJ3RRSJ7.js";
47
+ import "../../_node-chunks/chunk-VTBZVEBF.js";
39
48
  import {
40
49
  require_dist
41
- } from "../../_node-chunks/chunk-YFUVKP3W.js";
42
- import "../../_node-chunks/chunk-PGYIGHRK.js";
43
- import "../../_node-chunks/chunk-WVXPIXUS.js";
50
+ } from "../../_node-chunks/chunk-G7P42ZEY.js";
51
+ import "../../_node-chunks/chunk-IRMNO3QS.js";
52
+ import "../../_node-chunks/chunk-MU4E5UBA.js";
44
53
  import {
45
54
  require_picocolors
46
- } from "../../_node-chunks/chunk-FNQ5WLS5.js";
55
+ } from "../../_node-chunks/chunk-XI7HDOMY.js";
47
56
  import {
48
57
  __commonJS,
49
58
  __require,
50
59
  __toESM
51
- } from "../../_node-chunks/chunk-3PMH6BEP.js";
60
+ } from "../../_node-chunks/chunk-25OWI2RR.js";
52
61
 
53
62
  // ../../node_modules/shell-quote/quote.js
54
63
  var require_quote = __commonJS({
@@ -472,8 +481,8 @@ var require_launch_editor = __commonJS({
472
481
  });
473
482
 
474
483
  // src/core-server/presets/common-preset.ts
475
- import { existsSync as existsSync3 } from "node:fs";
476
- import { readFile as readFile3 } from "node:fs/promises";
484
+ import { existsSync as existsSync2 } from "node:fs";
485
+ import { readFile as readFile4 } from "node:fs/promises";
477
486
  import { normalizeStories, optionalEnvToBoolean } from "storybook/internal/common";
478
487
  import {
479
488
  JsPackageManagerFactory,
@@ -486,191 +495,51 @@ import {
486
495
  import { StoryIndexGenerator } from "storybook/internal/core-server";
487
496
  import { readCsf as readCsf2 } from "storybook/internal/csf-tools";
488
497
  import { logger as logger4 } from "storybook/internal/node-logger";
489
- import { telemetry as telemetry8 } from "storybook/internal/telemetry";
490
- var import_ts_dedent4 = __toESM(require_dist(), 1);
498
+ import { telemetry as telemetry9 } from "storybook/internal/telemetry";
499
+ var import_ts_dedent = __toESM(require_dist(), 1);
491
500
 
492
501
  // src/core-server/server-channel/create-new-story-channel.ts
493
- import { existsSync as existsSync2 } from "node:fs";
494
- import { writeFile } from "node:fs/promises";
495
- import { relative } from "node:path";
496
- import { getStoryId } from "storybook/internal/common";
497
502
  import {
498
503
  CREATE_NEW_STORYFILE_REQUEST,
499
504
  CREATE_NEW_STORYFILE_RESPONSE
500
505
  } from "storybook/internal/core-events";
501
506
  import { telemetry } from "storybook/internal/telemetry";
502
-
503
- // src/core-server/utils/get-new-story-file.ts
504
- import { existsSync } from "node:fs";
505
- import { readFile } from "node:fs/promises";
506
- import { basename, dirname, extname, join as join2 } from "node:path";
507
- import {
508
- extractFrameworkPackageName,
509
- findConfigFile,
510
- getFrameworkName,
511
- getProjectRoot
512
- } from "storybook/internal/common";
513
- import { isCsfFactoryPreview } from "storybook/internal/csf-tools";
514
-
515
- // src/core-server/utils/new-story-templates/csf-factory-template.ts
516
- var import_ts_dedent = __toESM(require_dist(), 1);
517
-
518
- // src/core-server/utils/get-component-variable-name.ts
519
- var getComponentVariableName = async (name) => (await import("../../_node-chunks/camelcase-ILOVTISA.js")).default(name.replace(/^[^a-zA-Z_$]*/, ""), { pascalCase: !0 }).replace(/[^a-zA-Z_$]+/, "");
520
-
521
- // src/core-server/utils/new-story-templates/csf-factory-template.ts
522
- async function getCsfFactoryTemplateForNewStoryFile(data) {
523
- let importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName, importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}';` : `import { ${importName} } from './${data.basenameWithoutExtension}';`;
524
- return import_ts_dedent.dedent`
525
- ${"import preview from '#.storybook/preview';"}
526
-
527
- ${importStatement}
528
-
529
- const meta = preview.meta({
530
- component: ${importName},
531
- });
532
-
533
- export const ${data.exportedStoryName} = meta.story({});
534
- `;
535
- }
536
-
537
- // src/core-server/utils/new-story-templates/javascript.ts
538
- var import_ts_dedent2 = __toESM(require_dist(), 1);
539
- async function getJavaScriptTemplateForNewStoryFile(data) {
540
- let importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName, importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}';` : `import { ${importName} } from './${data.basenameWithoutExtension}';`;
541
- return import_ts_dedent2.dedent`
542
- ${importStatement}
543
-
544
- const meta = {
545
- component: ${importName},
546
- };
547
-
548
- export default meta;
549
-
550
- export const ${data.exportedStoryName} = {};
551
- `;
552
- }
553
-
554
- // src/core-server/utils/new-story-templates/typescript.ts
555
- var import_ts_dedent3 = __toESM(require_dist(), 1);
556
- async function getTypeScriptTemplateForNewStoryFile(data) {
557
- let importName = data.componentIsDefaultExport ? await getComponentVariableName(data.basenameWithoutExtension) : data.componentExportName, importStatement = data.componentIsDefaultExport ? `import ${importName} from './${data.basenameWithoutExtension}'` : `import { ${importName} } from './${data.basenameWithoutExtension}'`;
558
- return import_ts_dedent3.dedent`
559
- import type { Meta, StoryObj } from '${data.frameworkPackage}';
560
-
561
- ${importStatement};
562
-
563
- const meta = {
564
- component: ${importName},
565
- } satisfies Meta<typeof ${importName}>;
566
-
567
- export default meta;
568
-
569
- type Story = StoryObj<typeof meta>;
570
-
571
- export const ${data.exportedStoryName}: Story = {};
572
- `;
573
- }
574
-
575
- // src/core-server/utils/get-new-story-file.ts
576
- async function getNewStoryFile({
577
- componentFilePath,
578
- componentExportName,
579
- componentIsDefaultExport,
580
- componentExportCount
581
- }, options) {
582
- let frameworkPackageName = await getFrameworkName(options), sanitizedFrameworkPackageName = extractFrameworkPackageName(frameworkPackageName), base = basename(componentFilePath), extension = extname(componentFilePath), basenameWithoutExtension = base.replace(extension, ""), dir = dirname(componentFilePath), { storyFileName, isTypescript, storyFileExtension } = getStoryMetadata(componentFilePath), storyFileNameWithExtension = `${storyFileName}.${storyFileExtension}`, alternativeStoryFileNameWithExtension = `${basenameWithoutExtension}.${componentExportName}.stories.${storyFileExtension}`, exportedStoryName = "Default", useCsfFactory = !1;
583
- try {
584
- let previewConfig = findConfigFile("preview", options.configDir);
585
- if (previewConfig) {
586
- let previewContent = await readFile(previewConfig, "utf-8");
587
- useCsfFactory = isCsfFactoryPreview(loadConfig(previewContent));
588
- }
589
- } catch {
590
- }
591
- let storyFileContent = "";
592
- return useCsfFactory ? storyFileContent = await getCsfFactoryTemplateForNewStoryFile({
593
- basenameWithoutExtension,
594
- componentExportName,
595
- componentIsDefaultExport,
596
- exportedStoryName
597
- }) : storyFileContent = isTypescript && frameworkPackageName ? await getTypeScriptTemplateForNewStoryFile({
598
- basenameWithoutExtension,
599
- componentExportName,
600
- componentIsDefaultExport,
601
- frameworkPackage: sanitizedFrameworkPackageName,
602
- exportedStoryName
603
- }) : await getJavaScriptTemplateForNewStoryFile({
604
- basenameWithoutExtension,
605
- componentExportName,
606
- componentIsDefaultExport,
607
- exportedStoryName
608
- }), { storyFilePath: doesStoryFileExist(join2(getProjectRoot(), dir), storyFileName) && componentExportCount > 1 ? join2(getProjectRoot(), dir, alternativeStoryFileNameWithExtension) : join2(getProjectRoot(), dir, storyFileNameWithExtension), exportedStoryName, storyFileContent, dirname };
609
- }
610
- var getStoryMetadata = (componentFilePath) => {
611
- let isTypescript = /\.(ts|tsx|mts|cts)$/.test(componentFilePath), base = basename(componentFilePath), extension = extname(componentFilePath), basenameWithoutExtension = base.replace(extension, ""), storyFileExtension = isTypescript ? "tsx" : "jsx";
612
- return {
613
- storyFileName: `${basenameWithoutExtension}.stories`,
614
- storyFileExtension,
615
- isTypescript
616
- };
617
- }, doesStoryFileExist = (parentFolder, storyFileName) => existsSync(join2(parentFolder, `${storyFileName}.ts`)) || existsSync(join2(parentFolder, `${storyFileName}.tsx`)) || existsSync(join2(parentFolder, `${storyFileName}.js`)) || existsSync(join2(parentFolder, `${storyFileName}.jsx`));
618
-
619
- // src/core-server/server-channel/create-new-story-channel.ts
620
507
  function initCreateNewStoryChannel(channel, options, coreOptions) {
621
508
  return channel.on(
622
509
  CREATE_NEW_STORYFILE_REQUEST,
623
510
  async (data) => {
624
- try {
625
- let { storyFilePath, exportedStoryName, storyFileContent } = await getNewStoryFile(
626
- data.payload,
627
- options
628
- ), relativeStoryFilePath = relative(process.cwd(), storyFilePath), { storyId, kind } = await getStoryId({ storyFilePath, exportedStoryName }, options);
629
- if (existsSync2(storyFilePath)) {
630
- channel.emit(CREATE_NEW_STORYFILE_RESPONSE, {
631
- success: !1,
632
- id: data.id,
633
- payload: {
634
- type: "STORY_FILE_EXISTS",
635
- kind
636
- },
637
- error: `A story file already exists at ${relativeStoryFilePath}`
638
- }), coreOptions.disableTelemetry || telemetry("create-new-story-file", {
639
- success: !1,
640
- error: "STORY_FILE_EXISTS"
641
- });
642
- return;
643
- }
644
- await writeFile(storyFilePath, storyFileContent, "utf-8"), channel.emit(CREATE_NEW_STORYFILE_RESPONSE, {
645
- success: !0,
646
- id: data.id,
647
- payload: {
648
- storyId,
649
- storyFilePath: relative(process.cwd(), storyFilePath),
650
- exportedStoryName
651
- },
652
- error: null
653
- }), coreOptions.disableTelemetry || telemetry("create-new-story-file", {
654
- success: !0
655
- });
656
- } catch (e) {
657
- channel.emit(CREATE_NEW_STORYFILE_RESPONSE, {
658
- success: !1,
659
- id: data.id,
660
- error: e?.message
661
- }), coreOptions.disableTelemetry || await telemetry("create-new-story-file", {
662
- success: !1,
663
- error: e
664
- });
665
- }
511
+ let result = await generateStoryFile(data.payload, options);
512
+ result.success ? (channel.emit(CREATE_NEW_STORYFILE_RESPONSE, {
513
+ success: !0,
514
+ id: data.id,
515
+ payload: {
516
+ storyId: result.storyId,
517
+ storyFilePath: result.storyFilePath,
518
+ exportedStoryName: result.exportedStoryName
519
+ },
520
+ error: null
521
+ }), coreOptions.disableTelemetry || telemetry("create-new-story-file", {
522
+ success: !0
523
+ })) : (channel.emit(CREATE_NEW_STORYFILE_RESPONSE, {
524
+ success: !1,
525
+ id: data.id,
526
+ payload: result.errorType === "STORY_FILE_EXISTS" ? {
527
+ type: "STORY_FILE_EXISTS",
528
+ kind: result.kind
529
+ } : void 0,
530
+ error: result.error || "Unknown error occurred"
531
+ }), coreOptions.disableTelemetry || await telemetry("create-new-story-file", {
532
+ success: !1,
533
+ error: result.errorType || result.error
534
+ }));
666
535
  }
667
536
  ), channel;
668
537
  }
669
538
 
670
539
  // src/core-server/server-channel/file-search-channel.ts
671
- import { readFile as readFile2 } from "node:fs/promises";
672
- import { dirname as dirname2, join as join3 } from "node:path";
673
- import { extractRenderer, getFrameworkName as getFrameworkName2, getProjectRoot as getProjectRoot2 } from "storybook/internal/common";
540
+ import { readFile } from "node:fs/promises";
541
+ import { dirname, join as join2 } from "node:path";
542
+ import { extractRenderer, getFrameworkName, getProjectRoot } from "storybook/internal/common";
674
543
  import {
675
544
  FILE_COMPONENT_SEARCH_REQUEST,
676
545
  FILE_COMPONENT_SEARCH_RESPONSE
@@ -781,7 +650,7 @@ async function searchFiles({
781
650
  ignoredFiles = IGNORED_FILES,
782
651
  fileExtensions = FILE_EXTENSIONS
783
652
  }) {
784
- let { globby, isDynamicPattern } = await import("../../_node-chunks/globby-A35XB3PP.js"), hasSearchSpecialGlobChars = isDynamicPattern(searchQuery, { cwd }), searchQueryHasExtension = /(\.[a-z]+)$/i.test(searchQuery), fileExtensionsPattern = `{${fileExtensions.join(",")}}`, globbedSearchQuery = hasSearchSpecialGlobChars ? searchQuery : searchQueryHasExtension ? [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`] : [
653
+ let { globby, isDynamicPattern } = await import("../../_node-chunks/globby-4BDMCAAD.js"), hasSearchSpecialGlobChars = isDynamicPattern(searchQuery, { cwd }), searchQueryHasExtension = /(\.[a-z]+)$/i.test(searchQuery), fileExtensionsPattern = `{${fileExtensions.join(",")}}`, globbedSearchQuery = hasSearchSpecialGlobChars ? searchQuery : searchQueryHasExtension ? [`**/*${searchQuery}*`, `**/*${searchQuery}*/**`] : [
785
654
  `**/*${searchQuery}*.${fileExtensionsPattern}`,
786
655
  `**/*${searchQuery}*/**/*.${fileExtensionsPattern}`
787
656
  ];
@@ -803,13 +672,13 @@ async function initFileSearchChannel(channel, options, coreOptions) {
803
672
  try {
804
673
  if (!searchQuery)
805
674
  return;
806
- let frameworkName = await getFrameworkName2(options), rendererName = await extractRenderer(frameworkName), entries = (await searchFiles({
675
+ let frameworkName = await getFrameworkName(options), rendererName = await extractRenderer(frameworkName), entries = (await searchFiles({
807
676
  searchQuery,
808
- cwd: getProjectRoot2()
677
+ cwd: getProjectRoot()
809
678
  })).map(async (file) => {
810
679
  let parser3 = getParser(rendererName);
811
680
  try {
812
- let content = await readFile2(join3(getProjectRoot2(), file), "utf-8"), { storyFileName } = getStoryMetadata(join3(getProjectRoot2(), file)), dir = dirname2(file), storyFileExists = doesStoryFileExist(join3(getProjectRoot2(), dir), storyFileName), info = await parser3.parse(content);
681
+ let content = await readFile(join2(getProjectRoot(), file), "utf-8"), { storyFileName } = getStoryMetadata(join2(getProjectRoot(), file)), dir = dirname(file), storyFileExists = doesStoryFileExist(join2(getProjectRoot(), dir), storyFileName), info = await parser3.parse(content);
813
682
  return {
814
683
  filepath: file,
815
684
  exportedComponents: info.exports,
@@ -854,14 +723,443 @@ ${e?.message}`
854
723
  ), channel;
855
724
  }
856
725
 
726
+ // src/core-server/server-channel/ghost-stories-channel.ts
727
+ import { GHOST_STORIES_REQUEST, GHOST_STORIES_RESPONSE } from "storybook/internal/core-events";
728
+ import {
729
+ getLastEvents,
730
+ getSessionId,
731
+ getStorybookMetadata,
732
+ telemetry as telemetry3
733
+ } from "storybook/internal/telemetry";
734
+
735
+ // src/core-server/utils/ghost-stories/get-candidates.ts
736
+ import { readFile as readFile2 } from "node:fs/promises";
737
+ import { babelParse, traverse } from "storybook/internal/babel";
738
+
739
+ // src/core-server/utils/ghost-stories/component-analyzer.ts
740
+ var COMPLEXITY_CONFIG = {
741
+ /** Weight applied to non-empty lines */
742
+ locWeight: 1,
743
+ /** Imports can be cheap, so they get a lower weight */
744
+ importWeight: 0.5,
745
+ /**
746
+ * Defines what raw complexity value should map to the upper bound of a "simple" file For instance
747
+ * 30 LOC + 4 imports = 32. This would result in a score of 0.3
748
+ */
749
+ simpleBaseline: 32,
750
+ simpleScore: 0.3
751
+ }, getComponentComplexity = (fileContent) => {
752
+ let lines = fileContent.split(`
753
+ `), nonEmptyLines = lines.filter((line) => line.trim() !== "").length, importCount = lines.filter((line) => line.trim().startsWith("import")).length, normalizedScore = (nonEmptyLines * COMPLEXITY_CONFIG.locWeight + importCount * COMPLEXITY_CONFIG.importWeight) / (COMPLEXITY_CONFIG.simpleBaseline / COMPLEXITY_CONFIG.simpleScore);
754
+ return Math.min(normalizedScore, 1);
755
+ };
756
+
757
+ // src/core-server/utils/ghost-stories/get-candidates.ts
758
+ function isValidCandidate(source) {
759
+ let ast = babelParse(source), hasJSX = !1, hasExport = !1;
760
+ return traverse(ast, {
761
+ JSXElement(path) {
762
+ hasJSX = !0, hasExport && path.stop();
763
+ },
764
+ JSXFragment(path) {
765
+ hasJSX = !0, hasExport && path.stop();
766
+ },
767
+ ExportNamedDeclaration(path) {
768
+ hasExport = !0, hasJSX && path.stop();
769
+ },
770
+ ExportDefaultDeclaration(path) {
771
+ hasExport = !0, hasJSX && path.stop();
772
+ },
773
+ ExportAllDeclaration(path) {
774
+ hasExport = !0, hasJSX && path.stop();
775
+ }
776
+ }), hasJSX && hasExport;
777
+ }
778
+ async function getCandidatesForStorybook(files, sampleCount) {
779
+ let simpleCandidates = [], analyzedCandidates = [];
780
+ for (let file of files) {
781
+ let source;
782
+ try {
783
+ if (source = await readFile2(file, "utf-8"), !isValidCandidate(source))
784
+ continue;
785
+ } catch {
786
+ continue;
787
+ }
788
+ let complexity = getComponentComplexity(source);
789
+ if (analyzedCandidates.push({ file, complexity }), complexity < 0.3 && (simpleCandidates.push({ file, complexity }), simpleCandidates.length >= sampleCount))
790
+ break;
791
+ }
792
+ let selectedCandidates = [];
793
+ simpleCandidates.length >= sampleCount ? selectedCandidates = simpleCandidates.sort((a, b) => a.complexity - b.complexity).slice(0, sampleCount) : selectedCandidates = analyzedCandidates.sort((a, b) => a.complexity - b.complexity).slice(0, sampleCount);
794
+ let avgComplexity = selectedCandidates.length > 0 ? Number(
795
+ (selectedCandidates.reduce((acc, curr) => acc + curr.complexity, 0) / selectedCandidates.length).toFixed(2)
796
+ ) : 0;
797
+ return {
798
+ candidates: selectedCandidates.map(({ file }) => file),
799
+ analyzedCount: analyzedCandidates.length,
800
+ avgComplexity
801
+ };
802
+ }
803
+ async function getComponentCandidates({
804
+ sampleSize = 20,
805
+ globPattern = "**/*.{tsx,jsx}"
806
+ } = {}) {
807
+ let globMatchCount = 0;
808
+ try {
809
+ let files = [];
810
+ if (files = await glob(globPattern, {
811
+ cwd: process.cwd(),
812
+ absolute: !0,
813
+ ignore: [
814
+ "**/node_modules/**",
815
+ "**/.git/**",
816
+ "**/dist/**",
817
+ "**/__mocks__/**",
818
+ "**/build/**",
819
+ "**/storybook-static/**",
820
+ "**/*.test.*",
821
+ "**/*.d.*",
822
+ "**/*.config.*",
823
+ "**/*.spec.*",
824
+ "**/*.stories.*",
825
+ // skip example story files that come from the CLI
826
+ "**/stories/{Button,Header,Page}.*",
827
+ "**/stories/{button,header,page}.*"
828
+ ]
829
+ }), globMatchCount = files.length, globMatchCount === 0)
830
+ return {
831
+ candidates: [],
832
+ globMatchCount
833
+ };
834
+ let { analyzedCount, avgComplexity, candidates } = await getCandidatesForStorybook(
835
+ files,
836
+ sampleSize
837
+ );
838
+ return {
839
+ analyzedCount,
840
+ avgComplexity,
841
+ candidates,
842
+ globMatchCount
843
+ };
844
+ } catch (error) {
845
+ let errorMessage = error instanceof Error ? error.message : String(error);
846
+ return {
847
+ candidates: [],
848
+ error: "Failed to find candidates",
849
+ globMatchCount
850
+ };
851
+ }
852
+ }
853
+
854
+ // src/core-server/utils/ghost-stories/run-story-tests.ts
855
+ import { existsSync } from "node:fs";
856
+ import { mkdir, readFile as readFile3 } from "node:fs/promises";
857
+ import { executeCommand, resolvePathInStorybookCache } from "storybook/internal/common";
858
+
859
+ // src/shared/utils/categorize-render-errors.ts
860
+ var ERROR_CATEGORIES = {
861
+ MISSING_PROVIDER: "MISSING_PROVIDER",
862
+ MISSING_STATE_PROVIDER: "MISSING_STATE_PROVIDER",
863
+ MISSING_ROUTER_PROVIDER: "MISSING_ROUTER_PROVIDER",
864
+ MISSING_THEME_PROVIDER: "MISSING_THEME_PROVIDER",
865
+ MISSING_TRANSLATION_PROVIDER: "MISSING_TRANSLATION_PROVIDER",
866
+ MISSING_PORTAL_ROOT: "MISSING_PORTAL_ROOT",
867
+ HOOK_USAGE_ERROR: "HOOK_USAGE_ERROR",
868
+ MODULE_IMPORT_ERROR: "MODULE_IMPORT_ERROR",
869
+ COMPONENT_RENDER_ERROR: "COMPONENT_RENDER_ERROR",
870
+ SERVER_COMPONENTS_ERROR: "SERVER_COMPONENTS_ERROR",
871
+ UNKNOWN_ERROR: "UNKNOWN_ERROR"
872
+ };
873
+ function buildErrorContext(message, stack) {
874
+ let normalizedMessage = message.toLowerCase(), normalizedStack = (stack ?? "").toLowerCase(), stackDeps = /* @__PURE__ */ new Set(), stackLines = normalizedStack.split(`
875
+ `).filter(Boolean);
876
+ for (let line of stackLines) {
877
+ let depMatch = line.match(/\/deps\/([^:]+)\.js/);
878
+ depMatch && stackDeps.add(depMatch[1]);
879
+ }
880
+ return {
881
+ message,
882
+ stack,
883
+ normalizedMessage,
884
+ normalizedStack,
885
+ stackDeps
886
+ };
887
+ }
888
+ var CATEGORIZATION_RULES = [
889
+ {
890
+ category: ERROR_CATEGORIES.MODULE_IMPORT_ERROR,
891
+ priority: 100,
892
+ match: (ctx) => ctx.normalizedMessage.includes("cannot find module") || ctx.normalizedMessage.includes("module not found") || ctx.normalizedMessage.includes("cannot resolve module")
893
+ },
894
+ {
895
+ category: ERROR_CATEGORIES.HOOK_USAGE_ERROR,
896
+ priority: 90,
897
+ match: (ctx) => ctx.normalizedMessage.includes("invalid hook call") || ctx.normalizedMessage.includes("rendered more hooks than") || ctx.normalizedMessage.includes("hooks can only be called")
898
+ },
899
+ {
900
+ category: ERROR_CATEGORIES.MISSING_STATE_PROVIDER,
901
+ priority: 85,
902
+ match: (ctx) => Array.from(ctx.stackDeps).some(isStateManagementPackage) && (ctx.normalizedMessage.includes("context") || ctx.normalizedMessage.includes("undefined") || ctx.normalizedMessage.includes("null"))
903
+ },
904
+ {
905
+ category: ERROR_CATEGORIES.MISSING_ROUTER_PROVIDER,
906
+ priority: 85,
907
+ match: (ctx) => Array.from(ctx.stackDeps).some(isRouterPackage) || ctx.normalizedMessage.includes("usenavigate") || ctx.normalizedMessage.includes("router")
908
+ },
909
+ {
910
+ category: ERROR_CATEGORIES.SERVER_COMPONENTS_ERROR,
911
+ priority: 85,
912
+ match: (ctx) => ctx.normalizedMessage.includes("server components") || ctx.normalizedMessage.includes("use client") || ctx.normalizedMessage.includes("async/await") && ctx.normalizedMessage.includes("not supported")
913
+ },
914
+ {
915
+ category: ERROR_CATEGORIES.MISSING_THEME_PROVIDER,
916
+ priority: 80,
917
+ match: (ctx) => Array.from(ctx.stackDeps).some(isStylingPackage) && (ctx.normalizedMessage.includes("theme") || ctx.normalizedMessage.includes("undefined")) || ctx.normalizedMessage.includes("usetheme") || ctx.normalizedMessage.includes("theme") && ctx.normalizedMessage.includes("provider")
918
+ },
919
+ {
920
+ category: ERROR_CATEGORIES.MISSING_TRANSLATION_PROVIDER,
921
+ priority: 80,
922
+ match: (ctx) => Array.from(ctx.stackDeps).some(isI18nPackage) || ctx.normalizedMessage.includes("i18n") || ctx.normalizedMessage.includes("translation") || ctx.normalizedMessage.includes("locale")
923
+ },
924
+ {
925
+ category: ERROR_CATEGORIES.MISSING_PORTAL_ROOT,
926
+ priority: 70,
927
+ match: (ctx) => ctx.normalizedMessage.includes("portal") && (ctx.normalizedMessage.includes("container") || ctx.normalizedMessage.includes("root")) && (ctx.normalizedMessage.includes("null") || ctx.normalizedMessage.includes("not found"))
928
+ },
929
+ {
930
+ category: ERROR_CATEGORIES.MISSING_PROVIDER,
931
+ priority: 60,
932
+ match: (ctx) => ctx.normalizedMessage.includes("use") && ctx.normalizedMessage.includes("provider") || ctx.normalizedMessage.includes("<provider>") || (ctx.normalizedMessage.includes("could not find") || ctx.normalizedMessage.includes("missing")) && ctx.normalizedMessage.includes("context") || ctx.normalizedMessage.includes("usecontext") && (ctx.normalizedMessage.includes("null") || ctx.normalizedMessage.includes("undefined"))
933
+ },
934
+ {
935
+ category: ERROR_CATEGORIES.COMPONENT_RENDER_ERROR,
936
+ priority: 10,
937
+ match: (ctx) => ctx.normalizedMessage.includes("cannot read") || ctx.normalizedMessage.includes("undefined is not a function") || ctx.normalizedMessage.includes("render")
938
+ }
939
+ ], RULES = CATEGORIZATION_RULES.sort((a, b) => b.priority - a.priority);
940
+ function categorizeError(message, stack) {
941
+ let ctx = buildErrorContext(message, stack), rule = RULES.find((r) => r.match(ctx));
942
+ if (!rule)
943
+ return { category: ERROR_CATEGORIES.UNKNOWN_ERROR, matchedDependencies: [] };
944
+ let matchedDependencies = getMatchedDependencies(rule.category, ctx);
945
+ return { category: rule.category, matchedDependencies };
946
+ }
947
+ function getMatchedDependencies(category, ctx) {
948
+ switch (category) {
949
+ case ERROR_CATEGORIES.MISSING_STATE_PROVIDER:
950
+ return Array.from(ctx.stackDeps).filter(isStateManagementPackage);
951
+ case ERROR_CATEGORIES.MISSING_ROUTER_PROVIDER:
952
+ return Array.from(ctx.stackDeps).filter(isRouterPackage);
953
+ case ERROR_CATEGORIES.MISSING_THEME_PROVIDER:
954
+ return Array.from(ctx.stackDeps).filter(isStylingPackage);
955
+ case ERROR_CATEGORIES.MISSING_TRANSLATION_PROVIDER:
956
+ return Array.from(ctx.stackDeps).filter(isI18nPackage);
957
+ default:
958
+ return [];
959
+ }
960
+ }
961
+ function getCategoryDescription(category) {
962
+ switch (category) {
963
+ case ERROR_CATEGORIES.MISSING_STATE_PROVIDER:
964
+ return "Component attempted to access shared state without a state management provider";
965
+ case ERROR_CATEGORIES.MISSING_ROUTER_PROVIDER:
966
+ return "Component attempted to access routing context without a router provider";
967
+ case ERROR_CATEGORIES.MISSING_THEME_PROVIDER:
968
+ return "Component attempted to access theme values without a theme provider";
969
+ case ERROR_CATEGORIES.MISSING_TRANSLATION_PROVIDER:
970
+ return "Component attempted to access translations without a translation provider";
971
+ case ERROR_CATEGORIES.MISSING_PROVIDER:
972
+ return "Component attempted to access React context without a matching provider";
973
+ case ERROR_CATEGORIES.MISSING_PORTAL_ROOT:
974
+ return "Component attempted to render a portal without a valid DOM container";
975
+ case ERROR_CATEGORIES.HOOK_USAGE_ERROR:
976
+ return "React hook was used incorrectly";
977
+ case ERROR_CATEGORIES.MODULE_IMPORT_ERROR:
978
+ return "A required dependency could not be resolved";
979
+ case ERROR_CATEGORIES.COMPONENT_RENDER_ERROR:
980
+ return "Component failed during render due to a runtime error";
981
+ case ERROR_CATEGORIES.SERVER_COMPONENTS_ERROR:
982
+ return "Server components usage in the browser";
983
+ default:
984
+ return "Error could not be categorized";
985
+ }
986
+ }
987
+
988
+ // src/core-server/utils/ghost-stories/parse-vitest-report.ts
989
+ function extractCategorizedErrors(testResults) {
990
+ let failed = testResults.filter((r) => r.status === "FAIL" && r.error), map = /* @__PURE__ */ new Map(), uniqueErrorMessages = /* @__PURE__ */ new Set();
991
+ for (let r of failed) {
992
+ let { category, matchedDependencies } = categorizeError(r.error, r.stack);
993
+ map.has(category) || map.set(category, { count: 0, matchedDependencies: /* @__PURE__ */ new Set() });
994
+ let data = map.get(category);
995
+ data.count++, matchedDependencies.forEach((dep) => data.matchedDependencies.add(dep)), uniqueErrorMessages.add(r.error);
996
+ }
997
+ let categorizedErrors = Array.from(map.entries()).reduce(
998
+ (acc, [category, data]) => (acc[category] = {
999
+ description: getCategoryDescription(category),
1000
+ count: data.count,
1001
+ matchedDependencies: Array.from(data.matchedDependencies).sort()
1002
+ }, acc),
1003
+ {}
1004
+ );
1005
+ return {
1006
+ totalErrors: failed.length,
1007
+ uniqueErrorCount: uniqueErrorMessages.size,
1008
+ categorizedErrors
1009
+ };
1010
+ }
1011
+ function parseVitestResults(testResults) {
1012
+ let storyTestResults = [], passedButEmptyRender = 0;
1013
+ for (let testSuite of testResults.testResults)
1014
+ for (let assertion of testSuite.assertionResults) {
1015
+ let storyId = assertion.meta?.storyId || assertion.fullName, status = assertion.status === "passed" ? "PASS" : assertion.status === "failed" ? "FAIL" : "PENDING", hasEmptyRender = assertion.meta?.reports?.some(
1016
+ (report) => report.type === "render-analysis" && report.result?.emptyRender === !0
1017
+ );
1018
+ status === "PASS" && hasEmptyRender && passedButEmptyRender++;
1019
+ let error, stack;
1020
+ assertion.failureMessages && assertion.failureMessages.length > 0 && (stack = assertion.failureMessages[0], error = stack?.split(`
1021
+ `)[0]), storyTestResults.push({
1022
+ storyId,
1023
+ status,
1024
+ error,
1025
+ stack
1026
+ });
1027
+ }
1028
+ let total = testResults.numTotalTests, passed = testResults.numPassedTests, failed = testResults.numFailedTests, successRate = total > 0 ? parseFloat((passed / total).toFixed(2)) : 0, failureRate = total > 0 ? parseFloat((failed / total).toFixed(2)) : 0, successRateWithoutEmptyRender = total > 0 ? parseFloat(((passed - passedButEmptyRender) / total).toFixed(2)) : 0, errorClassification = extractCategorizedErrors(storyTestResults), categorizedErrors = errorClassification.categorizedErrors, summary = {
1029
+ total,
1030
+ passed,
1031
+ passedButEmptyRender,
1032
+ failed,
1033
+ successRate,
1034
+ successRateWithoutEmptyRender,
1035
+ failureRate,
1036
+ uniqueErrorCount: errorClassification.uniqueErrorCount,
1037
+ categorizedErrors
1038
+ };
1039
+ return {
1040
+ success: testResults.success,
1041
+ summary
1042
+ };
1043
+ }
1044
+
1045
+ // src/core-server/utils/ghost-stories/run-story-tests.ts
1046
+ async function runStoryTests(componentFilePaths) {
1047
+ try {
1048
+ let cacheDir = resolvePathInStorybookCache("ghost-stories-tests");
1049
+ await mkdir(cacheDir, { recursive: !0 });
1050
+ let timestamp = Date.now(), outputFile = join(cacheDir, `test-results-${timestamp}.json`), startTime = Date.now(), testFailureMessage;
1051
+ try {
1052
+ await executeCommand({
1053
+ command: "npx",
1054
+ args: [
1055
+ "vitest",
1056
+ "run",
1057
+ "--reporter=json",
1058
+ "--testTimeout=1000",
1059
+ `--outputFile=${outputFile}`,
1060
+ ...componentFilePaths
1061
+ ],
1062
+ stdio: "pipe",
1063
+ env: {
1064
+ STORYBOOK_COMPONENT_PATHS: componentFilePaths.join(";")
1065
+ }
1066
+ });
1067
+ } catch (error) {
1068
+ let errorMessage = (error.stderr || String(error) || "").toLowerCase();
1069
+ errorMessage.includes("browsertype.launch") ? testFailureMessage = "Playwright is not installed" : errorMessage.includes("startup error") ? testFailureMessage = "Startup Error" : errorMessage.includes("no tests found") ? testFailureMessage = "No tests found" : errorMessage.includes("test timeout") ? testFailureMessage = "Test timeout" : errorMessage.includes("react-native-web") ? testFailureMessage = "React Native Web error" : errorMessage.includes("unhandled rejection") && (testFailureMessage = "Unhandled Rejection");
1070
+ }
1071
+ let duration = Date.now() - startTime;
1072
+ if (testFailureMessage)
1073
+ return {
1074
+ success: !1,
1075
+ duration,
1076
+ error: testFailureMessage
1077
+ };
1078
+ if (!existsSync(outputFile))
1079
+ return {
1080
+ success: !1,
1081
+ duration,
1082
+ error: "JSON report not found"
1083
+ };
1084
+ let testResults;
1085
+ try {
1086
+ let resultsJson = await readFile3(outputFile, "utf8");
1087
+ testResults = JSON.parse(resultsJson);
1088
+ } catch {
1089
+ return {
1090
+ success: !1,
1091
+ duration,
1092
+ error: "Failed to read or parse JSON report"
1093
+ };
1094
+ }
1095
+ return { ...parseVitestResults(testResults), duration };
1096
+ } catch {
1097
+ return {
1098
+ success: !1,
1099
+ error: "Uncaught error running story tests",
1100
+ duration: 0
1101
+ };
1102
+ }
1103
+ }
1104
+
1105
+ // src/core-server/server-channel/ghost-stories-channel.ts
1106
+ function initGhostStoriesChannel(channel, options, coreOptions) {
1107
+ return coreOptions.disableTelemetry || channel.on(GHOST_STORIES_REQUEST, async () => {
1108
+ let stats = {};
1109
+ try {
1110
+ let ghostRunStart = Date.now(), lastEvents = await getLastEvents(), sessionId = await getSessionId(), lastInit = lastEvents?.init;
1111
+ if (lastEvents?.["ghost-stories"] || lastInit?.body?.sessionId && lastInit?.body?.sessionId !== sessionId)
1112
+ return;
1113
+ let metadata = await getStorybookMetadata(options.configDir), isReactStorybook = metadata?.renderer?.includes("@storybook/react"), hasVitestAddon = !!metadata?.addons && Object.keys(metadata.addons).some(
1114
+ (addonKey) => addonKey.includes("@storybook/addon-vitest")
1115
+ );
1116
+ if (!isReactStorybook || !hasVitestAddon)
1117
+ return;
1118
+ let candidateAnalysisStart = Date.now(), candidatesResult = await getComponentCandidates();
1119
+ if (stats.candidateAnalysisDuration = Date.now() - candidateAnalysisStart, stats.globMatchCount = candidatesResult.globMatchCount, stats.analyzedCount = candidatesResult.analyzedCount ?? 0, stats.avgComplexity = candidatesResult.avgComplexity ?? 0, stats.candidateCount = candidatesResult.candidates.length, candidatesResult.error) {
1120
+ stats.totalRunDuration = Date.now() - ghostRunStart, telemetry3("ghost-stories", {
1121
+ success: !1,
1122
+ error: candidatesResult.error,
1123
+ stats
1124
+ });
1125
+ return;
1126
+ }
1127
+ if (candidatesResult.candidates.length === 0) {
1128
+ stats.totalRunDuration = Date.now() - ghostRunStart, telemetry3("ghost-stories", {
1129
+ success: !1,
1130
+ error: "No candidates found",
1131
+ stats
1132
+ });
1133
+ return;
1134
+ }
1135
+ let testRunResult = await runStoryTests(candidatesResult.candidates);
1136
+ stats.totalRunDuration = Date.now() - ghostRunStart, stats.testRunDuration = testRunResult.duration, telemetry3("ghost-stories", {
1137
+ ...testRunResult.error !== void 0 ? { error: testRunResult.error } : {},
1138
+ success: testRunResult.success,
1139
+ stats,
1140
+ results: testRunResult.summary
1141
+ });
1142
+ } catch (error) {
1143
+ let errorMessage = error instanceof Error ? error.message : String(error);
1144
+ telemetry3("ghost-stories", {
1145
+ success: !1,
1146
+ error: errorMessage,
1147
+ stats
1148
+ });
1149
+ } finally {
1150
+ channel.emit(GHOST_STORIES_RESPONSE);
1151
+ }
1152
+ }), channel;
1153
+ }
1154
+
857
1155
  // src/core-server/server-channel/open-in-editor-channel.ts
858
1156
  var import_launch_editor = __toESM(require_launch_editor(), 1);
859
1157
  import { OPEN_IN_EDITOR_REQUEST, OPEN_IN_EDITOR_RESPONSE } from "storybook/internal/core-events";
860
- import { telemetry as telemetry3 } from "storybook/internal/telemetry";
1158
+ import { telemetry as telemetry4 } from "storybook/internal/telemetry";
861
1159
  async function initOpenInEditorChannel(channel, _options, coreOptions) {
862
1160
  return channel.on(OPEN_IN_EDITOR_REQUEST, async (payload) => {
863
1161
  let sendTelemetry = (data) => {
864
- coreOptions.disableTelemetry || telemetry3("open-in-editor", data);
1162
+ coreOptions.disableTelemetry || telemetry4("open-in-editor", data);
865
1163
  };
866
1164
  try {
867
1165
  let { file: targetFile, line, column } = payload;
@@ -890,9 +1188,9 @@ async function initOpenInEditorChannel(channel, _options, coreOptions) {
890
1188
 
891
1189
  // src/core-server/server-channel/preview-initialized-channel.ts
892
1190
  import { PREVIEW_INITIALIZED } from "storybook/internal/core-events";
893
- import { telemetry as telemetry4 } from "storybook/internal/telemetry";
894
- import { getLastEvents } from "storybook/internal/telemetry";
895
- import { getSessionId } from "storybook/internal/telemetry";
1191
+ import { telemetry as telemetry5 } from "storybook/internal/telemetry";
1192
+ import { getLastEvents as getLastEvents2 } from "storybook/internal/telemetry";
1193
+ import { getSessionId as getSessionId2 } from "storybook/internal/telemetry";
896
1194
  var makePayload = (userAgent, lastInit, sessionId) => {
897
1195
  let payload = {
898
1196
  userAgent,
@@ -905,10 +1203,10 @@ function initPreviewInitializedChannel(channel, options, _coreConfig) {
905
1203
  channel.on(PREVIEW_INITIALIZED, async ({ userAgent }) => {
906
1204
  if (!options.disableTelemetry)
907
1205
  try {
908
- let sessionId = await getSessionId(), lastEvents = await getLastEvents(), lastInit = lastEvents.init;
1206
+ let sessionId = await getSessionId2(), lastEvents = await getLastEvents2(), lastInit = lastEvents.init;
909
1207
  if (!lastEvents["preview-first-load"]) {
910
1208
  let payload = makePayload(userAgent, lastInit, sessionId);
911
- telemetry4("preview-first-load", payload);
1209
+ telemetry5("preview-first-load", payload);
912
1210
  }
913
1211
  } catch {
914
1212
  }
@@ -916,10 +1214,10 @@ function initPreviewInitializedChannel(channel, options, _coreConfig) {
916
1214
  }
917
1215
 
918
1216
  // src/core-server/utils/checklist.ts
919
- import { createFileSystemCache, resolvePathInStorybookCache } from "storybook/internal/common";
1217
+ import { createFileSystemCache, resolvePathInStorybookCache as resolvePathInStorybookCache2 } from "storybook/internal/common";
920
1218
  import { experimental_UniversalStore } from "storybook/internal/core-server";
921
1219
  import { logger } from "storybook/internal/node-logger";
922
- import { telemetry as telemetry5 } from "storybook/internal/telemetry";
1220
+ import { telemetry as telemetry6 } from "storybook/internal/telemetry";
923
1221
 
924
1222
  // ../../node_modules/es-toolkit/dist/predicate/isPrimitive.mjs
925
1223
  function isPrimitive(value) {
@@ -1040,7 +1338,7 @@ async function initializeChecklist() {
1040
1338
  ...UNIVERSAL_CHECKLIST_STORE_OPTIONS,
1041
1339
  leader: !0
1042
1340
  }), cache = createFileSystemCache({
1043
- basePath: resolvePathInStorybookCache("checklist"),
1341
+ basePath: resolvePathInStorybookCache2("checklist"),
1044
1342
  ns: "storybook"
1045
1343
  }), [[userState, saveUserState], [projectState, saveProjectState]] = await Promise.all([
1046
1344
  globalSettings().then((settings) => {
@@ -1077,13 +1375,13 @@ async function initializeChecklist() {
1077
1375
  },
1078
1376
  { mutedItems: [], statusItems: [] }
1079
1377
  );
1080
- mutedItems.length > 0 && telemetry5("onboarding-checklist-muted", {
1378
+ mutedItems.length > 0 && telemetry6("onboarding-checklist-muted", {
1081
1379
  items: mutedItems,
1082
1380
  completedItems: entries.reduce((acc, [id, { status }]) => status === "done" || status === "accepted" ? acc.concat([id]) : acc, []),
1083
1381
  skippedItems: entries.reduce((acc, [id, { status }]) => status === "skipped" ? acc.concat([id]) : acc, [])
1084
1382
  }), statusItems.forEach((item) => {
1085
1383
  let { status } = state.items[item];
1086
- telemetry5("onboarding-checklist-status", { item, status });
1384
+ telemetry6("onboarding-checklist-status", { item, status });
1087
1385
  });
1088
1386
  });
1089
1387
  } catch (err) {
@@ -1100,8 +1398,8 @@ var defaultStaticDirs = [
1100
1398
  ], defaultFavicon = join(resolvePackageDir("storybook"), "assets/browser/favicon.svg");
1101
1399
 
1102
1400
  // src/core-server/utils/save-story/save-story.ts
1103
- import { writeFile as writeFile2 } from "node:fs/promises";
1104
- import { basename as basename2, join as join4 } from "node:path";
1401
+ import { writeFile } from "node:fs/promises";
1402
+ import { basename, join as join3 } from "node:path";
1105
1403
  import { formatFileContent } from "storybook/internal/common";
1106
1404
  import {
1107
1405
  SAVE_STORY_REQUEST,
@@ -1111,10 +1409,10 @@ import {
1111
1409
  import { storyNameFromExport, toId } from "storybook/internal/csf";
1112
1410
  import { printCsf, readCsf } from "storybook/internal/csf-tools";
1113
1411
  import { logger as logger2 } from "storybook/internal/node-logger";
1114
- import { isExampleStoryId, telemetry as telemetry6 } from "storybook/internal/telemetry";
1412
+ import { isExampleStoryId, telemetry as telemetry7 } from "storybook/internal/telemetry";
1115
1413
 
1116
1414
  // src/core-server/utils/save-story/duplicate-story-with-new-name.ts
1117
- import { types as t2, traverse } from "storybook/internal/babel";
1415
+ import { types as t2, traverse as traverse2 } from "storybook/internal/babel";
1118
1416
 
1119
1417
  // src/core-server/utils/save-story/utils.ts
1120
1418
  var SaveStoryError = class extends Error {
@@ -1126,7 +1424,7 @@ var duplicateStoryWithNewName = (csfFile, storyName, newStoryName) => {
1126
1424
  if (!cloned)
1127
1425
  throw new SaveStoryError("cannot clone Node");
1128
1426
  let found = !1;
1129
- if (traverse(cloned, {
1427
+ if (traverse2(cloned, {
1130
1428
  Identifier(path) {
1131
1429
  found || path.node.name === storyName && (found = !0, path.node.name = newStoryName);
1132
1430
  },
@@ -1137,7 +1435,7 @@ var duplicateStoryWithNewName = (csfFile, storyName, newStoryName) => {
1137
1435
  noScope: !0
1138
1436
  }), !(t2.isCallExpression(cloned.init) && t2.isMemberExpression(cloned.init.callee) && t2.isIdentifier(cloned.init.callee.property) && cloned.init.callee.property.name === "story") && (t2.isArrowFunctionExpression(cloned.init) || t2.isCallExpression(cloned.init)))
1139
1437
  throw new SaveStoryError("Creating a new story based on a CSF2 story is not supported");
1140
- return traverse(csfFile._ast, {
1438
+ return traverse2(csfFile._ast, {
1141
1439
  Program(path) {
1142
1440
  path.pushContainer(
1143
1441
  "body",
@@ -1148,7 +1446,7 @@ var duplicateStoryWithNewName = (csfFile, storyName, newStoryName) => {
1148
1446
  };
1149
1447
 
1150
1448
  // src/core-server/utils/save-story/update-args-in-csf-file.ts
1151
- import { types as t4, traverse as traverse2 } from "storybook/internal/babel";
1449
+ import { types as t4, traverse as traverse3 } from "storybook/internal/babel";
1152
1450
 
1153
1451
  // src/core-server/utils/save-story/valueToAST.ts
1154
1452
  import { parser as parser2, types as t3 } from "storybook/internal/babel";
@@ -1221,7 +1519,7 @@ var updateArgsInCsfFile = async (node, input) => {
1221
1519
  );
1222
1520
  return;
1223
1521
  }
1224
- traverse2(node, {
1522
+ traverse3(node, {
1225
1523
  ObjectExpression(path) {
1226
1524
  if (found)
1227
1525
  return;
@@ -1279,7 +1577,7 @@ function initializeSaveStory(channel, options, coreConfig) {
1279
1577
  channel.on(SAVE_STORY_REQUEST, async ({ id, payload }) => {
1280
1578
  let { csfId, importPath, args, name } = payload, newStoryId, newStoryName, sourceFileName, sourceFilePath, sourceStoryName;
1281
1579
  try {
1282
- sourceFileName = basename2(importPath), sourceFilePath = join4(process.cwd(), importPath);
1580
+ sourceFileName = basename(importPath), sourceFilePath = join3(process.cwd(), importPath);
1283
1581
  let csf = await readCsf(sourceFilePath, {
1284
1582
  makeTitle: (userTitle) => userTitle || "myTitle"
1285
1583
  }), parsed = csf.parse(), stories = Object.entries(parsed._stories), [componentId, storyId] = csfId.split("--");
@@ -1301,7 +1599,7 @@ function initializeSaveStory(channel, options, coreConfig) {
1301
1599
  new Promise((resolve) => {
1302
1600
  channel.on(STORY_RENDERED, resolve), setTimeout(() => resolve(channel.off(STORY_RENDERED, resolve)), 3e3);
1303
1601
  }),
1304
- writeFile2(sourceFilePath, code)
1602
+ writeFile(sourceFilePath, code)
1305
1603
  ]), channel.emit(SAVE_STORY_RESPONSE, {
1306
1604
  id,
1307
1605
  success: !0,
@@ -1318,7 +1616,7 @@ function initializeSaveStory(channel, options, coreConfig) {
1318
1616
  error: null
1319
1617
  });
1320
1618
  let isCLIExample = isExampleStoryId(newStoryId ?? csfId);
1321
- !coreConfig.disableTelemetry && !isCLIExample && await telemetry6("save-story", {
1619
+ !coreConfig.disableTelemetry && !isCLIExample && await telemetry7("save-story", {
1322
1620
  action: name ? "createStory" : "updateStory",
1323
1621
  success: !0
1324
1622
  });
@@ -1330,7 +1628,7 @@ function initializeSaveStory(channel, options, coreConfig) {
1330
1628
  }), logger2.error(
1331
1629
  `Error writing to ${sourceFilePath}:
1332
1630
  ${error.stack || error.message || error.toString()}`
1333
- ), !coreConfig.disableTelemetry && !(error instanceof SaveStoryError) && await telemetry6("save-story", {
1631
+ ), !coreConfig.disableTelemetry && !(error instanceof SaveStoryError) && await telemetry7("save-story", {
1334
1632
  action: name ? "createStory" : "updateStory",
1335
1633
  success: !1,
1336
1634
  error
@@ -1340,8 +1638,8 @@ ${error.stack || error.message || error.toString()}`
1340
1638
  }
1341
1639
 
1342
1640
  // src/core-server/utils/whats-new.ts
1343
- import { writeFile as writeFile3 } from "node:fs/promises";
1344
- import { findConfigFile as findConfigFile2, loadMainConfig } from "storybook/internal/common";
1641
+ import { writeFile as writeFile2 } from "node:fs/promises";
1642
+ import { findConfigFile, loadMainConfig } from "storybook/internal/common";
1345
1643
  import {
1346
1644
  REQUEST_WHATS_NEW_DATA,
1347
1645
  RESULT_WHATS_NEW_DATA,
@@ -1351,7 +1649,7 @@ import {
1351
1649
  } from "storybook/internal/core-events";
1352
1650
  import { printConfig, readConfig } from "storybook/internal/csf-tools";
1353
1651
  import { logger as logger3 } from "storybook/internal/node-logger";
1354
- import { telemetry as telemetry7 } from "storybook/internal/telemetry";
1652
+ import { telemetry as telemetry8 } from "storybook/internal/telemetry";
1355
1653
  var WHATS_NEW_CACHE = "whats-new-cache", WHATS_NEW_URL = "https://storybook.js.org/whats-new/v1";
1356
1654
  function initializeWhatsNew(channel, options, coreOptions) {
1357
1655
  channel.on(SET_WHATS_NEW_CACHE, async (data) => {
@@ -1381,14 +1679,14 @@ function initializeWhatsNew(channel, options, coreOptions) {
1381
1679
  async ({ disableWhatsNewNotifications }) => {
1382
1680
  let isTelemetryEnabled = coreOptions.disableTelemetry !== !0;
1383
1681
  try {
1384
- let mainPath = findConfigFile2("main", options.configDir);
1682
+ let mainPath = findConfigFile("main", options.configDir);
1385
1683
  invariant(mainPath, `unable to find Storybook main file in ${options.configDir}`);
1386
1684
  let main = await readConfig(mainPath);
1387
1685
  if (!main._exportsObject)
1388
1686
  throw new Error(
1389
1687
  "Unable to parse Storybook main file while trying to read 'core' property"
1390
1688
  );
1391
- main.setFieldValue(["core", "disableWhatsNewNotifications"], disableWhatsNewNotifications), await writeFile3(mainPath, printConfig(main).code), isTelemetryEnabled && await telemetry7("core-config", { disableWhatsNewNotifications });
1689
+ main.setFieldValue(["core", "disableWhatsNewNotifications"], disableWhatsNewNotifications), await writeFile2(mainPath, printConfig(main).code), isTelemetryEnabled && await telemetry8("core-config", { disableWhatsNewNotifications });
1392
1690
  } catch (error) {
1393
1691
  invariant(error instanceof Error), isTelemetryEnabled && await sendTelemetryError(error, "core-config", {
1394
1692
  cliOptions: options,
@@ -1419,9 +1717,9 @@ var interpolate = (string, data = {}) => Object.entries(data).reduce((acc, [k, v
1419
1717
  workingDir: process.cwd(),
1420
1718
  directory: dir
1421
1719
  }) : dir, { staticPath, targetEndpoint } = parseStaticDir(normalizedDir);
1422
- return ["/favicon.svg", "/favicon.ico"].includes(targetEndpoint) && results.push(staticPath), targetEndpoint === "/" && (results.push(join(staticPath, "favicon.svg")), results.push(join(staticPath, "favicon.ico"))), results.filter((path) => existsSync3(path));
1720
+ return ["/favicon.svg", "/favicon.ico"].includes(targetEndpoint) && results.push(staticPath), targetEndpoint === "/" && (results.push(join(staticPath, "favicon.svg")), results.push(join(staticPath, "favicon.ico"))), results.filter((path) => existsSync2(path));
1423
1721
  }).reduce((l1, l2) => l1.concat(l2), []);
1424
- return faviconPaths.length > 1 && logger4.warn(import_ts_dedent4.dedent`
1722
+ return faviconPaths.length > 1 && logger4.warn(import_ts_dedent.dedent`
1425
1723
  Looks like multiple favicons were detected. Using the first one.
1426
1724
 
1427
1725
  ${faviconPaths.join(", ")}
@@ -1478,7 +1776,7 @@ var interpolate = (string, data = {}) => Object.entries(data).reduce((acc, [k, v
1478
1776
  let removeAddon = removeAddonBase, packageManager = JsPackageManagerFactory.getPackageManager({
1479
1777
  configDir: options.configDir
1480
1778
  });
1481
- return options.disableTelemetry || (removeAddon = async (id, opts) => (await telemetry8("remove", { addon: id, source: "api" }), removeAddonBase(id, { ...opts, packageManager }))), { ...extension, removeAddon };
1779
+ return options.disableTelemetry || (removeAddon = async (id, opts) => (await telemetry9("remove", { addon: id, source: "api" }), removeAddonBase(id, { ...opts, packageManager }))), { ...extension, removeAddon };
1482
1780
  }, core = async (existing, options) => ({
1483
1781
  ...existing,
1484
1782
  disableTelemetry: options.disableTelemetry === !0,
@@ -1505,14 +1803,14 @@ var interpolate = (string, data = {}) => Object.entries(data).reduce((acc, [k, v
1505
1803
  return typeof config == "string" ? {} : typeof config > "u" ? null : config.options;
1506
1804
  }, managerHead = async (_, options) => {
1507
1805
  let location = join(options.configDir, "manager-head.html");
1508
- if (existsSync3(location)) {
1509
- let contents = readFile3(location, { encoding: "utf8" }), interpolations = options.presets.apply("env");
1806
+ if (existsSync2(location)) {
1807
+ let contents = readFile4(location, { encoding: "utf8" }), interpolations = options.presets.apply("env");
1510
1808
  return interpolate(await contents, await interpolations);
1511
1809
  }
1512
1810
  return "";
1513
1811
  }, experimental_serverChannel = async (channel, options) => {
1514
1812
  let coreOptions = await options.presets.apply("core");
1515
- return initializeChecklist(), initializeWhatsNew(channel, options, coreOptions), initializeSaveStory(channel, options, coreOptions), initFileSearchChannel(channel, options, coreOptions), initCreateNewStoryChannel(channel, options, coreOptions), initOpenInEditorChannel(channel, options, coreOptions), initPreviewInitializedChannel(channel, options, coreOptions), channel;
1813
+ return initializeChecklist(), initializeWhatsNew(channel, options, coreOptions), initializeSaveStory(channel, options, coreOptions), initFileSearchChannel(channel, options, coreOptions), initCreateNewStoryChannel(channel, options, coreOptions), initGhostStoriesChannel(channel, options, coreOptions), initOpenInEditorChannel(channel, options, coreOptions), initPreviewInitializedChannel(channel, options, coreOptions), channel;
1516
1814
  }, resolvedReact = async (existing) => {
1517
1815
  try {
1518
1816
  return {