storybook 10.2.0-alpha.8 → 10.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/_browser-chunks/{Color-E5XDEOX4.js → Color-XESOIGZP.js} +57 -3
  2. package/dist/_browser-chunks/chunk-AFVOZMXQ.js +23 -0
  3. package/dist/_browser-chunks/{chunk-3PJE6VLG.js → chunk-ASKQZAOS.js} +1 -12
  4. package/dist/_browser-chunks/chunk-IYCKG66Y.js +171 -0
  5. package/dist/_browser-chunks/chunk-LCHBOIHN.js +64 -0
  6. package/dist/_browser-chunks/{chunk-IPA5A322.js → chunk-MEXTPDJG.js} +1 -1
  7. package/dist/_browser-chunks/{chunk-54PNNATT.js → chunk-NQJGOFZV.js} +18 -1
  8. package/dist/_browser-chunks/{chunk-VUZYLZ4B.js → chunk-QOXZ7W26.js} +31 -15
  9. package/dist/_browser-chunks/{chunk-LOTN4ZCW.js → chunk-SI6AKD4S.js} +2 -2
  10. package/dist/_browser-chunks/chunk-YK43Z22A.js +263 -0
  11. package/dist/_node-chunks/{builder-manager-2XASU3VS.js → builder-manager-JEJE63VV.js} +15 -12
  12. package/dist/_node-chunks/camelcase-HALRJETF.js +62 -0
  13. package/dist/_node-chunks/{chunk-5GRHJJHD.js → chunk-3SKE4CCB.js} +9 -9
  14. package/dist/_node-chunks/chunk-4UYAC7Y2.js +18 -0
  15. package/dist/_node-chunks/{chunk-S7FIFCTX.js → chunk-6UAQEBJX.js} +10 -10
  16. package/dist/_node-chunks/{chunk-ZKB7MQRR.js → chunk-72K4WVI5.js} +18 -14
  17. package/dist/_node-chunks/{chunk-6TJUL42C.js → chunk-7ZX5CX6B.js} +15 -69
  18. package/dist/_node-chunks/{chunk-LEZENLG7.js → chunk-ADTWC7QJ.js} +7 -7
  19. package/dist/_node-chunks/{chunk-2OC7H5MZ.js → chunk-APUXGW3Y.js} +7 -7
  20. package/dist/_node-chunks/{chunk-5WQXPM6D.js → chunk-AXDM43NU.js} +6 -6
  21. package/dist/_node-chunks/{chunk-LOXLI4XT.js → chunk-B422K4XV.js} +6 -6
  22. package/dist/_node-chunks/{chunk-3K6P75SS.js → chunk-BJOXVTWM.js} +12 -571
  23. package/dist/_node-chunks/{chunk-TTGXODEY.js → chunk-BLGRU6F5.js} +7 -7
  24. package/dist/_node-chunks/{chunk-2KSITKBI.js → chunk-CG47ALAV.js} +7 -7
  25. package/dist/_node-chunks/chunk-FH4FRUMP.js +23 -0
  26. package/dist/_node-chunks/{chunk-DTM4A3DJ.js → chunk-GBZ23FIZ.js} +125 -73
  27. package/dist/_node-chunks/{chunk-IJ34563N.js → chunk-IZ3ATSWZ.js} +5262 -1480
  28. package/dist/_node-chunks/{chunk-JWL5NLJU.js → chunk-IZFEBWVB.js} +6 -6
  29. package/dist/_node-chunks/{chunk-5BRYY6XB.js → chunk-KL5CKFPT.js} +9 -9
  30. package/dist/_node-chunks/{chunk-COGO4JMD.js → chunk-MLXCYULR.js} +7 -7
  31. package/dist/_node-chunks/{chunk-7B4JYHGV.js → chunk-MV2QM7P3.js} +6 -6
  32. package/dist/_node-chunks/chunk-PHX5XNP7.js +144 -0
  33. package/dist/_node-chunks/{chunk-VJFHZL2T.js → chunk-QL6L57W7.js} +533 -144
  34. package/dist/_node-chunks/{chunk-Q6WPGVIW.js → chunk-RPBXVPRB.js} +6 -6
  35. package/dist/_node-chunks/{chunk-DYQ6QR45.js → chunk-UH2GWMFP.js} +260 -162
  36. package/dist/_node-chunks/chunk-WNGL2VRJ.js +126 -0
  37. package/dist/_node-chunks/{chunk-WKC523P7.js → chunk-XAL452XB.js} +36 -14
  38. package/dist/_node-chunks/{chunk-UNHOAAXU.js → chunk-YVXXMWQO.js} +7 -7
  39. package/dist/_node-chunks/chunk-YYDL7JOC.js +61 -0
  40. package/dist/_node-chunks/{chunk-MLYPMYG5.js → chunk-Z7FLE2TR.js} +6 -6
  41. package/dist/_node-chunks/{globby-FWMT4OOQ.js → globby-4D4NBVG7.js} +11 -20
  42. package/dist/_node-chunks/{lib-YCGXIMW5.js → lib-RM2DWHZQ.js} +7 -7
  43. package/dist/_node-chunks/{mdx-N42X6CFJ-CRGM5LTU.js → mdx-N42X6CFJ-RAL72UTP.js} +8 -8
  44. package/dist/_node-chunks/{p-limit-UJIYI4QT.js → p-limit-6PUJQL5X.js} +18 -14
  45. package/dist/babel/index.js +10 -10
  46. package/dist/bin/core.js +12 -12
  47. package/dist/bin/dispatcher.js +11 -11
  48. package/dist/bin/loader.js +9 -9
  49. package/dist/cli/index.d.ts +1504 -424
  50. package/dist/cli/index.js +18 -18
  51. package/dist/common/index.d.ts +1319 -271
  52. package/dist/common/index.js +22 -22
  53. package/dist/components/index.d.ts +4 -1
  54. package/dist/components/index.js +228 -227
  55. package/dist/core-events/index.d.ts +23 -7
  56. package/dist/core-events/index.js +5 -1
  57. package/dist/core-server/index.d.ts +108 -4
  58. package/dist/core-server/index.js +3459 -3086
  59. package/dist/core-server/presets/common-manager.js +208 -160
  60. package/dist/core-server/presets/common-override-preset.js +11 -11
  61. package/dist/core-server/presets/common-preset.js +576 -4536
  62. package/dist/csf/index.d.ts +147 -15
  63. package/dist/csf/index.js +52 -23
  64. package/dist/csf-tools/index.d.ts +19 -1
  65. package/dist/csf-tools/index.js +11 -9
  66. package/dist/docs-tools/index.d.ts +2 -2
  67. package/dist/docs-tools/index.js +4 -5
  68. package/dist/manager/globals-runtime.js +2749 -6907
  69. package/dist/manager/runtime.js +2939 -2295
  70. package/dist/manager-api/index.d.ts +89 -21
  71. package/dist/manager-api/index.js +82 -23
  72. package/dist/mocking-utils/index.js +8 -8
  73. package/dist/node-logger/index.d.ts +1453 -108
  74. package/dist/node-logger/index.js +9 -9
  75. package/dist/preview/runtime.js +784 -5059
  76. package/dist/preview-api/index.d.ts +26 -1
  77. package/dist/preview-api/index.js +11 -8
  78. package/dist/router/index.js +5 -4
  79. package/dist/server-errors.js +11 -11
  80. package/dist/telemetry/index.d.ts +14 -2
  81. package/dist/telemetry/index.js +23 -22
  82. package/dist/theming/index.d.ts +5 -5
  83. package/dist/theming/index.js +21 -2
  84. package/dist/types/index.d.ts +24 -11
  85. package/dist/viewport/index.d.ts +5 -3
  86. package/dist/viewport/index.js +12 -3
  87. package/package.json +27 -26
  88. package/dist/_browser-chunks/chunk-2NDLAB5X.js +0 -363
  89. package/dist/_browser-chunks/chunk-CLSHX4VX.js +0 -4140
  90. package/dist/_browser-chunks/chunk-HPYUT3WS.js +0 -199
  91. package/dist/_browser-chunks/chunk-XCZK5QUJ.js +0 -0
  92. package/dist/_node-chunks/camelcase-KIWRHB2G.js +0 -37
  93. package/dist/_node-chunks/chunk-2ANLCK4Y.js +0 -18
  94. package/dist/_node-chunks/chunk-3TW66YXG.js +0 -70
  95. package/dist/_node-chunks/chunk-UFXCGC4W.js +0 -23
  96. package/dist/_node-chunks/chunk-X4YDIHYE.js +0 -61
  97. package/dist/_node-chunks/dist-GICI6ZHU.js +0 -121
