storybook 10.2.0-alpha.16 → 10.2.0-alpha.18
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-DQ6DNDHX.js → builder-manager-RC5VXLE2.js} +14 -12
- package/dist/_node-chunks/{camelcase-ILOVTISA.js → camelcase-3YERF6B7.js} +7 -7
- package/dist/_node-chunks/chunk-2H33L3XJ.js +61 -0
- package/dist/_node-chunks/{chunk-47ZRY4XW.js → chunk-2M7TBZBZ.js} +6 -6
- package/dist/_node-chunks/{chunk-TTACLBSG.js → chunk-4HG57EIN.js} +7 -7
- package/dist/_node-chunks/{chunk-CFXIZS6A.js → chunk-4PWGJYBL.js} +7 -7
- package/dist/_node-chunks/{chunk-K6FMM5LS.js → chunk-54FLVGBQ.js} +6 -6
- package/dist/_node-chunks/{chunk-3PMH6BEP.js → chunk-5BYTBW23.js} +6 -6
- package/dist/_node-chunks/{chunk-TDBTCAEB.js → chunk-5QNVOHBZ.js} +125 -73
- package/dist/_node-chunks/{chunk-SWN4HCJE.js → chunk-6TOW3ZMZ.js} +6 -6
- package/dist/_node-chunks/{chunk-FNQ5WLS5.js → chunk-A2364FS2.js} +7 -7
- package/dist/_node-chunks/{chunk-ZN5DGHF3.js → chunk-BWA66NDS.js} +10 -10
- package/dist/_node-chunks/{chunk-RIEIAV32.js → chunk-DIZCVGPK.js} +7 -7
- package/dist/_node-chunks/{chunk-PGYIGHRK.js → chunk-F347QVLI.js} +9 -9
- package/dist/_node-chunks/chunk-GJRLPTXZ.js +144 -0
- package/dist/_node-chunks/{chunk-LOJ73E6E.js → chunk-H4TYBETM.js} +9 -9
- package/dist/_node-chunks/{chunk-IVYTDHSW.js → chunk-HXE2FZ3F.js} +7 -7
- package/dist/_node-chunks/{chunk-KAAWGCHX.js → chunk-IHBEBZVB.js} +12 -12
- package/dist/_node-chunks/chunk-JK62DOZL.js +23 -0
- package/dist/_node-chunks/{chunk-WVXPIXUS.js → chunk-LMYIILVH.js} +7 -7
- package/dist/_node-chunks/{chunk-XWGABQX7.js → chunk-N73BCSUL.js} +6 -6
- package/dist/_node-chunks/{chunk-OKUHCLLJ.js → chunk-OT3P3RDM.js} +9 -9
- package/dist/_node-chunks/{chunk-JXU4P6K3.js → chunk-OZGI27C5.js} +6 -6
- package/dist/_node-chunks/{chunk-6QEWR44T.js → chunk-OZHRGJKY.js} +7 -7
- package/dist/_node-chunks/chunk-Q3WHGQXN.js +18 -0
- package/dist/_node-chunks/{chunk-TLGG6YAX.js → chunk-QNYGS5WG.js} +511 -127
- package/dist/_node-chunks/{chunk-WIOSV6HC.js → chunk-QXDUEJWP.js} +6 -6
- package/dist/_node-chunks/{chunk-M6AUSQA3.js → chunk-USLMTVEL.js} +22 -22
- package/dist/_node-chunks/{chunk-YFUVKP3W.js → chunk-XH6HLMNG.js} +7 -7
- package/dist/_node-chunks/{chunk-XJMJA2L4.js → chunk-ZUTW3EKD.js} +250 -14
- package/dist/_node-chunks/{globby-A35XB3PP.js → globby-IVEL6LAU.js} +9 -9
- package/dist/_node-chunks/{lib-D5I6ETBH.js → lib-IDUN2DHZ.js} +7 -7
- package/dist/_node-chunks/{mdx-N42X6CFJ-DZ4EAFAE.js → mdx-N42X6CFJ-V7NAUWUX.js} +8 -8
- package/dist/_node-chunks/{p-limit-2CRKZRXN.js → p-limit-VA3OYXXM.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/components/index.d.ts +2 -1
- package/dist/components/index.js +55 -60
- package/dist/core-events/index.d.ts +19 -3
- package/dist/core-events/index.js +5 -1
- package/dist/core-server/index.d.ts +69 -2
- package/dist/core-server/index.js +38 -34
- package/dist/core-server/presets/common-override-preset.js +11 -11
- package/dist/core-server/presets/common-preset.js +519 -234
- package/dist/csf/index.d.ts +15 -3
- package/dist/csf/index.js +37 -13
- package/dist/csf-tools/index.d.ts +19 -1
- package/dist/csf-tools/index.js +11 -10
- package/dist/manager/globals-runtime.js +107 -81
- package/dist/manager/runtime.js +829 -167
- package/dist/manager-api/index.d.ts +2 -0
- package/dist/manager-api/index.js +10 -2
- 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 +14 -2
- package/dist/telemetry/index.js +23 -22
- package/dist/theming/index.js +16 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +2 -1
- package/dist/_node-chunks/chunk-5E2HAJXY.js +0 -35
- package/dist/_node-chunks/chunk-DGLVYUKY.js +0 -61
- package/dist/_node-chunks/chunk-MSK3YTQT.js +0 -23
- package/dist/_node-chunks/chunk-SPPXK6CQ.js +0 -18
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_bfa4dw0yocr from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_bfa4dw0yocr from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_bfa4dw0yocr from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_bfa4dw0yocr.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_bfa4dw0yocr.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_bfa4dw0yocr.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 {
|
|
13
|
-
Tag
|
|
14
|
-
} from "./chunk-5E2HAJXY.js";
|
|
15
12
|
import {
|
|
16
13
|
require_dist
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-XH6HLMNG.js";
|
|
18
15
|
import {
|
|
19
16
|
__toESM
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5BYTBW23.js";
|
|
21
18
|
|
|
22
19
|
// src/csf-tools/CsfFile.ts
|
|
23
20
|
var import_ts_dedent = __toESM(require_dist(), 1);
|
|
@@ -33,6 +30,26 @@ import {
|
|
|
33
30
|
import { isExportStory, storyNameFromExport, toId, toTestId } from "storybook/internal/csf";
|
|
34
31
|
import { logger } from "storybook/internal/node-logger";
|
|
35
32
|
|
|
33
|
+
// src/shared/constants/tags.ts
|
|
34
|
+
var Tag = {
|
|
35
|
+
/** Indicates that autodocs should be generated for this component */
|
|
36
|
+
AUTODOCS: "autodocs",
|
|
37
|
+
/** MDX documentation attached to a component's stories file */
|
|
38
|
+
ATTACHED_MDX: "attached-mdx",
|
|
39
|
+
/** Standalone MDX documentation not attached to stories */
|
|
40
|
+
UNATTACHED_MDX: "unattached-mdx",
|
|
41
|
+
/** Story has a play function */
|
|
42
|
+
PLAY_FN: "play-fn",
|
|
43
|
+
/** Story has a test function */
|
|
44
|
+
TEST_FN: "test-fn",
|
|
45
|
+
/** Development environment tag */
|
|
46
|
+
DEV: "dev",
|
|
47
|
+
/** Test environment tag */
|
|
48
|
+
TEST: "test",
|
|
49
|
+
/** Manifest generation tag */
|
|
50
|
+
MANIFEST: "manifest"
|
|
51
|
+
};
|
|
52
|
+
|
|
36
53
|
// src/csf-tools/findVarInitialization.ts
|
|
37
54
|
import { types as t } from "storybook/internal/babel";
|
|
38
55
|
var findVarInitialization = (identifier, program) => {
|
|
@@ -235,16 +252,16 @@ var formatLocation = (node, fileName) => {
|
|
|
235
252
|
let self = this;
|
|
236
253
|
if (traverse(this._ast, {
|
|
237
254
|
ExportDefaultDeclaration: {
|
|
238
|
-
enter(
|
|
239
|
-
let { node, parent } =
|
|
255
|
+
enter(path2) {
|
|
256
|
+
let { node, parent } = path2, isVariableReference = t2.isIdentifier(node.declaration) && t2.isProgram(parent);
|
|
240
257
|
if (self._options.transformInlineMeta && !isVariableReference && t2.isExpression(node.declaration)) {
|
|
241
|
-
let metaId =
|
|
258
|
+
let metaId = path2.scope.generateUidIdentifier("meta");
|
|
242
259
|
self._metaVariableName = metaId.name;
|
|
243
260
|
let nodes = [
|
|
244
261
|
t2.variableDeclaration("const", [t2.variableDeclarator(metaId, node.declaration)]),
|
|
245
262
|
t2.exportDefaultDeclaration(metaId)
|
|
246
263
|
];
|
|
247
|
-
nodes.forEach((_node) => _node.loc =
|
|
264
|
+
nodes.forEach((_node) => _node.loc = path2.node.loc), path2.replaceWithMultiple(nodes);
|
|
248
265
|
return;
|
|
249
266
|
}
|
|
250
267
|
let metaNode, decl;
|
|
@@ -253,12 +270,12 @@ var formatLocation = (node, fileName) => {
|
|
|
253
270
|
self._metaVariableName = variableName;
|
|
254
271
|
let isMetaVariable = (declaration) => t2.isIdentifier(declaration.id) && declaration.id.name === variableName;
|
|
255
272
|
self._metaStatementPath = self._file.path.get("body").find(
|
|
256
|
-
(
|
|
273
|
+
(path3) => path3.isVariableDeclaration() && path3.node.declarations.some(isMetaVariable)
|
|
257
274
|
), self._metaStatement = self._metaStatementPath?.node, decl = (self?._metaStatement?.declarations || []).find(
|
|
258
275
|
isMetaVariable
|
|
259
276
|
)?.init;
|
|
260
277
|
} else
|
|
261
|
-
self._metaStatement = node, self._metaStatementPath =
|
|
278
|
+
self._metaStatement = node, self._metaStatementPath = path2, decl = node.declaration;
|
|
262
279
|
if (t2.isObjectExpression(decl) ? metaNode = decl : /* export default { ... } as Meta<...> */ /* export default { ... } satisfies Meta<...> */ (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression) ? metaNode = decl.expression : (
|
|
263
280
|
// export default { ... } satisfies Meta as Meta<...>
|
|
264
281
|
t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression) && (metaNode = decl.expression.expression)
|
|
@@ -268,12 +285,12 @@ var formatLocation = (node, fileName) => {
|
|
|
268
285
|
self._metaStatement,
|
|
269
286
|
self._options.fileName
|
|
270
287
|
);
|
|
271
|
-
self._metaPath =
|
|
288
|
+
self._metaPath = path2;
|
|
272
289
|
}
|
|
273
290
|
},
|
|
274
291
|
ExportNamedDeclaration: {
|
|
275
|
-
enter(
|
|
276
|
-
let { node, parent } =
|
|
292
|
+
enter(path2) {
|
|
293
|
+
let { node, parent } = path2, declaration = path2.get("declaration"), declarations;
|
|
277
294
|
declaration.isVariableDeclaration() ? declarations = declaration.get("declarations").filter((d) => d.isVariableDeclarator()) : declaration.isFunctionDeclaration() && (declarations = [declaration]), declarations ? declarations.forEach((declPath) => {
|
|
278
295
|
let decl = declPath.node, id = declPath.node.id;
|
|
279
296
|
if (t2.isIdentifier(id)) {
|
|
@@ -282,7 +299,7 @@ var formatLocation = (node, fileName) => {
|
|
|
282
299
|
self._namedExportsOrder = parseExportsOrder(declPath.node.init);
|
|
283
300
|
return;
|
|
284
301
|
}
|
|
285
|
-
self._storyExports[exportName] = decl, self._storyDeclarationPath[exportName] = declPath, self._storyPaths[exportName] =
|
|
302
|
+
self._storyExports[exportName] = decl, self._storyDeclarationPath[exportName] = declPath, self._storyPaths[exportName] = path2, self._storyStatements[exportName] = node;
|
|
286
303
|
let name = storyNameFromExport(exportName);
|
|
287
304
|
self._storyAnnotations[exportName] ? logger.warn(
|
|
288
305
|
`Unexpected annotations for "${exportName}" before story declaration`
|
|
@@ -354,7 +371,7 @@ var formatLocation = (node, fileName) => {
|
|
|
354
371
|
let annotations = {}, storyNode = decl;
|
|
355
372
|
t2.isObjectExpression(storyNode) && storyNode.properties.forEach((p) => {
|
|
356
373
|
t2.isIdentifier(p.key) && (annotations[p.key.name] = p.value);
|
|
357
|
-
}), self._storyAnnotations[exportName] = annotations, self._storyStatements[exportName] = decl, self._storyPaths[exportName] =
|
|
374
|
+
}), self._storyAnnotations[exportName] = annotations, self._storyStatements[exportName] = decl, self._storyPaths[exportName] = path2, self._stories[exportName] = {
|
|
358
375
|
id: "FIXME",
|
|
359
376
|
name: exportName,
|
|
360
377
|
localName,
|
|
@@ -396,8 +413,8 @@ var formatLocation = (node, fileName) => {
|
|
|
396
413
|
}
|
|
397
414
|
},
|
|
398
415
|
CallExpression: {
|
|
399
|
-
enter(
|
|
400
|
-
let { node } =
|
|
416
|
+
enter(path2) {
|
|
417
|
+
let { node } = path2, { callee } = node;
|
|
401
418
|
if (t2.isIdentifier(callee) && callee.name === "storiesOf")
|
|
402
419
|
throw new Error(import_ts_dedent.dedent`
|
|
403
420
|
Unexpected \`storiesOf\` usage: ${formatLocation(node, self._options.fileName)}.
|
|
@@ -407,11 +424,11 @@ var formatLocation = (node, fileName) => {
|
|
|
407
424
|
if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && node.arguments.length > 0) {
|
|
408
425
|
let rootObject = callee.object;
|
|
409
426
|
if (t2.isCallExpression(rootObject) && t2.isMemberExpression(rootObject.callee) && (rootObject = rootObject.callee.object), t2.isIdentifier(rootObject)) {
|
|
410
|
-
let configParent =
|
|
427
|
+
let configParent = path2.scope.getBinding(rootObject.name)?.path?.parentPath?.node;
|
|
411
428
|
if (t2.isImportDeclaration(configParent))
|
|
412
429
|
if (isValidPreviewPath(configParent.source.value)) {
|
|
413
430
|
self._metaIsFactory = !0;
|
|
414
|
-
let metaDeclarator =
|
|
431
|
+
let metaDeclarator = path2.findParent(
|
|
415
432
|
(p) => p.isVariableDeclarator()
|
|
416
433
|
);
|
|
417
434
|
self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
|
|
@@ -457,7 +474,7 @@ var formatLocation = (node, fileName) => {
|
|
|
457
474
|
});
|
|
458
475
|
let storyExport = self.getStoryExport(key);
|
|
459
476
|
stats.storyFn = !!(t2.isArrowFunctionExpression(storyExport) || t2.isFunctionDeclaration(storyExport)), stats.mount = hasMount(storyAnnotations.play ?? self._metaAnnotations.play), stats.moduleMock = !!self.imports.find((fname) => isModuleMock(fname));
|
|
460
|
-
let storyNode = self._storyStatements[key], storyTests = self._tests.filter((
|
|
477
|
+
let storyNode = self._storyStatements[key], storyTests = self._tests.filter((t8) => t8.parent.node === storyNode);
|
|
461
478
|
return storyTests.length > 0 && (stats.tests = !0, storyTests.forEach((test) => {
|
|
462
479
|
test.id = toTestId(id, test.name);
|
|
463
480
|
})), acc;
|
|
@@ -486,7 +503,7 @@ var formatLocation = (node, fileName) => {
|
|
|
486
503
|
}
|
|
487
504
|
getStoryTests(story) {
|
|
488
505
|
let storyNode = typeof story == "string" ? this._storyStatements[story] : story;
|
|
489
|
-
return storyNode ? this._tests.filter((
|
|
506
|
+
return storyNode ? this._tests.filter((t8) => t8.parent.node === storyNode) : [];
|
|
490
507
|
}
|
|
491
508
|
get indexInputs() {
|
|
492
509
|
let { fileName } = this._options;
|
|
@@ -573,35 +590,35 @@ var getCsfParsingErrorMessage = ({
|
|
|
573
590
|
node
|
|
574
591
|
}) => import_ts_dedent2.dedent`
|
|
575
592
|
CSF Parsing error: Expected '${expectedType}' but found '${foundType}' instead in '${node?.type}'.
|
|
576
|
-
`, propKey = (p) => t3.isIdentifier(p.key) ? p.key.name : t3.isStringLiteral(p.key) ? p.key.value : null, _getPath = (
|
|
577
|
-
if (
|
|
593
|
+
`, propKey = (p) => t3.isIdentifier(p.key) ? p.key.name : t3.isStringLiteral(p.key) ? p.key.value : null, _getPath = (path2, node) => {
|
|
594
|
+
if (path2.length === 0)
|
|
578
595
|
return node;
|
|
579
596
|
if (t3.isObjectExpression(node)) {
|
|
580
|
-
let [first, ...rest] =
|
|
597
|
+
let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
|
|
581
598
|
if (field)
|
|
582
599
|
return _getPath(rest, field.value);
|
|
583
600
|
}
|
|
584
|
-
}, _getPathProperties = (
|
|
585
|
-
if (
|
|
601
|
+
}, _getPathProperties = (path2, node) => {
|
|
602
|
+
if (path2.length === 0) {
|
|
586
603
|
if (t3.isObjectExpression(node))
|
|
587
604
|
return node.properties;
|
|
588
605
|
throw new Error("Expected object expression");
|
|
589
606
|
}
|
|
590
607
|
if (t3.isObjectExpression(node)) {
|
|
591
|
-
let [first, ...rest] =
|
|
608
|
+
let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
|
|
592
609
|
if (field)
|
|
593
610
|
return rest.length === 0 ? node.properties : _getPathProperties(rest, field.value);
|
|
594
611
|
}
|
|
595
612
|
}, _findVarDeclarator = (identifier, program) => {
|
|
596
613
|
let declarator = null, declarations = null;
|
|
597
614
|
return program.body.find((node) => (t3.isVariableDeclaration(node) ? declarations = node.declarations : t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration) && (declarations = node.declaration.declarations), declarations && declarations.find((decl) => t3.isVariableDeclarator(decl) && t3.isIdentifier(decl.id) && decl.id.name === identifier ? (declarator = decl, !0) : !1))), declarator;
|
|
598
|
-
}, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (
|
|
599
|
-
if (
|
|
615
|
+
}, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (path2, value) => {
|
|
616
|
+
if (path2.length === 0)
|
|
600
617
|
return value;
|
|
601
|
-
let [first, ...rest] =
|
|
618
|
+
let [first, ...rest] = path2, innerExpression = _makeObjectExpression(rest, value);
|
|
602
619
|
return t3.objectExpression([t3.objectProperty(t3.identifier(first), innerExpression)]);
|
|
603
|
-
}, _updateExportNode = (
|
|
604
|
-
let [first, ...rest] =
|
|
620
|
+
}, _updateExportNode = (path2, expr, existing) => {
|
|
621
|
+
let [first, ...rest] = path2, existingField = existing.properties.find(
|
|
605
622
|
(p) => propKey(p) === first
|
|
606
623
|
);
|
|
607
624
|
existingField ? t3.isObjectExpression(existingField.value) && rest.length > 0 ? _updateExportNode(rest, expr, existingField.value) : existingField.value = _makeObjectExpression(rest, expr) : existing.properties.push(
|
|
@@ -715,31 +732,31 @@ var getCsfParsingErrorMessage = ({
|
|
|
715
732
|
}
|
|
716
733
|
}), self;
|
|
717
734
|
}
|
|
718
|
-
getFieldNode(
|
|
719
|
-
let [root, ...rest] =
|
|
735
|
+
getFieldNode(path2) {
|
|
736
|
+
let [root, ...rest] = path2, exported = this._exports[root];
|
|
720
737
|
if (exported)
|
|
721
738
|
return _getPath(rest, exported);
|
|
722
739
|
}
|
|
723
|
-
getFieldProperties(
|
|
724
|
-
let [root, ...rest] =
|
|
740
|
+
getFieldProperties(path2) {
|
|
741
|
+
let [root, ...rest] = path2, exported = this._exports[root];
|
|
725
742
|
if (exported)
|
|
726
743
|
return _getPathProperties(rest, exported);
|
|
727
744
|
}
|
|
728
|
-
getFieldValue(
|
|
729
|
-
let node = this.getFieldNode(
|
|
745
|
+
getFieldValue(path2) {
|
|
746
|
+
let node = this.getFieldNode(path2);
|
|
730
747
|
if (node) {
|
|
731
748
|
let { code } = generate2(node, {});
|
|
732
749
|
return (0, eval)(`(() => (${code}))()`);
|
|
733
750
|
}
|
|
734
751
|
}
|
|
735
|
-
getSafeFieldValue(
|
|
752
|
+
getSafeFieldValue(path2) {
|
|
736
753
|
try {
|
|
737
|
-
return this.getFieldValue(
|
|
754
|
+
return this.getFieldValue(path2);
|
|
738
755
|
} catch {
|
|
739
756
|
}
|
|
740
757
|
}
|
|
741
|
-
setFieldNode(
|
|
742
|
-
let [first, ...rest] =
|
|
758
|
+
setFieldNode(path2, expr) {
|
|
759
|
+
let [first, ...rest] = path2, exportNode = this._exports[first];
|
|
743
760
|
if (this._exportsObject) {
|
|
744
761
|
let existingProp = this._exportsObject.properties.find((p) => propKey(p) === first);
|
|
745
762
|
if (existingProp && t3.isIdentifier(existingProp.value)) {
|
|
@@ -749,7 +766,7 @@ var getCsfParsingErrorMessage = ({
|
|
|
749
766
|
return;
|
|
750
767
|
}
|
|
751
768
|
}
|
|
752
|
-
_updateExportNode(
|
|
769
|
+
_updateExportNode(path2, expr, this._exportsObject), this._exports[path2[0]] = expr;
|
|
753
770
|
return;
|
|
754
771
|
}
|
|
755
772
|
if (exportNode && t3.isObjectExpression(exportNode) && rest.length > 0) {
|
|
@@ -761,13 +778,13 @@ var getCsfParsingErrorMessage = ({
|
|
|
761
778
|
_updateExportNode(rest, expr, varDecl.init);
|
|
762
779
|
return;
|
|
763
780
|
}
|
|
764
|
-
if (exportNode && rest.length === 0 && this._exportDecls[
|
|
765
|
-
let decl = this._exportDecls[
|
|
781
|
+
if (exportNode && rest.length === 0 && this._exportDecls[path2[0]]) {
|
|
782
|
+
let decl = this._exportDecls[path2[0]];
|
|
766
783
|
t3.isVariableDeclarator(decl) && (decl.init = _makeObjectExpression([], expr));
|
|
767
784
|
} else {
|
|
768
785
|
if (this.hasDefaultExport)
|
|
769
786
|
throw new Error(
|
|
770
|
-
`Could not set the "${
|
|
787
|
+
`Could not set the "${path2.join(
|
|
771
788
|
"."
|
|
772
789
|
)}" field as the default export is not an object in this file.`
|
|
773
790
|
);
|
|
@@ -790,8 +807,8 @@ var getCsfParsingErrorMessage = ({
|
|
|
790
807
|
*
|
|
791
808
|
* @returns The name of a node in a given path, supporting the following formats:
|
|
792
809
|
*/
|
|
793
|
-
getNameFromPath(
|
|
794
|
-
let node = this.getFieldNode(
|
|
810
|
+
getNameFromPath(path2) {
|
|
811
|
+
let node = this.getFieldNode(path2);
|
|
795
812
|
if (node)
|
|
796
813
|
return this._getPresetValue(node, "name");
|
|
797
814
|
}
|
|
@@ -808,8 +825,8 @@ var getCsfParsingErrorMessage = ({
|
|
|
808
825
|
* getNamesFromPath(['addons']);
|
|
809
826
|
* ```
|
|
810
827
|
*/
|
|
811
|
-
getNamesFromPath(
|
|
812
|
-
let node = this.getFieldNode(
|
|
828
|
+
getNamesFromPath(path2) {
|
|
829
|
+
let node = this.getFieldNode(path2);
|
|
813
830
|
if (!node)
|
|
814
831
|
return;
|
|
815
832
|
let pathNames = [];
|
|
@@ -840,68 +857,68 @@ var getCsfParsingErrorMessage = ({
|
|
|
840
857
|
);
|
|
841
858
|
return value;
|
|
842
859
|
}
|
|
843
|
-
removeField(
|
|
860
|
+
removeField(path2) {
|
|
844
861
|
let removeProperty = (properties2, prop) => {
|
|
845
862
|
let index = properties2.findIndex(
|
|
846
863
|
(p) => t3.isIdentifier(p.key) && p.key.name === prop || t3.isStringLiteral(p.key) && p.key.value === prop
|
|
847
864
|
);
|
|
848
865
|
index >= 0 && properties2.splice(index, 1);
|
|
849
866
|
};
|
|
850
|
-
if (
|
|
867
|
+
if (path2.length === 1) {
|
|
851
868
|
let removedRootProperty = !1;
|
|
852
869
|
if (this._ast.program.body.forEach((node) => {
|
|
853
870
|
if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
|
|
854
871
|
let decl = node.declaration.declarations[0];
|
|
855
|
-
t3.isIdentifier(decl.id) && decl.id.name ===
|
|
872
|
+
t3.isIdentifier(decl.id) && decl.id.name === path2[0] && (this._ast.program.body.splice(this._ast.program.body.indexOf(node), 1), removedRootProperty = !0);
|
|
856
873
|
}
|
|
857
874
|
if (t3.isExportDefaultDeclaration(node)) {
|
|
858
875
|
let resolved = this._resolveDeclaration(node.declaration);
|
|
859
876
|
if (t3.isObjectExpression(resolved)) {
|
|
860
877
|
let properties2 = resolved.properties;
|
|
861
|
-
removeProperty(properties2,
|
|
878
|
+
removeProperty(properties2, path2[0]), removedRootProperty = !0;
|
|
862
879
|
}
|
|
863
880
|
}
|
|
864
881
|
if (t3.isExpressionStatement(node) && t3.isAssignmentExpression(node.expression) && t3.isMemberExpression(node.expression.left) && t3.isIdentifier(node.expression.left.object) && node.expression.left.object.name === "module" && t3.isIdentifier(node.expression.left.property) && node.expression.left.property.name === "exports" && t3.isObjectExpression(node.expression.right)) {
|
|
865
882
|
let properties2 = node.expression.right.properties;
|
|
866
|
-
removeProperty(properties2,
|
|
883
|
+
removeProperty(properties2, path2[0]), removedRootProperty = !0;
|
|
867
884
|
}
|
|
868
885
|
}), removedRootProperty)
|
|
869
886
|
return;
|
|
870
887
|
}
|
|
871
|
-
let properties = this.getFieldProperties(
|
|
888
|
+
let properties = this.getFieldProperties(path2);
|
|
872
889
|
if (properties) {
|
|
873
|
-
let lastPath =
|
|
890
|
+
let lastPath = path2.at(-1);
|
|
874
891
|
removeProperty(properties, lastPath);
|
|
875
892
|
}
|
|
876
893
|
}
|
|
877
|
-
appendValueToArray(
|
|
894
|
+
appendValueToArray(path2, value) {
|
|
878
895
|
let node = this.valueToNode(value);
|
|
879
|
-
node && this.appendNodeToArray(
|
|
896
|
+
node && this.appendNodeToArray(path2, node);
|
|
880
897
|
}
|
|
881
|
-
appendNodeToArray(
|
|
882
|
-
let current = this.getFieldNode(
|
|
898
|
+
appendNodeToArray(path2, node) {
|
|
899
|
+
let current = this.getFieldNode(path2);
|
|
883
900
|
if (!current)
|
|
884
|
-
this.setFieldNode(
|
|
901
|
+
this.setFieldNode(path2, t3.arrayExpression([node]));
|
|
885
902
|
else if (t3.isArrayExpression(current))
|
|
886
903
|
current.elements.push(node);
|
|
887
904
|
else
|
|
888
|
-
throw new Error(`Expected array at '${
|
|
905
|
+
throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
|
|
889
906
|
}
|
|
890
907
|
/**
|
|
891
908
|
* Specialized helper to remove addons or other array entries that can either be strings or
|
|
892
909
|
* objects with a name property.
|
|
893
910
|
*/
|
|
894
|
-
removeEntryFromArray(
|
|
895
|
-
let current = this.getFieldNode(
|
|
911
|
+
removeEntryFromArray(path2, value) {
|
|
912
|
+
let current = this.getFieldNode(path2);
|
|
896
913
|
if (current)
|
|
897
914
|
if (t3.isArrayExpression(current)) {
|
|
898
915
|
let index = current.elements.findIndex((element) => t3.isStringLiteral(element) ? element.value === value : t3.isObjectExpression(element) ? this._getPresetValue(element, "name") === value : this._getPnpWrappedValue(element) === value);
|
|
899
916
|
if (index >= 0)
|
|
900
917
|
current.elements.splice(index, 1);
|
|
901
918
|
else
|
|
902
|
-
throw new Error(`Could not find '${value}' in array at '${
|
|
919
|
+
throw new Error(`Could not find '${value}' in array at '${path2.join(".")}'`);
|
|
903
920
|
} else
|
|
904
|
-
throw new Error(`Expected array at '${
|
|
921
|
+
throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
|
|
905
922
|
}
|
|
906
923
|
_inferQuotes() {
|
|
907
924
|
if (!this._quotes) {
|
|
@@ -928,11 +945,11 @@ var getCsfParsingErrorMessage = ({
|
|
|
928
945
|
valueNode = t3.valueToNode(value);
|
|
929
946
|
return valueNode;
|
|
930
947
|
}
|
|
931
|
-
setFieldValue(
|
|
948
|
+
setFieldValue(path2, value) {
|
|
932
949
|
let valueNode = this.valueToNode(value);
|
|
933
950
|
if (!valueNode)
|
|
934
951
|
throw new Error(`Unexpected value ${JSON.stringify(value)}`);
|
|
935
|
-
this.setFieldNode(
|
|
952
|
+
this.setFieldNode(path2, valueNode);
|
|
936
953
|
}
|
|
937
954
|
getBodyDeclarations() {
|
|
938
955
|
return this._ast.program.body;
|
|
@@ -1296,14 +1313,14 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
|
|
|
1296
1313
|
);
|
|
1297
1314
|
csf._ast.program.body.push(addParameter);
|
|
1298
1315
|
}
|
|
1299
|
-
}, addComponentDescription = (node,
|
|
1300
|
-
if (!
|
|
1316
|
+
}, addComponentDescription = (node, path2, value) => {
|
|
1317
|
+
if (!path2.length) {
|
|
1301
1318
|
node.properties.find(
|
|
1302
1319
|
(p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === "component"
|
|
1303
1320
|
) || node.properties.unshift(value);
|
|
1304
1321
|
return;
|
|
1305
1322
|
}
|
|
1306
|
-
let [first, ...rest] =
|
|
1323
|
+
let [first, ...rest] = path2, existing = node.properties.find(
|
|
1307
1324
|
(p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === first && t5.isObjectExpression(p.value)
|
|
1308
1325
|
), subNode;
|
|
1309
1326
|
existing ? subNode = existing.value : (subNode = t5.objectExpression([]), node.properties.push(t5.objectProperty(t5.identifier(first), subNode))), addComponentDescription(subNode, rest, value);
|
|
@@ -1330,7 +1347,7 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
|
|
|
1330
1347
|
`) : "";
|
|
1331
1348
|
|
|
1332
1349
|
// src/csf-tools/index.ts
|
|
1333
|
-
import { babelParse as
|
|
1350
|
+
import { babelParse as babelParse5 } from "storybook/internal/babel";
|
|
1334
1351
|
|
|
1335
1352
|
// src/csf-tools/vitest-plugin/transformer.ts
|
|
1336
1353
|
var import_ts_dedent4 = __toESM(require_dist(), 1);
|
|
@@ -1339,6 +1356,38 @@ import { getStoryTitle } from "storybook/internal/common";
|
|
|
1339
1356
|
import { combineTags } from "storybook/internal/csf";
|
|
1340
1357
|
import { logger as logger4 } from "storybook/internal/node-logger";
|
|
1341
1358
|
var isValidTest = (storyTags, tagsFilter) => !(tagsFilter.include.length && !tagsFilter.include.some((tag) => storyTags?.includes(tag)) || tagsFilter.exclude.some((tag) => storyTags?.includes(tag))), DOUBLE_SPACES = " ", getLiteralWithZeroWidthSpace = (testTitle) => t6.stringLiteral(`${testTitle}${DOUBLE_SPACES}`);
|
|
1359
|
+
function createTestGuardDeclaration(scope, expectId, convertToFilePathId) {
|
|
1360
|
+
let isRunningFromThisFileId = scope.generateUidIdentifier("isRunningFromThisFile"), testPathProperty = t6.memberExpression(
|
|
1361
|
+
t6.callExpression(t6.memberExpression(expectId, t6.identifier("getState")), []),
|
|
1362
|
+
t6.identifier("testPath")
|
|
1363
|
+
), filePathProperty = t6.memberExpression(
|
|
1364
|
+
t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
|
|
1365
|
+
t6.identifier("filepath")
|
|
1366
|
+
), nullishCoalescingExpression = t6.logicalExpression(
|
|
1367
|
+
"??",
|
|
1368
|
+
// TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
|
|
1369
|
+
// https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
|
|
1370
|
+
filePathProperty,
|
|
1371
|
+
testPathProperty
|
|
1372
|
+
), includesCall = t6.callExpression(
|
|
1373
|
+
t6.memberExpression(
|
|
1374
|
+
t6.callExpression(convertToFilePathId, [
|
|
1375
|
+
t6.memberExpression(
|
|
1376
|
+
t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
|
|
1377
|
+
t6.identifier("url")
|
|
1378
|
+
)
|
|
1379
|
+
]),
|
|
1380
|
+
t6.identifier("includes")
|
|
1381
|
+
),
|
|
1382
|
+
[nullishCoalescingExpression]
|
|
1383
|
+
);
|
|
1384
|
+
return {
|
|
1385
|
+
declaration: t6.variableDeclaration("const", [
|
|
1386
|
+
t6.variableDeclarator(isRunningFromThisFileId, includesCall)
|
|
1387
|
+
]),
|
|
1388
|
+
identifier: isRunningFromThisFileId
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1342
1391
|
async function vitestTransform({
|
|
1343
1392
|
code,
|
|
1344
1393
|
fileName,
|
|
@@ -1403,37 +1452,13 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1403
1452
|
];
|
|
1404
1453
|
return ast.program.body.unshift(...imports2), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
|
|
1405
1454
|
}
|
|
1406
|
-
let vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect"), testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory"), skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
t6.identifier("filepath")
|
|
1414
|
-
), nullishCoalescingExpression = t6.logicalExpression(
|
|
1415
|
-
"??",
|
|
1416
|
-
// TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
|
|
1417
|
-
// https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
|
|
1418
|
-
filePathProperty,
|
|
1419
|
-
testPathProperty
|
|
1420
|
-
), includesCall = t6.callExpression(
|
|
1421
|
-
t6.memberExpression(
|
|
1422
|
-
t6.callExpression(t6.identifier("convertToFilePath"), [
|
|
1423
|
-
t6.memberExpression(
|
|
1424
|
-
t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
|
|
1425
|
-
t6.identifier("url")
|
|
1426
|
-
)
|
|
1427
|
-
]),
|
|
1428
|
-
t6.identifier("includes")
|
|
1429
|
-
),
|
|
1430
|
-
[nullishCoalescingExpression]
|
|
1431
|
-
);
|
|
1432
|
-
return { isRunningFromThisFileDeclaration: t6.variableDeclaration("const", [
|
|
1433
|
-
t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
|
|
1434
|
-
]), isRunningFromThisFileId: isRunningFromThisFileId2 };
|
|
1435
|
-
}
|
|
1436
|
-
let { isRunningFromThisFileDeclaration, isRunningFromThisFileId } = getTestGuardDeclaration();
|
|
1455
|
+
let vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect"), testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory"), skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip)), componentPathLiteral = parsed._rawComponentPath ? t6.stringLiteral(parsed._rawComponentPath) : null, componentNameLiteral = null;
|
|
1456
|
+
parsed._componentImportSpecifier && (t6.isImportSpecifier(parsed._componentImportSpecifier) || t6.isImportDefaultSpecifier(parsed._componentImportSpecifier)) && (componentNameLiteral = t6.stringLiteral(parsed._componentImportSpecifier.local.name));
|
|
1457
|
+
let { declaration: isRunningFromThisFileDeclaration, identifier: isRunningFromThisFileId } = createTestGuardDeclaration(
|
|
1458
|
+
parsed._file.path.scope,
|
|
1459
|
+
vitestExpectId,
|
|
1460
|
+
t6.identifier("convertToFilePath")
|
|
1461
|
+
);
|
|
1437
1462
|
ast.program.body.push(isRunningFromThisFileDeclaration);
|
|
1438
1463
|
let getTestStatementForStory = ({
|
|
1439
1464
|
localName,
|
|
@@ -1443,16 +1468,18 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1443
1468
|
overrideSourcemap = !0,
|
|
1444
1469
|
storyId
|
|
1445
1470
|
}) => {
|
|
1471
|
+
let objectProperties = [
|
|
1472
|
+
t6.objectProperty(t6.identifier("exportName"), t6.stringLiteral(exportName)),
|
|
1473
|
+
t6.objectProperty(t6.identifier("story"), t6.identifier(localName)),
|
|
1474
|
+
t6.objectProperty(t6.identifier("meta"), t6.identifier(metaExportName)),
|
|
1475
|
+
t6.objectProperty(t6.identifier("skipTags"), skipTagsId),
|
|
1476
|
+
t6.objectProperty(t6.identifier("storyId"), t6.stringLiteral(storyId))
|
|
1477
|
+
];
|
|
1478
|
+
componentPathLiteral && objectProperties.push(t6.objectProperty(t6.identifier("componentPath"), componentPathLiteral)), componentNameLiteral && objectProperties.push(t6.objectProperty(t6.identifier("componentName"), componentNameLiteral));
|
|
1446
1479
|
let testStoryCall = t6.expressionStatement(
|
|
1447
1480
|
t6.callExpression(vitestTestId, [
|
|
1448
1481
|
t6.stringLiteral(testTitle),
|
|
1449
|
-
t6.callExpression(testStoryId, [
|
|
1450
|
-
t6.stringLiteral(exportName),
|
|
1451
|
-
t6.identifier(localName),
|
|
1452
|
-
t6.identifier(metaExportName),
|
|
1453
|
-
skipTagsId,
|
|
1454
|
-
t6.stringLiteral(storyId)
|
|
1455
|
-
])
|
|
1482
|
+
t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
|
|
1456
1483
|
])
|
|
1457
1484
|
);
|
|
1458
1485
|
return overrideSourcemap && (testStoryCall.loc = node.loc), testStoryCall;
|
|
@@ -1469,17 +1496,24 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1469
1496
|
storyId: parentStoryId
|
|
1470
1497
|
}),
|
|
1471
1498
|
...tests.map(({ name: testName, node: testNode, id: storyId }) => {
|
|
1499
|
+
let objectProperties = [
|
|
1500
|
+
t6.objectProperty(t6.identifier("exportName"), t6.stringLiteral(exportName)),
|
|
1501
|
+
t6.objectProperty(t6.identifier("story"), t6.identifier(localName)),
|
|
1502
|
+
t6.objectProperty(t6.identifier("meta"), t6.identifier(metaExportName)),
|
|
1503
|
+
t6.objectProperty(t6.identifier("skipTags"), t6.arrayExpression([])),
|
|
1504
|
+
t6.objectProperty(t6.identifier("storyId"), t6.stringLiteral(storyId))
|
|
1505
|
+
];
|
|
1506
|
+
componentPathLiteral && objectProperties.push(
|
|
1507
|
+
t6.objectProperty(t6.identifier("componentPath"), componentPathLiteral)
|
|
1508
|
+
), componentNameLiteral && objectProperties.push(
|
|
1509
|
+
t6.objectProperty(t6.identifier("componentName"), componentNameLiteral)
|
|
1510
|
+
), testName && objectProperties.push(
|
|
1511
|
+
t6.objectProperty(t6.identifier("testName"), t6.stringLiteral(testName))
|
|
1512
|
+
);
|
|
1472
1513
|
let testStatement = t6.expressionStatement(
|
|
1473
1514
|
t6.callExpression(vitestTestId, [
|
|
1474
1515
|
t6.stringLiteral(testName),
|
|
1475
|
-
t6.callExpression(testStoryId, [
|
|
1476
|
-
t6.stringLiteral(exportName),
|
|
1477
|
-
t6.identifier(localName),
|
|
1478
|
-
t6.identifier(metaExportName),
|
|
1479
|
-
t6.arrayExpression([]),
|
|
1480
|
-
t6.stringLiteral(storyId),
|
|
1481
|
-
t6.stringLiteral(testName)
|
|
1482
|
-
])
|
|
1516
|
+
t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
|
|
1483
1517
|
])
|
|
1484
1518
|
);
|
|
1485
1519
|
return testStatement.loc = testNode.loc, testStatement;
|
|
@@ -1537,7 +1571,354 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1537
1571
|
return ast.program.body.unshift(...imports), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
|
|
1538
1572
|
}
|
|
1539
1573
|
|
|
1574
|
+
// src/csf-tools/vitest-plugin/component-transformer.ts
|
|
1575
|
+
import path from "node:path";
|
|
1576
|
+
import {
|
|
1577
|
+
BabelFileClass as BabelFileClass2,
|
|
1578
|
+
babelParse as babelParse4,
|
|
1579
|
+
generate as generate5,
|
|
1580
|
+
types as t7,
|
|
1581
|
+
traverse as traverse4
|
|
1582
|
+
} from "storybook/internal/babel";
|
|
1583
|
+
|
|
1584
|
+
// src/core-server/utils/get-dummy-args-from-argtypes.ts
|
|
1585
|
+
var STORYBOOK_FN_PLACEHOLDER = "[[STORYBOOK_FN_PLACEHOLDER]]";
|
|
1586
|
+
function generateDummyArgsFromArgTypes(argTypes, options = {}) {
|
|
1587
|
+
let required = {}, optional = {};
|
|
1588
|
+
for (let [propName, argType] of Object.entries(argTypes)) {
|
|
1589
|
+
let isRequired = argType.type && typeof argType.type == "object" && argType.type.required, dummyValue;
|
|
1590
|
+
if (typeof argType.type == "string") {
|
|
1591
|
+
let sbType = { name: argType.type };
|
|
1592
|
+
dummyValue = generateDummyValueFromSBType(sbType, propName, options);
|
|
1593
|
+
} else argType.type && typeof argType.type == "object" ? dummyValue = generateDummyValueFromSBType(argType.type, propName, options) : dummyValue = void 0;
|
|
1594
|
+
isRequired ? required[propName] = dummyValue : optional[propName] = dummyValue;
|
|
1595
|
+
}
|
|
1596
|
+
return { required, optional };
|
|
1597
|
+
}
|
|
1598
|
+
function tokenize(name) {
|
|
1599
|
+
return name ? name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-]+/g, " ").split(" ").map((t8) => t8.toLowerCase()).filter(Boolean) : [];
|
|
1600
|
+
}
|
|
1601
|
+
function hasAny(tokens, set) {
|
|
1602
|
+
return tokens.some((t8) => set.has(t8));
|
|
1603
|
+
}
|
|
1604
|
+
var URL_TOKENS = /* @__PURE__ */ new Set(["url", "href", "link"]), IMAGE_TOKENS = /* @__PURE__ */ new Set(["image", "img", "photo", "avatar", "logo"]), EMAIL_TOKENS = /* @__PURE__ */ new Set(["email", "e-mail", "mail"]), PHONE_TOKENS = /* @__PURE__ */ new Set(["phone", "tel", "telephone", "mobile", "cell"]), COLOR_TOKENS = /* @__PURE__ */ new Set(["color", "background", "bg"]), DATE_TOKENS = /* @__PURE__ */ new Set(["date", "at", "time", "timestamp"]), NEGATIVE_IMAGE_TOKENS = /* @__PURE__ */ new Set([
|
|
1605
|
+
"size",
|
|
1606
|
+
"width",
|
|
1607
|
+
"height",
|
|
1608
|
+
"ratio",
|
|
1609
|
+
"count",
|
|
1610
|
+
"status",
|
|
1611
|
+
"loading",
|
|
1612
|
+
"config",
|
|
1613
|
+
"options",
|
|
1614
|
+
"variant"
|
|
1615
|
+
]);
|
|
1616
|
+
function getMostLikelyTypeFromTokens(tokens) {
|
|
1617
|
+
let score = {};
|
|
1618
|
+
for (let token of tokens)
|
|
1619
|
+
IMAGE_TOKENS.has(token) && (score.image = (score.image ?? 0) + 3), URL_TOKENS.has(token) && (score.url = (score.url ?? 0) + 2), EMAIL_TOKENS.has(token) && (score.email = (score.email ?? 0) + 3), PHONE_TOKENS.has(token) && (score.phone = (score.phone ?? 0) + 3);
|
|
1620
|
+
hasAny(tokens, NEGATIVE_IMAGE_TOKENS) && (score.image = (score.image ?? 0) - 4);
|
|
1621
|
+
let best = null, bestScore = 0;
|
|
1622
|
+
for (let [kind, value] of Object.entries(score))
|
|
1623
|
+
value > bestScore && (bestScore = value, best = kind);
|
|
1624
|
+
return best;
|
|
1625
|
+
}
|
|
1626
|
+
function normalizeStringLiteral(value) {
|
|
1627
|
+
return typeof value != "string" ? value : value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'") ? value.slice(1, -1) : value;
|
|
1628
|
+
}
|
|
1629
|
+
function generateDummyValueFromSBType(sbType, propName, options) {
|
|
1630
|
+
switch (sbType.name) {
|
|
1631
|
+
case "boolean":
|
|
1632
|
+
return !0;
|
|
1633
|
+
case "number":
|
|
1634
|
+
return 0;
|
|
1635
|
+
case "string": {
|
|
1636
|
+
let name = propName ?? "", tokens = tokenize(name);
|
|
1637
|
+
if (hasAny(tokens, COLOR_TOKENS))
|
|
1638
|
+
return "#ff4785";
|
|
1639
|
+
if (hasAny(tokens, DATE_TOKENS))
|
|
1640
|
+
return (/* @__PURE__ */ new Date()).toLocaleDateString();
|
|
1641
|
+
let mostLikelyType = getMostLikelyTypeFromTokens(tokens);
|
|
1642
|
+
if (options?.skipUrlGeneration && (mostLikelyType === "image" || mostLikelyType === "url"))
|
|
1643
|
+
return name;
|
|
1644
|
+
switch (mostLikelyType) {
|
|
1645
|
+
case "image":
|
|
1646
|
+
return "https://placehold.co/600x400?text=Storybook";
|
|
1647
|
+
case "url":
|
|
1648
|
+
return "https://example.com";
|
|
1649
|
+
case "email":
|
|
1650
|
+
return "storybook@example.com";
|
|
1651
|
+
case "phone":
|
|
1652
|
+
return "1234567890";
|
|
1653
|
+
default:
|
|
1654
|
+
return name ?? "Hello world";
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
case "date":
|
|
1658
|
+
return /* @__PURE__ */ new Date();
|
|
1659
|
+
case "node":
|
|
1660
|
+
return propName ?? "Hello world";
|
|
1661
|
+
case "function":
|
|
1662
|
+
return STORYBOOK_FN_PLACEHOLDER;
|
|
1663
|
+
case "literal":
|
|
1664
|
+
return normalizeStringLiteral(sbType.value);
|
|
1665
|
+
case "object": {
|
|
1666
|
+
let result = {};
|
|
1667
|
+
for (let [key, valueType] of Object.entries(sbType.value))
|
|
1668
|
+
result[key] = generateDummyValueFromSBType(valueType, key, options);
|
|
1669
|
+
return result;
|
|
1670
|
+
}
|
|
1671
|
+
case "union": {
|
|
1672
|
+
if (!sbType.value?.length)
|
|
1673
|
+
return "";
|
|
1674
|
+
let literalType = sbType.value.find((t8) => t8.name === "literal");
|
|
1675
|
+
return literalType?.name === "literal" ? normalizeStringLiteral(literalType.value) : generateDummyValueFromSBType(sbType.value[0], propName, options);
|
|
1676
|
+
}
|
|
1677
|
+
case "array":
|
|
1678
|
+
return sbType.value.name === "other" ? [] : [generateDummyValueFromSBType(sbType.value, propName, options)];
|
|
1679
|
+
case "tuple":
|
|
1680
|
+
return sbType.value.map((el) => generateDummyValueFromSBType(el, void 0, options));
|
|
1681
|
+
case "enum":
|
|
1682
|
+
return sbType.value[0] ?? propName;
|
|
1683
|
+
case "intersection": {
|
|
1684
|
+
let objectTypes = sbType.value.filter((t8) => t8.name === "object");
|
|
1685
|
+
if (objectTypes.length > 0) {
|
|
1686
|
+
let result = {};
|
|
1687
|
+
return objectTypes.forEach((objType) => {
|
|
1688
|
+
objType.name === "object" && Object.entries(objType.value).forEach(([key, type]) => {
|
|
1689
|
+
result[key] = generateDummyValueFromSBType(type, key, options);
|
|
1690
|
+
});
|
|
1691
|
+
}), result;
|
|
1692
|
+
}
|
|
1693
|
+
return {};
|
|
1694
|
+
}
|
|
1695
|
+
case "other": {
|
|
1696
|
+
let value = sbType.value;
|
|
1697
|
+
return value?.startsWith("React") || value?.includes("Event") || value?.includes("Element") ? STORYBOOK_FN_PLACEHOLDER : value === "null" ? null : value === "void" || value === "undefined" ? void 0 : value ?? propName;
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
// src/csf-tools/vitest-plugin/component-transformer.ts
|
|
1703
|
+
var VITEST_IMPORT_SOURCE = "vitest", TEST_UTILS_IMPORT_SOURCE = "@storybook/addon-vitest/internal/test-utils", STORYBOOK_TEST_IMPORT_SOURCE = "storybook/test", sanitizeIdentifier = (value) => value.replace(/[^a-zA-Z0-9_$]+/g, "") || "Component", createComponentNameFromFileName = (fileName) => {
|
|
1704
|
+
if (!fileName)
|
|
1705
|
+
return "Component";
|
|
1706
|
+
let basename = path.basename(fileName, path.extname(fileName));
|
|
1707
|
+
return sanitizeIdentifier(basename);
|
|
1708
|
+
}, containsJsxNode = (valuePath) => {
|
|
1709
|
+
if (!valuePath?.node)
|
|
1710
|
+
return !1;
|
|
1711
|
+
let found = !1;
|
|
1712
|
+
return valuePath.traverse({
|
|
1713
|
+
JSXElement(path2) {
|
|
1714
|
+
found = !0, path2.stop();
|
|
1715
|
+
},
|
|
1716
|
+
JSXFragment(path2) {
|
|
1717
|
+
found = !0, path2.stop();
|
|
1718
|
+
}
|
|
1719
|
+
}), found;
|
|
1720
|
+
}, unwrapExpression = (node) => node ? t7.isTSAsExpression(node) || t7.isTSSatisfiesExpression(node) ? unwrapExpression(node.expression) : node : null, dedupeImports = (program, source, specifiers) => {
|
|
1721
|
+
let existing = program.body.find(
|
|
1722
|
+
(node) => t7.isImportDeclaration(node) && node.source.value === source
|
|
1723
|
+
);
|
|
1724
|
+
if (existing) {
|
|
1725
|
+
specifiers.forEach((specifier) => {
|
|
1726
|
+
existing.specifiers.every(
|
|
1727
|
+
(existingSpecifier) => !t7.isImportSpecifier(existingSpecifier) || existingSpecifier.local.name !== specifier.local.name
|
|
1728
|
+
) && existing.specifiers.push(specifier);
|
|
1729
|
+
});
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
program.body.unshift(t7.importDeclaration(specifiers, t7.stringLiteral(source)));
|
|
1733
|
+
}, collectComponentExports = (program, fileName) => {
|
|
1734
|
+
let components = [], addComponent = (exportedName, localIdentifier, valuePath) => {
|
|
1735
|
+
!valuePath || !valuePath.node || !unwrapExpression(valuePath.node) || containsJsxNode(valuePath) && components.push({ exportedName, localIdentifier });
|
|
1736
|
+
};
|
|
1737
|
+
return traverse4(program, {
|
|
1738
|
+
ExportNamedDeclaration(path2) {
|
|
1739
|
+
let { node } = path2;
|
|
1740
|
+
if (node.source)
|
|
1741
|
+
return;
|
|
1742
|
+
let declarationPath = path2.get("declaration");
|
|
1743
|
+
if (declarationPath.isVariableDeclaration())
|
|
1744
|
+
declarationPath.get("declarations").forEach((declPath) => {
|
|
1745
|
+
if (!declPath.isVariableDeclarator())
|
|
1746
|
+
return;
|
|
1747
|
+
let id = declPath.node.id;
|
|
1748
|
+
if (!t7.isIdentifier(id))
|
|
1749
|
+
return;
|
|
1750
|
+
let initPath = declPath.get("init");
|
|
1751
|
+
addComponent(id.name, id, initPath);
|
|
1752
|
+
});
|
|
1753
|
+
else if (declarationPath.isFunctionDeclaration() && declarationPath.node.id) {
|
|
1754
|
+
let declarationId = declarationPath.node.id;
|
|
1755
|
+
t7.isIdentifier(declarationId) && addComponent(declarationId.name, declarationId, declarationPath);
|
|
1756
|
+
} else if (declarationPath.isClassDeclaration() && declarationPath.node.id) {
|
|
1757
|
+
let declarationId = declarationPath.node.id;
|
|
1758
|
+
t7.isIdentifier(declarationId) && addComponent(declarationId.name, declarationId, declarationPath);
|
|
1759
|
+
}
|
|
1760
|
+
path2.get("specifiers").forEach((specifierPath) => {
|
|
1761
|
+
if (!specifierPath.isExportSpecifier())
|
|
1762
|
+
return;
|
|
1763
|
+
let { local, exported } = specifierPath.node;
|
|
1764
|
+
if (!t7.isIdentifier(local) || !t7.isIdentifier(exported))
|
|
1765
|
+
return;
|
|
1766
|
+
let binding = specifierPath.scope.getBinding(local.name);
|
|
1767
|
+
if (!binding)
|
|
1768
|
+
return;
|
|
1769
|
+
let bindingPath = binding.path, localIdentifier = binding.identifier;
|
|
1770
|
+
if (t7.isIdentifier(localIdentifier)) {
|
|
1771
|
+
if (bindingPath.isVariableDeclarator())
|
|
1772
|
+
addComponent(exported.name, localIdentifier, bindingPath.get("init"));
|
|
1773
|
+
else if (bindingPath.isFunctionDeclaration() || bindingPath.isClassDeclaration()) {
|
|
1774
|
+
let bindingNodeId = bindingPath.node.id;
|
|
1775
|
+
t7.isIdentifier(bindingNodeId) && addComponent(exported.name, localIdentifier, bindingPath);
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
});
|
|
1779
|
+
},
|
|
1780
|
+
ExportDefaultDeclaration(path2) {
|
|
1781
|
+
let { node } = path2, declaration = node.declaration;
|
|
1782
|
+
if (t7.isFunctionExpression(declaration) || t7.isArrowFunctionExpression(declaration) || t7.isClassExpression(declaration)) {
|
|
1783
|
+
let identifierName = createComponentNameFromFileName(fileName), identifier = path2.scope.generateUidIdentifier(identifierName), variableDeclaration = t7.variableDeclaration("const", [
|
|
1784
|
+
t7.variableDeclarator(identifier, declaration)
|
|
1785
|
+
]);
|
|
1786
|
+
variableDeclaration.loc = node.loc, path2.insertBefore(variableDeclaration), node.declaration = identifier;
|
|
1787
|
+
let insertedVarPath = path2.getPrevSibling(), initPath = null;
|
|
1788
|
+
if (insertedVarPath?.isVariableDeclaration()) {
|
|
1789
|
+
let declarationPath = insertedVarPath.get("declarations")[0];
|
|
1790
|
+
declarationPath?.isVariableDeclarator() && (initPath = declarationPath.get("init"));
|
|
1791
|
+
}
|
|
1792
|
+
addComponent(identifierName, identifier, initPath);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
if (t7.isIdentifier(declaration)) {
|
|
1796
|
+
let binding = path2.scope.getBinding(declaration.name);
|
|
1797
|
+
if (!binding)
|
|
1798
|
+
return;
|
|
1799
|
+
let bindingIdentifier = binding.identifier;
|
|
1800
|
+
if (!t7.isIdentifier(bindingIdentifier))
|
|
1801
|
+
return;
|
|
1802
|
+
if (binding.path.isVariableDeclarator())
|
|
1803
|
+
addComponent(
|
|
1804
|
+
createComponentNameFromFileName(fileName),
|
|
1805
|
+
bindingIdentifier,
|
|
1806
|
+
binding.path.get("init")
|
|
1807
|
+
);
|
|
1808
|
+
else if (binding.path.isFunctionDeclaration() || binding.path.isClassDeclaration()) {
|
|
1809
|
+
let bindingNodeId = binding.path.node.id;
|
|
1810
|
+
t7.isIdentifier(bindingNodeId) && addComponent(bindingNodeId.name, bindingIdentifier, binding.path);
|
|
1811
|
+
}
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
if (t7.isFunctionDeclaration(declaration) && declaration.id) {
|
|
1815
|
+
addComponent(
|
|
1816
|
+
declaration.id.name,
|
|
1817
|
+
declaration.id,
|
|
1818
|
+
path2.get("declaration")
|
|
1819
|
+
);
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
t7.isClassDeclaration(declaration) && declaration.id && addComponent(
|
|
1823
|
+
declaration.id.name,
|
|
1824
|
+
declaration.id,
|
|
1825
|
+
path2.get("declaration")
|
|
1826
|
+
);
|
|
1827
|
+
}
|
|
1828
|
+
}), components;
|
|
1829
|
+
}, componentTransform = async ({
|
|
1830
|
+
code,
|
|
1831
|
+
fileName,
|
|
1832
|
+
getComponentArgTypes
|
|
1833
|
+
}) => {
|
|
1834
|
+
let ast = babelParse4(code), file = new BabelFileClass2({ filename: fileName, highlightCode: !1 }, { code, ast }), components = collectComponentExports(ast.program, fileName);
|
|
1835
|
+
if (!components.length)
|
|
1836
|
+
return { code, map: null };
|
|
1837
|
+
let vitestTestId = file.path.scope.generateUidIdentifier("test"), vitestExpectId = file.path.scope.generateUidIdentifier("expect"), testStoryId = file.path.scope.generateUidIdentifier("testStory"), convertToFilePathId = t7.identifier("convertToFilePath"), fnId = file.path.scope.generateUidIdentifier("fn");
|
|
1838
|
+
dedupeImports(ast.program, VITEST_IMPORT_SOURCE, [
|
|
1839
|
+
t7.importSpecifier(vitestTestId, t7.identifier("test")),
|
|
1840
|
+
t7.importSpecifier(vitestExpectId, t7.identifier("expect"))
|
|
1841
|
+
]), dedupeImports(ast.program, TEST_UTILS_IMPORT_SOURCE, [
|
|
1842
|
+
t7.importSpecifier(testStoryId, t7.identifier("testStory")),
|
|
1843
|
+
t7.importSpecifier(convertToFilePathId, t7.identifier("convertToFilePath"))
|
|
1844
|
+
]);
|
|
1845
|
+
let testStatements = [], hasFunctionPlaceholder = (value) => JSON.stringify(value).includes(STORYBOOK_FN_PLACEHOLDER), valueToNodeRecursive = (value, replaceFnCalls) => {
|
|
1846
|
+
if (!replaceFnCalls)
|
|
1847
|
+
return t7.valueToNode(value);
|
|
1848
|
+
if (value === STORYBOOK_FN_PLACEHOLDER)
|
|
1849
|
+
return t7.callExpression(fnId, []);
|
|
1850
|
+
if (typeof value == "object" && value !== null) {
|
|
1851
|
+
if (Array.isArray(value))
|
|
1852
|
+
return t7.arrayExpression(value.map((val) => valueToNodeRecursive(val, replaceFnCalls)));
|
|
1853
|
+
let properties = Object.entries(value).map(([key, val]) => {
|
|
1854
|
+
let keyNode = t7.isValidIdentifier(key) ? t7.identifier(key) : t7.stringLiteral(key);
|
|
1855
|
+
return t7.objectProperty(keyNode, valueToNodeRecursive(val, replaceFnCalls));
|
|
1856
|
+
});
|
|
1857
|
+
return t7.objectExpression(properties);
|
|
1858
|
+
}
|
|
1859
|
+
return t7.valueToNode(value);
|
|
1860
|
+
}, buildArgsExpression = (args, useFnImport = !1) => {
|
|
1861
|
+
if (!args || Object.keys(args).length === 0)
|
|
1862
|
+
return t7.objectExpression([]);
|
|
1863
|
+
let properties = Object.entries(args).map(([key, value]) => {
|
|
1864
|
+
let keyNode = t7.isValidIdentifier(key) ? t7.identifier(key) : t7.stringLiteral(key);
|
|
1865
|
+
return t7.objectProperty(keyNode, valueToNodeRecursive(value, useFnImport));
|
|
1866
|
+
});
|
|
1867
|
+
return t7.objectExpression(properties);
|
|
1868
|
+
}, hasAnyFunctionPlaceholders = !1;
|
|
1869
|
+
for (let component of components) {
|
|
1870
|
+
let argTypes = getComponentArgTypes ? await getComponentArgTypes({ componentName: component.exportedName, fileName }) : void 0, generatedArgs = argTypes ? generateDummyArgsFromArgTypes(argTypes, { skipUrlGeneration: !0 }).required : void 0;
|
|
1871
|
+
!hasAnyFunctionPlaceholders && generatedArgs && hasFunctionPlaceholder(generatedArgs) && (hasAnyFunctionPlaceholders = !0);
|
|
1872
|
+
let meta = t7.objectExpression([
|
|
1873
|
+
t7.objectProperty(
|
|
1874
|
+
t7.identifier("title"),
|
|
1875
|
+
t7.stringLiteral(`generated/tests/${component.exportedName}`)
|
|
1876
|
+
),
|
|
1877
|
+
t7.objectProperty(t7.identifier("component"), component.localIdentifier)
|
|
1878
|
+
]), testStoryArgs = t7.objectExpression([
|
|
1879
|
+
t7.objectProperty(t7.identifier("exportName"), t7.stringLiteral(component.exportedName)),
|
|
1880
|
+
// This is where the story annotation for a particular component is defined, inline
|
|
1881
|
+
t7.objectProperty(
|
|
1882
|
+
t7.identifier("story"),
|
|
1883
|
+
t7.objectExpression([
|
|
1884
|
+
t7.objectProperty(
|
|
1885
|
+
t7.identifier("args"),
|
|
1886
|
+
buildArgsExpression(generatedArgs, hasAnyFunctionPlaceholders)
|
|
1887
|
+
)
|
|
1888
|
+
])
|
|
1889
|
+
),
|
|
1890
|
+
t7.objectProperty(t7.identifier("meta"), meta),
|
|
1891
|
+
t7.objectProperty(t7.identifier("skipTags"), t7.arrayExpression([])),
|
|
1892
|
+
t7.objectProperty(
|
|
1893
|
+
t7.identifier("storyId"),
|
|
1894
|
+
t7.stringLiteral(`generated-${component.exportedName}`)
|
|
1895
|
+
),
|
|
1896
|
+
t7.objectProperty(t7.identifier("componentPath"), t7.stringLiteral(fileName)),
|
|
1897
|
+
t7.objectProperty(
|
|
1898
|
+
t7.identifier("componentName"),
|
|
1899
|
+
t7.stringLiteral(component.localIdentifier.name)
|
|
1900
|
+
)
|
|
1901
|
+
]), testCall = t7.expressionStatement(
|
|
1902
|
+
t7.callExpression(vitestTestId, [
|
|
1903
|
+
t7.stringLiteral(component.exportedName),
|
|
1904
|
+
t7.callExpression(testStoryId, [testStoryArgs])
|
|
1905
|
+
])
|
|
1906
|
+
);
|
|
1907
|
+
testStatements.push(testCall);
|
|
1908
|
+
}
|
|
1909
|
+
hasAnyFunctionPlaceholders && dedupeImports(ast.program, STORYBOOK_TEST_IMPORT_SOURCE, [
|
|
1910
|
+
t7.importSpecifier(fnId, t7.identifier("fn"))
|
|
1911
|
+
]);
|
|
1912
|
+
let { declaration: guardDeclaration, identifier: guardIdentifier } = createTestGuardDeclaration(
|
|
1913
|
+
file.path.scope,
|
|
1914
|
+
vitestExpectId,
|
|
1915
|
+
convertToFilePathId
|
|
1916
|
+
);
|
|
1917
|
+
return ast.program.body.push(guardDeclaration), ast.program.body.push(t7.ifStatement(guardIdentifier, t7.blockStatement(testStatements))), generate5(ast, { sourceMaps: !0, sourceFileName: fileName }, code);
|
|
1918
|
+
};
|
|
1919
|
+
|
|
1540
1920
|
export {
|
|
1921
|
+
Tag,
|
|
1541
1922
|
isValidPreviewPath,
|
|
1542
1923
|
isModuleMock,
|
|
1543
1924
|
NoMetaError,
|
|
@@ -1565,5 +1946,8 @@ export {
|
|
|
1565
1946
|
extractSource,
|
|
1566
1947
|
extractDescription,
|
|
1567
1948
|
vitestTransform,
|
|
1568
|
-
|
|
1949
|
+
STORYBOOK_FN_PLACEHOLDER,
|
|
1950
|
+
generateDummyArgsFromArgTypes,
|
|
1951
|
+
componentTransform,
|
|
1952
|
+
babelParse5 as babelParse
|
|
1569
1953
|
};
|