storybook 10.0.0-beta.1 → 10.0.0-beta.11

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 (124) hide show
  1. package/assets/server/openBrowser.applescript +94 -0
  2. package/dist/_browser-chunks/Color-KPLIACXP.js +1569 -0
  3. package/dist/_browser-chunks/{WithTooltip-ERFLZL6W.js → WithTooltip-SK46ZJ2J.js} +1 -1
  4. package/dist/_browser-chunks/{chunk-YY5GICNT.js → chunk-6E2SHJSL.js} +175 -32
  5. package/dist/_browser-chunks/{chunk-EOILZP2R.js → chunk-BOOOPFZF.js} +7 -2
  6. package/dist/_browser-chunks/{chunk-YWDKX534.js → chunk-FA42P6MO.js} +49 -4
  7. package/dist/_browser-chunks/chunk-G33S6YM3.js +521 -0
  8. package/dist/_browser-chunks/{chunk-MZNYTCNT.js → chunk-HMIIJ6UD.js} +6 -6
  9. package/dist/_browser-chunks/{chunk-4QPX7WIQ.js → chunk-JJZMHC3A.js} +57 -166
  10. package/dist/_browser-chunks/{chunk-MD2FTHCZ.js → chunk-JVSKG4YS.js} +3 -16
  11. package/dist/_browser-chunks/{chunk-E7VLET3C.js → chunk-KSCAWCCE.js} +3947 -4291
  12. package/dist/_browser-chunks/{chunk-PYK5ZTFK.js → chunk-PS3AOQI4.js} +48 -25
  13. package/dist/_browser-chunks/chunk-QK3L5AXO.js +372 -0
  14. package/dist/_browser-chunks/chunk-SHR3NNR3.js +5810 -0
  15. package/dist/_browser-chunks/{chunk-O5R5CGFA.js → chunk-TMDZCWME.js} +1 -2
  16. package/dist/_browser-chunks/chunk-VUAFL5XK.js +20 -0
  17. package/dist/_browser-chunks/{chunk-T7RCAJIX.js → chunk-Y3M7TW6K.js} +43 -47
  18. package/dist/_browser-chunks/{syntaxhighlighter-YYAA4CS4.js → syntaxhighlighter-R46XOLMC.js} +1 -1
  19. package/dist/_node-chunks/{builder-manager-EXW4ETLN.js → builder-manager-VLFDK43H.js} +45 -155
  20. package/dist/_node-chunks/camelcase-RENSEFK6.js +18 -0
  21. package/dist/_node-chunks/{chunk-5ZX5SJOP.js → chunk-4SPBIDJV.js} +162 -103
  22. package/dist/_node-chunks/{chunk-PMEEE3UE.js → chunk-4WZFG35Z.js} +30 -21
  23. package/dist/_node-chunks/{chunk-WP7DV5JT.js → chunk-5K7G6NFK.js} +583 -180
  24. package/dist/_node-chunks/{chunk-FZP2YGG3.js → chunk-5NSMDC6F.js} +7 -7
  25. package/dist/_node-chunks/{chunk-6CCUFDHU.js → chunk-5THWZTEL.js} +7 -7
  26. package/dist/_node-chunks/chunk-7MUMULSR.js +79 -0
  27. package/dist/_node-chunks/chunk-7QAAJL75.js +1540 -0
  28. package/dist/_node-chunks/{chunk-EO4S3VXL.js → chunk-DVY3VWHZ.js} +653 -775
  29. package/dist/_node-chunks/{chunk-WDKWVNL2.js → chunk-EBLOP2C5.js} +7 -7
  30. package/dist/_node-chunks/{chunk-EDBXIJN5.js → chunk-EF56ZUQY.js} +7 -7
  31. package/dist/_node-chunks/{chunk-F5J33SXQ.js → chunk-ER2UQBIA.js} +7 -7
  32. package/dist/_node-chunks/chunk-GHICGP2P.js +18 -0
  33. package/dist/_node-chunks/{chunk-4WNZYNQY.js → chunk-GYBN5GXT.js} +623 -750
  34. package/dist/_node-chunks/{chunk-2G5THETV.js → chunk-H2YBWE3T.js} +12 -12
  35. package/dist/_node-chunks/{camelcase-VZZFWA2L.js → chunk-HYMBYTGJ.js} +9 -8
  36. package/dist/_node-chunks/{chunk-SUMFFLGF.js → chunk-Q5IJJX3T.js} +6 -6
  37. package/dist/_node-chunks/{chunk-U45F2NP6.js → chunk-QLRMR54O.js} +7 -7
  38. package/dist/_node-chunks/{chunk-XTSBFCVE.js → chunk-QSNDRP62.js} +7 -7
  39. package/dist/_node-chunks/chunk-S2RQAF7K.js +4741 -0
  40. package/dist/_node-chunks/{chunk-2QZOLZDJ.js → chunk-SDZVOIZI.js} +9 -9
  41. package/dist/_node-chunks/{chunk-VNLBDN2Z.js → chunk-SGJZDMJW.js} +6 -6
  42. package/dist/_node-chunks/{chunk-PL2PKDRO.js → chunk-TJOIDMXP.js} +60 -102
  43. package/dist/_node-chunks/{chunk-ICPKUV5G.js → chunk-U2UIPLJI.js} +7 -7
  44. package/dist/_node-chunks/{chunk-3SGKBLOL.js → chunk-UAMXREF3.js} +8 -8
  45. package/dist/_node-chunks/{chunk-GVCXNIAA.js → chunk-UC6O5PNX.js} +399 -116
  46. package/dist/_node-chunks/{chunk-CM3UGTR5.js → chunk-VFUP6Z4J.js} +7 -7
  47. package/dist/_node-chunks/{chunk-3ZKQWDCG.js → chunk-XKPJCSPD.js} +223 -243
  48. package/dist/_node-chunks/{chunk-24TGL6EX.js → chunk-XWCQWB3R.js} +8 -8
  49. package/dist/_node-chunks/{chunk-QC5FE2D7.js → chunk-XYFEBEHY.js} +7 -7
  50. package/dist/_node-chunks/chunk-YAEIMHFX.js +62 -0
  51. package/dist/_node-chunks/{chunk-5V6QH7WC.js → chunk-ZHBCPKYD.js} +7 -7
  52. package/dist/_node-chunks/{dist-VZL6D6Y3.js → dist-A2RPEHEC.js} +9 -9
  53. package/dist/_node-chunks/{globby-GZXJJ4W6.js → globby-3TWPXGQS.js} +17 -13
  54. package/dist/_node-chunks/{lib-PHT5GCV2.js → lib-MUNM6ZJ6.js} +40 -16
  55. package/dist/_node-chunks/{mdx-N42X6CFJ-EPDIV4A2.js → mdx-N42X6CFJ-QQDHJZQ3.js} +8 -8
  56. package/dist/_node-chunks/{p-limit-AJIFSZTI.js → p-limit-FEN55OV6.js} +76 -10
  57. package/dist/_node-chunks/{plugin-3VI56CEF.js → plugin-ESAYNJ5V.js} +11 -11
  58. package/dist/_node-chunks/{plugin-AV4OEKYM.js → plugin-GDMP3JPR.js} +10 -10
  59. package/dist/_node-chunks/{webpack-inject-mocker-runtime-plugin-E7J5FKLA.js → webpack-inject-mocker-runtime-plugin-5AKTLYIV.js} +1307 -847
  60. package/dist/_node-chunks/{webpack-mock-plugin-VTYGW7HO.js → webpack-mock-plugin-AWGZ65AQ.js} +9 -9
  61. package/dist/babel/index.d.ts +1 -1
  62. package/dist/babel/index.js +11 -11
  63. package/dist/bin/core.js +638 -187
  64. package/dist/bin/dispatcher.js +11 -11
  65. package/dist/bin/loader.js +77 -12
  66. package/dist/cli/index.d.ts +62 -75
  67. package/dist/cli/index.js +67 -55
  68. package/dist/common/index.d.ts +3 -1
  69. package/dist/common/index.js +22 -22
  70. package/dist/components/index.d.ts +228 -1
  71. package/dist/components/index.js +74 -5738
  72. package/dist/core-events/index.d.ts +18 -2
  73. package/dist/core-events/index.js +7 -1
  74. package/dist/core-server/index.d.ts +515 -14
  75. package/dist/core-server/index.js +4647 -4182
  76. package/dist/core-server/presets/common-manager.js +1570 -1272
  77. package/dist/core-server/presets/common-override-preset.js +9 -9
  78. package/dist/core-server/presets/common-preset.js +691 -38
  79. package/dist/core-server/presets/webpack/loaders/storybook-mock-transform-loader.js +9 -9
  80. package/dist/core-server/presets/webpack/loaders/webpack-automock-loader.js +10 -10
  81. package/dist/csf/index.d.ts +9 -4
  82. package/dist/csf/index.js +50 -15
  83. package/dist/csf-tools/index.d.ts +47 -6
  84. package/dist/csf-tools/index.js +9 -9
  85. package/dist/docs-tools/index.js +4 -4
  86. package/dist/instrumenter/index.js +1 -1
  87. package/dist/manager/globals-runtime.js +9230 -18109
  88. package/dist/manager/globals.d.ts +0 -4
  89. package/dist/manager/globals.js +1 -6
  90. package/dist/manager/runtime.js +13194 -11367
  91. package/dist/manager-api/index.d.ts +513 -5
  92. package/dist/manager-api/index.js +364 -90
  93. package/dist/manager-errors.d.ts +501 -0
  94. package/dist/node-logger/index.d.ts +1 -1
  95. package/dist/node-logger/index.js +1136 -662
  96. package/dist/preview/globals.js +1 -1
  97. package/dist/preview/runtime.js +12103 -21579
  98. package/dist/preview-api/index.d.ts +70 -71
  99. package/dist/preview-api/index.js +10 -10
  100. package/dist/preview-errors.d.ts +501 -0
  101. package/dist/router/index.d.ts +668 -10
  102. package/dist/router/index.js +2 -2
  103. package/dist/server-errors.d.ts +501 -0
  104. package/dist/server-errors.js +10 -10
  105. package/dist/telemetry/index.d.ts +1 -1
  106. package/dist/telemetry/index.js +23 -25
  107. package/dist/test/index.js +1874 -4024
  108. package/dist/theming/index.d.ts +2 -2
  109. package/dist/theming/index.js +6 -6
  110. package/dist/types/index.d.ts +553 -16
  111. package/dist/viewport/index.d.ts +36 -4
  112. package/dist/viewport/index.js +1 -1
  113. package/package.json +9 -46
  114. package/dist/_browser-chunks/Color-SFYJJKWL.js +0 -605
  115. package/dist/_browser-chunks/chunk-DHO2SA6L.js +0 -12
  116. package/dist/_browser-chunks/chunk-WPHPDNUA.js +0 -974
  117. package/dist/_node-chunks/chunk-32JYCD74.js +0 -80
  118. package/dist/_node-chunks/chunk-GE6I3YYG.js +0 -62
  119. package/dist/_node-chunks/chunk-KXCNXWXI.js +0 -18
  120. package/dist/_node-chunks/chunk-LAUOYAOX.js +0 -87
  121. package/dist/_node-chunks/chunk-QJTT4OC2.js +0 -266
  122. package/dist/_node-chunks/chunk-V2ZF4DUD.js +0 -2377
  123. package/dist/_node-chunks/chunk-ZMV3WY6R.js +0 -9845
  124. package/dist/_node-chunks/default-browser-id-JNATP42X.js +0 -1719
