storybook 10.2.0-alpha.15 → 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.
- package/dist/_node-chunks/{builder-manager-SOKYB5NF.js → builder-manager-Q4F5VX5J.js} +14 -12
- package/dist/_node-chunks/{camelcase-SXQWF7PW.js → camelcase-FL6OBJRZ.js} +7 -7
- package/dist/_node-chunks/{chunk-5KEIALUH.js → chunk-25OWI2RR.js} +6 -6
- package/dist/_node-chunks/{chunk-ENNDE4GC.js → chunk-2XSHQN7K.js} +10 -10
- package/dist/_node-chunks/{chunk-E3Y5MHXD.js → chunk-3D4SLKEE.js} +7 -7
- package/dist/_node-chunks/{chunk-FKBWQGIF.js → chunk-5Q5JEISY.js} +6 -6
- package/dist/_node-chunks/{chunk-Q6WUEJ4S.js → chunk-C3FPVGL4.js} +6 -6
- package/dist/_node-chunks/chunk-CBPOKBOR.js +18 -0
- package/dist/_node-chunks/{chunk-2FQAOAQ6.js → chunk-CCJGKJ27.js} +12 -12
- package/dist/_node-chunks/{chunk-MD52RVZX.js → chunk-DJ3RRSJ7.js} +7 -7
- package/dist/_node-chunks/chunk-EG3WZ464.js +23 -0
- package/dist/_node-chunks/{chunk-6SIUW3HU.js → chunk-EYPTVKFI.js} +123 -72
- package/dist/_node-chunks/{chunk-TN3Q52LO.js → chunk-FAARRTOD.js} +6 -6
- package/dist/_node-chunks/{chunk-QPKBPYOY.js → chunk-G7P42ZEY.js} +7 -7
- package/dist/_node-chunks/chunk-GYJ7LPFJ.js +144 -0
- package/dist/_node-chunks/{chunk-BOY3TNPC.js → chunk-IRMNO3QS.js} +9 -9
- package/dist/_node-chunks/{chunk-BRW7NFUP.js → chunk-IWM3WHZE.js} +7 -7
- package/dist/_node-chunks/{chunk-RGWB6DD7.js → chunk-JBRILZWU.js} +6 -6
- package/dist/_node-chunks/{chunk-HFKM7JHQ.js → chunk-KKNWPXMS.js} +6 -6
- package/dist/_node-chunks/{chunk-45UIB4YF.js → chunk-MU4E5UBA.js} +7 -7
- package/dist/_node-chunks/{chunk-274OMYGE.js → chunk-PWI3ORDV.js} +22 -22
- package/dist/_node-chunks/chunk-RGEHGZS6.js +61 -0
- package/dist/_node-chunks/{chunk-KNGN3UEO.js → chunk-V3SFCYKQ.js} +7 -7
- package/dist/_node-chunks/{chunk-4GKVZO2T.js → chunk-VK4OWRKU.js} +9 -9
- package/dist/_node-chunks/{chunk-K4YVLJRS.js → chunk-VT2FICF4.js} +6 -6
- package/dist/_node-chunks/{chunk-SZWIX5YC.js → chunk-VTBZVEBF.js} +529 -142
- package/dist/_node-chunks/{chunk-T57UCO67.js → chunk-XI7HDOMY.js} +7 -7
- package/dist/_node-chunks/{chunk-PI7P5HFH.js → chunk-XTIFAWOB.js} +250 -14
- package/dist/_node-chunks/{chunk-AIIQJ6UR.js → chunk-XYONORVT.js} +7 -7
- package/dist/_node-chunks/{chunk-MQZLLJRG.js → chunk-ZOUBYBCH.js} +9 -9
- package/dist/_node-chunks/{globby-LGQ5P2JB.js → globby-4BDMCAAD.js} +9 -9
- package/dist/_node-chunks/{lib-5LBLULG3.js → lib-XS2XQMOO.js} +7 -7
- package/dist/_node-chunks/{mdx-N42X6CFJ-TAPL5IEO.js → mdx-N42X6CFJ-JFERGMQH.js} +8 -8
- package/dist/_node-chunks/{p-limit-GTMOHYQF.js → p-limit-I4CLTHWH.js} +7 -7
- package/dist/babel/index.js +10 -10
- package/dist/bin/core.js +12 -12
- package/dist/bin/dispatcher.js +11 -11
- package/dist/bin/loader.js +9 -9
- package/dist/cli/index.js +18 -18
- package/dist/common/index.js +19 -19
- package/dist/core-events/index.d.ts +19 -3
- package/dist/core-events/index.js +5 -1
- package/dist/core-server/index.d.ts +64 -2
- package/dist/core-server/index.js +37 -34
- package/dist/core-server/presets/common-override-preset.js +11 -11
- package/dist/core-server/presets/common-preset.js +532 -234
- package/dist/csf/index.d.ts +139 -9
- package/dist/csf/index.js +41 -14
- package/dist/csf-tools/index.d.ts +19 -1
- package/dist/csf-tools/index.js +11 -10
- package/dist/manager/globals-runtime.js +6 -2
- package/dist/manager/runtime.js +17 -98
- package/dist/manager-api/index.js +1 -1
- package/dist/mocking-utils/index.js +8 -8
- package/dist/node-logger/index.js +9 -9
- package/dist/preview/runtime.js +33 -6
- package/dist/preview-api/index.d.ts +68 -67
- package/dist/server-errors.js +11 -11
- package/dist/telemetry/index.d.ts +13 -2
- package/dist/telemetry/index.js +23 -22
- package/package.json +1 -1
- package/dist/_node-chunks/chunk-2BHD5YKF.js +0 -35
- package/dist/_node-chunks/chunk-MM7Z4SG7.js +0 -23
- package/dist/_node-chunks/chunk-TYSSQECX.js +0 -61
- package/dist/_node-chunks/chunk-YP34ARUD.js +0 -18
|
@@ -1,54 +1,63 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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 =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
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-
|
|
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-
|
|
18
|
-
import "../../_node-chunks/chunk-
|
|
19
|
-
import "../../_node-chunks/chunk-
|
|
20
|
-
import "../../_node-chunks/chunk-
|
|
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-
|
|
32
|
+
} from "../../_node-chunks/chunk-VK4OWRKU.js";
|
|
24
33
|
import {
|
|
25
34
|
invariant
|
|
26
|
-
} from "../../_node-chunks/chunk-
|
|
27
|
-
import "../../_node-chunks/chunk-
|
|
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-
|
|
39
|
+
} from "../../_node-chunks/chunk-3D4SLKEE.js";
|
|
31
40
|
import {
|
|
32
41
|
isAbsolute,
|
|
33
42
|
join
|
|
34
|
-
} from "../../_node-chunks/chunk-
|
|
43
|
+
} from "../../_node-chunks/chunk-5Q5JEISY.js";
|
|
35
44
|
import {
|
|
36
|
-
|
|
37
|
-
} from "../../_node-chunks/chunk-
|
|
38
|
-
import "../../_node-chunks/chunk-
|
|
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-
|
|
42
|
-
import "../../_node-chunks/chunk-
|
|
43
|
-
import "../../_node-chunks/chunk-
|
|
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-
|
|
55
|
+
} from "../../_node-chunks/chunk-XI7HDOMY.js";
|
|
47
56
|
import {
|
|
48
57
|
__commonJS,
|
|
49
58
|
__require,
|
|
50
59
|
__toESM
|
|
51
|
-
} from "../../_node-chunks/chunk-
|
|
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
|
|
476
|
-
import { readFile as
|
|
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
|
|
490
|
-
var
|
|
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-SXQWF7PW.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
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
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
|
|
672
|
-
import { dirname
|
|
673
|
-
import { extractRenderer, getFrameworkName
|
|
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-
|
|
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
|
|
675
|
+
let frameworkName = await getFrameworkName(options), rendererName = await extractRenderer(frameworkName), entries = (await searchFiles({
|
|
807
676
|
searchQuery,
|
|
808
|
-
cwd:
|
|
677
|
+
cwd: getProjectRoot()
|
|
809
678
|
})).map(async (file) => {
|
|
810
679
|
let parser3 = getParser(rendererName);
|
|
811
680
|
try {
|
|
812
|
-
let content = await
|
|
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
|
|
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 ||
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
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 &&
|
|
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
|
-
|
|
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
|
|
1104
|
-
import { basename
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
1344
|
-
import { findConfigFile
|
|
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
|
|
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 =
|
|
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
|
|
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) =>
|
|
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(
|
|
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
|
|
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 (
|
|
1509
|
-
let contents =
|
|
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 {
|