storybook 10.1.0-alpha.10 → 10.1.0-alpha.12

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 (192) hide show
  1. package/dist/_browser-chunks/Color-FTG7SQDA.js +1097 -0
  2. package/dist/_browser-chunks/WithTooltip-LMROHDUP.js +1651 -0
  3. package/dist/_browser-chunks/chunk-2FRVAXCZ.js +7 -0
  4. package/dist/_browser-chunks/chunk-3IAH5M2U.js +171 -0
  5. package/dist/_browser-chunks/chunk-3OXGAGBE.js +779 -0
  6. package/dist/_browser-chunks/{chunk-TMDZCWME.js → chunk-3PJE6VLG.js} +1 -3
  7. package/dist/_browser-chunks/{chunk-VAMFPZY3.js → chunk-45UGUKRX.js} +2 -7
  8. package/dist/_browser-chunks/chunk-6XWLIJQL.js +11 -0
  9. package/dist/_browser-chunks/{chunk-FDWKXLBI.js → chunk-74YHFU5B.js} +44 -109
  10. package/dist/_browser-chunks/{chunk-MM7DTO55.js → chunk-A242L54C.js} +10 -16
  11. package/dist/_browser-chunks/chunk-AIOS4NGK.js +252 -0
  12. package/dist/_browser-chunks/chunk-AS2HQEYC.js +14 -0
  13. package/dist/_browser-chunks/chunk-AXG2BOBL.js +836 -0
  14. package/dist/_browser-chunks/chunk-BE2DAXKJ.js +2966 -0
  15. package/dist/_browser-chunks/{chunk-MH6AXFXB.js → chunk-CHUV5WSW.js} +0 -5
  16. package/dist/_browser-chunks/chunk-EBHB6RPS.js +61 -0
  17. package/dist/_browser-chunks/chunk-EUVGDK4H.js +93 -0
  18. package/dist/_browser-chunks/chunk-EZSQOHRI.js +18 -0
  19. package/dist/_browser-chunks/{chunk-CADGRH3P.js → chunk-FNXWN6IK.js} +3 -8
  20. package/dist/_browser-chunks/chunk-GFLS4VP3.js +64 -0
  21. package/dist/_browser-chunks/{chunk-L2D73C6Z.js → chunk-H6XK3RSC.js} +13 -21
  22. package/dist/_browser-chunks/chunk-IPA5A322.js +71 -0
  23. package/dist/_browser-chunks/chunk-JP7NCOJX.js +37 -0
  24. package/dist/_browser-chunks/chunk-KJHJLCBK.js +11 -0
  25. package/dist/_browser-chunks/{chunk-QMY4G4R2.js → chunk-L4RMQ7D7.js} +17 -64
  26. package/dist/_browser-chunks/{chunk-AB7OOPUX.js → chunk-QKODTO7K.js} +0 -5
  27. package/dist/_browser-chunks/chunk-RP5RXKFU.js +2491 -0
  28. package/dist/_browser-chunks/chunk-SL75JR6Y.js +9 -0
  29. package/dist/_browser-chunks/chunk-UD6FQLAF.js +1481 -0
  30. package/dist/_browser-chunks/chunk-VYJQ7RU5.js +2853 -0
  31. package/dist/_browser-chunks/chunk-WJYERY3R.js +136 -0
  32. package/dist/_browser-chunks/chunk-WXP2XJ3O.js +950 -0
  33. package/dist/_browser-chunks/chunk-X3DUQ5RA.js +47 -0
  34. package/dist/_browser-chunks/chunk-XJNX76GA.js +85 -0
  35. package/dist/_browser-chunks/{chunk-F4Q6SGTB.js → chunk-YKE5S47A.js} +177 -399
  36. package/dist/_browser-chunks/{chunk-SN4J4IQ3.js → chunk-ZUWEVLDX.js} +1 -7
  37. package/dist/_browser-chunks/{formatter-OMEEQ6HG.js → formatter-QJ4M4OGQ.js} +4 -9
  38. package/dist/_browser-chunks/{syntaxhighlighter-RJZASWHL.js → syntaxhighlighter-WKBQ5RC7.js} +704 -1848
  39. package/dist/_node-chunks/{builder-manager-HA7CYFCK.js → builder-manager-YUOHSIUB.js} +475 -1013
  40. package/dist/_node-chunks/camelcase-JREIL7NV.js +18 -0
  41. package/dist/_node-chunks/{chunk-RMHAL25C.js → chunk-2D2IODUU.js} +88 -228
  42. package/dist/_node-chunks/chunk-2DMESZFJ.js +943 -0
  43. package/dist/_node-chunks/chunk-4FT2DHGE.js +3009 -0
  44. package/dist/_node-chunks/chunk-5HV3B5OP.js +45571 -0
  45. package/dist/_node-chunks/{chunk-OVXB5GGT.js → chunk-5KLIDWFN.js} +292 -688
  46. package/dist/_node-chunks/chunk-A4APXFQ2.js +759 -0
  47. package/dist/_node-chunks/chunk-B6JWY6PC.js +37 -0
  48. package/dist/_node-chunks/chunk-CZ5GHJCC.js +603 -0
  49. package/dist/_node-chunks/chunk-DUXPWBOK.js +61 -0
  50. package/dist/_node-chunks/chunk-DWXTZT3D.js +58 -0
  51. package/dist/_node-chunks/chunk-E5FJS66Z.js +20 -0
  52. package/dist/_node-chunks/chunk-EZWWR7AR.js +936 -0
  53. package/dist/_node-chunks/chunk-FDXFVHIL.js +1114 -0
  54. package/dist/_node-chunks/{chunk-F3XOPI6H.js → chunk-FZLRAH4N.js} +469 -983
  55. package/dist/_node-chunks/chunk-HZG65SU3.js +34 -0
  56. package/dist/_node-chunks/chunk-IXVYNBMD.js +18 -0
  57. package/dist/_node-chunks/chunk-JARUEMEP.js +4523 -0
  58. package/dist/_node-chunks/chunk-LIH7MTP7.js +3214 -0
  59. package/dist/_node-chunks/chunk-N5GIRUP5.js +1047 -0
  60. package/dist/_node-chunks/{chunk-X4XU27M6.js → chunk-NAOYEL54.js} +15 -24
  61. package/dist/_node-chunks/chunk-O5DA7YLO.js +3171 -0
  62. package/dist/_node-chunks/chunk-OP3INKUD.js +54 -0
  63. package/dist/_node-chunks/chunk-QCO2ZM7F.js +209 -0
  64. package/dist/_node-chunks/chunk-QYQIZBS6.js +26 -0
  65. package/dist/_node-chunks/chunk-SEMIAAWG.js +1564 -0
  66. package/dist/_node-chunks/chunk-TS2UUH2J.js +301 -0
  67. package/dist/_node-chunks/chunk-WA6KZQZ2.js +119 -0
  68. package/dist/_node-chunks/{chunk-ZHSCUGNP.js → chunk-WFLWJO24.js} +3799 -7849
  69. package/dist/_node-chunks/chunk-WUXQMQCB.js +72 -0
  70. package/dist/_node-chunks/{chunk-VPR5IBMG.js → chunk-XXPJ7XR3.js} +8 -10
  71. package/dist/_node-chunks/chunk-Y4E6IGQF.js +61 -0
  72. package/dist/_node-chunks/chunk-ZL3AFKRX.js +1029 -0
  73. package/dist/_node-chunks/chunk-ZXSD6L3S.js +756 -0
  74. package/dist/_node-chunks/dist-DS2B5A3J.js +121 -0
  75. package/dist/_node-chunks/globby-6THB7HVX.js +3452 -0
  76. package/dist/_node-chunks/lib-5NKX4YGG.js +366 -0
  77. package/dist/_node-chunks/mdx-N42X6CFJ-ZLT3QOFF.js +14329 -0
  78. package/dist/_node-chunks/p-limit-PDMWNG7W.js +116 -0
  79. package/dist/_node-chunks/plugin-6XMWOGPO.js +123 -0
  80. package/dist/_node-chunks/{plugin-6ZPCS4LI.js → plugin-LTOXVT6A.js} +36 -56
  81. package/dist/_node-chunks/webpack-inject-mocker-runtime-plugin-2SFE5LQS.js +46582 -0
  82. package/dist/_node-chunks/webpack-mock-plugin-CX5J2U56.js +92 -0
  83. package/dist/actions/decorator.js +21 -42
  84. package/dist/actions/index.js +3 -3
  85. package/dist/babel/index.d.ts +671 -335
  86. package/dist/babel/index.js +11 -11
  87. package/dist/bin/core.js +592 -1546
  88. package/dist/bin/dispatcher.js +26 -37
  89. package/dist/bin/loader.js +23 -34
  90. package/dist/channels/index.js +98 -234
  91. package/dist/cli/index.js +1951 -5308
  92. package/dist/client-logger/index.js +31 -61
  93. package/dist/common/index.js +20 -20
  94. package/dist/components/index.js +4211 -8586
  95. package/dist/core-events/index.js +2 -66
  96. package/dist/core-server/index.js +3054 -7290
  97. package/dist/core-server/presets/common-manager.css +2 -2
  98. package/dist/core-server/presets/common-manager.js +1806 -3427
  99. package/dist/core-server/presets/common-override-preset.js +31 -60
  100. package/dist/core-server/presets/common-preset.js +434 -924
  101. package/dist/core-server/presets/webpack/loaders/storybook-mock-transform-loader.js +15 -19
  102. package/dist/core-server/presets/webpack/loaders/webpack-automock-loader.js +12 -17
  103. package/dist/csf/index.js +534 -1179
  104. package/dist/csf-tools/index.js +9 -9
  105. package/dist/docs-tools/index.js +6 -6
  106. package/dist/highlight/index.js +2 -2
  107. package/dist/instrumenter/index.js +199 -415
  108. package/dist/manager/globals-runtime.js +24150 -47364
  109. package/dist/manager/globals.js +2 -3
  110. package/dist/manager/runtime.js +3961 -8373
  111. package/dist/manager-api/index.js +1231 -2425
  112. package/dist/manager-errors.d.ts +3 -0
  113. package/dist/manager-errors.js +3 -3
  114. package/dist/node-logger/index.js +1253 -2601
  115. package/dist/preview/globals.js +2 -3
  116. package/dist/preview/runtime.js +10364 -21990
  117. package/dist/preview-api/index.d.ts +67 -68
  118. package/dist/preview-api/index.js +13 -13
  119. package/dist/preview-errors.d.ts +3 -0
  120. package/dist/preview-errors.js +4 -4
  121. package/dist/router/index.js +347 -899
  122. package/dist/server-errors.d.ts +3 -0
  123. package/dist/server-errors.js +10 -10
  124. package/dist/telemetry/index.js +24 -24
  125. package/dist/test/index.js +5860 -11645
  126. package/dist/theming/create.js +4 -4
  127. package/dist/theming/index.d.ts +3363 -2597
  128. package/dist/theming/index.js +490 -1086
  129. package/dist/types/index.js +2 -11
  130. package/dist/viewport/index.js +3 -3
  131. package/package.json +5 -5
  132. package/dist/_browser-chunks/Color-FQNEU7YS.js +0 -1695
  133. package/dist/_browser-chunks/WithTooltip-6NHN2GXF.js +0 -2343
  134. package/dist/_browser-chunks/chunk-6A7OIVEL.js +0 -66
  135. package/dist/_browser-chunks/chunk-AW46NMGV.js +0 -1308
  136. package/dist/_browser-chunks/chunk-B4A3ADP3.js +0 -3816
  137. package/dist/_browser-chunks/chunk-FSBVR7H5.js +0 -106
  138. package/dist/_browser-chunks/chunk-FUOHXXZT.js +0 -23
  139. package/dist/_browser-chunks/chunk-GTKOCWCT.js +0 -17
  140. package/dist/_browser-chunks/chunk-HHW4FUMO.js +0 -12
  141. package/dist/_browser-chunks/chunk-JVSKG4YS.js +0 -4052
  142. package/dist/_browser-chunks/chunk-LASUB7TL.js +0 -76
  143. package/dist/_browser-chunks/chunk-LYCSRYYR.js +0 -101
  144. package/dist/_browser-chunks/chunk-NVV6MIOE.js +0 -243
  145. package/dist/_browser-chunks/chunk-OBXWFEPB.js +0 -852
  146. package/dist/_browser-chunks/chunk-OPCDBBL3.js +0 -48
  147. package/dist/_browser-chunks/chunk-PB6FZ3WE.js +0 -130
  148. package/dist/_browser-chunks/chunk-RW5PKMWM.js +0 -4182
  149. package/dist/_browser-chunks/chunk-SYS437NN.js +0 -122
  150. package/dist/_browser-chunks/chunk-U46RQHA4.js +0 -12
  151. package/dist/_browser-chunks/chunk-UTNZYD2N.js +0 -311
  152. package/dist/_browser-chunks/chunk-VUAFL5XK.js +0 -20
  153. package/dist/_browser-chunks/chunk-XDGMHOV7.js +0 -2197
  154. package/dist/_browser-chunks/chunk-XW6KSYKF.js +0 -16
  155. package/dist/_browser-chunks/chunk-Y3M7TW6K.js +0 -1041
  156. package/dist/_browser-chunks/chunk-ZNRFDIVA.js +0 -233
  157. package/dist/_node-chunks/camelcase-QALD4XFE.js +0 -18
  158. package/dist/_node-chunks/chunk-2XY53ALL.js +0 -420
  159. package/dist/_node-chunks/chunk-3CBQMG2A.js +0 -6712
  160. package/dist/_node-chunks/chunk-3WDAPZYQ.js +0 -28
  161. package/dist/_node-chunks/chunk-4ZB555EJ.js +0 -697
  162. package/dist/_node-chunks/chunk-52DXKXY3.js +0 -4272
  163. package/dist/_node-chunks/chunk-5OVB4A6F.js +0 -69
  164. package/dist/_node-chunks/chunk-AGHGNXGH.js +0 -18
  165. package/dist/_node-chunks/chunk-B23X5ZCK.js +0 -1531
  166. package/dist/_node-chunks/chunk-B2DAHWJK.js +0 -220
  167. package/dist/_node-chunks/chunk-CC4PW5MJ.js +0 -34
  168. package/dist/_node-chunks/chunk-D7NIZELR.js +0 -2256
  169. package/dist/_node-chunks/chunk-DO5Q3H4L.js +0 -1250
  170. package/dist/_node-chunks/chunk-ECK7WVFX.js +0 -304
  171. package/dist/_node-chunks/chunk-EUH3NHXA.js +0 -79
  172. package/dist/_node-chunks/chunk-FOQHPHCV.js +0 -1657
  173. package/dist/_node-chunks/chunk-G6EL47NS.js +0 -111
  174. package/dist/_node-chunks/chunk-GFLS4TJB.js +0 -90
  175. package/dist/_node-chunks/chunk-J3XZKWHE.js +0 -1586
  176. package/dist/_node-chunks/chunk-LE63EHJ5.js +0 -1518
  177. package/dist/_node-chunks/chunk-M47XA42S.js +0 -4741
  178. package/dist/_node-chunks/chunk-OOI74AL3.js +0 -61
  179. package/dist/_node-chunks/chunk-PRJHT3GJ.js +0 -61
  180. package/dist/_node-chunks/chunk-Q52PVUSU.js +0 -101
  181. package/dist/_node-chunks/chunk-SDCF5RNN.js +0 -1198
  182. package/dist/_node-chunks/chunk-UJ5SJ23M.js +0 -5029
  183. package/dist/_node-chunks/chunk-UPHK4ETU.js +0 -64658
  184. package/dist/_node-chunks/chunk-V7VURIPB.js +0 -1544
  185. package/dist/_node-chunks/dist-6TXHNR5C.js +0 -175
  186. package/dist/_node-chunks/globby-PBTV6PX6.js +0 -5222
  187. package/dist/_node-chunks/lib-4RTDZVGX.js +0 -518
  188. package/dist/_node-chunks/mdx-N42X6CFJ-COWEH7KR.js +0 -22017
  189. package/dist/_node-chunks/p-limit-PBVZQOFY.js +0 -168
  190. package/dist/_node-chunks/plugin-EOZKYZAG.js +0 -159
  191. package/dist/_node-chunks/webpack-inject-mocker-runtime-plugin-35HMSMR5.js +0 -69102
  192. package/dist/_node-chunks/webpack-mock-plugin-GT3MA5E2.js +0 -124