@@ -1,21 +1,21 @@
1
- import CJS_COMPAT_NODE_URL_nodb7gfupnb from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_nodb7gfupnb from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_nodb7gfupnb from "node:module";
1
+ import CJS_COMPAT_NODE_URL_91hxho9jtpf from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_91hxho9jtpf from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_91hxho9jtpf from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_nodb7gfupnb.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_nodb7gfupnb.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_nodb7gfupnb.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_91hxho9jtpf.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_91hxho9jtpf.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_91hxho9jtpf.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-WDKWVNL2.js";
14
+ } from "./chunk-EBLOP2C5.js";
15
15
  import {
16
16
  __name,
17
17
  __toESM
18
- } from "./chunk-SUMFFLGF.js";
18
+ } from "./chunk-Q5IJJX3T.js";
19
19
 
20
20
  // src/csf-tools/CsfFile.ts
21
21
  var import_ts_dedent = __toESM(require_dist(), 1);
@@ -28,7 +28,7 @@ import {
28
28
  types as t2,
29
29
  traverse
30
30
  } from "storybook/internal/babel";
31
- import { isExportStory, storyNameFromExport, toId } from "storybook/internal/csf";
31
+ import { isExportStory, storyNameFromExport, toId, toTestId } from "storybook/internal/csf";
32
32
  import { logger } from "storybook/internal/node-logger";
