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,23 +1,20 @@
|
|
|
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 {
|
|
13
|
-
Tag
|
|
14
|
-
} from "./chunk-2BHD5YKF.js";
|
|
15
12
|
import {
|
|
16
13
|
require_dist
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-G7P42ZEY.js";
|
|
18
15
|
import {
|
|
19
16
|
__toESM
|
|
20
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-25OWI2RR.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,31 +413,34 @@ 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)}.
|
|
404
421
|
|
|
405
422
|
SB8 does not support \`storiesOf\`.
|
|
406
423
|
`);
|
|
407
|
-
if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" &&
|
|
408
|
-
let
|
|
409
|
-
if (t2.
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
+
if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && node.arguments.length > 0) {
|
|
425
|
+
let rootObject = callee.object;
|
|
426
|
+
if (t2.isCallExpression(rootObject) && t2.isMemberExpression(rootObject.callee) && (rootObject = rootObject.callee.object), t2.isIdentifier(rootObject)) {
|
|
427
|
+
let configParent = path2.scope.getBinding(rootObject.name)?.path?.parentPath?.node;
|
|
428
|
+
if (t2.isImportDeclaration(configParent))
|
|
429
|
+
if (isValidPreviewPath(configParent.source.value)) {
|
|
430
|
+
self._metaIsFactory = !0;
|
|
431
|
+
let metaDeclarator = path2.findParent(
|
|
432
|
+
(p) => p.isVariableDeclarator()
|
|
433
|
+
);
|
|
434
|
+
self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
|
|
435
|
+
let metaNode = node.arguments[0];
|
|
436
|
+
self._parseMeta(metaNode, self._ast.program);
|
|
437
|
+
} else
|
|
438
|
+
throw new BadMetaError(
|
|
439
|
+
"meta() factory must be imported from .storybook/preview configuration",
|
|
440
|
+
configParent,
|
|
441
|
+
self._options.fileName
|
|
442
|
+
);
|
|
443
|
+
}
|
|
424
444
|
}
|
|
425
445
|
}
|
|
426
446
|
},
|
|
@@ -454,7 +474,7 @@ var formatLocation = (node, fileName) => {
|
|
|
454
474
|
});
|
|
455
475
|
let storyExport = self.getStoryExport(key);
|
|
456
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));
|
|
457
|
-
let storyNode = self._storyStatements[key], storyTests = self._tests.filter((
|
|
477
|
+
let storyNode = self._storyStatements[key], storyTests = self._tests.filter((t8) => t8.parent.node === storyNode);
|
|
458
478
|
return storyTests.length > 0 && (stats.tests = !0, storyTests.forEach((test) => {
|
|
459
479
|
test.id = toTestId(id, test.name);
|
|
460
480
|
})), acc;
|
|
@@ -483,7 +503,7 @@ var formatLocation = (node, fileName) => {
|
|
|
483
503
|
}
|
|
484
504
|
getStoryTests(story) {
|
|
485
505
|
let storyNode = typeof story == "string" ? this._storyStatements[story] : story;
|
|
486
|
-
return storyNode ? this._tests.filter((
|
|
506
|
+
return storyNode ? this._tests.filter((t8) => t8.parent.node === storyNode) : [];
|
|
487
507
|
}
|
|
488
508
|
get indexInputs() {
|
|
489
509
|
let { fileName } = this._options;
|
|
@@ -570,35 +590,35 @@ var getCsfParsingErrorMessage = ({
|
|
|
570
590
|
node
|
|
571
591
|
}) => import_ts_dedent2.dedent`
|
|
572
592
|
CSF Parsing error: Expected '${expectedType}' but found '${foundType}' instead in '${node?.type}'.
|
|
573
|
-
`, propKey = (p) => t3.isIdentifier(p.key) ? p.key.name : t3.isStringLiteral(p.key) ? p.key.value : null, _getPath = (
|
|
574
|
-
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)
|
|
575
595
|
return node;
|
|
576
596
|
if (t3.isObjectExpression(node)) {
|
|
577
|
-
let [first, ...rest] =
|
|
597
|
+
let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
|
|
578
598
|
if (field)
|
|
579
599
|
return _getPath(rest, field.value);
|
|
580
600
|
}
|
|
581
|
-
}, _getPathProperties = (
|
|
582
|
-
if (
|
|
601
|
+
}, _getPathProperties = (path2, node) => {
|
|
602
|
+
if (path2.length === 0) {
|
|
583
603
|
if (t3.isObjectExpression(node))
|
|
584
604
|
return node.properties;
|
|
585
605
|
throw new Error("Expected object expression");
|
|
586
606
|
}
|
|
587
607
|
if (t3.isObjectExpression(node)) {
|
|
588
|
-
let [first, ...rest] =
|
|
608
|
+
let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
|
|
589
609
|
if (field)
|
|
590
610
|
return rest.length === 0 ? node.properties : _getPathProperties(rest, field.value);
|
|
591
611
|
}
|
|
592
612
|
}, _findVarDeclarator = (identifier, program) => {
|
|
593
613
|
let declarator = null, declarations = null;
|
|
594
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;
|
|
595
|
-
}, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (
|
|
596
|
-
if (
|
|
615
|
+
}, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (path2, value) => {
|
|
616
|
+
if (path2.length === 0)
|
|
597
617
|
return value;
|
|
598
|
-
let [first, ...rest] =
|
|
618
|
+
let [first, ...rest] = path2, innerExpression = _makeObjectExpression(rest, value);
|
|
599
619
|
return t3.objectExpression([t3.objectProperty(t3.identifier(first), innerExpression)]);
|
|
600
|
-
}, _updateExportNode = (
|
|
601
|
-
let [first, ...rest] =
|
|
620
|
+
}, _updateExportNode = (path2, expr, existing) => {
|
|
621
|
+
let [first, ...rest] = path2, existingField = existing.properties.find(
|
|
602
622
|
(p) => propKey(p) === first
|
|
603
623
|
);
|
|
604
624
|
existingField ? t3.isObjectExpression(existingField.value) && rest.length > 0 ? _updateExportNode(rest, expr, existingField.value) : existingField.value = _makeObjectExpression(rest, expr) : existing.properties.push(
|
|
@@ -712,31 +732,31 @@ var getCsfParsingErrorMessage = ({
|
|
|
712
732
|
}
|
|
713
733
|
}), self;
|
|
714
734
|
}
|
|
715
|
-
getFieldNode(
|
|
716
|
-
let [root, ...rest] =
|
|
735
|
+
getFieldNode(path2) {
|
|
736
|
+
let [root, ...rest] = path2, exported = this._exports[root];
|
|
717
737
|
if (exported)
|
|
718
738
|
return _getPath(rest, exported);
|
|
719
739
|
}
|
|
720
|
-
getFieldProperties(
|
|
721
|
-
let [root, ...rest] =
|
|
740
|
+
getFieldProperties(path2) {
|
|
741
|
+
let [root, ...rest] = path2, exported = this._exports[root];
|
|
722
742
|
if (exported)
|
|
723
743
|
return _getPathProperties(rest, exported);
|
|
724
744
|
}
|
|
725
|
-
getFieldValue(
|
|
726
|
-
let node = this.getFieldNode(
|
|
745
|
+
getFieldValue(path2) {
|
|
746
|
+
let node = this.getFieldNode(path2);
|
|
727
747
|
if (node) {
|
|
728
748
|
let { code } = generate2(node, {});
|
|
729
749
|
return (0, eval)(`(() => (${code}))()`);
|
|
730
750
|
}
|
|
731
751
|
}
|
|
732
|
-
getSafeFieldValue(
|
|
752
|
+
getSafeFieldValue(path2) {
|
|
733
753
|
try {
|
|
734
|
-
return this.getFieldValue(
|
|
754
|
+
return this.getFieldValue(path2);
|
|
735
755
|
} catch {
|
|
736
756
|
}
|
|
737
757
|
}
|
|
738
|
-
setFieldNode(
|
|
739
|
-
let [first, ...rest] =
|
|
758
|
+
setFieldNode(path2, expr) {
|
|
759
|
+
let [first, ...rest] = path2, exportNode = this._exports[first];
|
|
740
760
|
if (this._exportsObject) {
|
|
741
761
|
let existingProp = this._exportsObject.properties.find((p) => propKey(p) === first);
|
|
742
762
|
if (existingProp && t3.isIdentifier(existingProp.value)) {
|
|
@@ -746,7 +766,7 @@ var getCsfParsingErrorMessage = ({
|
|
|
746
766
|
return;
|
|
747
767
|
}
|
|
748
768
|
}
|
|
749
|
-
_updateExportNode(
|
|
769
|
+
_updateExportNode(path2, expr, this._exportsObject), this._exports[path2[0]] = expr;
|
|
750
770
|
return;
|
|
751
771
|
}
|
|
752
772
|
if (exportNode && t3.isObjectExpression(exportNode) && rest.length > 0) {
|
|
@@ -758,13 +778,13 @@ var getCsfParsingErrorMessage = ({
|
|
|
758
778
|
_updateExportNode(rest, expr, varDecl.init);
|
|
759
779
|
return;
|
|
760
780
|
}
|
|
761
|
-
if (exportNode && rest.length === 0 && this._exportDecls[
|
|
762
|
-
let decl = this._exportDecls[
|
|
781
|
+
if (exportNode && rest.length === 0 && this._exportDecls[path2[0]]) {
|
|
782
|
+
let decl = this._exportDecls[path2[0]];
|
|
763
783
|
t3.isVariableDeclarator(decl) && (decl.init = _makeObjectExpression([], expr));
|
|
764
784
|
} else {
|
|
765
785
|
if (this.hasDefaultExport)
|
|
766
786
|
throw new Error(
|
|
767
|
-
`Could not set the "${
|
|
787
|
+
`Could not set the "${path2.join(
|
|
768
788
|
"."
|
|
769
789
|
)}" field as the default export is not an object in this file.`
|
|
770
790
|
);
|
|
@@ -787,8 +807,8 @@ var getCsfParsingErrorMessage = ({
|
|
|
787
807
|
*
|
|
788
808
|
* @returns The name of a node in a given path, supporting the following formats:
|
|
789
809
|
*/
|
|
790
|
-
getNameFromPath(
|
|
791
|
-
let node = this.getFieldNode(
|
|
810
|
+
getNameFromPath(path2) {
|
|
811
|
+
let node = this.getFieldNode(path2);
|
|
792
812
|
if (node)
|
|
793
813
|
return this._getPresetValue(node, "name");
|
|
794
814
|
}
|
|
@@ -805,8 +825,8 @@ var getCsfParsingErrorMessage = ({
|
|
|
805
825
|
* getNamesFromPath(['addons']);
|
|
806
826
|
* ```
|
|
807
827
|
*/
|
|
808
|
-
getNamesFromPath(
|
|
809
|
-
let node = this.getFieldNode(
|
|
828
|
+
getNamesFromPath(path2) {
|
|
829
|
+
let node = this.getFieldNode(path2);
|
|
810
830
|
if (!node)
|
|
811
831
|
return;
|
|
812
832
|
let pathNames = [];
|
|
@@ -837,68 +857,68 @@ var getCsfParsingErrorMessage = ({
|
|
|
837
857
|
);
|
|
838
858
|
return value;
|
|
839
859
|
}
|
|
840
|
-
removeField(
|
|
860
|
+
removeField(path2) {
|
|
841
861
|
let removeProperty = (properties2, prop) => {
|
|
842
862
|
let index = properties2.findIndex(
|
|
843
863
|
(p) => t3.isIdentifier(p.key) && p.key.name === prop || t3.isStringLiteral(p.key) && p.key.value === prop
|
|
844
864
|
);
|
|
845
865
|
index >= 0 && properties2.splice(index, 1);
|
|
846
866
|
};
|
|
847
|
-
if (
|
|
867
|
+
if (path2.length === 1) {
|
|
848
868
|
let removedRootProperty = !1;
|
|
849
869
|
if (this._ast.program.body.forEach((node) => {
|
|
850
870
|
if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
|
|
851
871
|
let decl = node.declaration.declarations[0];
|
|
852
|
-
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);
|
|
853
873
|
}
|
|
854
874
|
if (t3.isExportDefaultDeclaration(node)) {
|
|
855
875
|
let resolved = this._resolveDeclaration(node.declaration);
|
|
856
876
|
if (t3.isObjectExpression(resolved)) {
|
|
857
877
|
let properties2 = resolved.properties;
|
|
858
|
-
removeProperty(properties2,
|
|
878
|
+
removeProperty(properties2, path2[0]), removedRootProperty = !0;
|
|
859
879
|
}
|
|
860
880
|
}
|
|
861
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)) {
|
|
862
882
|
let properties2 = node.expression.right.properties;
|
|
863
|
-
removeProperty(properties2,
|
|
883
|
+
removeProperty(properties2, path2[0]), removedRootProperty = !0;
|
|
864
884
|
}
|
|
865
885
|
}), removedRootProperty)
|
|
866
886
|
return;
|
|
867
887
|
}
|
|
868
|
-
let properties = this.getFieldProperties(
|
|
888
|
+
let properties = this.getFieldProperties(path2);
|
|
869
889
|
if (properties) {
|
|
870
|
-
let lastPath =
|
|
890
|
+
let lastPath = path2.at(-1);
|
|
871
891
|
removeProperty(properties, lastPath);
|
|
872
892
|
}
|
|
873
893
|
}
|
|
874
|
-
appendValueToArray(
|
|
894
|
+
appendValueToArray(path2, value) {
|
|
875
895
|
let node = this.valueToNode(value);
|
|
876
|
-
node && this.appendNodeToArray(
|
|
896
|
+
node && this.appendNodeToArray(path2, node);
|
|
877
897
|
}
|
|
878
|
-
appendNodeToArray(
|
|
879
|
-
let current = this.getFieldNode(
|
|
898
|
+
appendNodeToArray(path2, node) {
|
|
899
|
+
let current = this.getFieldNode(path2);
|
|
880
900
|
if (!current)
|
|
881
|
-
this.setFieldNode(
|
|
901
|
+
this.setFieldNode(path2, t3.arrayExpression([node]));
|
|
882
902
|
else if (t3.isArrayExpression(current))
|
|
883
903
|
current.elements.push(node);
|
|
884
904
|
else
|
|
885
|
-
throw new Error(`Expected array at '${
|
|
905
|
+
throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
|
|
886
906
|
}
|
|
887
907
|
/**
|
|
888
908
|
* Specialized helper to remove addons or other array entries that can either be strings or
|
|
889
909
|
* objects with a name property.
|
|
890
910
|
*/
|
|
891
|
-
removeEntryFromArray(
|
|
892
|
-
let current = this.getFieldNode(
|
|
911
|
+
removeEntryFromArray(path2, value) {
|
|
912
|
+
let current = this.getFieldNode(path2);
|
|
893
913
|
if (current)
|
|
894
914
|
if (t3.isArrayExpression(current)) {
|
|
895
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);
|
|
896
916
|
if (index >= 0)
|
|
897
917
|
current.elements.splice(index, 1);
|
|
898
918
|
else
|
|
899
|
-
throw new Error(`Could not find '${value}' in array at '${
|
|
919
|
+
throw new Error(`Could not find '${value}' in array at '${path2.join(".")}'`);
|
|
900
920
|
} else
|
|
901
|
-
throw new Error(`Expected array at '${
|
|
921
|
+
throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
|
|
902
922
|
}
|
|
903
923
|
_inferQuotes() {
|
|
904
924
|
if (!this._quotes) {
|
|
@@ -925,11 +945,11 @@ var getCsfParsingErrorMessage = ({
|
|
|
925
945
|
valueNode = t3.valueToNode(value);
|
|
926
946
|
return valueNode;
|
|
927
947
|
}
|
|
928
|
-
setFieldValue(
|
|
948
|
+
setFieldValue(path2, value) {
|
|
929
949
|
let valueNode = this.valueToNode(value);
|
|
930
950
|
if (!valueNode)
|
|
931
951
|
throw new Error(`Unexpected value ${JSON.stringify(value)}`);
|
|
932
|
-
this.setFieldNode(
|
|
952
|
+
this.setFieldNode(path2, valueNode);
|
|
933
953
|
}
|
|
934
954
|
getBodyDeclarations() {
|
|
935
955
|
return this._ast.program.body;
|
|
@@ -1293,14 +1313,14 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
|
|
|
1293
1313
|
);
|
|
1294
1314
|
csf._ast.program.body.push(addParameter);
|
|
1295
1315
|
}
|
|
1296
|
-
}, addComponentDescription = (node,
|
|
1297
|
-
if (!
|
|
1316
|
+
}, addComponentDescription = (node, path2, value) => {
|
|
1317
|
+
if (!path2.length) {
|
|
1298
1318
|
node.properties.find(
|
|
1299
1319
|
(p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === "component"
|
|
1300
1320
|
) || node.properties.unshift(value);
|
|
1301
1321
|
return;
|
|
1302
1322
|
}
|
|
1303
|
-
let [first, ...rest] =
|
|
1323
|
+
let [first, ...rest] = path2, existing = node.properties.find(
|
|
1304
1324
|
(p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === first && t5.isObjectExpression(p.value)
|
|
1305
1325
|
), subNode;
|
|
1306
1326
|
existing ? subNode = existing.value : (subNode = t5.objectExpression([]), node.properties.push(t5.objectProperty(t5.identifier(first), subNode))), addComponentDescription(subNode, rest, value);
|
|
@@ -1327,7 +1347,7 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
|
|
|
1327
1347
|
`) : "";
|
|
1328
1348
|
|
|
1329
1349
|
// src/csf-tools/index.ts
|
|
1330
|
-
import { babelParse as
|
|
1350
|
+
import { babelParse as babelParse5 } from "storybook/internal/babel";
|
|
1331
1351
|
|
|
1332
1352
|
// src/csf-tools/vitest-plugin/transformer.ts
|
|
1333
1353
|
var import_ts_dedent4 = __toESM(require_dist(), 1);
|
|
@@ -1336,6 +1356,38 @@ import { getStoryTitle } from "storybook/internal/common";
|
|
|
1336
1356
|
import { combineTags } from "storybook/internal/csf";
|
|
1337
1357
|
import { logger as logger4 } from "storybook/internal/node-logger";
|
|
1338
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
|
+
}
|
|
1339
1391
|
async function vitestTransform({
|
|
1340
1392
|
code,
|
|
1341
1393
|
fileName,
|
|
@@ -1400,37 +1452,13 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1400
1452
|
];
|
|
1401
1453
|
return ast.program.body.unshift(...imports2), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
|
|
1402
1454
|
}
|
|
1403
|
-
let vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect"), testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory"), skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
t6.identifier("filepath")
|
|
1411
|
-
), nullishCoalescingExpression = t6.logicalExpression(
|
|
1412
|
-
"??",
|
|
1413
|
-
// TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
|
|
1414
|
-
// https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
|
|
1415
|
-
filePathProperty,
|
|
1416
|
-
testPathProperty
|
|
1417
|
-
), includesCall = t6.callExpression(
|
|
1418
|
-
t6.memberExpression(
|
|
1419
|
-
t6.callExpression(t6.identifier("convertToFilePath"), [
|
|
1420
|
-
t6.memberExpression(
|
|
1421
|
-
t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
|
|
1422
|
-
t6.identifier("url")
|
|
1423
|
-
)
|
|
1424
|
-
]),
|
|
1425
|
-
t6.identifier("includes")
|
|
1426
|
-
),
|
|
1427
|
-
[nullishCoalescingExpression]
|
|
1428
|
-
);
|
|
1429
|
-
return { isRunningFromThisFileDeclaration: t6.variableDeclaration("const", [
|
|
1430
|
-
t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
|
|
1431
|
-
]), isRunningFromThisFileId: isRunningFromThisFileId2 };
|
|
1432
|
-
}
|
|
1433
|
-
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
|
+
);
|
|
1434
1462
|
ast.program.body.push(isRunningFromThisFileDeclaration);
|
|
1435
1463
|
let getTestStatementForStory = ({
|
|
1436
1464
|
localName,
|
|
@@ -1440,16 +1468,18 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1440
1468
|
overrideSourcemap = !0,
|
|
1441
1469
|
storyId
|
|
1442
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));
|
|
1443
1479
|
let testStoryCall = t6.expressionStatement(
|
|
1444
1480
|
t6.callExpression(vitestTestId, [
|
|
1445
1481
|
t6.stringLiteral(testTitle),
|
|
1446
|
-
t6.callExpression(testStoryId, [
|
|
1447
|
-
t6.stringLiteral(exportName),
|
|
1448
|
-
t6.identifier(localName),
|
|
1449
|
-
t6.identifier(metaExportName),
|
|
1450
|
-
skipTagsId,
|
|
1451
|
-
t6.stringLiteral(storyId)
|
|
1452
|
-
])
|
|
1482
|
+
t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
|
|
1453
1483
|
])
|
|
1454
1484
|
);
|
|
1455
1485
|
return overrideSourcemap && (testStoryCall.loc = node.loc), testStoryCall;
|
|
@@ -1466,17 +1496,24 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1466
1496
|
storyId: parentStoryId
|
|
1467
1497
|
}),
|
|
1468
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
|
+
);
|
|
1469
1513
|
let testStatement = t6.expressionStatement(
|
|
1470
1514
|
t6.callExpression(vitestTestId, [
|
|
1471
1515
|
t6.stringLiteral(testName),
|
|
1472
|
-
t6.callExpression(testStoryId, [
|
|
1473
|
-
t6.stringLiteral(exportName),
|
|
1474
|
-
t6.identifier(localName),
|
|
1475
|
-
t6.identifier(metaExportName),
|
|
1476
|
-
t6.arrayExpression([]),
|
|
1477
|
-
t6.stringLiteral(storyId),
|
|
1478
|
-
t6.stringLiteral(testName)
|
|
1479
|
-
])
|
|
1516
|
+
t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
|
|
1480
1517
|
])
|
|
1481
1518
|
);
|
|
1482
1519
|
return testStatement.loc = testNode.loc, testStatement;
|
|
@@ -1534,7 +1571,354 @@ Please make sure you have a default export with the meta object. If you are usin
|
|
|
1534
1571
|
return ast.program.body.unshift(...imports), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
|
|
1535
1572
|
}
|
|
1536
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
|
+
|
|
1537
1920
|
export {
|
|
1921
|
+
Tag,
|
|
1538
1922
|
isValidPreviewPath,
|
|
1539
1923
|
isModuleMock,
|
|
1540
1924
|
NoMetaError,
|
|
@@ -1562,5 +1946,8 @@ export {
|
|
|
1562
1946
|
extractSource,
|
|
1563
1947
|
extractDescription,
|
|
1564
1948
|
vitestTransform,
|
|
1565
|
-
|
|
1949
|
+
STORYBOOK_FN_PLACEHOLDER,
|
|
1950
|
+
generateDummyArgsFromArgTypes,
|
|
1951
|
+
componentTransform,
|
|
1952
|
+
babelParse5 as babelParse
|
|
1566
1953
|
};
|