@@ -1,2256 +0,0 @@
1
- import CJS_COMPAT_NODE_URL_8vqew0zn9si from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_8vqew0zn9si from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_8vqew0zn9si from "node:module";
4
-
5
- var __filename = CJS_COMPAT_NODE_URL_8vqew0zn9si.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_8vqew0zn9si.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_8vqew0zn9si.createRequire(import.meta.url);
8
-
9
- // ------------------------------------------------------------
10
- // end of CJS compatibility banner, injected by Storybook's esbuild configuration
11
- // ------------------------------------------------------------
12
- import {
13
- require_dist
14
- } from "./chunk-5OVB4A6F.js";
15
- import {
16
- __name,
17
- __toESM
18
- } from "./chunk-OOI74AL3.js";
19
-
20
- // src/csf-tools/CsfFile.ts
21
- var import_ts_dedent = __toESM(require_dist(), 1);
22
- import { readFile, writeFile } from "node:fs/promises";
23
- import {
24
- BabelFileClass,
25
- babelParse,
26
- generate,
27
- recast,
28
- types as t2,
29
- traverse
30
- } from "storybook/internal/babel";
31
- import { isExportStory, storyNameFromExport, toId, toTestId } from "storybook/internal/csf";
32
- import { logger } from "storybook/internal/node-logger";
33
-
34
- // src/csf-tools/findVarInitialization.ts
35
- import { types as t } from "storybook/internal/babel";
36
- var findVarInitialization = /* @__PURE__ */ __name((identifier, program) => {
37
- let init = null;
38
- let declarations = null;
39
- program.body.find((node) => {
40
- if (t.isVariableDeclaration(node)) {
41
- declarations = node.declarations;
42
- } else if (t.isExportNamedDeclaration(node) && t.isVariableDeclaration(node.declaration)) {
43
- declarations = node.declaration.declarations;
44
- }
45
- return declarations && declarations.find((decl) => {
46
- if (t.isVariableDeclarator(decl) && t.isIdentifier(decl.id) && decl.id.name === identifier) {
47
- init = decl.init;
48
- return true;
49
- }
50
- return false;
51
- });
52
- });
53
- return init;
54
- }, "findVarInitialization");
55
-
56
- // src/csf-tools/CsfFile.ts
57
- var PREVIEW_FILE_REGEX = /\/preview(.(js|jsx|mjs|ts|tsx))?$/;
58
- var isValidPreviewPath = /* @__PURE__ */ __name((filepath) => PREVIEW_FILE_REGEX.test(filepath), "isValidPreviewPath");
59
- function parseIncludeExclude(prop) {
60
- if (t2.isArrayExpression(prop)) {
61
- return prop.elements.map((e) => {
62
- if (t2.isStringLiteral(e)) {
63
- return e.value;
64
- }
65
- throw new Error(`Expected string literal: ${e}`);
66
- });
67
- }
68
- if (t2.isStringLiteral(prop)) {
69
- return new RegExp(prop.value);
70
- }
71
- if (t2.isRegExpLiteral(prop)) {
72
- return new RegExp(prop.pattern, prop.flags);
73
- }
74
- throw new Error(`Unknown include/exclude: ${prop}`);
75
- }
76
- __name(parseIncludeExclude, "parseIncludeExclude");
77
- function parseTags(prop) {
78
- if (!t2.isArrayExpression(prop)) {
79
- throw new Error("CSF: Expected tags array");
80
- }
81
- return prop.elements.map((e) => {
82
- if (t2.isStringLiteral(e)) {
83
- return e.value;
84
- }
85
- throw new Error(`CSF: Expected tag to be string literal`);
86
- });
87
- }
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");
112
- var formatLocation = /* @__PURE__ */ __name((node, fileName) => {
113
- let loc = "";
114
- if (node.loc) {
115
- const { line, column } = node.loc?.start || {};
116
- loc = `(line ${line}, col ${column})`;
117
- }
118
- return `${fileName || ""} ${loc}`.trim();
119
- }, "formatLocation");
120
- var isModuleMock = /* @__PURE__ */ __name((importPath) => MODULE_MOCK_REGEX.test(importPath), "isModuleMock");
121
- var isArgsStory = /* @__PURE__ */ __name((init, parent, csf) => {
122
- let storyFn = init;
123
- if (t2.isCallExpression(init)) {
124
- const { callee, arguments: bindArguments } = init;
125
- if (t2.isProgram(parent) && t2.isMemberExpression(callee) && t2.isIdentifier(callee.object) && t2.isIdentifier(callee.property) && callee.property.name === "bind" && (bindArguments.length === 0 || bindArguments.length === 1 && t2.isObjectExpression(bindArguments[0]) && bindArguments[0].properties.length === 0)) {
126
- const boundIdentifier = callee.object.name;
127
- const template = findVarInitialization(boundIdentifier, parent);
128
- if (template) {
129
- csf._templates[boundIdentifier] = template;
130
- storyFn = template;
131
- }
132
- }
133
- }
134
- if (t2.isArrowFunctionExpression(storyFn)) {
135
- return storyFn.params.length > 0;
136
- }
137
- if (t2.isFunctionDeclaration(storyFn)) {
138
- return storyFn.params.length > 0;
139
- }
140
- return false;
141
- }, "isArgsStory");
142
- var parseExportsOrder = /* @__PURE__ */ __name((init) => {
143
- if (t2.isArrayExpression(init)) {
144
- return init.elements.map((item) => {
145
- if (t2.isStringLiteral(item)) {
146
- return item.value;
147
- }
148
- throw new Error(`Expected string literal named export: ${item}`);
149
- });
150
- }
151
- throw new Error(`Expected array of string literals: ${init}`);
152
- }, "parseExportsOrder");
153
- var sortExports = /* @__PURE__ */ __name((exportByName, order) => {
154
- return order.reduce(
155
- (acc, name) => {
156
- const namedExport = exportByName[name];
157
- if (namedExport) {
158
- acc[name] = namedExport;
159
- }
160
- return acc;
161
- },
162
- {}
163
- );
164
- }, "sortExports");
165
- var hasMount = /* @__PURE__ */ __name((play) => {
166
- if (t2.isArrowFunctionExpression(play) || t2.isFunctionDeclaration(play) || t2.isObjectMethod(play)) {
167
- const params = play.params;
168
- if (params.length >= 1) {
169
- const [arg] = params;
170
- if (t2.isObjectPattern(arg)) {
171
- return !!arg.properties.find((prop) => {
172
- if (t2.isObjectProperty(prop) && t2.isIdentifier(prop.key)) {
173
- return prop.key.name === "mount";
174
- }
175
- });
176
- }
177
- }
178
- }
179
- return false;
180
- }, "hasMount");
181
- var MODULE_MOCK_REGEX = /^[.\/#].*\.mock($|\.[^.]*$)/i;
182
- var NoMetaError = class extends Error {
183
- static {
184
- __name(this, "NoMetaError");
185
- }
186
- constructor(message, ast, fileName) {
187
- const msg = message.trim();
188
- super(import_ts_dedent.dedent`
189
- CSF: ${msg} ${formatLocation(ast, fileName)}
190
-
191
- More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
192
- `);
193
- this.name = this.constructor.name;
194
- }
195
- };
196
- var MultipleMetaError = class extends Error {
197
- static {
198
- __name(this, "MultipleMetaError");
199
- }
200
- constructor(message, ast, fileName) {
201
- const msg = `${message} ${formatLocation(ast, fileName)}`.trim();
202
- super(import_ts_dedent.dedent`
203
- CSF: ${message} ${formatLocation(ast, fileName)}
204
-
205
- More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
206
- `);
207
- this.name = this.constructor.name;
208
- }
209
- };
210
- var MixedFactoryError = class extends Error {
211
- static {
212
- __name(this, "MixedFactoryError");
213
- }
214
- constructor(message, ast, fileName) {
215
- const msg = `${message} ${formatLocation(ast, fileName)}`.trim();
216
- super(import_ts_dedent.dedent`
217
- CSF: ${message} ${formatLocation(ast, fileName)}
218
-
219
- More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
220
- `);
221
- this.name = this.constructor.name;
222
- }
223
- };
224
- var BadMetaError = class extends Error {
225
- static {
226
- __name(this, "BadMetaError");
227
- }
228
- constructor(message, ast, fileName) {
229
- const msg = ``.trim();
230
- super(import_ts_dedent.dedent`
231
- CSF: ${message} ${formatLocation(ast, fileName)}
232
-
233
- More info: https://storybook.js.org/docs/writing-stories?ref=error#default-export
234
- `);
235
- this.name = this.constructor.name;
236
- }
237
- };
238
- var CsfFile = class {
239
- constructor(ast, options, file) {
240
- this._stories = {};
241
- this._metaAnnotations = {};
242
- this._storyExports = {};
243
- this._storyDeclarationPath = {};
244
- this._storyPaths = {};
245
- this._storyStatements = {};
246
- this._storyAnnotations = {};
247
- this._templates = {};
248
- this._tests = [];
249
- this._ast = ast;
250
- this._file = file;
251
- this._options = options;
252
- this.imports = [];
253
- }
254
- static {
255
- __name(this, "CsfFile");
256
- }
257
- _parseTitle(value) {
258
- const node = t2.isIdentifier(value) ? findVarInitialization(value.name, this._ast.program) : value;
259
- if (t2.isStringLiteral(node)) {
260
- return node.value;
261
- }
262
- if (t2.isTSSatisfiesExpression(node) && t2.isStringLiteral(node.expression)) {
263
- return node.expression.value;
264
- }
265
- throw new Error(import_ts_dedent.dedent`
266
- CSF: unexpected dynamic title ${formatLocation(node, this._options.fileName)}
267
-
268
- More info: https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#string-literal-titles
269
- `);
270
- }
271
- _parseMeta(declaration, program) {
272
- if (this._metaNode) {
273
- throw new MultipleMetaError("multiple meta objects", declaration, this._options.fileName);
274
- }
275
- this._metaNode = declaration;
276
- const meta = {};
277
- declaration.properties.forEach((p) => {
278
- if (t2.isIdentifier(p.key)) {
279
- const value = t2.isObjectMethod(p) ? p : p.value;
280
- this._metaAnnotations[p.key.name] = value;
281
- if (p.key.name === "title") {
282
- meta.title = this._parseTitle(p.value);
283
- } else if (["includeStories", "excludeStories"].includes(p.key.name)) {
284
- meta[p.key.name] = parseIncludeExclude(p.value);
285
- } else if (p.key.name === "component") {
286
- const n = p.value;
287
- if (t2.isIdentifier(n)) {
288
- const id = n.name;
289
- const importStmt = program.body.find(
290
- (stmt) => t2.isImportDeclaration(stmt) && stmt.specifiers.find((spec) => spec.local.name === id)
291
- );
292
- if (importStmt) {
293
- const { source } = importStmt;
294
- const specifier = importStmt.specifiers.find((spec) => spec.local.name === id);
295
- if (t2.isStringLiteral(source) && specifier) {
296
- this._rawComponentPath = source.value;
297
- if (t2.isImportSpecifier(specifier) || t2.isImportDefaultSpecifier(specifier)) {
298
- this._componentImportSpecifier = specifier;
299
- }
300
- }
301
- }
302
- }
303
- const { code } = recast.print(p.value, {});
304
- meta.component = code;
305
- } else if (p.key.name === "tags") {
306
- let node = p.value;
307
- if (t2.isIdentifier(node)) {
308
- node = findVarInitialization(node.name, this._ast.program);
309
- }
310
- meta.tags = parseTags(node);
311
- } else if (p.key.name === "id") {
312
- if (t2.isStringLiteral(p.value)) {
313
- meta.id = p.value.value;
314
- } else {
315
- throw new Error(`Unexpected component id: ${p.value}`);
316
- }
317
- }
318
- }
319
- });
320
- this._meta = meta;
321
- }
322
- getStoryExport(key) {
323
- let node = this._storyExports[key];
324
- node = t2.isVariableDeclarator(node) ? node.init : node;
325
- if (t2.isCallExpression(node)) {
326
- const { callee, arguments: bindArguments } = node;
327
- if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.object) && t2.isIdentifier(callee.property) && callee.property.name === "bind" && (bindArguments.length === 0 || bindArguments.length === 1 && t2.isObjectExpression(bindArguments[0]) && bindArguments[0].properties.length === 0)) {
328
- const { name } = callee.object;
329
- node = this._templates[name];
330
- }
331
- }
332
- return node;
333
- }
334
- parse() {
335
- const self = this;
336
- traverse(this._ast, {
337
- ExportDefaultDeclaration: {
338
- enter(path) {
339
- const { node, parent } = path;
340
- const isVariableReference = t2.isIdentifier(node.declaration) && t2.isProgram(parent);
341
- if (self._options.transformInlineMeta && !isVariableReference && t2.isExpression(node.declaration)) {
342
- const metaId = path.scope.generateUidIdentifier("meta");
343
- self._metaVariableName = metaId.name;
344
- const nodes = [
345
- t2.variableDeclaration("const", [t2.variableDeclarator(metaId, node.declaration)]),
346
- t2.exportDefaultDeclaration(metaId)
347
- ];
348
- nodes.forEach((_node) => _node.loc = path.node.loc);
349
- path.replaceWithMultiple(nodes);
350
- return;
351
- }
352
- let metaNode;
353
- let decl;
354
- if (isVariableReference) {
355
- const variableName = node.declaration.name;
356
- self._metaVariableName = variableName;
357
- const isMetaVariable = /* @__PURE__ */ __name((declaration) => t2.isIdentifier(declaration.id) && declaration.id.name === variableName, "isMetaVariable");
358
- self._metaStatementPath = self._file.path.get("body").find(
359
- (path2) => path2.isVariableDeclaration() && path2.node.declarations.some(isMetaVariable)
360
- );
361
- self._metaStatement = self._metaStatementPath?.node;
362
- decl = (self?._metaStatement?.declarations || []).find(
363
- isMetaVariable
364
- )?.init;
365
- } else {
366
- self._metaStatement = node;
367
- self._metaStatementPath = path;
368
- decl = node.declaration;
369
- }
370
- if (t2.isObjectExpression(decl)) {
371
- metaNode = decl;
372
- } else if (
373
- // export default { ... } as Meta<...>
374
- // export default { ... } satisfies Meta<...>
375
- (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
376
- ) {
377
- metaNode = decl.expression;
378
- } else if (
379
- // export default { ... } satisfies Meta as Meta<...>
380
- t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
381
- ) {
382
- metaNode = decl.expression.expression;
383
- }
384
- if (metaNode && t2.isProgram(parent)) {
385
- self._parseMeta(metaNode, parent);
386
- }
387
- if (self._metaStatement && !self._metaNode) {
388
- throw new NoMetaError(
389
- "default export must be an object",
390
- self._metaStatement,
391
- self._options.fileName
392
- );
393
- }
394
- self._metaPath = path;
395
- }
396
- },
397
- ExportNamedDeclaration: {
398
- enter(path) {
399
- const { node, parent } = path;
400
- const declaration = path.get("declaration");
401
- let declarations;
402
- if (declaration.isVariableDeclaration()) {
403
- declarations = declaration.get("declarations").filter((d) => d.isVariableDeclarator());
404
- } else if (declaration.isFunctionDeclaration()) {
405
- declarations = [declaration];
406
- }
407
- if (declarations) {
408
- declarations.forEach((declPath) => {
409
- const decl = declPath.node;
410
- const id = declPath.node.id;
411
- if (t2.isIdentifier(id)) {
412
- let storyIsFactory = false;
413
- const { name: exportName } = id;
414
- if (exportName === "__namedExportsOrder" && declPath.isVariableDeclarator()) {
415
- self._namedExportsOrder = parseExportsOrder(declPath.node.init);
416
- return;
417
- }
418
- self._storyExports[exportName] = decl;
419
- self._storyDeclarationPath[exportName] = declPath;
420
- self._storyPaths[exportName] = path;
421
- self._storyStatements[exportName] = node;
422
- let name = storyNameFromExport(exportName);
423
- if (self._storyAnnotations[exportName]) {
424
- logger.warn(
425
- `Unexpected annotations for "${exportName}" before story declaration`
426
- );
427
- } else {
428
- self._storyAnnotations[exportName] = {};
429
- }
430
- let storyNode;
431
- if (t2.isVariableDeclarator(decl)) {
432
- if (t2.isTSAsExpression(decl.init) && t2.isTSSatisfiesExpression(decl.init.expression)) {
433
- storyNode = decl.init.expression.expression;
434
- } else if (t2.isTSAsExpression(decl.init) || t2.isTSSatisfiesExpression(decl.init)) {
435
- storyNode = decl.init.expression;
436
- } else {
437
- storyNode = decl.init;
438
- }
439
- } else {
440
- storyNode = decl;
441
- }
442
- if (t2.isCallExpression(storyNode) && t2.isMemberExpression(storyNode.callee) && t2.isIdentifier(storyNode.callee.property) && (storyNode.callee.property.name === "story" || storyNode.callee.property.name === "extend")) {
443
- storyIsFactory = true;
444
- storyNode = storyNode.arguments[0];
445
- }
446
- if (self._metaIsFactory && !storyIsFactory) {
447
- throw new MixedFactoryError(
448
- "expected factory story",
449
- storyNode,
450
- self._options.fileName
451
- );
452
- } else if (!self._metaIsFactory && storyIsFactory) {
453
- if (self._metaNode) {
454
- throw new MixedFactoryError(
455
- "expected non-factory story",
456
- storyNode,
457
- self._options.fileName
458
- );
459
- } else {
460
- throw new BadMetaError(
461
- "meta() factory must be imported from .storybook/preview configuration",
462
- storyNode,
463
- self._options.fileName
464
- );
465
- }
466
- }
467
- const parameters = {};
468
- if (t2.isObjectExpression(storyNode)) {
469
- parameters.__isArgsStory = true;
470
- storyNode.properties.forEach((p) => {
471
- if (t2.isIdentifier(p.key)) {
472
- const key = p.key.name;
473
- if (t2.isObjectMethod(p)) {
474
- self._storyAnnotations[exportName][key] = p;
475
- } else {
476
- if (p.key.name === "render") {
477
- parameters.__isArgsStory = isArgsStory(
478
- p.value,
479
- parent,
480
- self
481
- );
482
- } else if (p.key.name === "name" && t2.isStringLiteral(p.value)) {
483
- name = p.value.value;
484
- } else if (p.key.name === "storyName" && t2.isStringLiteral(p.value)) {
485
- logger.warn(
486
- `Unexpected usage of "storyName" in "${exportName}". Please use "name" instead.`
487
- );
488
- } else if (p.key.name === "parameters" && t2.isObjectExpression(p.value)) {
489
- const idProperty = p.value.properties.find(
490
- (property) => t2.isObjectProperty(property) && t2.isIdentifier(property.key) && property.key.name === "__id"
491
- );
492
- if (idProperty) {
493
- parameters.__id = idProperty.value.value;
494
- }
495
- }
496
- self._storyAnnotations[exportName][p.key.name] = p.value;
497
- }
498
- }
499
- });
500
- } else {
501
- parameters.__isArgsStory = isArgsStory(storyNode, parent, self);
502
- }
503
- self._stories[exportName] = {
504
- id: "FIXME",
505
- name,
506
- parameters,
507
- __stats: {
508
- factory: storyIsFactory
509
- }
510
- };
511
- }
512
- });
513
- } else if (node.specifiers.length > 0) {
514
- node.specifiers.forEach((specifier) => {
515
- if (t2.isExportSpecifier(specifier) && t2.isIdentifier(specifier.exported)) {
516
- const { name: exportName } = specifier.exported;
517
- const { name: localName } = specifier.local;
518
- const decl = t2.isProgram(parent) ? findVarInitialization(localName, parent) : specifier.local;
519
- if (exportName === "default") {
520
- let metaNode;
521
- if (t2.isObjectExpression(decl)) {
522
- metaNode = decl;
523
- } else if (
524
- // export default { ... } as Meta<...>
525
- // export default { ... } satisfies Meta<...>
526
- (t2.isTSAsExpression(decl) || t2.isTSSatisfiesExpression(decl)) && t2.isObjectExpression(decl.expression)
527
- ) {
528
- metaNode = decl.expression;
529
- } else if (
530
- // export default { ... } satisfies Meta as Meta<...>
531
- t2.isTSAsExpression(decl) && t2.isTSSatisfiesExpression(decl.expression) && t2.isObjectExpression(decl.expression.expression)
532
- ) {
533
- metaNode = decl.expression.expression;
534
- }
535
- if (metaNode && t2.isProgram(parent)) {
536
- self._parseMeta(metaNode, parent);
537
- }
538
- } else {
539
- const annotations = {};
540
- const storyNode = decl;
541
- if (t2.isObjectExpression(storyNode)) {
542
- storyNode.properties.forEach((p) => {
543
- if (t2.isIdentifier(p.key)) {
544
- annotations[p.key.name] = p.value;
545
- }
546
- });
547
- }
548
- self._storyAnnotations[exportName] = annotations;
549
- self._storyStatements[exportName] = decl;
550
- self._storyPaths[exportName] = path;
551
- self._stories[exportName] = {
552
- id: "FIXME",
553
- name: exportName,
554
- localName,
555
- parameters: {},
556
- __stats: {}
557
- };
558
- }
559
- }
560
- });
561
- }
562
- }
563
- },
564
- ExpressionStatement: {
565
- enter({ node, parent }) {
566
- const { expression } = node;
567
- if (t2.isProgram(parent) && t2.isAssignmentExpression(expression) && t2.isMemberExpression(expression.left) && t2.isIdentifier(expression.left.object) && t2.isIdentifier(expression.left.property)) {
568
- const exportName = expression.left.object.name;
569
- const annotationKey = expression.left.property.name;
570
- const annotationValue = expression.right;
571
- if (self._storyAnnotations[exportName]) {
572
- if (annotationKey === "story" && t2.isObjectExpression(annotationValue)) {
573
- annotationValue.properties.forEach((prop) => {
574
- if (t2.isIdentifier(prop.key)) {
575
- self._storyAnnotations[exportName][prop.key.name] = prop.value;
576
- }
577
- });
578
- } else {
579
- self._storyAnnotations[exportName][annotationKey] = annotationValue;
580
- }
581
- }
582
- if (annotationKey === "storyName" && t2.isStringLiteral(annotationValue)) {
583
- const storyName = annotationValue.value;
584
- const story = self._stories[exportName];
585
- if (!story) {
586
- return;
587
- }
588
- story.name = storyName;
589
- }
590
- }
591
- 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])) {
592
- const exportName = expression.callee.object.name;
593
- const testName = expression.arguments[0].value;
594
- const testFunction = expression.arguments.length === 2 ? expression.arguments[1] : expression.arguments[2];
595
- const testArguments = expression.arguments.length === 2 ? null : expression.arguments[1];
596
- const tags = parseTestTags(testArguments, self._ast.program);
597
- self._tests.push({
598
- function: testFunction,
599
- name: testName,
600
- node: expression,
601
- // can't set id because meta title isn't available yet
602
- // so it's set later on
603
- id: "FIXME",
604
- tags,
605
- parent: { node: self._storyStatements[exportName] }
606
- });
607
- self._stories[exportName].__stats.tests = true;
608
- }
609
- }
610
- },
611
- CallExpression: {
612
- enter(path) {
613
- const { node } = path;
614
- const { callee } = node;
615
- if (t2.isIdentifier(callee) && callee.name === "storiesOf") {
616
- throw new Error(import_ts_dedent.dedent`
617
- Unexpected \`storiesOf\` usage: ${formatLocation(node, self._options.fileName)}.
618
-
619
- SB8 does not support \`storiesOf\`.
620
- `);
621
- }
622
- if (t2.isMemberExpression(callee) && t2.isIdentifier(callee.property) && callee.property.name === "meta" && t2.isIdentifier(callee.object) && node.arguments.length > 0) {
623
- const configCandidate = path.scope.getBinding(callee.object.name);
624
- const configParent = configCandidate?.path?.parentPath?.node;
625
- if (t2.isImportDeclaration(configParent)) {
626
- if (isValidPreviewPath(configParent.source.value)) {
627
- self._metaIsFactory = true;
628
- const metaDeclarator = path.findParent(
629
- (p) => p.isVariableDeclarator()
630
- );
631
- self._metaVariableName = t2.isIdentifier(metaDeclarator.node.id) ? metaDeclarator.node.id.name : callee.property.name;
632
- const metaNode = node.arguments[0];
633
- self._parseMeta(metaNode, self._ast.program);
634
- } else {
635
- throw new BadMetaError(
636
- "meta() factory must be imported from .storybook/preview configuration",
637
- configParent,
638
- self._options.fileName
639
- );
640
- }
641
- }
642
- }
643
- }
644
- },
645
- ImportDeclaration: {
646
- enter({ node }) {
647
- const { source } = node;
648
- if (t2.isStringLiteral(source)) {
649
- self.imports.push(source.value);
650
- } else {
651
- throw new Error("CSF: unexpected import source");
652
- }
653
- }
654
- }
655
- });
656
- if (!self._meta) {
657
- throw new NoMetaError("missing default export", self._ast, self._options.fileName);
658
- }
659
- const entries = Object.entries(self._stories);
660
- self._meta.title = this._options.makeTitle(self._meta?.title);
661
- if (self._metaAnnotations.play) {
662
- self._meta.tags = [...self._meta.tags || [], "play-fn"];
663
- }
664
- self._stories = entries.reduce(
665
- (acc, [key, story]) => {
666
- if (!isExportStory(key, self._meta)) {
667
- return acc;
668
- }
669
- const id = story.parameters?.__id ?? toId(self._meta?.id || self._meta?.title, storyNameFromExport(key));
670
- const parameters = { ...story.parameters, __id: id };
671
- const { includeStories } = self._meta || {};
672
- if (key === "__page" && (entries.length === 1 || Array.isArray(includeStories) && includeStories.length === 1)) {
673
- parameters.docsOnly = true;
674
- }
675
- acc[key] = { ...story, id, parameters };
676
- const storyAnnotations = self._storyAnnotations[key];
677
- const { tags, play } = storyAnnotations;
678
- if (tags) {
679
- const node = t2.isIdentifier(tags) ? findVarInitialization(tags.name, this._ast.program) : tags;
680
- acc[key].tags = parseTags(node);
681
- }
682
- if (play) {
683
- acc[key].tags = [...acc[key].tags || [], "play-fn"];
684
- }
685
- const stats = acc[key].__stats;
686
- ["play", "render", "loaders", "beforeEach", "globals", "tags"].forEach((annotation) => {
687
- stats[annotation] = !!storyAnnotations[annotation] || !!self._metaAnnotations[annotation];
688
- });
689
- const storyExport = self.getStoryExport(key);
690
- stats.storyFn = !!(t2.isArrowFunctionExpression(storyExport) || t2.isFunctionDeclaration(storyExport));
691
- stats.mount = hasMount(storyAnnotations.play ?? self._metaAnnotations.play);
692
- stats.moduleMock = !!self.imports.find((fname) => isModuleMock(fname));
693
- const storyNode = self._storyStatements[key];
694
- const storyTests = self._tests.filter((t7) => t7.parent.node === storyNode);
695
- if (storyTests.length > 0) {
696
- stats.tests = true;
697
- storyTests.forEach((test) => {
698
- test.id = toTestId(id, test.name);
699
- });
700
- }
701
- return acc;
702
- },
703
- {}
704
- );
705
- Object.keys(self._storyExports).forEach((key) => {
706
- if (!isExportStory(key, self._meta)) {
707
- delete self._storyExports[key];
708
- delete self._storyAnnotations[key];
709
- delete self._storyStatements[key];
710
- }
711
- });
712
- if (self._namedExportsOrder) {
713
- const unsortedExports = Object.keys(self._storyExports);
714
- self._storyExports = sortExports(self._storyExports, self._namedExportsOrder);
715
- self._stories = sortExports(self._stories, self._namedExportsOrder);
716
- const sortedExports = Object.keys(self._storyExports);
717
- if (unsortedExports.length !== sortedExports.length) {
718
- throw new Error(
719
- `Missing exports after sort: ${unsortedExports.filter(
720
- (key) => !sortedExports.includes(key)
721
- )}`
722
- );
723
- }
724
- }
725
- return self;
726
- }
727
- get meta() {
728
- return this._meta;
729
- }
730
- get stories() {
731
- return Object.values(this._stories);
732
- }
733
- getStoryTests(story) {
734
- const storyNode = typeof story === "string" ? this._storyStatements[story] : story;
735
- if (!storyNode) {
736
- return [];
737
- }
738
- return this._tests.filter((t7) => t7.parent.node === storyNode);
739
- }
740
- get indexInputs() {
741
- const { fileName } = this._options;
742
- if (!fileName) {
743
- throw new Error(
744
- import_ts_dedent.dedent`Cannot automatically create index inputs with CsfFile.indexInputs because the CsfFile instance was created without a the fileName option.
745
- Either add the fileName option when creating the CsfFile instance, or create the index inputs manually.`
746
- );
747
- }
748
- const index = [];
749
- Object.entries(this._stories).map(([exportName, story]) => {
750
- const tags = [...this._meta?.tags ?? [], ...story.tags ?? []];
751
- const storyInput = {
752
- importPath: fileName,
753
- rawComponentPath: this._rawComponentPath,
754
- exportName,
755
- title: this.meta?.title,
756
- metaId: this.meta?.id,
757
- tags,
758
- __id: story.id,
759
- __stats: story.__stats
760
- };
761
- const tests = this.getStoryTests(exportName);
762
- const hasTests = tests.length > 0;
763
- index.push({
764
- ...storyInput,
765
- type: "story",
766
- subtype: "story",
767
- name: story.name
768
- });
769
- if (hasTests) {
770
- tests.forEach((test) => {
771
- index.push({
772
- ...storyInput,
773
- // TODO implementent proper title => path behavior in `transformStoryIndexToStoriesHash`
774
- // title: `${storyInput.title}/${story.name}`,
775
- type: "story",
776
- subtype: "test",
777
- name: test.name,
778
- parent: story.id,
779
- parentName: story.name,
780
- tags: [
781
- ...storyInput.tags,
782
- // this tag comes before test tags so users can invert if they like
783
- "!autodocs",
784
- ...test.tags,
785
- // this tag comes after test tags so users can't change it
786
- "test-fn"
787
- ],
788
- __id: test.id
789
- });
790
- });
791
- }
792
- });
793
- return index;
794
- }
795
- };
796
- var babelParseFile = /* @__PURE__ */ __name(({
797
- code,
798
- filename = "",
799
- ast
800
- }) => {
801
- return new BabelFileClass(
802
- { filename, highlightCode: false },
803
- { code, ast: ast ?? babelParse(code) }
804
- );
805
- }, "babelParseFile");
806
- var loadCsf = /* @__PURE__ */ __name((code, options) => {
807
- const ast = babelParse(code);
808
- const file = babelParseFile({ code, filename: options.fileName, ast });
809
- return new CsfFile(ast, options, file);
810
- }, "loadCsf");
811
- var formatCsf = /* @__PURE__ */ __name((csf, options = { sourceMaps: false }, code) => {
812
- const result = generate(csf._ast, options, code);
813
- if (options.sourceMaps) {
814
- return result;
815
- }
816
- return result.code;
817
- }, "formatCsf");
818
- var printCsf = /* @__PURE__ */ __name((csf, options = {}) => {
819
- return recast.print(csf._ast, options);
820
- }, "printCsf");
821
- var readCsf = /* @__PURE__ */ __name(async (fileName, options) => {
822
- const code = (await readFile(fileName, "utf-8")).toString();
823
- return loadCsf(code, { ...options, fileName });
824
- }, "readCsf");
825
- var writeCsf = /* @__PURE__ */ __name(async (csf, fileName) => {
826
- const fname = fileName || csf._options.fileName;
827
- if (!fname) {
828
- throw new Error("Please specify a fileName for writeCsf");
829
- }
830
- await writeFile(fileName, printCsf(csf).code);
831
- }, "writeCsf");
832
-
833
- // src/csf-tools/ConfigFile.ts
834
- var import_ts_dedent2 = __toESM(require_dist(), 1);
835
- import { readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
836
- import {
837
- babelParse as babelParse2,
838
- generate as generate2,
839
- recast as recast2,
840
- types as t3,
841
- traverse as traverse2
842
- } from "storybook/internal/babel";
843
- import { logger as logger2 } from "storybook/internal/node-logger";
844
- var getCsfParsingErrorMessage = /* @__PURE__ */ __name(({
845
- expectedType,
846
- foundType,
847
- node
848
- }) => {
849
- return import_ts_dedent2.dedent`
850
- CSF Parsing error: Expected '${expectedType}' but found '${foundType}' instead in '${node?.type}'.
851
- `;
852
- }, "getCsfParsingErrorMessage");
853
- var propKey = /* @__PURE__ */ __name((p) => {
854
- if (t3.isIdentifier(p.key)) {
855
- return p.key.name;
856
- }
857
- if (t3.isStringLiteral(p.key)) {
858
- return p.key.value;
859
- }
860
- return null;
861
- }, "propKey");
862
- var _getPath = /* @__PURE__ */ __name((path, node) => {
863
- if (path.length === 0) {
864
- return node;
865
- }
866
- if (t3.isObjectExpression(node)) {
867
- const [first, ...rest] = path;
868
- const field = node.properties.find((p) => propKey(p) === first);
869
- if (field) {
870
- return _getPath(rest, field.value);
871
- }
872
- }
873
- return void 0;
874
- }, "_getPath");
875
- var _getPathProperties = /* @__PURE__ */ __name((path, node) => {
876
- if (path.length === 0) {
877
- if (t3.isObjectExpression(node)) {
878
- return node.properties;
879
- }
880
- throw new Error("Expected object expression");
881
- }
882
- if (t3.isObjectExpression(node)) {
883
- const [first, ...rest] = path;
884
- const field = node.properties.find((p) => propKey(p) === first);
885
- if (field) {
886
- if (rest.length === 0) {
887
- return node.properties;
888
- }
889
- return _getPathProperties(rest, field.value);
890
- }
891
- }
892
- return void 0;
893
- }, "_getPathProperties");
894
- var _findVarDeclarator = /* @__PURE__ */ __name((identifier, program) => {
895
- let declarator = null;
896
- let declarations = null;
897
- program.body.find((node) => {
898
- if (t3.isVariableDeclaration(node)) {
899
- declarations = node.declarations;
900
- } else if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
901
- declarations = node.declaration.declarations;
902
- }
903
- return declarations && declarations.find((decl) => {
904
- if (t3.isVariableDeclarator(decl) && t3.isIdentifier(decl.id) && decl.id.name === identifier) {
905
- declarator = decl;
906
- return true;
907
- }
908
- return false;
909
- });
910
- });
911
- return declarator;
912
- }, "_findVarDeclarator");
913
- var _findVarInitialization = /* @__PURE__ */ __name((identifier, program) => {
914
- const declarator = _findVarDeclarator(identifier, program);
915
- return declarator?.init;
916
- }, "_findVarInitialization");
917
- var _makeObjectExpression = /* @__PURE__ */ __name((path, value) => {
918
- if (path.length === 0) {
919
- return value;
920
- }
921
- const [first, ...rest] = path;
922
- const innerExpression = _makeObjectExpression(rest, value);
923
- return t3.objectExpression([t3.objectProperty(t3.identifier(first), innerExpression)]);
924
- }, "_makeObjectExpression");
925
- var _updateExportNode = /* @__PURE__ */ __name((path, expr, existing) => {
926
- const [first, ...rest] = path;
927
- const existingField = existing.properties.find(
928
- (p) => propKey(p) === first
929
- );
930
- if (!existingField) {
931
- existing.properties.push(
932
- t3.objectProperty(t3.identifier(first), _makeObjectExpression(rest, expr))
933
- );
934
- } else if (t3.isObjectExpression(existingField.value) && rest.length > 0) {
935
- _updateExportNode(rest, expr, existingField.value);
936
- } else {
937
- existingField.value = _makeObjectExpression(rest, expr);
938
- }
939
- }, "_updateExportNode");
940
- var ConfigFile = class {
941
- constructor(ast, code, fileName) {
942
- this._exports = {};
943
- // FIXME: this is a hack. this is only used in the case where the user is
944
- // modifying a named export that's a scalar. The _exports map is not suitable
945
- // for that. But rather than refactor the whole thing, we just use this as a stopgap.
946
- this._exportDecls = {};
947
- this.hasDefaultExport = false;
948
- /** Unwraps TS assertions/satisfies from a node, to get the underlying node. */
949
- this._unwrap = /* @__PURE__ */ __name((node) => {
950
- if (t3.isTSAsExpression(node) || t3.isTSSatisfiesExpression(node)) {
951
- return this._unwrap(node.expression);
952
- }
953
- return node;
954
- }, "_unwrap");
955
- /**
956
- * Resolve a declaration node by unwrapping TS assertions/satisfies and following identifiers to
957
- * resolve the correct node in case it's an identifier.
958
- */
959
- this._resolveDeclaration = /* @__PURE__ */ __name((node, parent = this._ast.program) => {
960
- const decl = this._unwrap(node);
961
- if (t3.isIdentifier(decl) && t3.isProgram(parent)) {
962
- const initialization = _findVarInitialization(decl.name, parent);
963
- return initialization ? this._unwrap(initialization) : decl;
964
- }
965
- return decl;
966
- }, "_resolveDeclaration");
967
- this._ast = ast;
968
- this._code = code;
969
- this.fileName = fileName;
970
- }
971
- static {
972
- __name(this, "ConfigFile");
973
- }
974
- _parseExportsObject(exportsObject) {
975
- this._exportsObject = exportsObject;
976
- exportsObject.properties.forEach((p) => {
977
- const exportName = propKey(p);
978
- if (exportName) {
979
- const exportVal = this._resolveDeclaration(p.value);
980
- this._exports[exportName] = exportVal;
981
- }
982
- });
983
- }
984
- parse() {
985
- const self = this;
986
- traverse2(this._ast, {
987
- ExportDefaultDeclaration: {
988
- enter({ node, parent }) {
989
- self.hasDefaultExport = true;
990
- let decl = self._resolveDeclaration(node.declaration, parent);
991
- if (t3.isCallExpression(decl) && t3.isObjectExpression(decl.arguments[0])) {
992
- decl = decl.arguments[0];
993
- }
994
- if (t3.isObjectExpression(decl)) {
995
- self._parseExportsObject(decl);
996
- } else {
997
- logger2.warn(
998
- getCsfParsingErrorMessage({
999
- expectedType: "ObjectExpression",
1000
- foundType: decl?.type,
1001
- node: decl || node.declaration
1002
- })
1003
- );
1004
- }
1005
- }
1006
- },
1007
- ExportNamedDeclaration: {
1008
- enter({ node, parent }) {
1009
- if (t3.isVariableDeclaration(node.declaration)) {
1010
- node.declaration.declarations.forEach((decl) => {
1011
- if (t3.isVariableDeclarator(decl) && t3.isIdentifier(decl.id)) {
1012
- const { name: exportName } = decl.id;
1013
- const exportVal = self._resolveDeclaration(decl.init, parent);
1014
- self._exports[exportName] = exportVal;
1015
- self._exportDecls[exportName] = decl;
1016
- }
1017
- });
1018
- } else if (t3.isFunctionDeclaration(node.declaration)) {
1019
- const decl = node.declaration;
1020
- if (t3.isIdentifier(decl.id)) {
1021
- const { name: exportName } = decl.id;
1022
- self._exportDecls[exportName] = decl;
1023
- }
1024
- } else if (node.specifiers) {
1025
- node.specifiers.forEach((spec) => {
1026
- if (t3.isExportSpecifier(spec) && t3.isIdentifier(spec.local) && t3.isIdentifier(spec.exported)) {
1027
- const { name: localName } = spec.local;
1028
- const { name: exportName } = spec.exported;
1029
- const decl = _findVarDeclarator(localName, parent);
1030
- if (decl) {
1031
- self._exports[exportName] = self._resolveDeclaration(decl.init, parent);
1032
- self._exportDecls[exportName] = decl;
1033
- }
1034
- }
1035
- });
1036
- } else {
1037
- logger2.warn(
1038
- getCsfParsingErrorMessage({
1039
- expectedType: "VariableDeclaration",
1040
- foundType: node.declaration?.type,
1041
- node: node.declaration
1042
- })
1043
- );
1044
- }
1045
- }
1046
- },
1047
- ExpressionStatement: {
1048
- enter({ node, parent }) {
1049
- if (t3.isAssignmentExpression(node.expression) && node.expression.operator === "=") {
1050
- const { left, right } = node.expression;
1051
- if (t3.isMemberExpression(left) && t3.isIdentifier(left.object) && left.object.name === "module" && t3.isIdentifier(left.property) && left.property.name === "exports") {
1052
- let exportObject = right;
1053
- exportObject = self._resolveDeclaration(exportObject, parent);
1054
- if (t3.isObjectExpression(exportObject)) {
1055
- self._exportsObject = exportObject;
1056
- exportObject.properties.forEach((p) => {
1057
- const exportName = propKey(p);
1058
- if (exportName) {
1059
- const exportVal = self._resolveDeclaration(p.value, parent);
1060
- self._exports[exportName] = exportVal;
1061
- }
1062
- });
1063
- } else {
1064
- logger2.warn(
1065
- getCsfParsingErrorMessage({
1066
- expectedType: "ObjectExpression",
1067
- foundType: exportObject?.type,
1068
- node: exportObject
1069
- })
1070
- );
1071
- }
1072
- }
1073
- }
1074
- }
1075
- },
1076
- CallExpression: {
1077
- enter: /* @__PURE__ */ __name(({ node }) => {
1078
- if (t3.isIdentifier(node.callee) && node.callee.name === "definePreview" && node.arguments.length === 1 && t3.isObjectExpression(node.arguments[0])) {
1079
- self._parseExportsObject(node.arguments[0]);
1080
- }
1081
- }, "enter")
1082
- }
1083
- });
1084
- return self;
1085
- }
1086
- getFieldNode(path) {
1087
- const [root, ...rest] = path;
1088
- const exported = this._exports[root];
1089
- if (!exported) {
1090
- return void 0;
1091
- }
1092
- return _getPath(rest, exported);
1093
- }
1094
- getFieldProperties(path) {
1095
- const [root, ...rest] = path;
1096
- const exported = this._exports[root];
1097
- if (!exported) {
1098
- return void 0;
1099
- }
1100
- return _getPathProperties(rest, exported);
1101
- }
1102
- getFieldValue(path) {
1103
- const node = this.getFieldNode(path);
1104
- if (node) {
1105
- const { code } = generate2(node, {});
1106
- const value = (0, eval)(`(() => (${code}))()`);
1107
- return value;
1108
- }
1109
- return void 0;
1110
- }
1111
- getSafeFieldValue(path) {
1112
- try {
1113
- return this.getFieldValue(path);
1114
- } catch (e) {
1115
- }
1116
- return void 0;
1117
- }
1118
- setFieldNode(path, expr) {
1119
- const [first, ...rest] = path;
1120
- const exportNode = this._exports[first];
1121
- if (this._exportsObject) {
1122
- const properties = this._exportsObject.properties;
1123
- const existingProp = properties.find((p) => propKey(p) === first);
1124
- if (existingProp && t3.isIdentifier(existingProp.value)) {
1125
- const varDecl2 = _findVarDeclarator(existingProp.value.name, this._ast.program);
1126
- if (varDecl2 && t3.isObjectExpression(varDecl2.init)) {
1127
- _updateExportNode(rest, expr, varDecl2.init);
1128
- return;
1129
- }
1130
- }
1131
- _updateExportNode(path, expr, this._exportsObject);
1132
- this._exports[path[0]] = expr;
1133
- return;
1134
- }
1135
- if (exportNode && t3.isObjectExpression(exportNode) && rest.length > 0) {
1136
- _updateExportNode(rest, expr, exportNode);
1137
- return;
1138
- }
1139
- const varDecl = _findVarDeclarator(first, this._ast.program);
1140
- if (varDecl && t3.isObjectExpression(varDecl.init)) {
1141
- _updateExportNode(rest, expr, varDecl.init);
1142
- return;
1143
- }
1144
- if (exportNode && rest.length === 0 && this._exportDecls[path[0]]) {
1145
- const decl = this._exportDecls[path[0]];
1146
- if (t3.isVariableDeclarator(decl)) {
1147
- decl.init = _makeObjectExpression([], expr);
1148
- }
1149
- } else if (this.hasDefaultExport) {
1150
- throw new Error(
1151
- `Could not set the "${path.join(
1152
- "."
1153
- )}" field as the default export is not an object in this file.`
1154
- );
1155
- } else {
1156
- const exportObj = _makeObjectExpression(rest, expr);
1157
- const newExport = t3.exportNamedDeclaration(
1158
- t3.variableDeclaration("const", [t3.variableDeclarator(t3.identifier(first), exportObj)])
1159
- );
1160
- this._exports[first] = exportObj;
1161
- this._ast.program.body.push(newExport);
1162
- }
1163
- }
1164
- /**
1165
- * @example
1166
- *
1167
- * ```ts
1168
- * // 1. { framework: 'framework-name' }
1169
- * // 2. { framework: { name: 'framework-name', options: {} }
1170
- * getNameFromPath(['framework']); // => 'framework-name'
1171
- * ```
1172
- *
1173
- * @returns The name of a node in a given path, supporting the following formats:
1174
- */
1175
- getNameFromPath(path) {
1176
- const node = this.getFieldNode(path);
1177
- if (!node) {
1178
- return void 0;
1179
- }
1180
- return this._getPresetValue(node, "name");
1181
- }
1182
- /**
1183
- * Returns an array of names of a node in a given path, supporting the following formats:
1184
- *
1185
- * @example
1186
- *
1187
- * ```ts
1188
- * const config = {
1189
- * addons: ['first-addon', { name: 'second-addon', options: {} }],
1190
- * };
1191
- * // => ['first-addon', 'second-addon']
1192
- * getNamesFromPath(['addons']);
1193
- * ```
1194
- */
1195
- getNamesFromPath(path) {
1196
- const node = this.getFieldNode(path);
1197
- if (!node) {
1198
- return void 0;
1199
- }
1200
- const pathNames = [];
1201
- if (t3.isArrayExpression(node)) {
1202
- node.elements.forEach((element) => {
1203
- pathNames.push(this._getPresetValue(element, "name"));
1204
- });
1205
- }
1206
- return pathNames;
1207
- }
1208
- _getPnpWrappedValue(node) {
1209
- if (t3.isCallExpression(node)) {
1210
- const arg = node.arguments[0];
1211
- if (t3.isStringLiteral(arg)) {
1212
- return arg.value;
1213
- }
1214
- }
1215
- return void 0;
1216
- }
1217
- /**
1218
- * Given a node and a fallback property, returns a **non-evaluated** string value of the node.
1219
- *
1220
- * 1. `{ node: 'value' }`
1221
- * 2. `{ node: { fallbackProperty: 'value' } }`
1222
- */
1223
- _getPresetValue(node, fallbackProperty) {
1224
- let value;
1225
- if (t3.isStringLiteral(node)) {
1226
- value = node.value;
1227
- } else if (t3.isObjectExpression(node)) {
1228
- node.properties.forEach((prop) => {
1229
- if (t3.isObjectProperty(prop) && t3.isIdentifier(prop.key) && prop.key.name === fallbackProperty) {
1230
- if (t3.isStringLiteral(prop.value)) {
1231
- value = prop.value.value;
1232
- } else {
1233
- value = this._getPnpWrappedValue(prop.value);
1234
- }
1235
- }
1236
- if (t3.isObjectProperty(prop) && t3.isStringLiteral(prop.key) && prop.key.value === "name" && t3.isStringLiteral(prop.value)) {
1237
- value = prop.value.value;
1238
- }
1239
- });
1240
- } else if (t3.isCallExpression(node)) {
1241
- value = this._getPnpWrappedValue(node);
1242
- }
1243
- if (!value) {
1244
- throw new Error(
1245
- `The given node must be a string literal or an object expression with a "${fallbackProperty}" property that is a string literal.`
1246
- );
1247
- }
1248
- return value;
1249
- }
1250
- removeField(path) {
1251
- const removeProperty = /* @__PURE__ */ __name((properties2, prop) => {
1252
- const index = properties2.findIndex(
1253
- (p) => t3.isIdentifier(p.key) && p.key.name === prop || t3.isStringLiteral(p.key) && p.key.value === prop
1254
- );
1255
- if (index >= 0) {
1256
- properties2.splice(index, 1);
1257
- }
1258
- }, "removeProperty");
1259
- if (path.length === 1) {
1260
- let removedRootProperty = false;
1261
- this._ast.program.body.forEach((node) => {
1262
- if (t3.isExportNamedDeclaration(node) && t3.isVariableDeclaration(node.declaration)) {
1263
- const decl = node.declaration.declarations[0];
1264
- if (t3.isIdentifier(decl.id) && decl.id.name === path[0]) {
1265
- this._ast.program.body.splice(this._ast.program.body.indexOf(node), 1);
1266
- removedRootProperty = true;
1267
- }
1268
- }
1269
- if (t3.isExportDefaultDeclaration(node)) {
1270
- const resolved = this._resolveDeclaration(node.declaration);
1271
- if (t3.isObjectExpression(resolved)) {
1272
- const properties2 = resolved.properties;
1273
- removeProperty(properties2, path[0]);
1274
- removedRootProperty = true;
1275
- }
1276
- }
1277
- 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)) {
1278
- const properties2 = node.expression.right.properties;
1279
- removeProperty(properties2, path[0]);
1280
- removedRootProperty = true;
1281
- }
1282
- });
1283
- if (removedRootProperty) {
1284
- return;
1285
- }
1286
- }
1287
- const properties = this.getFieldProperties(path);
1288
- if (properties) {
1289
- const lastPath = path.at(-1);
1290
- removeProperty(properties, lastPath);
1291
- }
1292
- }
1293
- appendValueToArray(path, value) {
1294
- const node = this.valueToNode(value);
1295
- if (node) {
1296
- this.appendNodeToArray(path, node);
1297
- }
1298
- }
1299
- appendNodeToArray(path, node) {
1300
- const current = this.getFieldNode(path);
1301
- if (!current) {
1302
- this.setFieldNode(path, t3.arrayExpression([node]));
1303
- } else if (t3.isArrayExpression(current)) {
1304
- current.elements.push(node);
1305
- } else {
1306
- throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
1307
- }
1308
- }
1309
- /**
1310
- * Specialized helper to remove addons or other array entries that can either be strings or
1311
- * objects with a name property.
1312
- */
1313
- removeEntryFromArray(path, value) {
1314
- const current = this.getFieldNode(path);
1315
- if (!current) {
1316
- return;
1317
- }
1318
- if (t3.isArrayExpression(current)) {
1319
- const index = current.elements.findIndex((element) => {
1320
- if (t3.isStringLiteral(element)) {
1321
- return element.value === value;
1322
- }
1323
- if (t3.isObjectExpression(element)) {
1324
- const name = this._getPresetValue(element, "name");
1325
- return name === value;
1326
- }
1327
- return this._getPnpWrappedValue(element) === value;
1328
- });
1329
- if (index >= 0) {
1330
- current.elements.splice(index, 1);
1331
- } else {
1332
- throw new Error(`Could not find '${value}' in array at '${path.join(".")}'`);
1333
- }
1334
- } else {
1335
- throw new Error(`Expected array at '${path.join(".")}', got '${current.type}'`);
1336
- }
1337
- }
1338
- _inferQuotes() {
1339
- if (!this._quotes) {
1340
- const occurrences = (this._ast.tokens || []).slice(0, 500).reduce(
1341
- (acc, token) => {
1342
- if (token.type.label === "string") {
1343
- acc[this._code[token.start]] += 1;
1344
- }
1345
- return acc;
1346
- },
1347
- { "'": 0, '"': 0 }
1348
- );
1349
- this._quotes = occurrences["'"] > occurrences['"'] ? "single" : "double";
1350
- }
1351
- return this._quotes;
1352
- }
1353
- valueToNode(value) {
1354
- const quotes = this._inferQuotes();
1355
- let valueNode;
1356
- if (quotes === "single") {
1357
- const { code } = generate2(t3.valueToNode(value), { jsescOption: { quotes } });
1358
- const program = babelParse2(`const __x = ${code}`);
1359
- traverse2(program, {
1360
- VariableDeclaration: {
1361
- enter({ node }) {
1362
- if (node.declarations.length === 1 && t3.isVariableDeclarator(node.declarations[0]) && t3.isIdentifier(node.declarations[0].id) && node.declarations[0].id.name === "__x") {
1363
- valueNode = node.declarations[0].init;
1364
- }
1365
- }
1366
- }
1367
- });
1368
- } else {
1369
- valueNode = t3.valueToNode(value);
1370
- }
1371
- return valueNode;
1372
- }
1373
- setFieldValue(path, value) {
1374
- const valueNode = this.valueToNode(value);
1375
- if (!valueNode) {
1376
- throw new Error(`Unexpected value ${JSON.stringify(value)}`);
1377
- }
1378
- this.setFieldNode(path, valueNode);
1379
- }
1380
- getBodyDeclarations() {
1381
- return this._ast.program.body;
1382
- }
1383
- setBodyDeclaration(declaration) {
1384
- this._ast.program.body.push(declaration);
1385
- }
1386
- /**
1387
- * Import specifiers for a specific require import
1388
- *
1389
- * @example
1390
- *
1391
- * ```ts
1392
- * // const { foo } = require('bar');
1393
- * setRequireImport(['foo'], 'bar');
1394
- *
1395
- * // const foo = require('bar');
1396
- * setRequireImport('foo', 'bar');
1397
- * ```
1398
- *
1399
- * @param importSpecifiers - The import specifiers to set. If a string is passed in, a default
1400
- * import will be set. Otherwise, an array of named imports will be set
1401
- * @param fromImport - The module to import from
1402
- */
1403
- setRequireImport(importSpecifier, fromImport) {
1404
- const requireDeclaration = this._ast.program.body.find((node) => {
1405
- 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]);
1406
- if (hasDeclaration) {
1407
- fromImport = node.declarations[0].init.arguments[0].value;
1408
- }
1409
- return hasDeclaration;
1410
- });
1411
- const hasRequireSpecifier = /* @__PURE__ */ __name((name) => t3.isObjectPattern(requireDeclaration?.declarations[0].id) && requireDeclaration?.declarations[0].id.properties.find(
1412
- (specifier) => t3.isObjectProperty(specifier) && t3.isIdentifier(specifier.key) && specifier.key.name === name
1413
- ), "hasRequireSpecifier");
1414
- const hasDefaultRequireSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.declarations.length === 1 && t3.isVariableDeclarator(declaration.declarations[0]) && t3.isIdentifier(declaration.declarations[0].id) && declaration.declarations[0].id.name === name, "hasDefaultRequireSpecifier");
1415
- if (typeof importSpecifier === "string") {
1416
- const addDefaultRequireSpecifier = /* @__PURE__ */ __name(() => {
1417
- this._ast.program.body.unshift(
1418
- t3.variableDeclaration("const", [
1419
- t3.variableDeclarator(
1420
- t3.identifier(importSpecifier),
1421
- t3.callExpression(t3.identifier("require"), [t3.stringLiteral(fromImport)])
1422
- )
1423
- ])
1424
- );
1425
- }, "addDefaultRequireSpecifier");
1426
- if (requireDeclaration) {
1427
- if (!hasDefaultRequireSpecifier(requireDeclaration, importSpecifier)) {
1428
- addDefaultRequireSpecifier();
1429
- }
1430
- } else {
1431
- addDefaultRequireSpecifier();
1432
- }
1433
- } else if (requireDeclaration) {
1434
- importSpecifier.forEach((specifier) => {
1435
- if (!hasRequireSpecifier(specifier)) {
1436
- requireDeclaration.declarations[0].id.properties.push(
1437
- t3.objectProperty(t3.identifier(specifier), t3.identifier(specifier), void 0, true)
1438
- );
1439
- }
1440
- });
1441
- } else {
1442
- this._ast.program.body.unshift(
1443
- t3.variableDeclaration("const", [
1444
- t3.variableDeclarator(
1445
- t3.objectPattern(
1446
- importSpecifier.map(
1447
- (specifier) => t3.objectProperty(t3.identifier(specifier), t3.identifier(specifier), void 0, true)
1448
- )
1449
- ),
1450
- t3.callExpression(t3.identifier("require"), [t3.stringLiteral(fromImport)])
1451
- )
1452
- ])
1453
- );
1454
- }
1455
- }
1456
- /**
1457
- * Set import specifiers for a given import statement.
1458
- *
1459
- * Does not support setting type imports (yet)
1460
- *
1461
- * @example
1462
- *
1463
- * ```ts
1464
- * // import { foo } from 'bar';
1465
- * setImport(['foo'], 'bar');
1466
- *
1467
- * // import foo from 'bar';
1468
- * setImport('foo', 'bar');
1469
- *
1470
- * // import * as foo from 'bar';
1471
- * setImport({ namespace: 'foo' }, 'bar');
1472
- *
1473
- * // import 'bar';
1474
- * setImport(null, 'bar');
1475
- * ```
1476
- *
1477
- * @param importSpecifiers - The import specifiers to set. If a string is passed in, a default
1478
- * import will be set. Otherwise, an array of named imports will be set
1479
- * @param fromImport - The module to import from
1480
- */
1481
- setImport(importSpecifier, fromImport) {
1482
- const importDeclaration = this._ast.program.body.find((node) => {
1483
- const hasDeclaration = t3.isImportDeclaration(node) && (node.source.value === fromImport || node.source.value === fromImport.split("node:")[1]);
1484
- if (hasDeclaration) {
1485
- fromImport = node.source.value;
1486
- }
1487
- return hasDeclaration;
1488
- });
1489
- const getNewImportSpecifier = /* @__PURE__ */ __name((specifier) => t3.importSpecifier(t3.identifier(specifier), t3.identifier(specifier)), "getNewImportSpecifier");
1490
- const hasImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
1491
- (specifier) => t3.isImportSpecifier(specifier) && t3.isIdentifier(specifier.imported) && specifier.imported.name === name
1492
- ), "hasImportSpecifier");
1493
- const hasNamespaceImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
1494
- (specifier) => t3.isImportNamespaceSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === name
1495
- ), "hasNamespaceImportSpecifier");
1496
- const hasDefaultImportSpecifier = /* @__PURE__ */ __name((declaration, name) => declaration.specifiers.find(
1497
- (specifier) => t3.isImportDefaultSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === name
1498
- ), "hasDefaultImportSpecifier");
1499
- if (importSpecifier === null) {
1500
- if (!importDeclaration) {
1501
- this._ast.program.body.unshift(t3.importDeclaration([], t3.stringLiteral(fromImport)));
1502
- }
1503
- } else if (typeof importSpecifier === "string") {
1504
- if (importDeclaration) {
1505
- if (!hasDefaultImportSpecifier(importDeclaration, importSpecifier)) {
1506
- importDeclaration.specifiers.push(
1507
- t3.importDefaultSpecifier(t3.identifier(importSpecifier))
1508
- );
1509
- }
1510
- } else {
1511
- this._ast.program.body.unshift(
1512
- t3.importDeclaration(
1513
- [t3.importDefaultSpecifier(t3.identifier(importSpecifier))],
1514
- t3.stringLiteral(fromImport)
1515
- )
1516
- );
1517
- }
1518
- } else if (Array.isArray(importSpecifier)) {
1519
- if (importDeclaration) {
1520
- importSpecifier.forEach((specifier) => {
1521
- if (!hasImportSpecifier(importDeclaration, specifier)) {
1522
- importDeclaration.specifiers.push(getNewImportSpecifier(specifier));
1523
- }
1524
- });
1525
- } else {
1526
- this._ast.program.body.unshift(
1527
- t3.importDeclaration(
1528
- importSpecifier.map(getNewImportSpecifier),
1529
- t3.stringLiteral(fromImport)
1530
- )
1531
- );
1532
- }
1533
- } else if (importSpecifier.namespace) {
1534
- if (importDeclaration) {
1535
- if (!hasNamespaceImportSpecifier(importDeclaration, importSpecifier.namespace)) {
1536
- importDeclaration.specifiers.push(
1537
- t3.importNamespaceSpecifier(t3.identifier(importSpecifier.namespace))
1538
- );
1539
- }
1540
- } else {
1541
- this._ast.program.body.unshift(
1542
- t3.importDeclaration(
1543
- [t3.importNamespaceSpecifier(t3.identifier(importSpecifier.namespace))],
1544
- t3.stringLiteral(fromImport)
1545
- )
1546
- );
1547
- }
1548
- }
1549
- }
1550
- _removeRequireImport(importSpecifier, fromImport) {
1551
- const requireDeclarationIndex = this._ast.program.body.findIndex((node) => {
1552
- 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]);
1553
- return hasDeclaration;
1554
- });
1555
- if (requireDeclarationIndex === -1) {
1556
- return;
1557
- }
1558
- const requireDeclaration = this._ast.program.body[requireDeclarationIndex];
1559
- const declarator = requireDeclaration.declarations[0];
1560
- if (importSpecifier === null) {
1561
- return;
1562
- }
1563
- if (typeof importSpecifier === "string") {
1564
- if (t3.isIdentifier(declarator.id) && declarator.id.name === importSpecifier) {
1565
- this._ast.program.body.splice(requireDeclarationIndex, 1);
1566
- }
1567
- return;
1568
- }
1569
- if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
1570
- return;
1571
- }
1572
- if (Array.isArray(importSpecifier) && t3.isObjectPattern(declarator.id)) {
1573
- const objectPattern = declarator.id;
1574
- importSpecifier.forEach((specifier) => {
1575
- const index = objectPattern.properties.findIndex(
1576
- (prop) => t3.isObjectProperty(prop) && t3.isIdentifier(prop.key) && prop.key.name === specifier
1577
- );
1578
- if (index !== -1) {
1579
- objectPattern.properties.splice(index, 1);
1580
- }
1581
- });
1582
- if (objectPattern.properties.length === 0) {
1583
- this._ast.program.body.splice(requireDeclarationIndex, 1);
1584
- }
1585
- }
1586
- }
1587
- _removeImport(importSpecifier, fromImport) {
1588
- const importDeclarationIndex = this._ast.program.body.findIndex(
1589
- (node) => t3.isImportDeclaration(node) && (node.source.value === fromImport || node.source.value === fromImport.split("node:")[1])
1590
- );
1591
- if (importDeclarationIndex === -1) {
1592
- return;
1593
- }
1594
- const importDeclaration = this._ast.program.body[importDeclarationIndex];
1595
- if (importSpecifier === null) {
1596
- if (importDeclaration.specifiers.length === 0) {
1597
- this._ast.program.body.splice(importDeclarationIndex, 1);
1598
- }
1599
- return;
1600
- }
1601
- if (typeof importSpecifier === "object" && "namespace" in importSpecifier) {
1602
- const index = importDeclaration.specifiers.findIndex(
1603
- (specifier) => t3.isImportNamespaceSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier.namespace
1604
- );
1605
- if (index !== -1) {
1606
- importDeclaration.specifiers.splice(index, 1);
1607
- }
1608
- }
1609
- if (typeof importSpecifier === "string") {
1610
- const index = importDeclaration.specifiers.findIndex(
1611
- (specifier) => t3.isImportDefaultSpecifier(specifier) && t3.isIdentifier(specifier.local) && specifier.local.name === importSpecifier
1612
- );
1613
- if (index !== -1) {
1614
- importDeclaration.specifiers.splice(index, 1);
1615
- }
1616
- }
1617
- if (Array.isArray(importSpecifier)) {
1618
- importSpecifier.forEach((specifier) => {
1619
- const index = importDeclaration.specifiers.findIndex(
1620
- (current) => t3.isImportSpecifier(current) && t3.isIdentifier(current.imported) && current.imported.name === specifier
1621
- );
1622
- if (index !== -1) {
1623
- importDeclaration.specifiers.splice(index, 1);
1624
- }
1625
- });
1626
- }
1627
- if (importDeclaration.specifiers.length === 0) {
1628
- this._ast.program.body.splice(importDeclarationIndex, 1);
1629
- }
1630
- }
1631
- /**
1632
- * Remove import specifiers for a given import statement.
1633
- *
1634
- * Does not support removing type imports (yet)
1635
- *
1636
- * @example
1637
- *
1638
- * ```ts
1639
- * // import { foo } from 'bar';
1640
- * setImport(['foo'], 'bar');
1641
- *
1642
- * // import foo from 'bar';
1643
- * setImport('foo', 'bar');
1644
- *
1645
- * // import * as foo from 'bar';
1646
- * setImport({ namespace: 'foo' }, 'bar');
1647
- *
1648
- * // import 'bar';
1649
- * setImport(null, 'bar');
1650
- * ```
1651
- *
1652
- * @param importSpecifiers - The import specifiers to remove. If a string is passed in, will only
1653
- * remove the default import. Otherwise, named imports matching the array will be removed.
1654
- * @param fromImport - The module to import from
1655
- */
1656
- removeImport(importSpecifier, fromImport) {
1657
- this._removeRequireImport(importSpecifier, fromImport);
1658
- this._removeImport(importSpecifier, fromImport);
1659
- }
1660
- };
1661
- var loadConfig = /* @__PURE__ */ __name((code, fileName) => {
1662
- const ast = babelParse2(code);
1663
- return new ConfigFile(ast, code, fileName);
1664
- }, "loadConfig");
1665
- var formatConfig = /* @__PURE__ */ __name((config) => {
1666
- return printConfig(config).code;
1667
- }, "formatConfig");
1668
- var printConfig = /* @__PURE__ */ __name((config, options = {}) => {
1669
- return recast2.print(config._ast, options);
1670
- }, "printConfig");
1671
- var readConfig = /* @__PURE__ */ __name(async (fileName) => {
1672
- const code = (await readFile2(fileName, "utf-8")).toString();
1673
- return loadConfig(code, fileName).parse();
1674
- }, "readConfig");
1675
- var writeConfig = /* @__PURE__ */ __name(async (config, fileName) => {
1676
- const fname = fileName || config.fileName;
1677
- if (!fname) {
1678
- throw new Error("Please specify a fileName for writeConfig");
1679
- }
1680
- await writeFile2(fname, formatConfig(config));
1681
- }, "writeConfig");
1682
- var isCsfFactoryPreview = /* @__PURE__ */ __name((previewConfig) => {
1683
- const program = previewConfig._ast.program;
1684
- return !!program.body.find((node) => {
1685
- return t3.isImportDeclaration(node) && node.source.value.includes("@storybook") && node.specifiers.some((specifier) => {
1686
- return t3.isImportSpecifier(specifier) && t3.isIdentifier(specifier.imported) && specifier.imported.name === "definePreview";
1687
- });
1688
- });
1689
- }, "isCsfFactoryPreview");
1690
-
1691
- // src/csf-tools/getStorySortParameter.ts
1692
- var import_ts_dedent3 = __toESM(require_dist(), 1);
1693
- import { babelParse as babelParse3, generate as generate3, types as t4, traverse as traverse3 } from "storybook/internal/babel";
1694
- import { logger as logger3 } from "storybook/internal/node-logger";
1695
- var getValue = /* @__PURE__ */ __name((obj, key) => {
1696
- let value;
1697
- obj.properties.forEach((p) => {
1698
- if (t4.isIdentifier(p.key) && p.key.name === key) {
1699
- value = p.value;
1700
- }
1701
- });
1702
- return value;
1703
- }, "getValue");
1704
- var parseValue = /* @__PURE__ */ __name((value) => {
1705
- const expr = stripTSModifiers(value);
1706
- if (t4.isArrayExpression(expr)) {
1707
- return expr.elements.map((o) => {
1708
- return parseValue(o);
1709
- });
1710
- }
1711
- if (t4.isObjectExpression(expr)) {
1712
- return expr.properties.reduce((acc, p) => {
1713
- if (t4.isIdentifier(p.key)) {
1714
- acc[p.key.name] = parseValue(p.value);
1715
- }
1716
- return acc;
1717
- }, {});
1718
- }
1719
- if (t4.isLiteral(expr)) {
1720
- return expr.value;
1721
- }
1722
- if (t4.isIdentifier(expr)) {
1723
- return unsupported(expr.name, true);
1724
- }
1725
- throw new Error(`Unknown node type ${expr.type}`);
1726
- }, "parseValue");
1727
- var unsupported = /* @__PURE__ */ __name((unexpectedVar, isError) => {
1728
- const message = import_ts_dedent3.dedent`
1729
- Unexpected '${unexpectedVar}'. Parameter 'options.storySort' should be defined inline e.g.:
1730
-
1731
- export default {
1732
- parameters: {
1733
- options: {
1734
- storySort: <array | object | function>
1735
- },
1736
- },
1737
- };
1738
- `;
1739
- if (isError) {
1740
- throw new Error(message);
1741
- } else {
1742
- logger3.log(message);
1743
- }
1744
- }, "unsupported");
1745
- var stripTSModifiers = /* @__PURE__ */ __name((expr) => t4.isTSAsExpression(expr) || t4.isTSSatisfiesExpression(expr) ? expr.expression : expr, "stripTSModifiers");
1746
- var parseParameters = /* @__PURE__ */ __name((params) => {
1747
- const paramsObject = stripTSModifiers(params);
1748
- if (t4.isObjectExpression(paramsObject)) {
1749
- const options = getValue(paramsObject, "options");
1750
- if (options) {
1751
- if (t4.isObjectExpression(options)) {
1752
- return getValue(options, "storySort");
1753
- }
1754
- unsupported("options", true);
1755
- }
1756
- }
1757
- return void 0;
1758
- }, "parseParameters");
1759
- var parseDefault = /* @__PURE__ */ __name((defaultExpr, program) => {
1760
- const defaultObj = stripTSModifiers(defaultExpr);
1761
- if (t4.isObjectExpression(defaultObj)) {
1762
- let params = getValue(defaultObj, "parameters");
1763
- if (t4.isIdentifier(params)) {
1764
- params = findVarInitialization(params.name, program);
1765
- }
1766
- if (params) {
1767
- return parseParameters(params);
1768
- }
1769
- } else {
1770
- unsupported("default", true);
1771
- }
1772
- return void 0;
1773
- }, "parseDefault");
1774
- var getStorySortParameter = /* @__PURE__ */ __name((previewCode) => {
1775
- if (!previewCode.includes("storySort")) {
1776
- return void 0;
1777
- }
1778
- let storySort;
1779
- const ast = babelParse3(previewCode);
1780
- traverse3(ast, {
1781
- ExportNamedDeclaration: {
1782
- enter({ node }) {
1783
- if (t4.isVariableDeclaration(node.declaration)) {
1784
- node.declaration.declarations.forEach((decl) => {
1785
- if (t4.isVariableDeclarator(decl) && t4.isIdentifier(decl.id)) {
1786
- const { name: exportName } = decl.id;
1787
- if (exportName === "parameters" && decl.init) {
1788
- const paramsObject = stripTSModifiers(decl.init);
1789
- storySort = parseParameters(paramsObject);
1790
- }
1791
- }
1792
- });
1793
- } else {
1794
- node.specifiers.forEach((spec) => {
1795
- if (t4.isIdentifier(spec.exported) && spec.exported.name === "parameters") {
1796
- unsupported("parameters", false);
1797
- }
1798
- });
1799
- }
1800
- }
1801
- },
1802
- ExportDefaultDeclaration: {
1803
- enter({ node }) {
1804
- let defaultObj = node.declaration;
1805
- if (t4.isIdentifier(defaultObj)) {
1806
- defaultObj = findVarInitialization(defaultObj.name, ast.program);
1807
- }
1808
- defaultObj = stripTSModifiers(defaultObj);
1809
- if (t4.isCallExpression(defaultObj) && t4.isObjectExpression(defaultObj.arguments?.[0])) {
1810
- storySort = parseDefault(defaultObj.arguments[0], ast.program);
1811
- } else if (t4.isObjectExpression(defaultObj)) {
1812
- storySort = parseDefault(defaultObj, ast.program);
1813
- } else {
1814
- unsupported("default", false);
1815
- }
1816
- }
1817
- }
1818
- });
1819
- if (!storySort) {
1820
- return void 0;
1821
- }
1822
- if (t4.isArrowFunctionExpression(storySort)) {
1823
- const { code: sortCode } = generate3(storySort, {});
1824
- return (0, eval)(sortCode);
1825
- }
1826
- if (t4.isFunctionExpression(storySort)) {
1827
- const { code: sortCode } = generate3(storySort, {});
1828
- const functionName = storySort.id?.name;
1829
- const wrapper = `(a, b) => {
1830
- ${sortCode};
1831
- return ${functionName}(a, b)
1832
- }`;
1833
- return (0, eval)(wrapper);
1834
- }
1835
- if (t4.isLiteral(storySort) || t4.isArrayExpression(storySort) || t4.isObjectExpression(storySort)) {
1836
- return parseValue(storySort);
1837
- }
1838
- return unsupported("storySort", true);
1839
- }, "getStorySortParameter");
1840
-
1841
- // src/csf-tools/enrichCsf.ts
1842
- import { generate as generate4, types as t5 } from "storybook/internal/babel";
1843
- var enrichCsfStory = /* @__PURE__ */ __name((csf, csfSource, key, options) => {
1844
- const storyExport = csfSource.getStoryExport(key);
1845
- const isCsfFactory = t5.isCallExpression(storyExport) && t5.isMemberExpression(storyExport.callee) && t5.isIdentifier(storyExport.callee.object) && storyExport.callee.object.name === "meta";
1846
- const source = !options?.disableSource && extractSource(storyExport);
1847
- const description = !options?.disableDescription && extractDescription(csfSource._storyStatements[key]);
1848
- const parameters = [];
1849
- const baseStoryObject = isCsfFactory ? t5.memberExpression(t5.identifier(key), t5.identifier("input")) : t5.identifier(key);
1850
- const originalParameters = t5.memberExpression(baseStoryObject, t5.identifier("parameters"));
1851
- parameters.push(t5.spreadElement(originalParameters));
1852
- const optionalDocs = t5.optionalMemberExpression(
1853
- originalParameters,
1854
- t5.identifier("docs"),
1855
- false,
1856
- true
1857
- );
1858
- const extraDocsParameters = [];
1859
- if (source) {
1860
- const optionalSource = t5.optionalMemberExpression(
1861
- optionalDocs,
1862
- t5.identifier("source"),
1863
- false,
1864
- true
1865
- );
1866
- extraDocsParameters.push(
1867
- t5.objectProperty(
1868
- t5.identifier("source"),
1869
- t5.objectExpression([
1870
- t5.objectProperty(t5.identifier("originalSource"), t5.stringLiteral(source)),
1871
- t5.spreadElement(optionalSource)
1872
- ])
1873
- )
1874
- );
1875
- }
1876
- if (description) {
1877
- const optionalDescription = t5.optionalMemberExpression(
1878
- optionalDocs,
1879
- t5.identifier("description"),
1880
- false,
1881
- true
1882
- );
1883
- extraDocsParameters.push(
1884
- t5.objectProperty(
1885
- t5.identifier("description"),
1886
- t5.objectExpression([
1887
- t5.objectProperty(t5.identifier("story"), t5.stringLiteral(description)),
1888
- t5.spreadElement(optionalDescription)
1889
- ])
1890
- )
1891
- );
1892
- }
1893
- if (extraDocsParameters.length > 0) {
1894
- parameters.push(
1895
- t5.objectProperty(
1896
- t5.identifier("docs"),
1897
- t5.objectExpression([t5.spreadElement(optionalDocs), ...extraDocsParameters])
1898
- )
1899
- );
1900
- const addParameter = t5.expressionStatement(
1901
- t5.assignmentExpression("=", originalParameters, t5.objectExpression(parameters))
1902
- );
1903
- csf._ast.program.body.push(addParameter);
1904
- }
1905
- }, "enrichCsfStory");
1906
- var addComponentDescription = /* @__PURE__ */ __name((node, path, value) => {
1907
- if (!path.length) {
1908
- const hasExistingComponent = node.properties.find(
1909
- (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === "component"
1910
- );
1911
- if (!hasExistingComponent) {
1912
- node.properties.unshift(value);
1913
- }
1914
- return;
1915
- }
1916
- const [first, ...rest] = path;
1917
- const existing = node.properties.find(
1918
- (p) => t5.isObjectProperty(p) && t5.isIdentifier(p.key) && p.key.name === first && t5.isObjectExpression(p.value)
1919
- );
1920
- let subNode;
1921
- if (existing) {
1922
- subNode = existing.value;
1923
- } else {
1924
- subNode = t5.objectExpression([]);
1925
- node.properties.push(t5.objectProperty(t5.identifier(first), subNode));
1926
- }
1927
- addComponentDescription(subNode, rest, value);
1928
- }, "addComponentDescription");
1929
- var enrichCsfMeta = /* @__PURE__ */ __name((csf, csfSource, options) => {
1930
- const description = !options?.disableDescription && extractDescription(csfSource._metaStatement);
1931
- if (description) {
1932
- const metaNode = csf._metaNode;
1933
- if (metaNode && t5.isObjectExpression(metaNode)) {
1934
- addComponentDescription(
1935
- metaNode,
1936
- ["parameters", "docs", "description"],
1937
- t5.objectProperty(t5.identifier("component"), t5.stringLiteral(description))
1938
- );
1939
- }
1940
- }
1941
- }, "enrichCsfMeta");
1942
- var enrichCsf = /* @__PURE__ */ __name(async (csf, csfSource, options) => {
1943
- enrichCsfMeta(csf, csfSource, options);
1944
- await options?.enrichCsf?.(csf, csfSource);
1945
- Object.keys(csf._storyExports).forEach((key) => {
1946
- enrichCsfStory(csf, csfSource, key, options);
1947
- });
1948
- }, "enrichCsf");
1949
- var extractSource = /* @__PURE__ */ __name((node) => {
1950
- const src = t5.isVariableDeclarator(node) ? node.init : node;
1951
- const { code } = generate4(src, {});
1952
- return code;
1953
- }, "extractSource");
1954
- var extractDescription = /* @__PURE__ */ __name((node) => {
1955
- if (!node?.leadingComments) {
1956
- return "";
1957
- }
1958
- const comments = node.leadingComments.map((comment) => {
1959
- if (comment.type === "CommentLine" || !comment.value.startsWith("*")) {
1960
- return null;
1961
- }
1962
- return comment.value.split("\n").map((line) => line.replace(/^(\s+)?(\*+)?(\s)?/, "")).join("\n").trim();
1963
- }).filter(Boolean);
1964
- return comments.join("\n");
1965
- }, "extractDescription");
1966
-
1967
- // src/csf-tools/index.ts
1968
- import { babelParse as babelParse4 } from "storybook/internal/babel";
1969
-
1970
- // src/csf-tools/vitest-plugin/transformer.ts
1971
- var import_ts_dedent4 = __toESM(require_dist(), 1);
1972
- import { types as t6 } from "storybook/internal/babel";
1973
- import { getStoryTitle } from "storybook/internal/common";
1974
- import { combineTags } from "storybook/internal/csf";
1975
- import { logger as logger4 } from "storybook/internal/node-logger";
1976
- var isValidTest = /* @__PURE__ */ __name((storyTags, tagsFilter) => {
1977
- if (tagsFilter.include.length && !tagsFilter.include.some((tag) => storyTags?.includes(tag))) {
1978
- return false;
1979
- }
1980
- if (tagsFilter.exclude.some((tag) => storyTags?.includes(tag))) {
1981
- return false;
1982
- }
1983
- return true;
1984
- }, "isValidTest");
1985
- var DOUBLE_SPACES = " ";
1986
- var getLiteralWithZeroWidthSpace = /* @__PURE__ */ __name((testTitle) => t6.stringLiteral(`${testTitle}${DOUBLE_SPACES}`), "getLiteralWithZeroWidthSpace");
1987
- async function vitestTransform({
1988
- code,
1989
- fileName,
1990
- configDir,
1991
- stories,
1992
- tagsFilter,
1993
- previewLevelTags = []
1994
- }) {
1995
- const parsed = loadCsf(code, {
1996
- fileName,
1997
- transformInlineMeta: true,
1998
- makeTitle: /* @__PURE__ */ __name((title) => {
1999
- const result = getStoryTitle({
2000
- storyFilePath: fileName,
2001
- configDir,
2002
- stories,
2003
- userTitle: title
2004
- }) || "unknown";
2005
- if (result === "unknown") {
2006
- logger4.warn(
2007
- import_ts_dedent4.dedent`
2008
- [Storybook]: Could not calculate story title for "${fileName}".
2009
- Please make sure that this file matches the globs included in the "stories" field in your Storybook configuration at "${configDir}".
2010
- `
2011
- );
2012
- }
2013
- return result;
2014
- }, "makeTitle")
2015
- }).parse();
2016
- const ast = parsed._ast;
2017
- const metaExportName = parsed._metaVariableName;
2018
- const metaNode = parsed._metaNode;
2019
- const metaTitleProperty = metaNode.properties.find(
2020
- (prop) => t6.isObjectProperty(prop) && t6.isIdentifier(prop.key) && prop.key.name === "title"
2021
- );
2022
- const metaTitle = t6.stringLiteral(parsed._meta?.title || "unknown");
2023
- if (!metaTitleProperty) {
2024
- metaNode.properties.push(t6.objectProperty(t6.identifier("title"), metaTitle));
2025
- } else if (t6.isObjectProperty(metaTitleProperty)) {
2026
- metaTitleProperty.value = metaTitle;
2027
- }
2028
- if (!metaNode || !parsed._meta) {
2029
- throw new Error(
2030
- "The Storybook vitest plugin could not detect the meta (default export) object in the story file. \n\nPlease make sure you have a default export with the meta object. If you are using a different export format that is not supported, please file an issue with details about your use case."
2031
- );
2032
- }
2033
- const validStories = {};
2034
- Object.keys(parsed._stories).forEach((key) => {
2035
- const finalTags = combineTags(
2036
- "test",
2037
- "dev",
2038
- ...previewLevelTags,
2039
- ...parsed.meta?.tags || [],
2040
- ...parsed._stories[key].tags || []
2041
- );
2042
- if (isValidTest(finalTags, tagsFilter)) {
2043
- validStories[key] = parsed._storyStatements[key];
2044
- }
2045
- });
2046
- const vitestTestId = parsed._file.path.scope.generateUidIdentifier("test");
2047
- const vitestDescribeId = parsed._file.path.scope.generateUidIdentifier("describe");
2048
- if (Object.keys(validStories).length === 0) {
2049
- const describeSkipBlock = t6.expressionStatement(
2050
- t6.callExpression(t6.memberExpression(vitestDescribeId, t6.identifier("skip")), [
2051
- t6.stringLiteral("No valid tests found")
2052
- ])
2053
- );
2054
- ast.program.body.push(describeSkipBlock);
2055
- const imports2 = [
2056
- t6.importDeclaration(
2057
- [
2058
- t6.importSpecifier(vitestTestId, t6.identifier("test")),
2059
- t6.importSpecifier(vitestDescribeId, t6.identifier("describe"))
2060
- ],
2061
- t6.stringLiteral("vitest")
2062
- )
2063
- ];
2064
- ast.program.body.unshift(...imports2);
2065
- return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
2066
- }
2067
- const vitestExpectId = parsed._file.path.scope.generateUidIdentifier("expect");
2068
- const testStoryId = parsed._file.path.scope.generateUidIdentifier("testStory");
2069
- const skipTagsId = t6.identifier(JSON.stringify(tagsFilter.skip));
2070
- function getTestGuardDeclaration() {
2071
- const isRunningFromThisFileId2 = parsed._file.path.scope.generateUidIdentifier("isRunningFromThisFile");
2072
- const testPathProperty = t6.memberExpression(
2073
- t6.callExpression(t6.memberExpression(vitestExpectId, t6.identifier("getState")), []),
2074
- t6.identifier("testPath")
2075
- );
2076
- const filePathProperty = t6.memberExpression(
2077
- t6.memberExpression(t6.identifier("globalThis"), t6.identifier("__vitest_worker__")),
2078
- t6.identifier("filepath")
2079
- );
2080
- const nullishCoalescingExpression = t6.logicalExpression(
2081
- "??",
2082
- // TODO: switch order of testPathProperty and filePathProperty when the bug is fixed
2083
- // https://github.com/vitest-dev/vitest/issues/6367 (or probably just use testPathProperty)
2084
- filePathProperty,
2085
- testPathProperty
2086
- );
2087
- const includesCall = t6.callExpression(
2088
- t6.memberExpression(
2089
- t6.callExpression(t6.identifier("convertToFilePath"), [
2090
- t6.memberExpression(
2091
- t6.memberExpression(t6.identifier("import"), t6.identifier("meta")),
2092
- t6.identifier("url")
2093
- )
2094
- ]),
2095
- t6.identifier("includes")
2096
- ),
2097
- [nullishCoalescingExpression]
2098
- );
2099
- const isRunningFromThisFileDeclaration2 = t6.variableDeclaration("const", [
2100
- t6.variableDeclarator(isRunningFromThisFileId2, includesCall)
2101
- ]);
2102
- return { isRunningFromThisFileDeclaration: isRunningFromThisFileDeclaration2, isRunningFromThisFileId: isRunningFromThisFileId2 };
2103
- }
2104
- __name(getTestGuardDeclaration, "getTestGuardDeclaration");
2105
- const { isRunningFromThisFileDeclaration, isRunningFromThisFileId } = getTestGuardDeclaration();
2106
- ast.program.body.push(isRunningFromThisFileDeclaration);
2107
- const getTestStatementForStory = /* @__PURE__ */ __name(({
2108
- localName,
2109
- exportName,
2110
- testTitle,
2111
- node,
2112
- overrideSourcemap = true,
2113
- storyId
2114
- }) => {
2115
- const testStoryCall = t6.expressionStatement(
2116
- t6.callExpression(vitestTestId, [
2117
- t6.stringLiteral(testTitle),
2118
- t6.callExpression(testStoryId, [
2119
- t6.stringLiteral(exportName),
2120
- t6.identifier(localName),
2121
- t6.identifier(metaExportName),
2122
- skipTagsId,
2123
- t6.stringLiteral(storyId)
2124
- ])
2125
- ])
2126
- );
2127
- if (overrideSourcemap) {
2128
- testStoryCall.loc = node.loc;
2129
- }
2130
- return testStoryCall;
2131
- }, "getTestStatementForStory");
2132
- const getDescribeStatementForStory = /* @__PURE__ */ __name((options) => {
2133
- const { localName, describeTitle, exportName, tests, node, parentStoryId } = options;
2134
- const describeBlock = t6.callExpression(vitestDescribeId, [
2135
- getLiteralWithZeroWidthSpace(describeTitle),
2136
- t6.arrowFunctionExpression(
2137
- [],
2138
- t6.blockStatement([
2139
- getTestStatementForStory({
2140
- ...options,
2141
- testTitle: "base story",
2142
- overrideSourcemap: false,
2143
- storyId: parentStoryId
2144
- }),
2145
- ...tests.map(({ name: testName, node: testNode, id: storyId }) => {
2146
- const testStatement = t6.expressionStatement(
2147
- t6.callExpression(vitestTestId, [
2148
- t6.stringLiteral(testName),
2149
- t6.callExpression(testStoryId, [
2150
- t6.stringLiteral(exportName),
2151
- t6.identifier(localName),
2152
- t6.identifier(metaExportName),
2153
- t6.arrayExpression([]),
2154
- t6.stringLiteral(storyId),
2155
- t6.stringLiteral(testName)
2156
- ])
2157
- ])
2158
- );
2159
- testStatement.loc = testNode.loc;
2160
- return testStatement;
2161
- })
2162
- ])
2163
- )
2164
- ]);
2165
- describeBlock.loc = node.loc;
2166
- return t6.expressionStatement(describeBlock);
2167
- }, "getDescribeStatementForStory");
2168
- const storyTestStatements = Object.entries(validStories).map(([exportName, node]) => {
2169
- if (node === null) {
2170
- logger4.warn(
2171
- import_ts_dedent4.dedent`
2172
- [Storybook]: Could not transform "${exportName}" story into test at "${fileName}".
2173
- Please make sure to define stories in the same file and not re-export stories coming from other files".
2174
- `
2175
- );
2176
- return;
2177
- }
2178
- const localName = parsed._stories[exportName].localName ?? exportName;
2179
- const testTitle = parsed._stories[exportName].name ?? exportName;
2180
- const storyId = parsed._stories[exportName].id;
2181
- const tests = parsed.getStoryTests(exportName);
2182
- if (tests?.length > 0) {
2183
- return getDescribeStatementForStory({
2184
- localName,
2185
- describeTitle: testTitle,
2186
- exportName,
2187
- tests,
2188
- node,
2189
- parentStoryId: storyId
2190
- });
2191
- }
2192
- return getTestStatementForStory({
2193
- testTitle,
2194
- localName,
2195
- exportName,
2196
- node,
2197
- storyId
2198
- });
2199
- }).filter((st) => !!st);
2200
- const testBlock = t6.ifStatement(isRunningFromThisFileId, t6.blockStatement(storyTestStatements));
2201
- ast.program.body.push(testBlock);
2202
- const hasTests = Object.keys(validStories).some(
2203
- (exportName) => parsed.getStoryTests(exportName).length > 0
2204
- );
2205
- const imports = [
2206
- t6.importDeclaration(
2207
- [
2208
- t6.importSpecifier(vitestTestId, t6.identifier("test")),
2209
- t6.importSpecifier(vitestExpectId, t6.identifier("expect")),
2210
- ...hasTests ? [t6.importSpecifier(vitestDescribeId, t6.identifier("describe"))] : []
2211
- ],
2212
- t6.stringLiteral("vitest")
2213
- ),
2214
- t6.importDeclaration(
2215
- [
2216
- t6.importSpecifier(testStoryId, t6.identifier("testStory")),
2217
- t6.importSpecifier(t6.identifier("convertToFilePath"), t6.identifier("convertToFilePath"))
2218
- ],
2219
- t6.stringLiteral("@storybook/addon-vitest/internal/test-utils")
2220
- )
2221
- ];
2222
- ast.program.body.unshift(...imports);
2223
- return formatCsf(parsed, { sourceMaps: true, sourceFileName: fileName }, code);
2224
- }
2225
- __name(vitestTransform, "vitestTransform");
2226
-
2227
- export {
2228
- isValidPreviewPath,
2229
- isModuleMock,
2230
- NoMetaError,
2231
- MultipleMetaError,
2232
- MixedFactoryError,
2233
- BadMetaError,
2234
- CsfFile,
2235
- babelParseFile,
2236
- loadCsf,
2237
- formatCsf,
2238
- printCsf,
2239
- readCsf,
2240
- writeCsf,
2241
- ConfigFile,
2242
- loadConfig,
2243
- formatConfig,
2244
- printConfig,
2245
- readConfig,
2246
- writeConfig,
2247
- isCsfFactoryPreview,
2248
- getStorySortParameter,
2249
- enrichCsfStory,
2250
- enrichCsfMeta,
2251
- enrichCsf,
2252
- extractSource,
2253
- extractDescription,
2254
- vitestTransform,
2255
- babelParse4 as babelParse
2256
- };