33
33
 
34
34
  // src/csf-tools/findVarInitialization.ts
@@ -86,6 +86,29 @@ function parseTags(prop) {
86
86
  });
87
87
  }
88
88
  __name(parseTags, "parseTags");
89
+ function parseTestTags(optionsNode, program) {
90
+ if (!optionsNode) {
91
+ return [];
92
+ }
93
+ let node = optionsNode;
94
+ if (t2.isIdentifier(node)) {
95
+ node = findVarInitialization(node.name, program);
96
+ }
97
+ if (t2.isObjectExpression(node)) {
98
+ const tagsProp = node.properties.find(
99
+ (property) => t2.isObjectProperty(property) && t2.isIdentifier(property.key) && property.key.name === "tags"
100
+ );
101
+ if (tagsProp) {
102
+ let tagsNode = tagsProp.value;
103
+ if (t2.isIdentifier(tagsNode)) {
104
+ tagsNode = findVarInitialization(tagsNode.name, program);
105
+ }
106
+ return parseTags(tagsNode);
107
+ }
108
+ }
109
+ return [];
110
+ }
111
+ __name(parseTestTags, "parseTestTags");
89
112
  var formatLocation = /* @__PURE__ */ __name((node, fileName) => {
90
113
  let loc = "";
91
114
  if (node.loc) {
@@ -165,7 +188,7 @@ var NoMetaError = class extends Error {
165
188
  super(import_ts_dedent.dedent`
166
189
  CSF: ${msg} ${formatLocation(ast, fileName)}
167
190
 
168
- More info: https://storybook.js.org/docs/writing-stories#default-export?ref=error
191
+ More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
169
192
  `);
170
193
  this.name = this.constructor.name;
171
194
  }
@@ -179,7 +202,7 @@ var MultipleMetaError = class extends Error {
179
202
  super(import_ts_dedent.dedent`
180
203
  CSF: ${message} ${formatLocation(ast, fileName)}
181
204
 
182
- More info: https://storybook.js.org/docs/writing-stories#default-export?ref=error
205
+ More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
183
206
  `);
184
207
  this.name = this.constructor.name;
185
208
  }
@@ -193,7 +216,7 @@ var MixedFactoryError = class extends Error {
193
216
  super(import_ts_dedent.dedent`
194
217
  CSF: ${message} ${formatLocation(ast, fileName)}
195
218
 
196
- More info: https://storybook.js.org/docs/writing-stories#default-export?ref=error
219
+ More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
197
220
  `);
198
221
  this.name = this.constructor.name;
199
222
  }
@@ -207,7 +230,7 @@ var BadMetaError = class extends Error {
207
230
  super(import_ts_dedent.dedent`
208
231
  CSF: ${message} ${formatLocation(ast, fileName)}
209
232
 
210
- More info: https://storybook.js.org/docs/writing-stories#default-export?ref=error
233
+ More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
211
234
  `);
212
235
  this.name = this.constructor.name;
213
236
  }
@@ -221,6 +244,7 @@ var CsfFile = class {
221
244
  this._storyStatements = {};
222
245
  this._storyAnnotations = {};
223
246
  this._templates = {};
247
+ this._tests = [];
224
248
  this._ast = ast;
225
249
  this._file = file;
226
250
  this._options = options;
@@ -339,9 +363,15 @@ var CsfFile = class {
339
363
  metaNode = decl;
340
364
  } else if (
341
365
  // export default { ... } as Meta<...>
366
+ // export default { ... } satisfies Meta<...>
342
367
  (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
343
368
  ) {
344
369
  metaNode = decl.expression;
370
+ } else if (
371
+ // export default { ... } satisfies Meta as Meta<...>
372
+ t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
373
+ ) {
374
+ metaNode = decl.expression.expression;
345
375
  }
346
376
  if (metaNode && t2.isProgram(parent)) {
347
377
  self._parseMeta(metaNode, parent);
@@ -387,7 +417,13 @@ var CsfFile = class {
387
417
  }
388
418
  let storyNode;
389
419
  if (t2.isVariableDeclarator(decl)) {
390
- storyNode = t2.isTSAsExpression(decl.init) || t2.isTSSatisfiesExpression(decl.init) ? decl.init.expression : decl.init;
420
+ if (t2.isTSAsExpression(decl.init) && t2.isTSSatisfiesExpression(decl.init.expression)) {
421
+ storyNode = decl.init.expression.expression;
422
+ } else if (t2.isTSAsExpression(decl.init) || t2.isTSSatisfiesExpression(decl.init)) {
423
+ storyNode = decl.init.expression;
424
+ } else {
425
+ storyNode = decl.init;
426
+ }
391
427
  } else {
392
428
  storyNode = decl;
393
429
  }
@@ -469,9 +505,15 @@ var CsfFile = class {
469
505
  metaNode = decl;
470
506
  } else if (
471
507
  // export default { ... } as Meta<...>
472
- t2.isTSAsExpression(decl) && t2.isObjectExpression(decl.expression)
508
+ // export default { ... } satisfies Meta<...>
509
+ (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
473
510
  ) {
474
511
  metaNode = decl.expression;
512
+ } else if (
513
+ // export default { ... } satisfies Meta as Meta<...>
514
+ t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
515
+ ) {
516
+ metaNode = decl.expression.expression;
475
517
  }
476
518
  if (metaNode && t2.isProgram(parent)) {
477
519
  self._parseMeta(metaNode, parent);
@@ -529,6 +571,24 @@ var CsfFile = class {
529
571
  story.name = storyName;
530
572
  }
531
573
  }
574
+ if (t2.isCallExpression(expression) && t2.isMemberExpression(expression.callee) && t2.isIdentifier(expression.callee.object) && t2.isIdentifier(expression.callee.property) && expression.callee.property.name === "test" && expression.arguments.length >= 2 && t2.isStringLiteral(expression.arguments[0])) {
575
+ const exportName = expression.callee.object.name;
576
+ const testName = expression.arguments[0].value;
577
+ const testFunction = expression.arguments.length === 2 ? expression.arguments[1] : expression.arguments[2];
578
+ const testArguments = expression.arguments.length === 2 ? null : expression.arguments[1];
579
+ const tags = parseTestTags(testArguments, self._ast.program);
580
+ self._tests.push({
581
+ function: testFunction,
582
+ name: testName,
583
+ node: expression,
584
+ // can't set id because meta title isn't available yet
585
+ // so it's set later on
586
+ id: "FIXME",
587
+ tags,
588
+ parent: { node: self._storyStatements[exportName] }
589
+ });
590
+ self._stories[exportName].__stats.tests = true;
591
+ }
532
592
  }
533
593
  },
534
594
  CallExpression: {
@@ -539,7 +599,7 @@ var CsfFile = class {
539
599
  throw new Error(import_ts_dedent.dedent`
540
600
  Unexpected \`storiesOf\` usage: ${formatLocation(node, self._options.fileName)}.
541
601
 
542
- SB8 does not support \`storiesOf\`.
602
+ SB8 does not support \`storiesOf\`.
543
603
  `);
544
604
  }
545
605
  if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && t2.isIdentifier(callee.object) && node.arguments.length > 0) {
@@ -547,9 +607,12 @@ var CsfFile = class {
547
607
  const configParent = configCandidate?.path?.parentPath?.node;
548
608
  if (t2.isImportDeclaration(configParent)) {
549
609
  if (isValidPreviewPath(configParent.source.value)) {
550
- const metaNode = node.arguments[0];
551
- self._metaVariableName = callee.property.name;
552
610
  self._metaIsFactory = true;
611
+ const metaDeclarator = path.findParent(
612
+ (p) => p.isVariableDeclarator()
613
+ );
614
+ self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
615
+ const metaNode = node.arguments[0];
553
616
  self._parseMeta(metaNode, self._ast.program);
554
617
  } else {
555
618
  throw new BadMetaError(
@@ -610,6 +673,14 @@ var CsfFile = class {
610
673
  stats.storyFn = !!(t2.isArrowFunctionExpression(storyExport) || t2.isFunctionDeclaration(storyExport));
611
674
  stats.mount = hasMount(storyAnnotations.play ?? self._metaAnnotations.play);
612
675
  stats.moduleMock = !!self.imports.find((fname) => isModuleMock(fname));
676
+ const storyNode = self._storyStatements[key];
677
+ const storyTests = self._tests.filter((t7) => t7.parent.node === storyNode);
678
+ if (storyTests.length > 0) {
679
+ stats.tests = true;
680
+ storyTests.forEach((test) => {
681
+ test.id = toTestId(id, test.name);
682
+ });
683
+ }
613
684
  return acc;
614
685
  },
615
686
  {}
@@ -642,6 +713,13 @@ var CsfFile = class {
642
713
  get stories() {
643
714
  return Object.values(this._stories);
644
715
  }
716
+ getStoryTests(story) {
717
+ const storyNode = typeof story === "string" ? this._storyStatements[story] : story;
718
+ if (!storyNode) {
719
+ return [];
720
+ }
721
+ return this._tests.filter((t7) => t7.parent.node === storyNode);
722
+ }
645
723
  get indexInputs() {
646
724
  const { fileName } = this._options;
647
725
  if (!fileName) {
@@ -650,21 +728,52 @@ var CsfFile = class {
650
728
  Either add the fileName option when creating the CsfFile instance, or create the index inputs manually.`
651
729
  );
652
730
  }
653
- return Object.entries(this._stories).map(([exportName, story]) => {
731
+ const index = [];
732
+ Object.entries(this._stories).map(([exportName, story]) => {
654
733
  const tags = [...this._meta?.tags ?? [], ...story.tags ?? []];
655
- return {
656
- type: "story",
734
+ const storyInput = {
657
735
  importPath: fileName,
658
736
  rawComponentPath: this._rawComponentPath,
659
737
  exportName,
660
- name: story.name,
661
738
  title: this.meta?.title,
662
739
  metaId: this.meta?.id,
663
740
  tags,
664
741
  __id: story.id,
665
742
  __stats: story.__stats
666
743
  };
744
+ const tests = this.getStoryTests(exportName);
745
+ const hasTests = tests.length > 0;
746
+ index.push({
747
+ ...storyInput,
748
+ type: "story",
749
+ subtype: "story",
750
+ name: story.name
751
+ });
752
+ if (hasTests) {
753
+ tests.forEach((test) => {
754
+ index.push({
755
+ ...storyInput,
756
+ // TODO implementent proper title => path behavior in `transformStoryIndexToStoriesHash`
757
+ // title: `${storyInput.title}/${story.name}`,
758
+ type: "story",
759
+ subtype: "test",
760
+ name: test.name,
761
+ parent: story.id,
762
+ parentName: story.name,
763
+ tags: [
764
+ ...storyInput.tags,
765
+ // this tag comes before test tags so users can invert if they like
766
+ "!autodocs",
767
+ ...test.tags,
768
+ // this tag comes after test tags so users can't change it
769
+ "test-fn"
770
+ ],
771
+ __id: test.id
772
+ });
773
+ });
774
+ }
667
775
  });
776
+ return index;
668
777
  }
669
778
  };
670
779
  var babelParseFile = /* @__PURE__ */ __name(({
@@ -1425,6 +1534,116 @@ var ConfigFile = class {
1425
1534
  }
1426
1535
  }
1427
1536
  }
1537
+ _removeRequireImport(importSpecifier, fromImport) {
1538
+ const requireDeclarationIndex = this._ast.program.body.findIndex((node) => {
1539
+ const hasDeclaration = t3.isVariableDeclaration(node) && node.declarations.length === 1 && t3.isVariableDeclarator(node.declarations[0]) && t3.isCallExpression(node.declarations[0].init) && t3.isIdentifier(node.declarations[0].init.callee) && node.declarations[0].init.callee.name === "require" && t3.isStringLiteral(node.declarations[0].init.arguments[0]) && (node.declarations[0].init.arguments[0].value === fromImport || node.declarations[0].init.arguments[0].value === fromImport.split("node:")[1]);
1540
+ return hasDeclaration;
1541
+ });
1542
+ if (requireDeclarationIndex === -1) {
1543
+ return;
1544
+ }
1545
+ const requireDeclaration = this._ast.program.body[requireDeclarationIndex];
1546
+ const declarator = requireDeclaration.declarations[0];
1547
+ if (importSpecifier === null) {
1548
+ return;
1549
+ }
1550
+ if (typeof importSpecifier === "string") {
1551
+ if (t3.isIdentifier(declarator.id) && declarator.id.name === importSpecifier) {
1552
+ this._ast.program.body.splice(requireDeclarationIndex, 1);
1553
+ }
1554
+ return;
1555
+ }
1556
+ if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
1557
+ return;
1558
+ }
1559
+ if (Array.isArray(importSpecifier) && t3.isObjectPattern(declarator.id)) {
1560
+ const objectPattern = declarator.id;
1561
+ importSpecifier.forEach((specifier) => {
1562
+ const index = objectPattern.properties.findIndex(
1563
+ (prop) => t3.isObjectProperty(prop) && t3.isIdentifier(prop.key) && prop.key.name === specifier
1564
+ );
1565
+ if (index !== -1) {
1566
+ objectPattern.properties.splice(index, 1);
1567
+ }
1568
+ });
1569
+ if (objectPattern.properties.length === 0) {
1570
+ this._ast.program.body.splice(requireDeclarationIndex, 1);
1571
+ }
1572
+ }
1573
+ }
1574
+ _removeImport(importSpecifier, fromImport) {
1575
+ const importDeclarationIndex = this._ast.program.body.findIndex(
1576
+ (node) => t3.isImportDeclaration(node) && (node.source.value === fromImport || node.source.value === fromImport.split("node:")[1])
1577
+ );
1578
+ if (importDeclarationIndex === -1) {
1579
+ return;
1580
+ }
1581
+ const importDeclaration = this._ast.program.body[importDeclarationIndex];
1582
+ if (importSpecifier === null) {
1583
+ if (importDeclaration.specifiers.length === 0) {
1584
+ this._ast.program.body.splice(importDeclarationIndex, 1);
1585
+ }
1586
+ return;
1587
+ }
1588
+ if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
1589
+ const index = importDeclaration.specifiers.findIndex(
1590
+ (specifier) => t3.isImportNamespaceSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier.namespace
1591
+ );
1592
+ if (index !== -1) {
1593
+ importDeclaration.specifiers.splice(index, 1);
1594
+ }
1595
+ }
1596
+ if (typeof importSpecifier === "string") {
1597
+ const index = importDeclaration.specifiers.findIndex(
1598
+ (specifier) => t3.isImportDefaultSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier
1599
+ );
1600
+ if (index !== -1) {
1601
+ importDeclaration.specifiers.splice(index, 1);
1602
+ }
1603
+ }
1604
+ if (Array.isArray(importSpecifier)) {
1605
+ importSpecifier.forEach((specifier) => {
1606
+ const index = importDeclaration.specifiers.findIndex(
1607
+ (current) => t3.isImportSpecifier(current) && t3.isIdentifier(current.imported) && current.imported.name === specifier
1608
+ );
1609
+ if (index !== -1) {
1610
+ importDeclaration.specifiers.splice(index, 1);
1611
+ }
1612
+ });
1613
+ }
1614
+ if (importDeclaration.specifiers.length === 0) {
1615
+ this._ast.program.body.splice(importDeclarationIndex, 1);
1616
+ }
1617
+ }
1618
+ /**
1619
+ * Remove import specifiers for a given import statement.
1620
+ *
1621
+ * Does not support removing type imports (yet)
1622
+ *
1623
+ * @example
1624
+ *
1625
+ * ```ts
1626
+ * // import { foo } from 'bar';
1627
+ * setImport(['foo'], 'bar');
1628
+ *
1629
+ * // import foo from 'bar';
1630
+ * setImport('foo', 'bar');
1631
+ *
1632
+ * // import * as foo from 'bar';
1633
+ * setImport({ namespace: 'foo' }, 'bar');
1634
+ *
1635
+ * // import 'bar';
1636
+ * setImport(null, 'bar');
1637
+ * ```
1638
+ *
1639
+ * @param importSpecifiers - The import specifiers to remove. If a string is passed in, will only
1640
+ * remove the default import. Otherwise, named imports matching the array will be removed.
1641
+ * @param fromImport - The module to import from
1642
+ */
1643
+ removeImport(importSpecifier, fromImport) {
1644
+ this._removeRequireImport(importSpecifier, fromImport);
1645
+ this._removeImport(importSpecifier, fromImport);
1646
+ }
1428
1647
  };
1429
1648
  var loadConfig = /* @__PURE__ */ __name((code, fileName) => {
1430
1649
  const ast = babelParse2(code);
@@ -1749,6 +1968,8 @@ var isValidTest = /* @__PURE__ */ __name((storyTags, tagsFilter) => {
1749
1968
  }
1750
1969
  return true;
1751
1970
  }, "isValidTest");
1971
+ var DOUBLE_SPACES = " ";
1972
+ var getLiteralWithZeroWidthSpace = /* @__PURE__ */ __name((testTitle) => t6.stringLiteral(`${testTitle}${DOUBLE_SPACES}`), "getLiteralWithZeroWidthSpace");
1752
1973
  async function vitestTransform({
1753
1974
  code,
1754
1975
  fileName,
@@ -1796,7 +2017,7 @@ async function vitestTransform({
1796
2017
  );
1797
2018
  }
1798
2019
  const validStories = {};
1799
- Object.keys(parsed._stories).map((key) => {
2020
+ Object.keys(parsed._stories).forEach((key) => {
1800
2021
  const finalTags = combineTags(
1801
2022
  "test",
1802
2023
  "dev",
@@ -1817,7 +2038,7 @@ async function vitestTransform({
1817
2038
  ])
1818
2039
  );
1819
2040
  ast.program.body.push(describeSkipBlock);
1820
- const imports = [
2041
+ const imports2 = [
1821
2042
  t6.importDeclaration(
1822
2043
  [
1823
2044
  t6.importSpecifier(vitestTestId, t6.identifier("test")),
@@ -1826,103 +2047,165 @@ async function vitestTransform({
1826
2047
  t6.stringLiteral("vitest")
1827
2048
  )
1828
2049
  ];
1829
- ast.program.body.unshift(...imports);
1830
- } else {
1831
- let getTestGuardDeclaration2 = function() {
1832
- const isRunningFromThisFileId2 = parsed._file.path.scope.generateUidIdentifier("isRunningFromThisFile");
1833
- const testPathProperty = t6.memberExpression(
1834
- t6.callExpression(t6.memberExpression(vitestExpectId, t6.identifier("getState")), []),
1835
- t6.identifier("testPath")
1836
- );
1837
- const filePathProperty = t6.memberExpression(
1838
- t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
1839
- t6.identifier("filepath")
1840
- );
1841
- const nullishCoalescingExpression = t6.logicalExpression(
1842
- "??",
1843
- // TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
1844
- // https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
1845
- filePathProperty,
1846
- testPathProperty
1847
- );
1848
- const includesCall = t6.callExpression(
1849
- t6.memberExpression(
1850
- t6.callExpression(t6.identifier("convertToFilePath"), [
1851
- t6.memberExpression(
1852
- t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
1853
- t6.identifier("url")
1854
- )
1855
- ]),
1856
- t6.identifier("includes")
1857
- ),
1858
- [nullishCoalescingExpression]
1859
- );
1860
- const isRunningFromThisFileDeclaration2 = t6.variableDeclaration("const", [
1861
- t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
1862
- ]);
1863
- return { isRunningFromThisFileDeclaration: isRunningFromThisFileDeclaration2, isRunningFromThisFileId: isRunningFromThisFileId2 };
1864
- };
1865
- var getTestGuardDeclaration = getTestGuardDeclaration2;
1866
- __name(getTestGuardDeclaration2, "getTestGuardDeclaration");
1867
- const vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect");
1868
- const testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory");
1869
- const skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
1870
- const { isRunningFromThisFileDeclaration, isRunningFromThisFileId } = getTestGuardDeclaration2();
1871
- ast.program.body.push(isRunningFromThisFileDeclaration);
1872
- const getTestStatementForStory = /* @__PURE__ */ __name(({
1873
- localName,
1874
- exportName,
1875
- testTitle,
1876
- node
1877
- }) => {
1878
- const testStoryCall = t6.expressionStatement(
1879
- t6.callExpression(vitestTestId, [
1880
- t6.stringLiteral(testTitle),
1881
- t6.callExpression(testStoryId, [
1882
- t6.stringLiteral(exportName),
1883
- t6.identifier(localName),
1884
- t6.identifier(metaExportName),
1885
- skipTagsId
1886
- ])
2050
+ ast.program.body.unshift(...imports2);
2051
+ return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
2052
+ }
2053
+ const vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect");
2054
+ const testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory");
2055
+ const skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
2056
+ function getTestGuardDeclaration() {
2057
+ const isRunningFromThisFileId2 = parsed._file.path.scope.generateUidIdentifier("isRunningFromThisFile");
2058
+ const testPathProperty = t6.memberExpression(
2059
+ t6.callExpression(t6.memberExpression(vitestExpectId, t6.identifier("getState")), []),
2060
+ t6.identifier("testPath")
2061
+ );
2062
+ const filePathProperty = t6.memberExpression(
2063
+ t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
2064
+ t6.identifier("filepath")
2065
+ );
2066
+ const nullishCoalescingExpression = t6.logicalExpression(
2067
+ "??",
2068
+ // TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
2069
+ // https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
2070
+ filePathProperty,
2071
+ testPathProperty
2072
+ );
2073
+ const includesCall = t6.callExpression(
2074
+ t6.memberExpression(
2075
+ t6.callExpression(t6.identifier("convertToFilePath"), [
2076
+ t6.memberExpression(
2077
+ t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
2078
+ t6.identifier("url")
2079
+ )
2080
+ ]),
2081
+ t6.identifier("includes")
2082
+ ),
2083
+ [nullishCoalescingExpression]
2084
+ );
2085
+ const isRunningFromThisFileDeclaration2 = t6.variableDeclaration("const", [
2086
+ t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
2087
+ ]);
2088
+ return { isRunningFromThisFileDeclaration: isRunningFromThisFileDeclaration2, isRunningFromThisFileId: isRunningFromThisFileId2 };
2089
+ }
2090
+ __name(getTestGuardDeclaration, "getTestGuardDeclaration");
2091
+ const { isRunningFromThisFileDeclaration, isRunningFromThisFileId } = getTestGuardDeclaration();
2092
+ ast.program.body.push(isRunningFromThisFileDeclaration);
2093
+ const getTestStatementForStory = /* @__PURE__ */ __name(({
2094
+ localName,
2095
+ exportName,
2096
+ testTitle,
2097
+ node,
2098
+ overrideSourcemap = true,
2099
+ storyId
2100
+ }) => {
2101
+ const testStoryCall = t6.expressionStatement(
2102
+ t6.callExpression(vitestTestId, [
2103
+ t6.stringLiteral(testTitle),
2104
+ t6.callExpression(testStoryId, [
2105
+ t6.stringLiteral(exportName),
2106
+ t6.identifier(localName),
2107
+ t6.identifier(metaExportName),
2108
+ skipTagsId,
2109
+ t6.stringLiteral(storyId)
1887
2110
  ])
1888
- );
2111
+ ])
2112
+ );
2113
+ if (overrideSourcemap) {
1889
2114
  testStoryCall.loc = node.loc;
1890
- return testStoryCall;
1891
- }, "getTestStatementForStory");
1892
- const storyTestStatements = Object.entries(validStories).map(([exportName, node]) => {
1893
- if (node === null) {
1894
- logger4.warn(
1895
- import_ts_dedent4.dedent`
2115
+ }
2116
+ return testStoryCall;
2117
+ }, "getTestStatementForStory");
2118
+ const getDescribeStatementForStory = /* @__PURE__ */ __name((options) => {
2119
+ const { localName, describeTitle, exportName, tests, node, parentStoryId } = options;
2120
+ const describeBlock = t6.callExpression(vitestDescribeId, [
2121
+ getLiteralWithZeroWidthSpace(describeTitle),
2122
+ t6.arrowFunctionExpression(
2123
+ [],
2124
+ t6.blockStatement([
2125
+ getTestStatementForStory({
2126
+ ...options,
2127
+ testTitle: "base story",
2128
+ overrideSourcemap: false,
2129
+ storyId: parentStoryId
2130
+ }),
2131
+ ...tests.map(({ name: testName, node: testNode, id: storyId }) => {
2132
+ const testStatement = t6.expressionStatement(
2133
+ t6.callExpression(vitestTestId, [
2134
+ t6.stringLiteral(testName),
2135
+ t6.callExpression(testStoryId, [
2136
+ t6.stringLiteral(exportName),
2137
+ t6.identifier(localName),
2138
+ t6.identifier(metaExportName),
2139
+ t6.arrayExpression([]),
2140
+ t6.stringLiteral(storyId),
2141
+ t6.stringLiteral(testName)
2142
+ ])
2143
+ ])
2144
+ );
2145
+ testStatement.loc = testNode.loc;
2146
+ return testStatement;
2147
+ })
2148
+ ])
2149
+ )
2150
+ ]);
2151
+ describeBlock.loc = node.loc;
2152
+ return t6.expressionStatement(describeBlock);
2153
+ }, "getDescribeStatementForStory");
2154
+ const storyTestStatements = Object.entries(validStories).map(([exportName, node]) => {
2155
+ if (node === null) {
2156
+ logger4.warn(
2157
+ import_ts_dedent4.dedent`
1896
2158
  [Storybook]: Could not transform "${exportName}" story into test at "${fileName}".
1897
2159
  Please make sure to define stories in the same file and not re-export stories coming from other files".
1898
2160
  `
1899
- );
1900
- return;
1901
- }
1902
- const localName = parsed._stories[exportName].localName ?? exportName;
1903
- const testTitle = parsed._stories[exportName].name ?? exportName;
1904
- return getTestStatementForStory({ testTitle, localName, exportName, node });
1905
- }).filter((st) => !!st);
1906
- const testBlock = t6.ifStatement(isRunningFromThisFileId, t6.blockStatement(storyTestStatements));
1907
- ast.program.body.push(testBlock);
1908
- const imports = [
1909
- t6.importDeclaration(
1910
- [
1911
- t6.importSpecifier(vitestTestId, t6.identifier("test")),
1912
- t6.importSpecifier(vitestExpectId, t6.identifier("expect"))
1913
- ],
1914
- t6.stringLiteral("vitest")
1915
- ),
1916
- t6.importDeclaration(
1917
- [
1918
- t6.importSpecifier(testStoryId, t6.identifier("testStory")),
1919
- t6.importSpecifier(t6.identifier("convertToFilePath"), t6.identifier("convertToFilePath"))
1920
- ],
1921
- t6.stringLiteral("@storybook/addon-vitest/internal/test-utils")
1922
- )
1923
- ];
1924
- ast.program.body.unshift(...imports);
1925
- }
2161
+ );
2162
+ return;
2163
+ }
2164
+ const localName = parsed._stories[exportName].localName ?? exportName;
2165
+ const testTitle = parsed._stories[exportName].name ?? exportName;
2166
+ const storyId = parsed._stories[exportName].id;
2167
+ const tests = parsed.getStoryTests(exportName);
2168
+ if (tests?.length > 0) {
2169
+ return getDescribeStatementForStory({
2170
+ localName,
2171
+ describeTitle: testTitle,
2172
+ exportName,
2173
+ tests,
2174
+ node,
2175
+ parentStoryId: storyId
2176
+ });
2177
+ }
2178
+ return getTestStatementForStory({
2179
+ testTitle,
2180
+ localName,
2181
+ exportName,
2182
+ node,
2183
+ storyId
2184
+ });
2185
+ }).filter((st) => !!st);
2186
+ const testBlock = t6.ifStatement(isRunningFromThisFileId, t6.blockStatement(storyTestStatements));
2187
+ ast.program.body.push(testBlock);
2188
+ const hasTests = Object.keys(validStories).some(
2189
+ (exportName) => parsed.getStoryTests(exportName).length > 0
2190
+ );
2191
+ const imports = [
2192
+ t6.importDeclaration(
2193
+ [
2194
+ t6.importSpecifier(vitestTestId, t6.identifier("test")),
2195
+ t6.importSpecifier(vitestExpectId, t6.identifier("expect")),
2196
+ ...hasTests ? [t6.importSpecifier(vitestDescribeId, t6.identifier("describe"))] : []
2197
+ ],
2198
+ t6.stringLiteral("vitest")
2199
+ ),
2200
+ t6.importDeclaration(
2201
+ [
2202
+ t6.importSpecifier(testStoryId, t6.identifier("testStory")),
2203
+ t6.importSpecifier(t6.identifier("convertToFilePath"), t6.identifier("convertToFilePath"))
2204
+ ],
2205
+ t6.stringLiteral("@storybook/addon-vitest/internal/test-utils")
2206
+ )
2207
+ ];
2208
+ ast.program.body.unshift(...imports);
1926
2209
  return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
1927
2210
  }
1928
2211
  __name(vitestTransform, "vitestTransform");