@@ -1,20 +1,20 @@
1
- import CJS_COMPAT_NODE_URL_3bfbtrdgjix from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_3bfbtrdgjix from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_3bfbtrdgjix from "node:module";
1
+ import CJS_COMPAT_NODE_URL_phceqgr585q from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_phceqgr585q from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_phceqgr585q from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_3bfbtrdgjix.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_3bfbtrdgjix.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_3bfbtrdgjix.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_phceqgr585q.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_phceqgr585q.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_phceqgr585q.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
11
11
  // ------------------------------------------------------------
12
12
  import {
13
13
  require_dist
14
- } from "./chunk-TTGXODEY.js";
14
+ } from "./chunk-BLGRU6F5.js";
15
15
  import {
16
16
  __toESM
17
- } from "./chunk-5WQXPM6D.js";
17
+ } from "./chunk-AXDM43NU.js";
18
18
 
19
19
  // src/csf-tools/CsfFile.ts
20
20
  var import_ts_dedent = __toESM(require_dist(), 1);
@@ -30,6 +30,26 @@ import {
30
30
  import { isExportStory, storyNameFromExport, toId, toTestId } from "storybook/internal/csf";
31
31
  import { logger } from "storybook/internal/node-logger";
32
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
+
33
53
  // src/csf-tools/findVarInitialization.ts
34
54
  import { types as t } from "storybook/internal/babel";
35
55
  var findVarInitialization = (identifier, program) => {
@@ -232,16 +252,16 @@ var formatLocation = (node, fileName) => {
232
252
  let self = this;
233
253
  if (traverse(this._ast, {
234
254
  ExportDefaultDeclaration: {
235
- enter(path) {
236
- let { node, parent } = path, isVariableReference = t2.isIdentifier(node.declaration) && t2.isProgram(parent);
255
+ enter(path2) {
256
+ let { node, parent } = path2, isVariableReference = t2.isIdentifier(node.declaration) && t2.isProgram(parent);
237
257
  if (self._options.transformInlineMeta && !isVariableReference && t2.isExpression(node.declaration)) {
238
- let metaId = path.scope.generateUidIdentifier("meta");
258
+ let metaId = path2.scope.generateUidIdentifier("meta");
239
259
  self._metaVariableName = metaId.name;
240
260
  let nodes = [
241
261
  t2.variableDeclaration("const", [t2.variableDeclarator(metaId, node.declaration)]),
242
262
  t2.exportDefaultDeclaration(metaId)
243
263
  ];
244
- nodes.forEach((_node) => _node.loc = path.node.loc), path.replaceWithMultiple(nodes);
264
+ nodes.forEach((_node) => _node.loc = path2.node.loc), path2.replaceWithMultiple(nodes);
245
265
  return;
246
266
  }
247
267
  let metaNode, decl;
@@ -250,12 +270,12 @@ var formatLocation = (node, fileName) => {
250
270
  self._metaVariableName = variableName;
251
271
  let isMetaVariable = (declaration) => t2.isIdentifier(declaration.id) && declaration.id.name === variableName;
252
272
  self._metaStatementPath = self._file.path.get("body").find(
253
- (path2) => path2.isVariableDeclaration() && path2.node.declarations.some(isMetaVariable)
273
+ (path3) => path3.isVariableDeclaration() && path3.node.declarations.some(isMetaVariable)
254
274
  ), self._metaStatement = self._metaStatementPath?.node, decl = (self?._metaStatement?.declarations || []).find(
255
275
  isMetaVariable
256
276
  )?.init;
257
277
  } else
258
- self._metaStatement = node, self._metaStatementPath = path, decl = node.declaration;
278
+ self._metaStatement = node, self._metaStatementPath = path2, decl = node.declaration;
259
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 : (
260
280
  // export default { ... } satisfies Meta as Meta<...>
261
281
  t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression) && (metaNode = decl.expression.expression)
@@ -265,12 +285,12 @@ var formatLocation = (node, fileName) => {
265
285
  self._metaStatement,
266
286
  self._options.fileName
267
287
  );
268
- self._metaPath = path;
288
+ self._metaPath = path2;
269
289
  }
270
290
  },
271
291
  ExportNamedDeclaration: {
272
- enter(path) {
273
- let { node, parent } = path, declaration = path.get("declaration"), declarations;
292
+ enter(path2) {
293
+ let { node, parent } = path2, declaration = path2.get("declaration"), declarations;
274
294
  declaration.isVariableDeclaration() ? declarations = declaration.get("declarations").filter((d) => d.isVariableDeclarator()) : declaration.isFunctionDeclaration() && (declarations = [declaration]), declarations ? declarations.forEach((declPath) => {
275
295
  let decl = declPath.node, id = declPath.node.id;
276
296
  if (t2.isIdentifier(id)) {
@@ -279,7 +299,7 @@ var formatLocation = (node, fileName) => {
279
299
  self._namedExportsOrder = parseExportsOrder(declPath.node.init);
280
300
  return;
281
301
  }
282
- self._storyExports[exportName] = decl, self._storyDeclarationPath[exportName] = declPath, self._storyPaths[exportName] = path, self._storyStatements[exportName] = node;
302
+ self._storyExports[exportName] = decl, self._storyDeclarationPath[exportName] = declPath, self._storyPaths[exportName] = path2, self._storyStatements[exportName] = node;
283
303
  let name = storyNameFromExport(exportName);
284
304
  self._storyAnnotations[exportName] ? logger.warn(
285
305
  `Unexpected annotations for "${exportName}" before story declaration`
@@ -351,7 +371,7 @@ var formatLocation = (node, fileName) => {
351
371
  let annotations = {}, storyNode = decl;
352
372
  t2.isObjectExpression(storyNode) && storyNode.properties.forEach((p) => {
353
373
  t2.isIdentifier(p.key) && (annotations[p.key.name] = p.value);
354
- }), self._storyAnnotations[exportName] = annotations, self._storyStatements[exportName] = decl, self._storyPaths[exportName] = path, self._stories[exportName] = {
374
+ }), self._storyAnnotations[exportName] = annotations, self._storyStatements[exportName] = decl, self._storyPaths[exportName] = path2, self._stories[exportName] = {
355
375
  id: "FIXME",
356
376
  name: exportName,
357
377
  localName,
@@ -393,31 +413,34 @@ var formatLocation = (node, fileName) => {
393
413
  }
394
414
  },
395
415
  CallExpression: {
396
- enter(path) {
397
- let { node } = path, { callee } = node;
416
+ enter(path2) {
417
+ let { node } = path2, { callee } = node;
398
418
  if (t2.isIdentifier(callee) && callee.name === "storiesOf")
399
419
  throw new Error(import_ts_dedent.dedent`
400
420
  Unexpected \`storiesOf\` usage: ${formatLocation(node, self._options.fileName)}.
401
421
 
402
422
  SB8 does not support \`storiesOf\`.
403
423
  `);
404
- if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && t2.isIdentifier(callee.object) && node.arguments.length > 0) {
405
- let configParent = path.scope.getBinding(callee.object.name)?.path?.parentPath?.node;
406
- if (t2.isImportDeclaration(configParent))
407
- if (isValidPreviewPath(configParent.source.value)) {
408
- self._metaIsFactory = !0;
409
- let metaDeclarator = path.findParent(
410
- (p) => p.isVariableDeclarator()
411
- );
412
- self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
413
- let metaNode = node.arguments[0];
414
- self._parseMeta(metaNode, self._ast.program);
415
- } else
416
- throw new BadMetaError(
417
- "meta() factory must be imported from .storybook/preview configuration",
418
- configParent,
419
- self._options.fileName
420
- );
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
+ }
421
444
  }
422
445
  }
423
446
  },
@@ -433,7 +456,7 @@ var formatLocation = (node, fileName) => {
433
456
  }), !self._meta)
434
457
  throw new NoMetaError("missing default export", self._ast, self._options.fileName);
435
458
  let entries = Object.entries(self._stories);
436
- if (self._meta.title = this._options.makeTitle(self._meta?.title), self._metaAnnotations.play && (self._meta.tags = [...self._meta.tags || [], "play-fn"]), self._stories = entries.reduce(
459
+ if (self._meta.title = this._options.makeTitle(self._meta?.title), self._metaAnnotations.play && (self._meta.tags = [...self._meta.tags || [], Tag.PLAY_FN]), self._stories = entries.reduce(
437
460
  (acc, [key, story]) => {
438
461
  if (!isExportStory(key, self._meta))
439
462
  return acc;
@@ -444,14 +467,14 @@ var formatLocation = (node, fileName) => {
444
467
  let node = t2.isIdentifier(tags) ? findVarInitialization(tags.name, this._ast.program) : tags;
445
468
  acc[key].tags = parseTags(node);
446
469
  }
447
- play && (acc[key].tags = [...acc[key].tags || [], "play-fn"]);
470
+ play && (acc[key].tags = [...acc[key].tags || [], Tag.PLAY_FN]);
448
471
  let stats = acc[key].__stats;
449
472
  ["play", "render", "loaders", "beforeEach", "globals", "tags"].forEach((annotation) => {
450
473
  stats[annotation] = !!storyAnnotations[annotation] || !!self._metaAnnotations[annotation];
451
474
  });
452
475
  let storyExport = self.getStoryExport(key);
453
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));
454
- let storyNode = self._storyStatements[key], storyTests = self._tests.filter((t7) => t7.parent.node === storyNode);
477
+ let storyNode = self._storyStatements[key], storyTests = self._tests.filter((t8) => t8.parent.node === storyNode);
455
478
  return storyTests.length > 0 && (stats.tests = !0, storyTests.forEach((test) => {
456
479
  test.id = toTestId(id, test.name);
457
480
  })), acc;
@@ -480,7 +503,7 @@ var formatLocation = (node, fileName) => {
480
503
  }
481
504
  getStoryTests(story) {
482
505
  let storyNode = typeof story == "string" ? this._storyStatements[story] : story;
483
- return storyNode ? this._tests.filter((t7) => t7.parent.node === storyNode) : [];
506
+ return storyNode ? this._tests.filter((t8) => t8.parent.node === storyNode) : [];
484
507
  }
485
508
  get indexInputs() {
486
509
  let { fileName } = this._options;
@@ -492,7 +515,6 @@ var formatLocation = (node, fileName) => {
492
515
  let index = [];
493
516
  return Object.entries(this._stories).map(([exportName, story]) => {
494
517
  let tags = [...this._meta?.tags ?? [], ...story.tags ?? []], storyInput = {
495
- importPath: fileName,
496
518
  rawComponentPath: this._rawComponentPath,
497
519
  exportName,
498
520
  title: this.meta?.title,
@@ -519,10 +541,10 @@ var formatLocation = (node, fileName) => {
519
541
  tags: [
520
542
  ...storyInput.tags,
521
543
  // this tag comes before test tags so users can invert if they like
522
- "!autodocs",
544
+ `!${Tag.AUTODOCS}`,
523
545
  ...test.tags,
524
546
  // this tag comes after test tags so users can't change it
525
- "test-fn"
547
+ Tag.TEST_FN
526
548
  ],
527
549
  __id: test.id
528
550
  });
@@ -568,35 +590,35 @@ var getCsfParsingErrorMessage = ({
568
590
  node
569
591
  }) => import_ts_dedent2.dedent`
570
592
  CSF Parsing error: Expected '${expectedType}' but found '${foundType}' instead in '${node?.type}'.
571
- `, propKey = (p) => t3.isIdentifier(p.key) ? p.key.name : t3.isStringLiteral(p.key) ? p.key.value : null, _getPath = (path, node) => {
572
- if (path.length === 0)
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)
573
595
  return node;
574
596
  if (t3.isObjectExpression(node)) {
575
- let [first, ...rest] = path, field = node.properties.find((p) => propKey(p) === first);
597
+ let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
576
598
  if (field)
577
599
  return _getPath(rest, field.value);
578
600
  }
579
- }, _getPathProperties = (path, node) => {
580
- if (path.length === 0) {
601
+ }, _getPathProperties = (path2, node) => {
602
+ if (path2.length === 0) {
581
603
  if (t3.isObjectExpression(node))
582
604
  return node.properties;
583
605
  throw new Error("Expected object expression");
584
606
  }
585
607
  if (t3.isObjectExpression(node)) {
586
- let [first, ...rest] = path, field = node.properties.find((p) => propKey(p) === first);
608
+ let [first, ...rest] = path2, field = node.properties.find((p) => propKey(p) === first);
587
609
  if (field)
588
610
  return rest.length === 0 ? node.properties : _getPathProperties(rest, field.value);
589
611
  }
590
612
  }, _findVarDeclarator = (identifier, program) => {
591
613
  let declarator = null, declarations = null;
592
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;
593
- }, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (path, value) => {
594
- if (path.length === 0)
615
+ }, _findVarInitialization = (identifier, program) => _findVarDeclarator(identifier, program)?.init, _makeObjectExpression = (path2, value) => {
616
+ if (path2.length === 0)
595
617
  return value;
596
- let [first, ...rest] = path, innerExpression = _makeObjectExpression(rest, value);
618
+ let [first, ...rest] = path2, innerExpression = _makeObjectExpression(rest, value);
597
619
  return t3.objectExpression([t3.objectProperty(t3.identifier(first), innerExpression)]);
598
- }, _updateExportNode = (path, expr, existing) => {
599
- let [first, ...rest] = path, existingField = existing.properties.find(
620
+ }, _updateExportNode = (path2, expr, existing) => {
621
+ let [first, ...rest] = path2, existingField = existing.properties.find(
600
622
  (p) => propKey(p) === first
601
623
  );
602
624
  existingField ? t3.isObjectExpression(existingField.value) && rest.length > 0 ? _updateExportNode(rest, expr, existingField.value) : existingField.value = _makeObjectExpression(rest, expr) : existing.properties.push(
@@ -710,31 +732,31 @@ var getCsfParsingErrorMessage = ({
710
732
  }
711
733
  }), self;
712
734
  }
713
- getFieldNode(path) {
714
- let [root, ...rest] = path, exported = this._exports[root];
735
+ getFieldNode(path2) {
736
+ let [root, ...rest] = path2, exported = this._exports[root];
715
737
  if (exported)
716
738
  return _getPath(rest, exported);
717
739
  }
718
- getFieldProperties(path) {
719
- let [root, ...rest] = path, exported = this._exports[root];
740
+ getFieldProperties(path2) {
741
+ let [root, ...rest] = path2, exported = this._exports[root];
720
742
  if (exported)
721
743
  return _getPathProperties(rest, exported);
722
744
  }
723
- getFieldValue(path) {
724
- let node = this.getFieldNode(path);
745
+ getFieldValue(path2) {
746
+ let node = this.getFieldNode(path2);
725
747
  if (node) {
726
748
  let { code } = generate2(node, {});
727
749
  return (0, eval)(`(() => (${code}))()`);
728
750
  }
729
751
  }
730
- getSafeFieldValue(path) {
752
+ getSafeFieldValue(path2) {
731
753
  try {
732
- return this.getFieldValue(path);
754
+ return this.getFieldValue(path2);
733
755
  } catch {
734
756
  }
735
757
  }
736
- setFieldNode(path, expr) {
737
- let [first, ...rest] = path, exportNode = this._exports[first];
758
+ setFieldNode(path2, expr) {
759
+ let [first, ...rest] = path2, exportNode = this._exports[first];
738
760
  if (this._exportsObject) {
739
761
  let existingProp = this._exportsObject.properties.find((p) => propKey(p) === first);
740
762
  if (existingProp && t3.isIdentifier(existingProp.value)) {
@@ -744,7 +766,7 @@ var getCsfParsingErrorMessage = ({
744
766
  return;
745
767
  }
746
768
  }
747
- _updateExportNode(path, expr, this._exportsObject), this._exports[path[0]] = expr;
769
+ _updateExportNode(path2, expr, this._exportsObject), this._exports[path2[0]] = expr;
748
770
  return;
749
771
  }
750
772
  if (exportNode && t3.isObjectExpression(exportNode) && rest.length > 0) {
@@ -756,13 +778,13 @@ var getCsfParsingErrorMessage = ({
756
778
  _updateExportNode(rest, expr, varDecl.init);
757
779
  return;
758
780
  }
759
- if (exportNode && rest.length === 0 && this._exportDecls[path[0]]) {
760
- let decl = this._exportDecls[path[0]];
781
+ if (exportNode && rest.length === 0 && this._exportDecls[path2[0]]) {
782
+ let decl = this._exportDecls[path2[0]];
761
783
  t3.isVariableDeclarator(decl) && (decl.init = _makeObjectExpression([], expr));
762
784
  } else {
763
785
  if (this.hasDefaultExport)
764
786
  throw new Error(
765
- `Could not set the "${path.join(
787
+ `Could not set the "${path2.join(
766
788
  "."
767
789
  )}" field as the default export is not an object in this file.`
768
790
  );
@@ -785,8 +807,8 @@ var getCsfParsingErrorMessage = ({
785
807
  *
786
808
  * @returns The name of a node in a given path, supporting the following formats:
787
809
  */
788
- getNameFromPath(path) {
789
- let node = this.getFieldNode(path);
810
+ getNameFromPath(path2) {
811
+ let node = this.getFieldNode(path2);
790
812
  if (node)
791
813
  return this._getPresetValue(node, "name");
792
814
  }
@@ -803,8 +825,8 @@ var getCsfParsingErrorMessage = ({
803
825
  * getNamesFromPath(['addons']);
804
826
  * ```
805
827
  */
806
- getNamesFromPath(path) {
807
- let node = this.getFieldNode(path);
828
+ getNamesFromPath(path2) {
829
+ let node = this.getFieldNode(path2);
808
830
  if (!node)
809
831
  return;
810
832
  let pathNames = [];
@@ -835,68 +857,68 @@ var getCsfParsingErrorMessage = ({
835
857
  );
836
858
  return value;
837
859
  }
838
- removeField(path) {
860
+ removeField(path2) {
839
861
  let removeProperty = (properties2, prop) => {
840
862
  let index = properties2.findIndex(
841
863
  (p) => t3.isIdentifier(p.key) && p.key.name === prop || t3.isStringLiteral(p.key) && p.key.value === prop
842
864
  );
843
865
  index >= 0 && properties2.splice(index, 1);
844
866
  };
845
- if (path.length === 1) {
867
+ if (path2.length === 1) {
846
868
  let removedRootProperty = !1;
847
869
  if (this._ast.program.body.forEach((node) => {
848
870
  if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
849
871
  let decl = node.declaration.declarations[0];
850
- t3.isIdentifier(decl.id) && decl.id.name === path[0] && (this._ast.program.body.splice(this._ast.program.body.indexOf(node), 1), removedRootProperty = !0);
872
+ t3.isIdentifier(decl.id) && decl.id.name === path2[0] && (this._ast.program.body.splice(this._ast.program.body.indexOf(node), 1), removedRootProperty = !0);
851
873
  }
852
874
  if (t3.isExportDefaultDeclaration(node)) {
853
875
  let resolved = this._resolveDeclaration(node.declaration);
854
876
  if (t3.isObjectExpression(resolved)) {
855
877
  let properties2 = resolved.properties;
856
- removeProperty(properties2, path[0]), removedRootProperty = !0;
878
+ removeProperty(properties2, path2[0]), removedRootProperty = !0;
857
879
  }
858
880
  }
859
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)) {
860
882
  let properties2 = node.expression.right.properties;
861
- removeProperty(properties2, path[0]), removedRootProperty = !0;
883
+ removeProperty(properties2, path2[0]), removedRootProperty = !0;
862
884
  }
863
885
  }), removedRootProperty)
864
886
  return;
865
887
  }
866
- let properties = this.getFieldProperties(path);
888
+ let properties = this.getFieldProperties(path2);
867
889
  if (properties) {
868
- let lastPath = path.at(-1);
890
+ let lastPath = path2.at(-1);
869
891
  removeProperty(properties, lastPath);
870
892
  }
871
893
  }
872
- appendValueToArray(path, value) {
894
+ appendValueToArray(path2, value) {
873
895
  let node = this.valueToNode(value);
874
- node && this.appendNodeToArray(path, node);
896
+ node && this.appendNodeToArray(path2, node);
875
897
  }
876
- appendNodeToArray(path, node) {
877
- let current = this.getFieldNode(path);
898
+ appendNodeToArray(path2, node) {
899
+ let current = this.getFieldNode(path2);
878
900
  if (!current)
879
- this.setFieldNode(path, t3.arrayExpression([node]));
901
+ this.setFieldNode(path2, t3.arrayExpression([node]));
880
902
  else if (t3.isArrayExpression(current))
881
903
  current.elements.push(node);
882
904
  else
883
- throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
905
+ throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
884
906
  }
885
907
  /**
886
908
  * Specialized helper to remove addons or other array entries that can either be strings or
887
909
  * objects with a name property.
888
910
  */
889
- removeEntryFromArray(path, value) {
890
- let current = this.getFieldNode(path);
911
+ removeEntryFromArray(path2, value) {
912
+ let current = this.getFieldNode(path2);
891
913
  if (current)
892
914
  if (t3.isArrayExpression(current)) {
893
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);
894
916
  if (index >= 0)
895
917
  current.elements.splice(index, 1);
896
918
  else
897
- throw new Error(`Could not find '${value}' in array at '${path.join(".")}'`);
919
+ throw new Error(`Could not find '${value}' in array at '${path2.join(".")}'`);
898
920
  } else
899
- throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
921
+ throw new Error(`Expected array at '${path2.join(".")}', got '${current.type}'`);
900
922
  }
901
923
  _inferQuotes() {
902
924
  if (!this._quotes) {
@@ -923,11 +945,11 @@ var getCsfParsingErrorMessage = ({
923
945
  valueNode = t3.valueToNode(value);
924
946
  return valueNode;
925
947
  }
926
- setFieldValue(path, value) {
948
+ setFieldValue(path2, value) {
927
949
  let valueNode = this.valueToNode(value);
928
950
  if (!valueNode)
929
951
  throw new Error(`Unexpected value ${JSON.stringify(value)}`);
930
- this.setFieldNode(path, valueNode);
952
+ this.setFieldNode(path2, valueNode);
931
953
  }
932
954
  getBodyDeclarations() {
933
955
  return this._ast.program.body;
@@ -1291,14 +1313,14 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
1291
1313
  );
1292
1314
  csf._ast.program.body.push(addParameter);
1293
1315
  }
1294
- }, addComponentDescription = (node, path, value) => {
1295
- if (!path.length) {
1316
+ }, addComponentDescription = (node, path2, value) => {
1317
+ if (!path2.length) {
1296
1318
  node.properties.find(
1297
1319
  (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === "component"
1298
1320
  ) || node.properties.unshift(value);
1299
1321
  return;
1300
1322
  }
1301
- let [first, ...rest] = path, existing = node.properties.find(
1323
+ let [first, ...rest] = path2, existing = node.properties.find(
1302
1324
  (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === first && t5.isObjectExpression(p.value)
1303
1325
  ), subNode;
1304
1326
  existing ? subNode = existing.value : (subNode = t5.objectExpression([]), node.properties.push(t5.objectProperty(t5.identifier(first), subNode))), addComponentDescription(subNode, rest, value);
@@ -1325,7 +1347,7 @@ var enrichCsfStory = (csf, csfSource, key, options) => {
1325
1347
  `) : "";
1326
1348
 
1327
1349
  // src/csf-tools/index.ts
1328
- import { babelParse as babelParse4 } from "storybook/internal/babel";
1350
+ import { babelParse as babelParse5 } from "storybook/internal/babel";
1329
1351
 
1330
1352
  // src/csf-tools/vitest-plugin/transformer.ts
1331
1353
  var import_ts_dedent4 = __toESM(require_dist(), 1);
@@ -1334,6 +1356,38 @@ import { getStoryTitle } from "storybook/internal/common";
1334
1356
  import { combineTags } from "storybook/internal/csf";
1335
1357
  import { logger as logger4 } from "storybook/internal/node-logger";
1336
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
+ }
1337
1391
  async function vitestTransform({
1338
1392
  code,
1339
1393
  fileName,
@@ -1398,37 +1452,13 @@ Please make sure you have a default export with the meta object. If you are usin
1398
1452
  ];
1399
1453
  return ast.program.body.unshift(...imports2), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
1400
1454
  }
1401
- let vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect"), testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory"), skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
1402
- function getTestGuardDeclaration() {
1403
- let isRunningFromThisFileId2 = parsed._file.path.scope.generateUidIdentifier("isRunningFromThisFile"), testPathProperty = t6.memberExpression(
1404
- t6.callExpression(t6.memberExpression(vitestExpectId, t6.identifier("getState")), []),
1405
- t6.identifier("testPath")
1406
- ), filePathProperty = t6.memberExpression(
1407
- t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
1408
- t6.identifier("filepath")
1409
- ), nullishCoalescingExpression = t6.logicalExpression(
1410
- "??",
1411
- // TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
1412
- // https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
1413
- filePathProperty,
1414
- testPathProperty
1415
- ), includesCall = t6.callExpression(
1416
- t6.memberExpression(
1417
- t6.callExpression(t6.identifier("convertToFilePath"), [
1418
- t6.memberExpression(
1419
- t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
1420
- t6.identifier("url")
1421
- )
1422
- ]),
1423
- t6.identifier("includes")
1424
- ),
1425
- [nullishCoalescingExpression]
1426
- );
1427
- return { isRunningFromThisFileDeclaration: t6.variableDeclaration("const", [
1428
- t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
1429
- ]), isRunningFromThisFileId: isRunningFromThisFileId2 };
1430
- }
1431
- 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
+ );
1432
1462
  ast.program.body.push(isRunningFromThisFileDeclaration);
1433
1463
  let getTestStatementForStory = ({
1434
1464
  localName,
@@ -1438,16 +1468,18 @@ Please make sure you have a default export with the meta object. If you are usin
1438
1468
  overrideSourcemap = !0,
1439
1469
  storyId
1440
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));
1441
1479
  let testStoryCall = t6.expressionStatement(
1442
1480
  t6.callExpression(vitestTestId, [
1443
1481
  t6.stringLiteral(testTitle),
1444
- t6.callExpression(testStoryId, [
1445
- t6.stringLiteral(exportName),
1446
- t6.identifier(localName),
1447
- t6.identifier(metaExportName),
1448
- skipTagsId,
1449
- t6.stringLiteral(storyId)
1450
- ])
1482
+ t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
1451
1483
  ])
1452
1484
  );
1453
1485
  return overrideSourcemap && (testStoryCall.loc = node.loc), testStoryCall;
@@ -1464,17 +1496,24 @@ Please make sure you have a default export with the meta object. If you are usin
1464
1496
  storyId: parentStoryId
1465
1497
  }),
1466
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
+ );
1467
1513
  let testStatement = t6.expressionStatement(
1468
1514
  t6.callExpression(vitestTestId, [
1469
1515
  t6.stringLiteral(testName),
1470
- t6.callExpression(testStoryId, [
1471
- t6.stringLiteral(exportName),
1472
- t6.identifier(localName),
1473
- t6.identifier(metaExportName),
1474
- t6.arrayExpression([]),
1475
- t6.stringLiteral(storyId),
1476
- t6.stringLiteral(testName)
1477
- ])
1516
+ t6.callExpression(testStoryId, [t6.objectExpression(objectProperties)])
1478
1517
  ])
1479
1518
  );
1480
1519
  return testStatement.loc = testNode.loc, testStatement;
@@ -1532,7 +1571,354 @@ Please make sure you have a default export with the meta object. If you are usin
1532
1571
  return ast.program.body.unshift(...imports), formatCsf(parsed, { sourceMaps: !0, sourceFileName: fileName }, code);
1533
1572
  }
1534
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
+
1535
1920
  export {
1921
+ Tag,
1536
1922
  isValidPreviewPath,
1537
1923
  isModuleMock,
1538
1924
  NoMetaError,
@@ -1560,5 +1946,8 @@ export {
1560
1946
  extractSource,
1561
1947
  extractDescription,
1562
1948
  vitestTransform,
1563
- babelParse4 as babelParse
1949
+ STORYBOOK_FN_PLACEHOLDER,
1950
+ generateDummyArgsFromArgTypes,
1951
+ componentTransform,
1952
+ babelParse5 as babelParse
1564
1953
  };