@aussieljk/forkbook 0.0.0-stage → 0.0.1-2

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 (598) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +77 -2
  3. package/assets/addon-vitest/templates/vitest.config.4.template.ts +36 -0
  4. package/assets/browser/favicon-wrapper.svg +46 -0
  5. package/assets/browser/favicon.svg +1 -0
  6. package/assets/browser/nunito-sans-bold-italic.woff2 +0 -0
  7. package/assets/browser/nunito-sans-bold.woff2 +0 -0
  8. package/assets/browser/nunito-sans-italic.woff2 +0 -0
  9. package/assets/browser/nunito-sans-regular.woff2 +0 -0
  10. package/assets/builder-vite/iframe.html +99 -0
  11. package/assets/create/rendererAssets/.eslintrc.json +16 -0
  12. package/assets/create/rendererAssets/common/Configure.mdx +388 -0
  13. package/assets/create/rendererAssets/common/assets/accessibility.png +0 -0
  14. package/assets/create/rendererAssets/common/assets/accessibility.svg +1 -0
  15. package/assets/create/rendererAssets/common/assets/addon-library.png +0 -0
  16. package/assets/create/rendererAssets/common/assets/assets.png +0 -0
  17. package/assets/create/rendererAssets/common/assets/avif-test-image.avif +0 -0
  18. package/assets/create/rendererAssets/common/assets/context.png +0 -0
  19. package/assets/create/rendererAssets/common/assets/discord.svg +1 -0
  20. package/assets/create/rendererAssets/common/assets/docs.png +0 -0
  21. package/assets/create/rendererAssets/common/assets/figma-plugin.png +0 -0
  22. package/assets/create/rendererAssets/common/assets/github.svg +1 -0
  23. package/assets/create/rendererAssets/common/assets/share.png +0 -0
  24. package/assets/create/rendererAssets/common/assets/styling.png +0 -0
  25. package/assets/create/rendererAssets/common/assets/testing.png +0 -0
  26. package/assets/create/rendererAssets/common/assets/theming.png +0 -0
  27. package/assets/create/rendererAssets/common/assets/tutorials.svg +1 -0
  28. package/assets/create/rendererAssets/common/assets/youtube.svg +1 -0
  29. package/assets/create/rendererAssets/common/button.css +30 -0
  30. package/assets/create/rendererAssets/common/header.css +32 -0
  31. package/assets/create/rendererAssets/common/page.css +68 -0
  32. package/assets/create/templates/react-native/index.expo.js +20 -0
  33. package/assets/create/templates/react-native/index.js +25 -0
  34. package/assets/docs/addon-backgrounds.gif +0 -0
  35. package/assets/docs/addon-controls-args-annotated.png +0 -0
  36. package/assets/docs/addon-controls-args-background-color.png +0 -0
  37. package/assets/docs/addon-controls-args-background-string.png +0 -0
  38. package/assets/docs/addon-controls-args-docs.png +0 -0
  39. package/assets/docs/addon-controls-args-logging.png +0 -0
  40. package/assets/docs/addon-controls-args-no-annotation.png +0 -0
  41. package/assets/docs/addon-controls-args-reflow-slider.png +0 -0
  42. package/assets/docs/addon-controls-args-reflow.png +0 -0
  43. package/assets/docs/addon-controls-args-template.png +0 -0
  44. package/assets/docs/addon-controls-expanded.png +0 -0
  45. package/assets/docs/addon-controls-hero.gif +0 -0
  46. package/assets/docs/addon-controls-install.png +0 -0
  47. package/assets/docs/hero.gif +0 -0
  48. package/assets/docs/highlight.png +0 -0
  49. package/assets/docs/message-reference.png +0 -0
  50. package/assets/docs/viewport.png +0 -0
  51. package/assets/react-native/metro-env.d.ts +69 -0
  52. package/assets/server/addon.tsconfig.json +6 -0
  53. package/assets/server/base-preview-body.html +116 -0
  54. package/assets/server/base-preview-head.html +494 -0
  55. package/assets/server/openBrowser.applescript +94 -0
  56. package/assets/server/template.ejs +87 -0
  57. package/dist/.build-stamp +0 -0
  58. package/dist/_browser-chunks/Color-PCLE2J36.js +1025 -0
  59. package/dist/_browser-chunks/DocsRenderer-JXND3PVQ.js +10 -0
  60. package/dist/_browser-chunks/WithTooltip-XSQFTBMB.js +1619 -0
  61. package/dist/_browser-chunks/chunk-2JDQ35OA.js +247 -0
  62. package/dist/_browser-chunks/chunk-2JT76G3E.js +104 -0
  63. package/dist/_browser-chunks/chunk-2MEPHP35.js +17 -0
  64. package/dist/_browser-chunks/chunk-2SCZVUKW.js +24 -0
  65. package/dist/_browser-chunks/chunk-46Z7NGAS.js +41 -0
  66. package/dist/_browser-chunks/chunk-4ATQOMJB.js +30 -0
  67. package/dist/_browser-chunks/chunk-52CW7FF7.js +49 -0
  68. package/dist/_browser-chunks/chunk-5I7E4GMO.js +62 -0
  69. package/dist/_browser-chunks/chunk-5P4QA6MY.js +20 -0
  70. package/dist/_browser-chunks/chunk-5WMXI5GW.js +816 -0
  71. package/dist/_browser-chunks/chunk-66OCZ54D.js +2604 -0
  72. package/dist/_browser-chunks/chunk-6SXYJQST.js +253 -0
  73. package/dist/_browser-chunks/chunk-AYRF6EJB.js +36 -0
  74. package/dist/_browser-chunks/chunk-B4AUNNU4.js +156 -0
  75. package/dist/_browser-chunks/chunk-BCP2FFXF.js +369 -0
  76. package/dist/_browser-chunks/chunk-C3D4HEFY.js +3396 -0
  77. package/dist/_browser-chunks/chunk-CFAOWGL7.js +43 -0
  78. package/dist/_browser-chunks/chunk-CFWWCCZV.js +223 -0
  79. package/dist/_browser-chunks/chunk-CNED6RYH.js +18 -0
  80. package/dist/_browser-chunks/chunk-DRQKCCAG.js +136 -0
  81. package/dist/_browser-chunks/chunk-ECQ75MKQ.js +0 -0
  82. package/dist/_browser-chunks/chunk-EIYAKDGP.js +302 -0
  83. package/dist/_browser-chunks/chunk-ENKK74N4.js +12 -0
  84. package/dist/_browser-chunks/chunk-FENFYI4X.js +698 -0
  85. package/dist/_browser-chunks/chunk-FJGWSWL5.js +155 -0
  86. package/dist/_browser-chunks/chunk-FVSEPWWX.js +2810 -0
  87. package/dist/_browser-chunks/chunk-GNZY6LOW.js +10116 -0
  88. package/dist/_browser-chunks/chunk-IE4ULIOQ.js +14 -0
  89. package/dist/_browser-chunks/chunk-IMSF75WX.js +42 -0
  90. package/dist/_browser-chunks/chunk-IWQGIXJS.js +14 -0
  91. package/dist/_browser-chunks/chunk-JMC7AIKT.js +108 -0
  92. package/dist/_browser-chunks/chunk-JPUOQJUI.js +8 -0
  93. package/dist/_browser-chunks/chunk-JSBKXXXF.js +218 -0
  94. package/dist/_browser-chunks/chunk-JWSKPMPC.js +73 -0
  95. package/dist/_browser-chunks/chunk-JYVGARBG.js +2943 -0
  96. package/dist/_browser-chunks/chunk-KBK7GKBN.js +35 -0
  97. package/dist/_browser-chunks/chunk-KQ7CRO2B.js +108 -0
  98. package/dist/_browser-chunks/chunk-LAWXTSXK.js +18 -0
  99. package/dist/_browser-chunks/chunk-LE2LTDW3.js +14 -0
  100. package/dist/_browser-chunks/chunk-LEVSOOLQ.js +48 -0
  101. package/dist/_browser-chunks/chunk-LV5PIKV4.js +93 -0
  102. package/dist/_browser-chunks/chunk-MDOL7KML.js +56 -0
  103. package/dist/_browser-chunks/chunk-MFMDGWP6.js +34 -0
  104. package/dist/_browser-chunks/chunk-MLBOOZL4.js +67 -0
  105. package/dist/_browser-chunks/chunk-NQUD4B7H.js +91 -0
  106. package/dist/_browser-chunks/chunk-NULBREPZ.js +43 -0
  107. package/dist/_browser-chunks/chunk-NZMVUW5T.js +7 -0
  108. package/dist/_browser-chunks/chunk-OD6IBQCC.js +117 -0
  109. package/dist/_browser-chunks/chunk-ODVJ3XZJ.js +157 -0
  110. package/dist/_browser-chunks/chunk-OQWFVDIN.js +386 -0
  111. package/dist/_browser-chunks/chunk-OVH3USFB.js +20 -0
  112. package/dist/_browser-chunks/chunk-OZZPSYQR.js +14 -0
  113. package/dist/_browser-chunks/chunk-P6PK47TQ.js +1970 -0
  114. package/dist/_browser-chunks/chunk-PFRNG3UC.js +22 -0
  115. package/dist/_browser-chunks/chunk-PJSMZ27A.js +13 -0
  116. package/dist/_browser-chunks/chunk-QC4HFS6K.js +41 -0
  117. package/dist/_browser-chunks/chunk-QDXFODK4.js +274 -0
  118. package/dist/_browser-chunks/chunk-RBCHTR7C.js +28 -0
  119. package/dist/_browser-chunks/chunk-RMYQ3QN3.js +294 -0
  120. package/dist/_browser-chunks/chunk-RNTIV5CE.js +411 -0
  121. package/dist/_browser-chunks/chunk-RSPAQWVJ.js +80 -0
  122. package/dist/_browser-chunks/chunk-S6TK43XQ.js +836 -0
  123. package/dist/_browser-chunks/chunk-SC67XZST.js +18 -0
  124. package/dist/_browser-chunks/chunk-SFVA4SBT.js +683 -0
  125. package/dist/_browser-chunks/chunk-SZYFOQMT.js +25 -0
  126. package/dist/_browser-chunks/chunk-TBJCJXK4.js +18 -0
  127. package/dist/_browser-chunks/chunk-UMDO3KB7.js +205 -0
  128. package/dist/_browser-chunks/chunk-V2G23FV7.js +11 -0
  129. package/dist/_browser-chunks/chunk-V5M7Q4HT.js +88 -0
  130. package/dist/_browser-chunks/chunk-W5M6NPS3.js +198 -0
  131. package/dist/_browser-chunks/chunk-W7NE2JXW.js +84 -0
  132. package/dist/_browser-chunks/chunk-WGVAAM43.js +1110 -0
  133. package/dist/_browser-chunks/chunk-WHQRNHXD.js +8 -0
  134. package/dist/_browser-chunks/chunk-WOSOWBCA.js +12 -0
  135. package/dist/_browser-chunks/chunk-WZ7KR7SH.js +85 -0
  136. package/dist/_browser-chunks/chunk-YEKO6BHJ.js +20 -0
  137. package/dist/_browser-chunks/chunk-YI2IBIQS.js +7 -0
  138. package/dist/_browser-chunks/chunk-YTIT5NA5.js +1966 -0
  139. package/dist/_browser-chunks/chunk-ZEHRUHTA.js +6 -0
  140. package/dist/_browser-chunks/chunk-ZTQ5MEJ5.js +203 -0
  141. package/dist/_browser-chunks/matchers-YLBYSYAF.js +1263 -0
  142. package/dist/_browser-chunks/react-dom-client-4OHE3QDV.js +9 -0
  143. package/dist/_node-chunks/attached-runtime-I2G4WLJI.js +282 -0
  144. package/dist/_node-chunks/builder-manager-VVHYQXCH.js +1661 -0
  145. package/dist/_node-chunks/chunk-2BUPBPFB.js +82 -0
  146. package/dist/_node-chunks/chunk-2DSIDINN.js +884 -0
  147. package/dist/_node-chunks/chunk-2RU7BKEW.js +23 -0
  148. package/dist/_node-chunks/chunk-34EO2PUT.js +26 -0
  149. package/dist/_node-chunks/chunk-3BKIBF5S.js +3008 -0
  150. package/dist/_node-chunks/chunk-3SDUYDXH.js +98 -0
  151. package/dist/_node-chunks/chunk-3T4ZSNPH.js +662 -0
  152. package/dist/_node-chunks/chunk-3W7F2B7P.js +79 -0
  153. package/dist/_node-chunks/chunk-3Y6AAY5H.js +80 -0
  154. package/dist/_node-chunks/chunk-42UWAGPW.js +1193 -0
  155. package/dist/_node-chunks/chunk-4FEANXWU.js +1986 -0
  156. package/dist/_node-chunks/chunk-5DQFEZEA.js +40 -0
  157. package/dist/_node-chunks/chunk-6KEHV53S.js +1218 -0
  158. package/dist/_node-chunks/chunk-6LMWA44H.js +3837 -0
  159. package/dist/_node-chunks/chunk-6YKBRP72.js +20 -0
  160. package/dist/_node-chunks/chunk-7GUDZVRQ.js +110 -0
  161. package/dist/_node-chunks/chunk-B5J7Q7J4.js +21 -0
  162. package/dist/_node-chunks/chunk-BS2WMZMR.js +90 -0
  163. package/dist/_node-chunks/chunk-BSKFCWQD.js +47 -0
  164. package/dist/_node-chunks/chunk-BXVYT7SB.js +36 -0
  165. package/dist/_node-chunks/chunk-CCOTJ4FC.js +688 -0
  166. package/dist/_node-chunks/chunk-CQKMLL5J.js +33 -0
  167. package/dist/_node-chunks/chunk-CXRU72ET.js +63 -0
  168. package/dist/_node-chunks/chunk-DC7DKR5K.js +20 -0
  169. package/dist/_node-chunks/chunk-DHJFTB4K.js +25 -0
  170. package/dist/_node-chunks/chunk-DUR55DJJ.js +1094 -0
  171. package/dist/_node-chunks/chunk-E6YESGLX.js +7032 -0
  172. package/dist/_node-chunks/chunk-EHUNOMDD.js +52345 -0
  173. package/dist/_node-chunks/chunk-ET7PWEO7.js +298 -0
  174. package/dist/_node-chunks/chunk-EWOX7HPJ.js +20 -0
  175. package/dist/_node-chunks/chunk-F3ZFKBHY.js +844 -0
  176. package/dist/_node-chunks/chunk-FK7KGTV7.js +26 -0
  177. package/dist/_node-chunks/chunk-FPZB5OI7.js +35 -0
  178. package/dist/_node-chunks/chunk-FW2HQUBQ.js +25 -0
  179. package/dist/_node-chunks/chunk-FY6UXW6G.js +11 -0
  180. package/dist/_node-chunks/chunk-GEFQN7K3.js +499 -0
  181. package/dist/_node-chunks/chunk-GRBLDJCR.js +989 -0
  182. package/dist/_node-chunks/chunk-H32DYT6P.js +87 -0
  183. package/dist/_node-chunks/chunk-H4PPVMP5.js +23 -0
  184. package/dist/_node-chunks/chunk-HMP2G23X.js +25 -0
  185. package/dist/_node-chunks/chunk-ICPBH3E7.js +59 -0
  186. package/dist/_node-chunks/chunk-IDEL2J23.js +23 -0
  187. package/dist/_node-chunks/chunk-IK4FGZLR.js +223 -0
  188. package/dist/_node-chunks/chunk-JDXXX6LB.js +68 -0
  189. package/dist/_node-chunks/chunk-JGGFYIG5.js +5468 -0
  190. package/dist/_node-chunks/chunk-JPAZLYJ3.js +29 -0
  191. package/dist/_node-chunks/chunk-JZOO7GGC.js +48 -0
  192. package/dist/_node-chunks/chunk-KISMCCP5.js +4744 -0
  193. package/dist/_node-chunks/chunk-LCK4ZQKG.js +115 -0
  194. package/dist/_node-chunks/chunk-LO56I6E2.js +132 -0
  195. package/dist/_node-chunks/chunk-LXBD4UL4.js +104 -0
  196. package/dist/_node-chunks/chunk-MA24JW6C.js +7162 -0
  197. package/dist/_node-chunks/chunk-MK2KYAI6.js +5414 -0
  198. package/dist/_node-chunks/chunk-NDWKJ4CL.js +2102 -0
  199. package/dist/_node-chunks/chunk-NIBT7XDZ.js +168 -0
  200. package/dist/_node-chunks/chunk-NPO45IMH.js +33 -0
  201. package/dist/_node-chunks/chunk-OISX4AGQ.js +414 -0
  202. package/dist/_node-chunks/chunk-OUW6R7C3.js +26 -0
  203. package/dist/_node-chunks/chunk-OWNFOGTA.js +194 -0
  204. package/dist/_node-chunks/chunk-Q7QNUM5H.js +49 -0
  205. package/dist/_node-chunks/chunk-QEQLR22M.js +1877 -0
  206. package/dist/_node-chunks/chunk-RRN2V55B.js +45 -0
  207. package/dist/_node-chunks/chunk-RWFIFGO5.js +144 -0
  208. package/dist/_node-chunks/chunk-RXNJDRGO.js +209 -0
  209. package/dist/_node-chunks/chunk-RZMQ7S3L.js +92 -0
  210. package/dist/_node-chunks/chunk-SIEXZVCR.js +51 -0
  211. package/dist/_node-chunks/chunk-SLWQNBGO.js +2034 -0
  212. package/dist/_node-chunks/chunk-SVTBJ7Q3.js +35 -0
  213. package/dist/_node-chunks/chunk-SWO5CDYU.js +32 -0
  214. package/dist/_node-chunks/chunk-TD5PLLQG.js +121 -0
  215. package/dist/_node-chunks/chunk-TEQGGSP7.js +33 -0
  216. package/dist/_node-chunks/chunk-TFCEV2XX.js +155 -0
  217. package/dist/_node-chunks/chunk-TFEWM4E3.js +1073 -0
  218. package/dist/_node-chunks/chunk-TINO74G5.js +21 -0
  219. package/dist/_node-chunks/chunk-TNJIXE37.js +40 -0
  220. package/dist/_node-chunks/chunk-TWI4GVH7.js +19 -0
  221. package/dist/_node-chunks/chunk-U5W53R2J.js +1011 -0
  222. package/dist/_node-chunks/chunk-UBOGWBEA.js +148 -0
  223. package/dist/_node-chunks/chunk-UMUBKI6E.js +3787 -0
  224. package/dist/_node-chunks/chunk-UVINFLGY.js +56 -0
  225. package/dist/_node-chunks/chunk-V2DY426G.js +1133 -0
  226. package/dist/_node-chunks/chunk-VLOXOXXE.js +45 -0
  227. package/dist/_node-chunks/chunk-W4OMYLSP.js +1297 -0
  228. package/dist/_node-chunks/chunk-WAXVSN3O.js +18 -0
  229. package/dist/_node-chunks/chunk-WCULS5TP.js +3767 -0
  230. package/dist/_node-chunks/chunk-WNZ2UMFM.js +153 -0
  231. package/dist/_node-chunks/chunk-WZJF2OUH.js +74 -0
  232. package/dist/_node-chunks/chunk-XGIUVY52.js +611 -0
  233. package/dist/_node-chunks/chunk-XHL2LVBM.js +415 -0
  234. package/dist/_node-chunks/chunk-XI6B6P47.js +59 -0
  235. package/dist/_node-chunks/chunk-XLP2ZKXV.js +60 -0
  236. package/dist/_node-chunks/chunk-YCMRA6RX.js +95 -0
  237. package/dist/_node-chunks/chunk-YZFWBA5L.js +2700 -0
  238. package/dist/_node-chunks/chunk-ZMAMXQKP.js +4731 -0
  239. package/dist/_node-chunks/chunk-ZWBCQ4MJ.js +110 -0
  240. package/dist/_node-chunks/dist-VTSTZKUB.js +16 -0
  241. package/dist/_node-chunks/globby-OEMHPBFY.js +2884 -0
  242. package/dist/_node-chunks/jiti-NFX6UU74.js +3848 -0
  243. package/dist/_node-chunks/lib-MDVARD7W.js +366 -0
  244. package/dist/_node-chunks/local-runtime-NTKIN2QT.js +78 -0
  245. package/dist/_node-chunks/mdx-plugin-MWISDWDQ.js +5680 -0
  246. package/dist/_node-chunks/monorepo-LIRFMQXE.js +121 -0
  247. package/dist/_node-chunks/monorepo-optimized-tests-relaxed-limits-no-story-deletion-CPDW4XTW.js +121 -0
  248. package/dist/_node-chunks/optimized-tests-HDOLR3EY.js +22 -0
  249. package/dist/_node-chunks/pattern-copy-play-EKHIUAU2.js +807 -0
  250. package/dist/_node-chunks/postinstallAddon-GYGMWDL6.js +20 -0
  251. package/dist/_node-chunks/rehype-external-links-BUN3HUCO.js +121 -0
  252. package/dist/_node-chunks/rehype-slug-PLADX223.js +52 -0
  253. package/dist/_node-chunks/relaxed-limits-GBHW6KIQ.js +117 -0
  254. package/dist/_node-chunks/run-KDTIZNSY.js +103 -0
  255. package/dist/_node-chunks/run-NL66VTNR.js +4532 -0
  256. package/dist/_node-chunks/session-id-KIIVOQLR.js +23 -0
  257. package/dist/_node-chunks/setup-MGC7BQO6.js +278 -0
  258. package/dist/_node-chunks/vitest.config.4.template-JH2THZFG.js +54 -0
  259. package/dist/actions/decorator.d.ts +7 -0
  260. package/dist/actions/decorator.js +43 -0
  261. package/dist/actions/index.d.ts +67 -0
  262. package/dist/actions/index.js +28 -0
  263. package/dist/addon-a11y/index.d.ts +52 -0
  264. package/dist/addon-a11y/index.js +16 -0
  265. package/dist/addon-a11y/manager.js +1429 -0
  266. package/dist/addon-a11y/preset.js +18 -0
  267. package/dist/addon-a11y/preview.d.ts +17 -0
  268. package/dist/addon-a11y/preview.js +15 -0
  269. package/dist/addon-docs/blocks.d.ts +1061 -0
  270. package/dist/addon-docs/blocks.js +2461 -0
  271. package/dist/addon-docs/index.d.ts +236 -0
  272. package/dist/addon-docs/index.js +16 -0
  273. package/dist/addon-docs/manager.js +90 -0
  274. package/dist/addon-docs/mdx-react-shim.d.ts +1 -0
  275. package/dist/addon-docs/mdx-react-shim.js +2 -0
  276. package/dist/addon-docs/preset.js +378 -0
  277. package/dist/addon-docs/preview.d.ts +4 -0
  278. package/dist/addon-docs/preview.js +7 -0
  279. package/dist/addon-links/index.d.ts +22 -0
  280. package/dist/addon-links/index.js +20 -0
  281. package/dist/addon-links/manager.js +14 -0
  282. package/dist/addon-links/preview.d.ts +6 -0
  283. package/dist/addon-links/preview.js +9 -0
  284. package/dist/addon-links/react/index.d.ts +25 -0
  285. package/dist/addon-links/react/index.js +52 -0
  286. package/dist/addon-mcp/preset.js +1345 -0
  287. package/dist/addon-mcp/preview.js +29 -0
  288. package/dist/addon-mcp/tools/preview-stories/preview-stories-app-script.js +1153 -0
  289. package/dist/addon-ondevice-actions/index.d.ts +4 -0
  290. package/dist/addon-ondevice-actions/index.js +7 -0
  291. package/dist/addon-ondevice-actions/register.js +7 -0
  292. package/dist/addon-ondevice-controls/index.d.ts +6 -0
  293. package/dist/addon-ondevice-controls/index.js +14 -0
  294. package/dist/addon-ondevice-controls/register.js +10 -0
  295. package/dist/addon-pseudo-states/index.d.ts +35 -0
  296. package/dist/addon-pseudo-states/index.js +15 -0
  297. package/dist/addon-pseudo-states/manager.js +53 -0
  298. package/dist/addon-pseudo-states/preview.d.ts +9 -0
  299. package/dist/addon-pseudo-states/preview.js +10 -0
  300. package/dist/addon-themes/index.d.ts +80 -0
  301. package/dist/addon-themes/index.js +104 -0
  302. package/dist/addon-themes/manager.js +97 -0
  303. package/dist/addon-themes/postinstall.js +33 -0
  304. package/dist/addon-themes/preview.d.ts +6 -0
  305. package/dist/addon-themes/preview.js +8 -0
  306. package/dist/addon-vitest/constants.d.ts +132 -0
  307. package/dist/addon-vitest/constants.js +66 -0
  308. package/dist/addon-vitest/index.d.ts +4 -0
  309. package/dist/addon-vitest/index.js +8 -0
  310. package/dist/addon-vitest/manager.js +665 -0
  311. package/dist/addon-vitest/node/coverage-reporter.js +1284 -0
  312. package/dist/addon-vitest/node/vitest.js +674 -0
  313. package/dist/addon-vitest/postinstall.js +24 -0
  314. package/dist/addon-vitest/preset.js +943 -0
  315. package/dist/addon-vitest/vitest-plugin/global-setup.js +162 -0
  316. package/dist/addon-vitest/vitest-plugin/index.d.ts +56 -0
  317. package/dist/addon-vitest/vitest-plugin/index.js +463 -0
  318. package/dist/addon-vitest/vitest-plugin/setup-file-with-project-annotations.js +9 -0
  319. package/dist/addon-vitest/vitest-plugin/setup-file.browser.4.js +20 -0
  320. package/dist/addon-vitest/vitest-plugin/setup-file.js +50 -0
  321. package/dist/addon-vitest/vitest-plugin/test-utils.js +128 -0
  322. package/dist/babel/index.d.ts +2301 -0
  323. package/dist/babel/index.js +61 -0
  324. package/dist/backgrounds/index.d.ts +6 -0
  325. package/dist/backgrounds/index.js +15 -0
  326. package/dist/bin/core.js +1705 -0
  327. package/dist/bin/dispatcher.js +43 -0
  328. package/dist/bin/loader.js +115 -0
  329. package/dist/builder-vite/index.d.ts +50 -0
  330. package/dist/builder-vite/index.js +245 -0
  331. package/dist/builder-vite/preset.js +27 -0
  332. package/dist/channels/index.d.ts +2 -0
  333. package/dist/channels/index.js +352 -0
  334. package/dist/chunk-B2t1tGRh.d.ts +284 -0
  335. package/dist/chunk-BCoJQE-f.d.ts +602 -0
  336. package/dist/chunk-BGkgZp-H.d.ts +214 -0
  337. package/dist/chunk-BTVrWliM.d.ts +115 -0
  338. package/dist/chunk-BXLImeLy.d.ts +197 -0
  339. package/dist/chunk-BfBzpgct.d.ts +916 -0
  340. package/dist/chunk-Bpi2tz-6.d.ts +511 -0
  341. package/dist/chunk-BxWufQms.d.ts +142 -0
  342. package/dist/chunk-C-bavsOH.d.ts +34 -0
  343. package/dist/chunk-C2p5r3Vt.d.ts +13001 -0
  344. package/dist/chunk-C6PAgHLT.d.ts +12 -0
  345. package/dist/chunk-CMeX4WRe.d.ts +179 -0
  346. package/dist/chunk-Ct9xd6IM.d.ts +65 -0
  347. package/dist/chunk-CwQKNaYL.d.ts +15 -0
  348. package/dist/chunk-D7DwV41f.d.ts +3622 -0
  349. package/dist/chunk-DEVFdzxR.d.ts +253 -0
  350. package/dist/chunk-DaVb55-_.d.ts +124 -0
  351. package/dist/chunk-DgRNfmj_.d.ts +40 -0
  352. package/dist/chunk-DoIGKY33.d.ts +666 -0
  353. package/dist/chunk-Dr3R0DXk.d.ts +40 -0
  354. package/dist/chunk-DtHByo32.d.ts +55 -0
  355. package/dist/chunk-Dw1z1Pki.d.ts +933 -0
  356. package/dist/chunk-DzuY9DXg.d.ts +79 -0
  357. package/dist/chunk-FjDVzZTj.d.ts +62 -0
  358. package/dist/chunk-Kt1tW-D1.d.ts +59 -0
  359. package/dist/chunk-XP8oHzpE.d.ts +6 -0
  360. package/dist/chunk-gCX81nOr.d.ts +61 -0
  361. package/dist/chunk-pcFXCimE.d.ts +741 -0
  362. package/dist/cli/index.d.ts +1174 -0
  363. package/dist/cli/index.js +5613 -0
  364. package/dist/cli/skills/content/index.d.ts +72 -0
  365. package/dist/cli/skills/content/index.js +335 -0
  366. package/dist/cli/tools/sdk/child-host.d.ts +61 -0
  367. package/dist/cli/tools/sdk/child-host.js +131 -0
  368. package/dist/cli/tools/sdk/index.d.ts +137 -0
  369. package/dist/cli/tools/sdk/index.js +44 -0
  370. package/dist/cli-commands/bin/index.js +25 -0
  371. package/dist/client-logger/index.d.ts +31 -0
  372. package/dist/client-logger/index.js +63 -0
  373. package/dist/common/index.d.ts +1103 -0
  374. package/dist/common/index.js +364 -0
  375. package/dist/components/index.d.ts +1924 -0
  376. package/dist/components/index.js +13759 -0
  377. package/dist/core-events/index.d.ts +155 -0
  378. package/dist/core-events/index.js +136 -0
  379. package/dist/core-server/index.d.ts +2200 -0
  380. package/dist/core-server/index.js +4165 -0
  381. package/dist/core-server/presets/common-manager.css +170 -0
  382. package/dist/core-server/presets/common-manager.js +4168 -0
  383. package/dist/core-server/presets/common-override-preset.js +81 -0
  384. package/dist/core-server/presets/common-preset.js +2187 -0
  385. package/dist/create/bin/index.js +23 -0
  386. package/dist/create/index.js +25 -0
  387. package/dist/csf/csf-utils.d.ts +2 -0
  388. package/dist/csf/csf-utils.js +19 -0
  389. package/dist/csf/index.d.ts +7 -0
  390. package/dist/csf/index.js +2142 -0
  391. package/dist/csf-tools/index.d.ts +1157 -0
  392. package/dist/csf-tools/index.js +736 -0
  393. package/dist/docs-tools/index.d.ts +197 -0
  394. package/dist/docs-tools/index.js +61 -0
  395. package/dist/highlight/index.d.ts +10 -0
  396. package/dist/highlight/index.js +15 -0
  397. package/dist/instrumenter/index.d.ts +113 -0
  398. package/dist/instrumenter/index.js +2595 -0
  399. package/dist/manager/_manager-chunks/globals-runtime-8HkdnU2F.js +6144 -0
  400. package/dist/manager/_manager-chunks/globals-runtime-BIKBO23x.js +3389 -0
  401. package/dist/manager/_manager-chunks/globals-runtime-BdGkqNEt.js +45 -0
  402. package/dist/manager/_manager-chunks/globals-runtime-BmphMP6z.js +1190 -0
  403. package/dist/manager/_manager-chunks/globals-runtime-BvM-NY2g.js +13307 -0
  404. package/dist/manager/_manager-chunks/globals-runtime-C02fvgcd.js +9243 -0
  405. package/dist/manager/_manager-chunks/globals-runtime-DkAPXCvc.js +9766 -0
  406. package/dist/manager/_manager-chunks/globals-runtime-DpNYC-qi.js +5564 -0
  407. package/dist/manager/_manager-chunks/globals-runtime-DtcOnYHR.js +5357 -0
  408. package/dist/manager/_manager-chunks/globals-runtime-DwFqpqya.js +722 -0
  409. package/dist/manager/_manager-chunks/globals-runtime-FC201B7s.js +6837 -0
  410. package/dist/manager/_manager-chunks/globals-runtime-Rp_zjGnh.js +121 -0
  411. package/dist/manager/_manager-chunks/globals-runtime-ZHrQFa3-.js +10463 -0
  412. package/dist/manager/_manager-chunks/globals-runtime-eLPTIfX-.js +7759 -0
  413. package/dist/manager/_manager-chunks/globals-runtime-qKvCZHFY.js +4468 -0
  414. package/dist/manager/_manager-chunks/globals-runtime-sGpNlIJ1.js +5102 -0
  415. package/dist/manager/_manager-chunks/runtime-B1L9TH89.js +452 -0
  416. package/dist/manager/_manager-chunks/runtime-BK0zF7FN.js +22 -0
  417. package/dist/manager/_manager-chunks/runtime-BhkT2CXl.js +1408 -0
  418. package/dist/manager/_manager-chunks/runtime-Bly6WJLN.js +998 -0
  419. package/dist/manager/_manager-chunks/runtime-D0UOWx0U.js +979 -0
  420. package/dist/manager/_manager-chunks/runtime-D94Vq3oR.js +4014 -0
  421. package/dist/manager/_manager-chunks/runtime-DMig8mT7.js +77 -0
  422. package/dist/manager/_manager-chunks/runtime-EITvVbkG.js +46 -0
  423. package/dist/manager/_manager-chunks/runtime-cp5pazY2.js +8936 -0
  424. package/dist/manager/_manager-chunks/runtime-eDVAYF7N.js +6860 -0
  425. package/dist/manager/_manager-chunks/runtime-i-PDAHLR.js +2493 -0
  426. package/dist/manager/globals-runtime.js +2 -0
  427. package/dist/manager/globals.d.ts +23 -0
  428. package/dist/manager/globals.js +26 -0
  429. package/dist/manager/manager-stores.d.ts +2 -0
  430. package/dist/manager/manager-stores.js +19 -0
  431. package/dist/manager/runtime.js +2 -0
  432. package/dist/manager-api/index.d.ts +2 -0
  433. package/dist/manager-api/index.js +3257 -0
  434. package/dist/manager-errors.d.ts +89 -0
  435. package/dist/manager-errors.js +20 -0
  436. package/dist/mcp/index.d.ts +270 -0
  437. package/dist/mcp/index.js +305 -0
  438. package/dist/mocking-utils/index.d.ts +689 -0
  439. package/dist/mocking-utils/index.js +521 -0
  440. package/dist/mocking-utils/mocker-runtime.js +1254 -0
  441. package/dist/nextjs-vite/config/preview.js +3 -0
  442. package/dist/nextjs-vite/export-mocks/cache/index.d.ts +25 -0
  443. package/dist/nextjs-vite/export-mocks/cache/index.js +29 -0
  444. package/dist/nextjs-vite/export-mocks/headers/index.d.ts +37 -0
  445. package/dist/nextjs-vite/export-mocks/headers/index.js +54 -0
  446. package/dist/nextjs-vite/export-mocks/link/index.d.ts +9 -0
  447. package/dist/nextjs-vite/export-mocks/link/index.js +59 -0
  448. package/dist/nextjs-vite/export-mocks/navigation/index.d.ts +28 -0
  449. package/dist/nextjs-vite/export-mocks/navigation/index.js +58 -0
  450. package/dist/nextjs-vite/export-mocks/router/index.d.ts +34 -0
  451. package/dist/nextjs-vite/export-mocks/router/index.js +63 -0
  452. package/dist/nextjs-vite/index.d.ts +92 -0
  453. package/dist/nextjs-vite/index.js +58 -0
  454. package/dist/nextjs-vite/node/index.d.ts +6 -0
  455. package/dist/nextjs-vite/node/index.js +20 -0
  456. package/dist/nextjs-vite/preset.js +648 -0
  457. package/dist/nextjs-vite/preview.d.ts +20 -0
  458. package/dist/nextjs-vite/preview.js +11 -0
  459. package/dist/nextjs-vite/vite-plugin/index.d.ts +6 -0
  460. package/dist/nextjs-vite/vite-plugin/index.js +19 -0
  461. package/dist/nextjs-vite-plugin/index.d.ts +28 -0
  462. package/dist/nextjs-vite-plugin/index.js +923 -0
  463. package/dist/nextjs-vite-plugin/mocks/storybook.global.js +29 -0
  464. package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-context.js +8 -0
  465. package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-default-loader.js +23 -0
  466. package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-image.js +28 -0
  467. package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-legacy-image.js +17 -0
  468. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/cache/index.js +29 -0
  469. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/dynamic/index.js +40 -0
  470. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/headers/index.js +55 -0
  471. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/link/index.js +63 -0
  472. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/navigation/index.js +71 -0
  473. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/router/index.js +74 -0
  474. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/rsc/server-only.js +7 -0
  475. package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/safe-stable-stringify/index.js +13 -0
  476. package/dist/nextjs-vite-plugin/plugins/next-mocks/compatibility/draft-mode.compat.js +7 -0
  477. package/dist/node-logger/index.d.ts +495 -0
  478. package/dist/node-logger/index.js +42 -0
  479. package/dist/oxc-parser/index.d.ts +99 -0
  480. package/dist/oxc-parser/index.js +275 -0
  481. package/dist/oxc-parser/worker.js +37 -0
  482. package/dist/preview/_chunks/runtime-BIzIdDbb.js +10263 -0
  483. package/dist/preview/_chunks/runtime-BTPtVY1p.js +1102 -0
  484. package/dist/preview/_chunks/runtime-BZSnICCg.js +8484 -0
  485. package/dist/preview/_chunks/runtime-BdGkqNEt.js +45 -0
  486. package/dist/preview/_chunks/runtime-BwSxqk3t.js +63 -0
  487. package/dist/preview/_chunks/runtime-CqHxptiK.js +6143 -0
  488. package/dist/preview/_chunks/runtime-CsV4HZPV.js +5064 -0
  489. package/dist/preview/_chunks/runtime-CxZK_Ln3.js +284 -0
  490. package/dist/preview/_chunks/runtime-DZToXfvO.js +9767 -0
  491. package/dist/preview/_chunks/runtime-DrTjJkPY.js +3872 -0
  492. package/dist/preview/_chunks/runtime-DuHdxMFA.js +387 -0
  493. package/dist/preview/_chunks/runtime-iXdo8CR8.js +3635 -0
  494. package/dist/preview/_chunks/runtime-q3wt0e_N.js +6838 -0
  495. package/dist/preview/globals.d.ts +16 -0
  496. package/dist/preview/globals.js +20 -0
  497. package/dist/preview/runtime.js +6 -0
  498. package/dist/preview-api/index.d.ts +4 -0
  499. package/dist/preview-api/index.js +147 -0
  500. package/dist/preview-errors.d.ts +186 -0
  501. package/dist/preview-errors.js +56 -0
  502. package/dist/react/docgen/docgen-worker.js +38 -0
  503. package/dist/react/entry-preview-argtypes.js +9 -0
  504. package/dist/react/entry-preview-docs.js +12 -0
  505. package/dist/react/entry-preview-rsc.js +11 -0
  506. package/dist/react/entry-preview.js +21 -0
  507. package/dist/react/index.d.ts +119 -0
  508. package/dist/react/index.js +26 -0
  509. package/dist/react/preset.js +301 -0
  510. package/dist/react/preview.d.ts +2 -0
  511. package/dist/react/preview.js +11 -0
  512. package/dist/react-native/bin/get-stories.js +34 -0
  513. package/dist/react-native/index.d.ts +160 -0
  514. package/dist/react-native/index.js +1547 -0
  515. package/dist/react-native/metro/node.d.ts +83 -0
  516. package/dist/react-native/metro/node.js +21 -0
  517. package/dist/react-native/metro/withStorybook.d.ts +2269 -0
  518. package/dist/react-native/metro/withStorybook.js +138 -0
  519. package/dist/react-native/preview.d.ts +6 -0
  520. package/dist/react-native/preview.js +20 -0
  521. package/dist/react-native/scripts/generate.d.ts +22 -0
  522. package/dist/react-native/scripts/generate.js +18 -0
  523. package/dist/react-native/stub.js +20 -0
  524. package/dist/react-native-theming/index.d.ts +175 -0
  525. package/dist/react-native-theming/index.js +2591 -0
  526. package/dist/react-native-ui/index.d.ts +130 -0
  527. package/dist/react-native-ui/index.js +1448 -0
  528. package/dist/react-native-ui-common/index.d.ts +230 -0
  529. package/dist/react-native-ui-common/index.js +514 -0
  530. package/dist/react-vite/index.d.ts +4 -0
  531. package/dist/react-vite/index.js +8 -0
  532. package/dist/react-vite/node/index.d.ts +6 -0
  533. package/dist/react-vite/node/index.js +20 -0
  534. package/dist/react-vite/preset.d.ts +6 -0
  535. package/dist/react-vite/preset.js +21 -0
  536. package/dist/router/index.d.ts +141 -0
  537. package/dist/router/index.js +1217 -0
  538. package/dist/server-errors.d.ts +2 -0
  539. package/dist/server-errors.js +149 -0
  540. package/dist/shared/open-service/index.d.ts +3 -0
  541. package/dist/shared/open-service/index.js +115 -0
  542. package/dist/shared/open-service/services/docgen/worker/docgen-worker.js +75 -0
  543. package/dist/shared/open-service/toolsets/docs/public.d.ts +1296 -0
  544. package/dist/shared/open-service/toolsets/docs/public.js +991 -0
  545. package/dist/telemetry/index.d.ts +314 -0
  546. package/dist/telemetry/index.js +103 -0
  547. package/dist/test/index.d.ts +158 -0
  548. package/dist/test/index.js +19421 -0
  549. package/dist/theming/create.d.ts +15 -0
  550. package/dist/theming/create.js +11 -0
  551. package/dist/theming/index.d.ts +54 -0
  552. package/dist/theming/index.js +511 -0
  553. package/dist/types/index.d.ts +2 -0
  554. package/dist/types/index.js +48 -0
  555. package/dist/viewport/index.d.ts +275 -0
  556. package/dist/viewport/index.js +21 -0
  557. package/package.json +1054 -4
  558. package/template/nextjs-vite/cli/.eslintrc.json +6 -0
  559. package/template/nextjs-vite/cli/js/Button.jsx +42 -0
  560. package/template/nextjs-vite/cli/js/Button.stories.js +49 -0
  561. package/template/nextjs-vite/cli/js/Configure.mdx +470 -0
  562. package/template/nextjs-vite/cli/js/Header.jsx +58 -0
  563. package/template/nextjs-vite/cli/js/Header.stories.js +30 -0
  564. package/template/nextjs-vite/cli/js/Page.jsx +68 -0
  565. package/template/nextjs-vite/cli/js/Page.stories.js +28 -0
  566. package/template/nextjs-vite/cli/ts/Button.stories.ts +54 -0
  567. package/template/nextjs-vite/cli/ts/Button.tsx +39 -0
  568. package/template/nextjs-vite/cli/ts/Configure.mdx +446 -0
  569. package/template/nextjs-vite/cli/ts/Header.stories.ts +34 -0
  570. package/template/nextjs-vite/cli/ts/Header.tsx +54 -0
  571. package/template/nextjs-vite/cli/ts/Page.stories.ts +33 -0
  572. package/template/nextjs-vite/cli/ts/Page.tsx +73 -0
  573. package/template/react/cli/.eslintrc.json +5 -0
  574. package/template/react/cli/js/Button.jsx +39 -0
  575. package/template/react/cli/js/Button.stories.js +49 -0
  576. package/template/react/cli/js/Header.jsx +56 -0
  577. package/template/react/cli/js/Header.stories.js +29 -0
  578. package/template/react/cli/js/Page.jsx +69 -0
  579. package/template/react/cli/js/Page.stories.js +28 -0
  580. package/template/react/cli/ts/Button.stories.ts +54 -0
  581. package/template/react/cli/ts/Button.tsx +37 -0
  582. package/template/react/cli/ts/Header.stories.ts +34 -0
  583. package/template/react/cli/ts/Header.tsx +56 -0
  584. package/template/react/cli/ts/Page.stories.ts +33 -0
  585. package/template/react/cli/ts/Page.tsx +73 -0
  586. package/template/react-vite/cli/.eslintrc.json +5 -0
  587. package/template/react-vite/cli/js/Button.jsx +39 -0
  588. package/template/react-vite/cli/js/Button.stories.js +49 -0
  589. package/template/react-vite/cli/js/Header.jsx +56 -0
  590. package/template/react-vite/cli/js/Header.stories.js +29 -0
  591. package/template/react-vite/cli/js/Page.jsx +69 -0
  592. package/template/react-vite/cli/js/Page.stories.js +28 -0
  593. package/template/react-vite/cli/ts/Button.stories.ts +54 -0
  594. package/template/react-vite/cli/ts/Button.tsx +37 -0
  595. package/template/react-vite/cli/ts/Header.stories.ts +34 -0
  596. package/template/react-vite/cli/ts/Header.tsx +56 -0
  597. package/template/react-vite/cli/ts/Page.stories.ts +33 -0
  598. package/template/react-vite/cli/ts/Page.tsx +73 -0
@@ -0,0 +1,2102 @@
1
+ import CJS_COMPAT_NODE_URL_ro17f80mg6k from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_ro17f80mg6k from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_ro17f80mg6k from "node:module";
4
+
5
+ var __filename = CJS_COMPAT_NODE_URL_ro17f80mg6k.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_ro17f80mg6k.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_ro17f80mg6k.createRequire(import.meta.url);
8
+
9
+ // ------------------------------------------------------------
10
+ // end of CJS compatibility banner, injected by Forkbook's esbuild configuration
11
+ // ------------------------------------------------------------
12
+ import {
13
+ postInstall
14
+ } from "./chunk-XHL2LVBM.js";
15
+ import {
16
+ RN_STORYBOOK_DIR,
17
+ applyPreviewImportsMap
18
+ } from "./chunk-SWO5CDYU.js";
19
+ import {
20
+ any,
21
+ up2 as up
22
+ } from "./chunk-JDXXX6LB.js";
23
+ import {
24
+ invariant
25
+ } from "./chunk-34EO2PUT.js";
26
+ import {
27
+ resolvePackageDir
28
+ } from "./chunk-F3ZFKBHY.js";
29
+
30
+ // src/create/initiate.ts
31
+ import { resolve as resolve3 } from "node:path";
32
+ import { installSkills, supportsSkills, supportsAiSetup } from "@aussieljk/forkbook/internal/cli";
33
+ import {
34
+ PackageManagerName as PackageManagerName2,
35
+ cache,
36
+ executeCommand as executeCommand3
37
+ } from "@aussieljk/forkbook/internal/common";
38
+ import { getServerPort, withTelemetry } from "@aussieljk/forkbook/internal/core-server";
39
+ import { logTracker as logTracker2, logger as logger14 } from "@aussieljk/forkbook/internal/node-logger";
40
+ import { telemetry as telemetry4 } from "@aussieljk/forkbook/internal/telemetry";
41
+ import { Feature as Feature6 } from "@aussieljk/forkbook/internal/types";
42
+
43
+ // src/create/commands/PreflightCheckCommand.ts
44
+ import {
45
+ JsPackageManagerFactory,
46
+ PackageManagerName,
47
+ getPrettyPackageManagerName,
48
+ resolveStorybookVersionSpecifier,
49
+ isCI,
50
+ invalidateProjectRootCache,
51
+ warnOnYarn1,
52
+ getProcessAncestry as getProcessAncestry2
53
+ } from "@aussieljk/forkbook/internal/common";
54
+ import { CLI_COLORS, logger as logger2 } from "@aussieljk/forkbook/internal/node-logger";
55
+ import { MinimumReleaseAgeHandledError } from "@aussieljk/forkbook/internal/server-errors";
56
+ import { dedent } from "ts-dedent";
57
+
58
+ // src/create/scaffold-new-project.ts
59
+ import { readdirSync } from "node:fs";
60
+ import { rm } from "node:fs/promises";
61
+ import { executeCommand } from "@aussieljk/forkbook/internal/common";
62
+ import { logger, prompt } from "@aussieljk/forkbook/internal/node-logger";
63
+ import { GenerateNewProjectOnInitError } from "@aussieljk/forkbook/internal/server-errors";
64
+ import { telemetry as telemetry2 } from "@aussieljk/forkbook/internal/telemetry";
65
+
66
+ // src/create/prompt-cancel.ts
67
+ var createPromptCancelOptions = (telemetryService, promptName) => ({
68
+ async onCancel() {
69
+ let timeout, timeoutPromise = new Promise((resolve4) => {
70
+ timeout = setTimeout(resolve4, 2e3), timeout.unref?.();
71
+ });
72
+ try {
73
+ await Promise.race([
74
+ telemetryService.trackPromptCancel(promptName).catch(() => {
75
+ }),
76
+ timeoutPromise
77
+ ]);
78
+ } finally {
79
+ timeout !== void 0 && clearTimeout(timeout);
80
+ }
81
+ process.exit(0);
82
+ }
83
+ });
84
+
85
+ // src/create/services/TelemetryService.ts
86
+ import {
87
+ getProcessAncestry,
88
+ getStorybookVersionSpecifierFromAncestry
89
+ } from "@aussieljk/forkbook/internal/common";
90
+ import { telemetry } from "@aussieljk/forkbook/internal/telemetry";
91
+ import { Feature } from "@aussieljk/forkbook/internal/types";
92
+
93
+ // src/create/services/VersionService.ts
94
+ import { versions } from "@aussieljk/forkbook/internal/common";
95
+ import { lt, prerelease } from "semver";
96
+ var VersionService = class {
97
+ /** Get the current Forkbook version */
98
+ getCurrentVersion() {
99
+ return versions["@aussieljk/forkbook"];
100
+ }
101
+ /** Get the latest Forkbook version from the package manager */
102
+ async getLatestVersion(packageManager) {
103
+ return packageManager.latestVersion("@aussieljk/forkbook");
104
+ }
105
+ /** Check if the current version is a prerelease version */
106
+ isPrerelease(version) {
107
+ return !!prerelease(version);
108
+ }
109
+ /** Check if the current version is outdated compared to the latest version */
110
+ isOutdated(currentVersion, latestVersion) {
111
+ return lt(currentVersion, latestVersion);
112
+ }
113
+ /** Extract CLI integration from process ancestry. Detects if Forkbook was invoked via vike. */
114
+ getCliIntegrationFromAncestry(ancestry) {
115
+ return ancestry.some((ancestor) => ancestor.command?.includes("vike")) ? "vike" : void 0;
116
+ }
117
+ /** Get version info including current, latest, and prerelease status */
118
+ async getVersionInfo(packageManager) {
119
+ let currentVersion = this.getCurrentVersion(), latestVersion = await this.getLatestVersion(packageManager), isPrereleaseVersion = this.isPrerelease(currentVersion), isOutdatedVersion = latestVersion && !isPrereleaseVersion ? this.isOutdated(currentVersion, latestVersion) : !1;
120
+ return {
121
+ currentVersion,
122
+ latestVersion,
123
+ isPrerelease: isPrereleaseVersion,
124
+ isOutdated: isOutdatedVersion
125
+ };
126
+ }
127
+ };
128
+
129
+ // src/create/services/TelemetryService.ts
130
+ var TelemetryService = class {
131
+ constructor() {
132
+ this.versionService = new VersionService();
133
+ }
134
+ /** Track install type selection */
135
+ async trackInstallType(installType) {
136
+ await telemetry("init-step", {
137
+ step: "install-type",
138
+ installType
139
+ });
140
+ }
141
+ /** Track when a user accepts the AI setup nudge prompt */
142
+ async trackAiSetupNudge(context) {
143
+ await telemetry("ai-prompt-nudge", {
144
+ id: "setup",
145
+ origin: "init",
146
+ context
147
+ });
148
+ }
149
+ /** Track Playwright prompt decision (install | skip | aborted) */
150
+ async trackPlaywrightPromptDecision(result) {
151
+ await telemetry("init-step", {
152
+ step: "playwright-install",
153
+ result
154
+ });
155
+ }
156
+ /** Track the outcome of the official Forkbook skills install step */
157
+ async trackSkills(result) {
158
+ await telemetry("init-step", {
159
+ step: "skills",
160
+ ...result
161
+ });
162
+ }
163
+ /** Track the main init event with all metadata */
164
+ async trackInit(data, options = {}) {
165
+ await telemetry("init", data, { configDir: options.configDir });
166
+ }
167
+ /** Track empty directory scaffolding event */
168
+ async trackScaffolded(data) {
169
+ await telemetry("scaffolded-empty", data);
170
+ }
171
+ /**
172
+ * Track init with complete context including version and CLI integration from ancestry This
173
+ * method encapsulates all telemetry gathering and tracking logic
174
+ */
175
+ async trackInitWithContext(projectType, selectedFeatures, configDir) {
176
+ let versionSpecifier, cliIntegration;
177
+ try {
178
+ let ancestry = getProcessAncestry();
179
+ versionSpecifier = getStorybookVersionSpecifierFromAncestry(ancestry), cliIntegration = this.versionService.getCliIntegrationFromAncestry(ancestry);
180
+ } catch {
181
+ }
182
+ let telemetryFeatures = {
183
+ dev: !0,
184
+ // Always true during init
185
+ docs: selectedFeatures.has(Feature.DOCS),
186
+ test: selectedFeatures.has(Feature.TEST),
187
+ ai: selectedFeatures.has(Feature.AI)
188
+ };
189
+ await this.trackInit(
190
+ {
191
+ projectType,
192
+ features: telemetryFeatures,
193
+ versionSpecifier,
194
+ cliIntegration
195
+ },
196
+ { configDir }
197
+ );
198
+ }
199
+ async trackPromptCancel(prompt10) {
200
+ await telemetry(
201
+ "canceled",
202
+ { eventType: "init", prompt: prompt10 },
203
+ { stripMetadata: !0, immediate: !0 }
204
+ );
205
+ }
206
+ };
207
+
208
+ // src/create/scaffold-new-project.ts
209
+ var SUPPORTED_PROJECTS = {
210
+ "react-vite-ts": {
211
+ displayName: {
212
+ type: "React",
213
+ builder: "Vite",
214
+ language: "TS"
215
+ },
216
+ createScript: {
217
+ npm: "npm create vite@latest . -- --template react-ts",
218
+ yarn: "yarn create vite . --template react-ts",
219
+ pnpm: "pnpm create vite@latest . --template react-ts"
220
+ }
221
+ },
222
+ "nextjs-ts": {
223
+ displayName: {
224
+ type: "Next.js",
225
+ language: "TS"
226
+ },
227
+ createScript: {
228
+ npm: 'npm create next-app . -- --turbopack --typescript --use-npm --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler',
229
+ // yarn doesn't support version ranges, so we have to use npx
230
+ yarn: 'npx create-next-app . --turbopack --typescript --use-yarn --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler',
231
+ pnpm: 'pnpm create next-app . --turbopack --typescript --use-pnpm --eslint --tailwind --no-app --import-alias="@/*" --src-dir --no-react-compiler'
232
+ }
233
+ }
234
+ }, packageManagerToCoercedName = (packageManager) => {
235
+ switch (packageManager) {
236
+ case "npm":
237
+ return "npm";
238
+ case "pnpm":
239
+ return "pnpm";
240
+ default:
241
+ return "yarn";
242
+ }
243
+ }, buildProjectDisplayNameForPrint = ({ displayName }) => {
244
+ let { type, builder, language } = displayName;
245
+ return `${type} ${builder ? `+ ${builder} ` : ""}(${language})`;
246
+ }, scaffoldNewProject = async (packageManager, telemetryService = new TelemetryService()) => {
247
+ let packageManagerName = packageManagerToCoercedName(packageManager), projectStrategy;
248
+ process.env.FORKBOOK_INIT_EMPTY_TYPE && (projectStrategy = process.env.FORKBOOK_INIT_EMPTY_TYPE), projectStrategy || (projectStrategy = await prompt.select(
249
+ {
250
+ message: "Empty directory detected:",
251
+ options: [
252
+ ...Object.entries(SUPPORTED_PROJECTS).map(([key, value]) => ({
253
+ label: buildProjectDisplayNameForPrint(value),
254
+ value: key
255
+ })),
256
+ {
257
+ label: "Other",
258
+ value: "other",
259
+ hint: "To install Forkbook on another framework, first generate a project with that framework and then rerun this command."
260
+ }
261
+ ]
262
+ },
263
+ createPromptCancelOptions(telemetryService, "empty-directory")
264
+ )), projectStrategy === "other" && (await telemetry2(
265
+ "exit",
266
+ { eventType: "init", reason: "scaffold-other" },
267
+ { stripMetadata: !0, immediate: !0 }
268
+ ), logger.warn(
269
+ "To install Forkbook on another framework, first generate a project with that framework and then rerun this command."
270
+ ), logger.outro("Exiting..."), process.exit(1));
271
+ let projectStrategyConfig = SUPPORTED_PROJECTS[projectStrategy], projectDisplayName = buildProjectDisplayNameForPrint(projectStrategyConfig), createScript = projectStrategyConfig.createScript[packageManagerName], spinner = prompt.spinner({
272
+ id: "create-new-project"
273
+ });
274
+ spinner.start(`Creating a new "${projectDisplayName}" project with ${packageManagerName}...`);
275
+ let targetDir = process.cwd();
276
+ try {
277
+ await rm(`${targetDir}/.cache`, { recursive: !0, force: !0 });
278
+ } catch {
279
+ }
280
+ try {
281
+ await rm(`${targetDir}/node_modules`, { recursive: !0, force: !0 });
282
+ } catch {
283
+ }
284
+ try {
285
+ spinner.message(`Executing ${createScript}`), await executeCommand({
286
+ command: createScript,
287
+ shell: !0,
288
+ stdio: "pipe",
289
+ cwd: targetDir
290
+ });
291
+ } catch (e) {
292
+ throw spinner.error(
293
+ `Failed to create a new "${projectDisplayName}" project with ${packageManagerName}`
294
+ ), new GenerateNewProjectOnInitError({
295
+ error: e,
296
+ packageManager: packageManagerName,
297
+ projectType: projectStrategy
298
+ });
299
+ }
300
+ spinner.stop(`${projectDisplayName} project with ${packageManagerName} created successfully!`), await telemetry2("scaffolded-empty", {
301
+ packageManager: packageManagerName,
302
+ projectType: projectStrategy
303
+ });
304
+ }, FILES_TO_IGNORE = [
305
+ ".git",
306
+ ".gitignore",
307
+ ".DS_Store",
308
+ ".cache",
309
+ "node_modules",
310
+ ".yarnrc.yml",
311
+ ".yarn"
312
+ ], currentDirectoryIsEmpty = () => {
313
+ let cwdFolderEntries = readdirSync(process.cwd());
314
+ return cwdFolderEntries.length === 0 || cwdFolderEntries.every((entry) => FILES_TO_IGNORE.includes(entry));
315
+ };
316
+
317
+ // src/create/services/FeatureCompatibilityService.ts
318
+ import { AddonVitestService } from "@aussieljk/forkbook/internal/cli";
319
+ var FeatureCompatibilityService = class {
320
+ constructor(packageManager, addonVitestService = new AddonVitestService(packageManager)) {
321
+ this.packageManager = packageManager;
322
+ this.addonVitestService = addonVitestService;
323
+ }
324
+ /**
325
+ * Validate all compatibility checks for test feature
326
+ *
327
+ * @param packageManager - Package manager instance
328
+ * @param framework - Detected framework (e.g., 'nextjs', 'react-vite')
329
+ * @param builder - Detected builder (e.g. SupportedBuilder.Vite)
330
+ * @param directory - Project root directory
331
+ * @returns Compatibility result with reasons if incompatible
332
+ */
333
+ async validateTestFeatureCompatibility(framework, builder, directory) {
334
+ let compatibilityResult = await this.addonVitestService.validateCompatibility({
335
+ framework,
336
+ builder,
337
+ projectRoot: directory
338
+ });
339
+ return compatibilityResult.compatible ? { compatible: !0 } : compatibilityResult;
340
+ }
341
+ };
342
+
343
+ // src/create/services/AddonService.ts
344
+ import { getPackageDetails } from "@aussieljk/forkbook/internal/common";
345
+ import { Feature as Feature2 } from "@aussieljk/forkbook/internal/types";
346
+ var AddonService = class {
347
+ /** Get addons based on selected features */
348
+ getAddonsForFeatures(features) {
349
+ let addons = [];
350
+ return features.has(Feature2.TEST) && addons.push("@aussieljk/forkbook/addon-vitest"), features.has(Feature2.A11Y) && addons.push("@aussieljk/forkbook/addon-a11y"), features.has(Feature2.DOCS) && addons.push("@aussieljk/forkbook/addon-docs"), addons;
351
+ }
352
+ /** Strip version numbers from addon names */
353
+ stripVersions(addons) {
354
+ return addons.map((addon) => getPackageDetails(addon)[0]);
355
+ }
356
+ /** Configure addons for the project */
357
+ configureAddons(features, extraAddons = []) {
358
+ let addonsForMain = this.stripVersions(extraAddons).filter(Boolean), addonPackages = extraAddons.filter(Boolean);
359
+ return {
360
+ addonsForMain,
361
+ addonPackages
362
+ };
363
+ }
364
+ };
365
+
366
+ // src/create/commands/PreflightCheckCommand.ts
367
+ var PreflightCheckCommand = class {
368
+ /** Execute preflight checks */
369
+ constructor(versionService = new VersionService(), telemetryService = new TelemetryService()) {
370
+ this.versionService = versionService;
371
+ this.telemetryService = telemetryService;
372
+ }
373
+ async execute(options) {
374
+ if (options.storybookVersionSpecifier === void 0)
375
+ try {
376
+ options.storybookVersionSpecifier = resolveStorybookVersionSpecifier(getProcessAncestry2());
377
+ } catch {
378
+ }
379
+ let isEmptyDirProject = options.force !== !0 && currentDirectoryIsEmpty(), packageManagerType = JsPackageManagerFactory.getPackageManagerType();
380
+ isEmptyDirProject && ((options.packageManager ? options.packageManager === PackageManagerName.YARN1 : packageManagerType === PackageManagerName.YARN1) && (logger2.warn("Empty directory with yarn1 is unsupported. Falling back to npm."), packageManagerType = PackageManagerName.NPM, options.packageManager = packageManagerType), logger2.intro(CLI_COLORS.info("Initializing a new project")), await scaffoldNewProject(packageManagerType, this.telemetryService), logger2.outro(CLI_COLORS.info("Project created successfully")), invalidateProjectRootCache()), logger2.intro(CLI_COLORS.info("Initializing Forkbook"));
381
+ let packageManager = JsPackageManagerFactory.getPackageManager({
382
+ force: options.packageManager
383
+ });
384
+ logger2.info(`Package manager: ${getPrettyPackageManagerName(packageManager.type)}`), warnOnYarn1(packageManager.type), isEmptyDirProject && !options.skipInstall && await packageManager.installDependencies(), this.checkPackageNameConflict(packageManager), await this.displayVersionInfo(packageManager);
385
+ try {
386
+ await packageManager.precheckStorybookPackageInstall({
387
+ storybookVersion: this.versionService.getCurrentVersion(),
388
+ nonInteractive: !!options.yes || !process.stdout.isTTY || !!isCI()
389
+ });
390
+ } catch (error) {
391
+ if (error instanceof MinimumReleaseAgeHandledError)
392
+ throw error;
393
+ logger2.debug(`Skipping minimum-release-age precheck after an unexpected failure: ${error}`);
394
+ }
395
+ return { packageManager, isEmptyProject: isEmptyDirProject };
396
+ }
397
+ /**
398
+ * Warn when the project's package.json "name" is "@aussieljk/forkbook", which shadows
399
+ * the real storybook package in workspaces.
400
+ *
401
+ * See: https://github.com/storybookjs/storybook/issues/28725
402
+ */
403
+ checkPackageNameConflict(packageManager) {
404
+ packageManager.primaryPackageJson.packageJson.name === "@aussieljk/forkbook" && logger2.warn(dedent`
405
+ Your package.json "name" field is set to "@aussieljk/forkbook".
406
+
407
+ In npm, pnpm, or yarn workspaces this creates a symlink at
408
+ node_modules/storybook that shadows the real Forkbook package,
409
+ causing "Cannot find module @aussieljk/forkbook/internal/..." errors.
410
+
411
+ Please rename the "name" field in your package.json to something
412
+ other than "@aussieljk/forkbook" (e.g. "my-storybook", "docs", "@myorg/storybook").
413
+ `);
414
+ }
415
+ /** Display version information and warnings */
416
+ async displayVersionInfo(packageManager) {
417
+ let { currentVersion, latestVersion, isPrerelease, isOutdated } = await this.versionService.getVersionInfo(packageManager);
418
+ isOutdated && !isPrerelease ? logger2.warn(dedent`
419
+ This version is behind the latest release, which is: ${latestVersion}!
420
+ You likely ran the init command through npx, which can use a locally cached version.
421
+
422
+ To get the latest, please run: ${CLI_COLORS.cta("npx storybook@latest init")}
423
+ You may want to ${CLI_COLORS.cta("CTRL+C")} to stop, and run with the latest version instead.
424
+ `) : isPrerelease ? logger2.warn(`This is a pre-release version: ${currentVersion}`) : logger2.info(`Adding Forkbook version ${currentVersion} to your project`);
425
+ }
426
+ }, executePreflightCheck = async (options) => new PreflightCheckCommand().execute(options);
427
+
428
+ // src/create/commands/ProjectDetectionCommand.ts
429
+ import { logger as logger4, prompt as prompt2 } from "@aussieljk/forkbook/internal/node-logger";
430
+ import { telemetry as telemetry3 } from "@aussieljk/forkbook/internal/telemetry";
431
+ import { SupportedLanguage } from "@aussieljk/forkbook/internal/types";
432
+ import { dedent as dedent3 } from "ts-dedent";
433
+
434
+ // src/create/services/ProjectTypeService.ts
435
+ import { existsSync } from "node:fs";
436
+ import { resolve } from "node:path";
437
+ import {
438
+ ProjectType,
439
+ detectIncompatiblePackageVersions,
440
+ detectLanguage
441
+ } from "@aussieljk/forkbook/internal/cli";
442
+ import { HandledError, getProjectRoot } from "@aussieljk/forkbook/internal/common";
443
+ import { logger as logger3 } from "@aussieljk/forkbook/internal/node-logger";
444
+ import { NxProjectDetectedError } from "@aussieljk/forkbook/internal/server-errors";
445
+ import { dedent as dedent2 } from "ts-dedent";
446
+ var ProjectTypeService = class {
447
+ constructor(jsPackageManager) {
448
+ this.jsPackageManager = jsPackageManager;
449
+ }
450
+ /** Sorted configuration to match a Forkbook preset template */
451
+ getSupportedTemplates() {
452
+ return [
453
+ {
454
+ preset: ProjectType.NEXTJS,
455
+ dependencies: ["next"],
456
+ matcherFunction: ({ dependencies }) => dependencies?.every(Boolean) ?? !0
457
+ },
458
+ {
459
+ preset: ProjectType.REACT_NATIVE,
460
+ dependencies: ["react-native", "react-native-scripts", "expo"],
461
+ peerDependencies: ["react-native", "react-native-scripts", "expo"],
462
+ matcherFunction: ({ dependencies, peerDependencies }) => (dependencies?.some(Boolean) || peerDependencies?.some(Boolean)) ?? !1
463
+ },
464
+ // DO NOT MOVE ANY TEMPLATES BELOW THIS LINE
465
+ // React is part of every Template, after Forkbook is initialized once
466
+ {
467
+ preset: ProjectType.REACT,
468
+ dependencies: ["react"],
469
+ peerDependencies: ["react"],
470
+ matcherFunction: ({ dependencies, peerDependencies }) => (dependencies?.some(Boolean) || peerDependencies?.some(Boolean)) ?? !1
471
+ }
472
+ ];
473
+ }
474
+ isStorybookInstantiated(configDir = resolve(process.cwd(), ".forkbook")) {
475
+ return existsSync(configDir);
476
+ }
477
+ async validateProvidedType(projectTypeProvided) {
478
+ if (Object.values(ProjectType).filter(
479
+ (t2) => !["undetected", "unsupported", "nx"].includes(String(t2))
480
+ ).includes(projectTypeProvided))
481
+ return projectTypeProvided;
482
+ throw logger3.error(`The provided project type ${projectTypeProvided} was not recognized by Forkbook`), new HandledError(`Unknown project type supplied: ${projectTypeProvided}`);
483
+ }
484
+ async autoDetectProjectType() {
485
+ try {
486
+ let detectedType = await this.detectProjectType();
487
+ if (detectedType === ProjectType.UNDETECTED || detectedType === null)
488
+ throw logger3.error(dedent2`
489
+ Unable to initialize Forkbook in this directory.
490
+
491
+ Forkbook couldn't detect a supported framework or configuration for your project. Make sure you're inside a React, Next.js or React Native project and that its dependencies are installed.
492
+
493
+ Tips:
494
+ - Run init in an empty directory or create a new framework app first.
495
+ - If this directory contains unrelated files, try a new directory for Forkbook.
496
+ `), new HandledError("Forkbook failed to detect your project type");
497
+ if (detectedType === ProjectType.NX)
498
+ throw new NxProjectDetectedError();
499
+ return detectedType;
500
+ } catch (err) {
501
+ throw err instanceof HandledError || err instanceof NxProjectDetectedError ? err : (logger3.error(String(err)), new HandledError(err instanceof Error ? err.message : String(err)));
502
+ }
503
+ }
504
+ async detectLanguage() {
505
+ return detectLanguage(this.jsPackageManager);
506
+ }
507
+ /** Check installed tooling versions for TypeScript compatibility constraints */
508
+ async detectIncompatiblePackageVersions() {
509
+ return detectIncompatiblePackageVersions(this.jsPackageManager);
510
+ }
511
+ async detectProjectType() {
512
+ try {
513
+ if (this.isNxProject())
514
+ return ProjectType.NX;
515
+ let { packageJson } = this.jsPackageManager.primaryPackageJson;
516
+ return this.detectFrameworkPreset(packageJson);
517
+ } catch {
518
+ return ProjectType.UNDETECTED;
519
+ }
520
+ }
521
+ detectFrameworkPreset(packageJson) {
522
+ let result = [...this.getSupportedTemplates(), this.getUnsupportedTemplate()].find(
523
+ (framework) => this.getProjectType(packageJson, framework) !== null
524
+ );
525
+ return result ? result.preset : ProjectType.UNDETECTED;
526
+ }
527
+ /** Template that matches unsupported frameworks */
528
+ getUnsupportedTemplate() {
529
+ return {
530
+ preset: ProjectType.UNSUPPORTED,
531
+ dependencies: {},
532
+ matcherFunction: ({ dependencies }) => dependencies?.some(Boolean) ?? !1
533
+ };
534
+ }
535
+ getProjectType(packageJson, framework) {
536
+ let matcher = {
537
+ dependencies: [!1],
538
+ peerDependencies: [!1],
539
+ files: [!1]
540
+ }, { preset, files, dependencies, peerDependencies, matcherFunction } = framework, dependencySearches = [];
541
+ Array.isArray(dependencies) ? dependencySearches = dependencies.map((name) => [name, void 0]) : typeof dependencies == "object" && (dependencySearches = Object.entries(dependencies)), dependencySearches.length > 0 && (matcher.dependencies = dependencySearches.map(
542
+ ([name, matchFn]) => this.hasDependency(packageJson, name, matchFn)
543
+ ));
544
+ let peerDependencySearches = [];
545
+ return Array.isArray(peerDependencies) ? peerDependencySearches = peerDependencies.map((name) => [name, void 0]) : typeof peerDependencies == "object" && (peerDependencySearches = Object.entries(peerDependencies)), peerDependencySearches.length > 0 && (matcher.peerDependencies = peerDependencySearches.map(
546
+ ([name, matchFn]) => this.hasPeerDependency(packageJson, name, matchFn)
547
+ )), Array.isArray(files) && files.length > 0 && (matcher.files = files.map((name) => existsSync(name))), matcherFunction(matcher) ? preset : null;
548
+ }
549
+ hasDependency(packageJson, name, matcher) {
550
+ let version = packageJson.dependencies?.[name] || packageJson.devDependencies?.[name];
551
+ return version && typeof matcher == "function" ? matcher(version) : !!version;
552
+ }
553
+ hasPeerDependency(packageJson, name, matcher) {
554
+ let version = packageJson.peerDependencies?.[name];
555
+ return version && typeof matcher == "function" ? matcher(version) : !!version;
556
+ }
557
+ isNxProject() {
558
+ return up("nx.json", { last: getProjectRoot() });
559
+ }
560
+ };
561
+
562
+ // src/create/commands/ProjectDetectionCommand.ts
563
+ var ProjectDetectionCommand = class {
564
+ constructor(options, jsPackageManager, projectTypeService = new ProjectTypeService(jsPackageManager), telemetryService = new TelemetryService()) {
565
+ this.options = options;
566
+ this.projectTypeService = projectTypeService;
567
+ this.telemetryService = telemetryService;
568
+ }
569
+ /** Execute project type detection */
570
+ async execute() {
571
+ let projectType, projectTypeProvided = this.options.type;
572
+ projectTypeProvided ? (projectType = await this.projectTypeService.validateProvidedType(projectTypeProvided), logger4.step(`Installing Forkbook for user specified project type: ${projectTypeProvided}`)) : (projectType = await this.projectTypeService.autoDetectProjectType(), logger4.debug(`Project type detected: ${projectType}`)), await this.checkExistingInstallation();
573
+ let language = this.options.language || await this.detectAndReportLanguage();
574
+ return { projectType, language };
575
+ }
576
+ /** Detect language and warn about incompatible packages */
577
+ async detectAndReportLanguage() {
578
+ let language = await this.projectTypeService.detectLanguage();
579
+ if (language === SupportedLanguage.JAVASCRIPT) {
580
+ let incompatibleReasons = await this.projectTypeService.detectIncompatiblePackageVersions();
581
+ incompatibleReasons.length > 0 && logger4.warn(
582
+ `Populating with JavaScript examples due to incompatible package versions:
583
+ ${incompatibleReasons.map((r) => ` - ${r}`).join(`
584
+ `)}`
585
+ );
586
+ }
587
+ return language;
588
+ }
589
+ /** Check if Forkbook is already installed and handle force option */
590
+ async checkExistingInstallation() {
591
+ let storybookInstantiated = this.projectTypeService.isStorybookInstantiated(), options = this.options;
592
+ options.force !== !0 && options.yes !== !0 && storybookInstantiated && (await prompt2.confirm(
593
+ {
594
+ message: dedent3`We found a .forkbook config directory in your project.
595
+ We assume that Forkbook is already instantiated for your project. Do you still want to continue and force the initialization?`
596
+ },
597
+ createPromptCancelOptions(this.telemetryService, "force-on-existing-installation")
598
+ ) || options.yes ? options.force = !0 : (await telemetry3(
599
+ "exit",
600
+ { eventType: "init", reason: "existing-installation" },
601
+ { stripMetadata: !0, immediate: !0 }
602
+ ), process.exit(0)));
603
+ }
604
+ }, executeProjectDetection = (packageManager, options) => new ProjectDetectionCommand(options, packageManager).execute();
605
+
606
+ // src/create/commands/FrameworkDetectionCommand.ts
607
+ import { logger as logger6 } from "@aussieljk/forkbook/internal/node-logger";
608
+
609
+ // src/create/generators/GeneratorRegistry.ts
610
+ import { logger as logger5 } from "@aussieljk/forkbook/internal/node-logger";
611
+ var GeneratorRegistry = class {
612
+ constructor() {
613
+ this.generators = /* @__PURE__ */ new Map();
614
+ }
615
+ /** Register a generator for a specific project type */
616
+ register(generator) {
617
+ let { metadata } = generator;
618
+ this.generators.has(metadata.projectType) && logger5.warn(
619
+ `Generator for project type ${metadata.projectType} is already registered. Overwriting.`
620
+ ), this.generators.set(metadata.projectType, generator);
621
+ }
622
+ /** Get a generator for a specific project type */
623
+ get(projectType) {
624
+ return this.generators.get(projectType);
625
+ }
626
+ }, generatorRegistry = new GeneratorRegistry();
627
+
628
+ // src/create/services/FrameworkDetectionService.ts
629
+ import { getProjectRoot as getProjectRoot2 } from "@aussieljk/forkbook/internal/common";
630
+ import { prompt as prompt3 } from "@aussieljk/forkbook/internal/node-logger";
631
+ import { SupportedBuilder, SupportedFramework } from "@aussieljk/forkbook/internal/types";
632
+ var viteConfigFiles = ["vite.config.ts", "vite.config.js", "vite.config.mjs"], FrameworkDetectionService = class {
633
+ constructor(jsPackageManager, telemetryService = new TelemetryService()) {
634
+ this.jsPackageManager = jsPackageManager;
635
+ this.telemetryService = telemetryService;
636
+ }
637
+ detectFramework(renderer, builder) {
638
+ if (Object.values(SupportedFramework).includes(renderer))
639
+ return renderer;
640
+ let maybeFramework = `${renderer}-${builder}`;
641
+ if (Object.values(SupportedFramework).includes(maybeFramework))
642
+ return maybeFramework;
643
+ throw new Error(`Could not find framework for renderer: ${renderer} and builder: ${builder}`);
644
+ }
645
+ async detectBuilder() {
646
+ let viteConfig = any(viteConfigFiles, { last: getProjectRoot2() }), dependencies = this.jsPackageManager.getAllDependencies();
647
+ return viteConfig || dependencies.vite ? SupportedBuilder.VITE : prompt3.select(
648
+ {
649
+ message: "We were not able to detect the right builder for your project. Please select one:",
650
+ options: [{ label: "Vite", value: SupportedBuilder.VITE }]
651
+ },
652
+ createPromptCancelOptions(this.telemetryService, "builder-selection")
653
+ );
654
+ }
655
+ };
656
+
657
+ // src/create/commands/FrameworkDetectionCommand.ts
658
+ var FrameworkDetectionCommand = class {
659
+ constructor(packageManager, frameworkDetectionService = new FrameworkDetectionService(packageManager)) {
660
+ this.frameworkDetectionService = frameworkDetectionService;
661
+ }
662
+ async execute(projectType, options) {
663
+ let generatorModule = generatorRegistry.get(projectType);
664
+ if (!generatorModule)
665
+ throw new Error(`No generator found for project type: ${projectType}`);
666
+ let { metadata } = generatorModule, builder;
667
+ options.builder ? builder = options.builder : metadata.builderOverride ? builder = metadata.builderOverride : builder = await this.frameworkDetectionService.detectBuilder();
668
+ let renderer = metadata.renderer, framework = metadata.framework !== void 0 ? metadata.framework : this.frameworkDetectionService.detectFramework(renderer, builder);
669
+ return framework && logger6.step(`Framework detected: ${framework}`), {
670
+ framework,
671
+ renderer,
672
+ builder
673
+ };
674
+ }
675
+ }, executeFrameworkDetection = (projectType, packageManager, options) => new FrameworkDetectionCommand(packageManager).execute(projectType, options);
676
+
677
+ // src/create/commands/UserPreferencesCommand.ts
678
+ import { isCI as isCI2 } from "@aussieljk/forkbook/internal/common";
679
+ import { logger as logger7, prompt as prompt4 } from "@aussieljk/forkbook/internal/node-logger";
680
+ import { Feature as Feature3 } from "@aussieljk/forkbook/internal/types";
681
+ import { dedent as dedent4 } from "ts-dedent";
682
+ var UserPreferencesCommand = class {
683
+ constructor(commandOptions, telemetryService = new TelemetryService()) {
684
+ this.commandOptions = commandOptions;
685
+ this.telemetryService = telemetryService;
686
+ }
687
+ /** Execute user preferences gathering */
688
+ async execute(options) {
689
+ let skipPrompt = !(process.stdout.isTTY && !isCI2()) || !!this.commandOptions.yes, commandOptionsFeatures = this.handleCommandOptionsFeatureFlag();
690
+ if (commandOptionsFeatures)
691
+ return { selectedFeatures: commandOptionsFeatures };
692
+ let installType = this.commandOptions.features ? "recommended" : await this.promptInstallType(skipPrompt, options.isTestFeatureAvailable), useAi = options.isAiAvailable ? await this.promptAiSetup(skipPrompt, options.isAiSetupAvailable) : !1;
693
+ return { selectedFeatures: this.determineFeatures(
694
+ installType,
695
+ options.isTestFeatureAvailable,
696
+ useAi,
697
+ options.isAiSetupAvailable
698
+ ) };
699
+ }
700
+ handleCommandOptionsFeatureFlag() {
701
+ return this.commandOptions.features && this.commandOptions.features?.length > 0 ? (logger7.warn(dedent4`
702
+ Skipping feature validation as these features were explicitly selected:
703
+ ${Array.from(this.commandOptions.features).join(", ")}
704
+ `), new Set(this.commandOptions.features)) : this.commandOptions.features?.length === 0 ? (logger7.warn(dedent4`
705
+ All features have been disabled via --no-features flag.
706
+ `), /* @__PURE__ */ new Set()) : null;
707
+ }
708
+ /** Prompt user for install type */
709
+ async promptInstallType(skipPrompt, isTestFeatureAvailable) {
710
+ let installType = "recommended", recommendedLabel = isTestFeatureAvailable ? "Recommended: Component development, docs, and testing features." : "Recommended: Component development and docs";
711
+ return skipPrompt || (installType = await prompt4.select(
712
+ {
713
+ message: "What configuration should we install?",
714
+ options: [
715
+ {
716
+ label: recommendedLabel,
717
+ value: "recommended"
718
+ },
719
+ {
720
+ label: "Minimal: Just the essentials for component development.",
721
+ value: "light"
722
+ }
723
+ ]
724
+ },
725
+ createPromptCancelOptions(this.telemetryService, "install-type")
726
+ )), await this.telemetryService.trackInstallType(installType), installType;
727
+ }
728
+ /** Determine features based on install type and user status */
729
+ determineFeatures(installType, isTestFeatureAvailable, useAi, isAiSetupAvailable) {
730
+ let features = /* @__PURE__ */ new Set();
731
+ return installType === "recommended" && (features.add(Feature3.DOCS), features.add(Feature3.A11Y), isTestFeatureAvailable && features.add(Feature3.TEST)), useAi && features.add(Feature3.AI), useAi && isAiSetupAvailable && isTestFeatureAvailable && features.add(Feature3.TEST), features;
732
+ }
733
+ /** Prompt user about AI-assisted Forkbook setup */
734
+ async promptAiSetup(skipPrompt, isAiSetupAvailable) {
735
+ let useAi = skipPrompt ? !0 : await prompt4.confirm(
736
+ {
737
+ message: isAiSetupAvailable ? "Do you want AI features, like skills and prompts, in your Forkbook?" : "Do you want AI features, like skills, in your Forkbook?",
738
+ initialValue: !0
739
+ },
740
+ createPromptCancelOptions(this.telemetryService, "ai-setup")
741
+ );
742
+ return useAi && isAiSetupAvailable && await this.telemetryService.trackAiSetupNudge({ skipPrompt }), useAi;
743
+ }
744
+ }, executeUserPreferences = ({
745
+ options,
746
+ ...restOptions
747
+ }) => new UserPreferencesCommand(options).execute(restOptions);
748
+
749
+ // src/create/generators/baseGenerator.ts
750
+ import { mkdir } from "node:fs/promises";
751
+ import { join } from "node:path";
752
+ import {
753
+ configureEslintPlugin,
754
+ copyTemplateFiles,
755
+ extractEslintInfo
756
+ } from "@aussieljk/forkbook/internal/cli";
757
+ import {
758
+ frameworkPackages,
759
+ getPackageDetails as getPackageDetails2,
760
+ isCI as isCI3,
761
+ isCorePackage
762
+ } from "@aussieljk/forkbook/internal/common";
763
+ import { prompt as prompt5 } from "@aussieljk/forkbook/internal/node-logger";
764
+ import { SupportedFramework as SupportedFramework2, SupportedLanguage as SupportedLanguage3 } from "@aussieljk/forkbook/internal/types";
765
+ import { dedent as dedent6 } from "ts-dedent";
766
+
767
+ // src/create/generators/configure.ts
768
+ import { stat, writeFile } from "node:fs/promises";
769
+ import { resolve as resolve2 } from "node:path";
770
+ import { logger as logger8 } from "@aussieljk/forkbook/internal/node-logger";
771
+ import { Feature as Feature4, SupportedLanguage as SupportedLanguage2, SupportedRenderer } from "@aussieljk/forkbook/internal/types";
772
+ import { dedent as dedent5 } from "ts-dedent";
773
+ var pathExists = async (path3) => stat(path3).then(() => !0).catch(() => !1);
774
+ async function configureMain({
775
+ addons,
776
+ extensions = ["js", "jsx", "mjs", "ts", "tsx"],
777
+ storybookConfigFolder,
778
+ language,
779
+ frameworkPackage,
780
+ prefixes = [],
781
+ features,
782
+ ...custom
783
+ }) {
784
+ let srcPath = resolve2(storybookConfigFolder, "../src"), prefix = await pathExists(srcPath) ? "../src" : "../stories", stories = features.has(Feature4.DOCS) ? [`${prefix}/**/*.mdx`] : [];
785
+ stories.push(`${prefix}/**/*.stories.@(${extensions.join("|")})`);
786
+ let config = {
787
+ stories,
788
+ addons,
789
+ ...custom
790
+ }, isTypescript = language === SupportedLanguage2.TYPESCRIPT, mainConfigTemplate = dedent5`<<import>><<prefix>>const config<<type>> = <<mainContents>>;
791
+ export default config;`;
792
+ frameworkPackage || (mainConfigTemplate = mainConfigTemplate.replace("<<import>>", "").replace("<<type>>", ""), logger8.warn("Could not find framework package name"));
793
+ let mainContents = JSON.stringify(config, null, 2).replace(/['"]%%/g, "").replace(/%%['"]/g, ""), imports = [], finalPrefixes = [...prefixes];
794
+ custom.framework.includes("path.dirname(") && imports.push("import path from 'node:path';"), isTypescript ? imports.push(`import type { StorybookConfig } from '${frameworkPackage}';`) : finalPrefixes.push(`/** @type { import('${frameworkPackage}').StorybookConfig } */`);
795
+ let mainJsContents = "";
796
+ mainJsContents = mainConfigTemplate.replace("<<import>>", `${imports.join(`
797
+
798
+ `)}
799
+
800
+ `).replace("<<prefix>>", finalPrefixes.length > 0 ? `${finalPrefixes.join(`
801
+
802
+ `)}
803
+ ` : "").replace("<<type>>", isTypescript ? ": StorybookConfig" : "").replace("<<mainContents>>", mainContents);
804
+ let mainPath = `./${storybookConfigFolder}/main.${isTypescript ? "ts" : "js"}`;
805
+ return await writeFile(mainPath, mainJsContents, { encoding: "utf8" }), { mainPath };
806
+ }
807
+ async function configurePreview(options) {
808
+ let { prefix: frameworkPrefix = "" } = options.frameworkPreviewParts || {}, isTypescript = options.language === SupportedLanguage2.TYPESCRIPT, isJsx = [SupportedRenderer.REACT, SupportedRenderer.REACT_NATIVE].includes(
809
+ options.renderer
810
+ ), previewConfigPath = `./${options.storybookConfigFolder}/preview.${isTypescript ? "ts" : "js"}${isJsx ? "x" : ""}`;
811
+ if (await pathExists(previewConfigPath))
812
+ return { previewConfigPath };
813
+ let frameworkPackage = options.frameworkPackage, prefix = [
814
+ isTypescript && frameworkPackage ? `import type { Preview } from '${frameworkPackage}'` : "",
815
+ frameworkPrefix
816
+ ].filter(Boolean).join(`
817
+ `), preview = "";
818
+ return preview = dedent5`
819
+ ${prefix}${prefix.length > 0 ? `
820
+ ` : ""}
821
+ ${!isTypescript && frameworkPackage ? `/** @type { import('${frameworkPackage}').Preview } */
822
+ ` : ""}const preview${isTypescript ? ": Preview" : ""} = {
823
+ parameters: {
824
+ controls: {
825
+ matchers: {
826
+ color: /(background|color)$/i,
827
+ date: /Date$/i,
828
+ },
829
+ },
830
+ },
831
+ };
832
+
833
+ export default preview;
834
+ `.replace(`
835
+ `, "").trim(), await writeFile(previewConfigPath, preview, { encoding: "utf8" }), { previewConfigPath };
836
+ }
837
+
838
+ // src/create/generators/baseGenerator.ts
839
+ var defaultOptions = {
840
+ extraPackages: [],
841
+ extraAddons: [],
842
+ staticDir: void 0,
843
+ addScripts: !0,
844
+ addComponents: !0,
845
+ extraMain: void 0,
846
+ extensions: void 0,
847
+ componentsDestinationPath: void 0,
848
+ storybookConfigFolder: ".forkbook",
849
+ installFrameworkPackages: !0
850
+ }, getPackageByValue = (type, value, packages) => {
851
+ let foundPackage = value ? Object.entries(packages).find(([key, pkgValue]) => pkgValue === value)?.[0] : void 0;
852
+ if (foundPackage)
853
+ return foundPackage;
854
+ throw new Error(
855
+ dedent6`
856
+ Could not find ${type} package for ${value}.
857
+ Make sure this package exists, and if it does, please file an issue as this might be a bug in Forkbook.
858
+ `
859
+ );
860
+ }, applyGetAbsolutePathWrapper = (packageName) => isCorePackage(packageName) ? packageName : `%%getAbsolutePath('${packageName}')%%`, applyAddonGetAbsolutePathWrapper = (pkg) => {
861
+ if (typeof pkg == "string")
862
+ return applyGetAbsolutePathWrapper(pkg);
863
+ let obj = { ...pkg };
864
+ return obj.name = applyGetAbsolutePathWrapper(pkg.name), obj;
865
+ }, getFrameworkDetails = ({
866
+ framework,
867
+ shouldApplyRequireWrapperOnPackageNames
868
+ }) => {
869
+ let frameworkPackage = getPackageByValue("framework", framework, frameworkPackages), frameworkPackagePath = shouldApplyRequireWrapperOnPackageNames ? applyGetAbsolutePathWrapper(frameworkPackage) : frameworkPackage;
870
+ return {
871
+ frameworkPackage,
872
+ frameworkPackagePath
873
+ };
874
+ }, hasFrameworkTemplates = (framework) => framework ? [
875
+ SupportedFramework2.NEXTJS_VITE,
876
+ SupportedFramework2.REACT_VITE
877
+ ].includes(framework) : !1;
878
+ async function baseGenerator(packageManager, npmOptions, {
879
+ language,
880
+ builder,
881
+ framework,
882
+ renderer,
883
+ features,
884
+ dependencyCollector,
885
+ storybookVersionSpecifier
886
+ }, _options) {
887
+ let options = { ...defaultOptions, ..._options }, shouldApplyRequireWrapperOnPackageNames = packageManager.isStorybookInMonorepo(), taskLog = prompt5.taskLog({
888
+ id: "base-generator",
889
+ title: "Generating Forkbook configuration"
890
+ }), { frameworkPackagePath, frameworkPackage } = getFrameworkDetails({
891
+ framework,
892
+ shouldApplyRequireWrapperOnPackageNames
893
+ }), {
894
+ extraAddons = [],
895
+ extraPackages,
896
+ staticDir,
897
+ addScripts,
898
+ addComponents,
899
+ extraMain,
900
+ extensions,
901
+ storybookConfigFolder,
902
+ componentsDestinationPath,
903
+ installFrameworkPackages
904
+ } = {
905
+ ...defaultOptions,
906
+ ...options
907
+ }, addonManager = new AddonService(), { addonsForMain: addons, addonPackages } = addonManager.configureAddons(
908
+ features,
909
+ extraAddons
910
+ ), { packageJson } = packageManager.primaryPackageJson, installedDependencies = new Set(
911
+ Object.keys({ ...packageJson.dependencies, ...packageJson.devDependencies })
912
+ ), extraPackagesToInstall = typeof extraPackages == "function" ? await extraPackages({
913
+ builder
914
+ }) : extraPackages, allPackages = [
915
+ "@aussieljk/forkbook",
916
+ ...installFrameworkPackages ? [frameworkPackage] : [],
917
+ ...addonPackages,
918
+ ...extraPackagesToInstall || []
919
+ ].filter((pkg) => pkg && (pkg === "@aussieljk/forkbook" || !isCorePackage(pkg))), packagesToInstall = [...new Set(allPackages)].filter(
920
+ (packageToInstall) => !installedDependencies.has(getPackageDetails2(packageToInstall)[0])
921
+ ), eslintPluginPackage = null;
922
+ try {
923
+ if (!isCI3()) {
924
+ let { hasEslint, isStorybookPluginInstalled, isFlatConfig, eslintConfigFile } = (
925
+ // TODO: Investigate why packageManager type does not match on CI
926
+ await extractEslintInfo(packageManager)
927
+ );
928
+ hasEslint && !isStorybookPluginInstalled && (eslintPluginPackage = "eslint-plugin-storybook", packagesToInstall.push(eslintPluginPackage), taskLog.message("- Configuring ESLint plugin"), await configureEslintPlugin({
929
+ eslintConfigFile,
930
+ // TODO: Investigate why packageManager type does not match on CI
931
+ packageManager,
932
+ isFlatConfig
933
+ }));
934
+ }
935
+ } catch {
936
+ }
937
+ let versionedPackages = await packageManager.getVersionedPackages(
938
+ packagesToInstall,
939
+ { storybookVersionSpecifier }
940
+ );
941
+ versionedPackages.length > 0 && (npmOptions.type === "devDependencies" ? dependencyCollector.addDevDependencies(versionedPackages) : dependencyCollector.addDependencies(versionedPackages)), await mkdir(`./${storybookConfigFolder}`, { recursive: !0 });
942
+ let prefixes = shouldApplyRequireWrapperOnPackageNames ? [
943
+ 'import { dirname } from "path"',
944
+ 'import { fileURLToPath } from "url"',
945
+ language === SupportedLanguage3.JAVASCRIPT ? dedent6`/**
946
+ * This function is used to resolve the absolute path of a package.
947
+ * It is needed in projects that are set up within a monorepo.
948
+ */
949
+ function getAbsolutePath(value) {
950
+ return dirname(fileURLToPath(import.meta.resolve(\`\${value}/package.json\`)))
951
+ }` : dedent6`/**
952
+ * This function is used to resolve the absolute path of a package.
953
+ * It is needed in projects that are set up within a monorepo.
954
+ */
955
+ function getAbsolutePath(value: string) {
956
+ return dirname(fileURLToPath(import.meta.resolve(\`\${value}/package.json\`)))
957
+ }`
958
+ ] : [], configurationFileExtension = language === SupportedLanguage3.TYPESCRIPT ? "ts" : "js";
959
+ if (taskLog.message(`- Configuring main.${configurationFileExtension}`), await configureMain({
960
+ framework: frameworkPackagePath,
961
+ features,
962
+ frameworkPackage,
963
+ prefixes,
964
+ storybookConfigFolder,
965
+ addons: shouldApplyRequireWrapperOnPackageNames ? addons.map((addon) => applyAddonGetAbsolutePathWrapper(addon)) : addons,
966
+ extensions,
967
+ language,
968
+ ...staticDir ? { staticDirs: [join("..", staticDir)] } : null,
969
+ ...extraMain
970
+ }), taskLog.message(`- Configuring preview.${configurationFileExtension}`), await configurePreview({
971
+ frameworkPreviewParts: _options.frameworkPreviewParts,
972
+ storybookConfigFolder,
973
+ language,
974
+ frameworkPackage,
975
+ renderer
976
+ }), addScripts && (taskLog.message("- Adding Forkbook command to package.json"), packageManager.addStorybookCommandInScripts({
977
+ port: 6006
978
+ })), addComponents) {
979
+ let templateLocation = hasFrameworkTemplates(framework) ? framework : renderer;
980
+ invariant(templateLocation, `Could not find template location for ${framework} or ${renderer}`), taskLog.message("- Copying framework templates"), await copyTemplateFiles({
981
+ templateLocation,
982
+ packageManager,
983
+ language,
984
+ destination: componentsDestinationPath,
985
+ commonAssetsDir: join(
986
+ resolvePackageDir("@aussieljk/forkbook"),
987
+ "assets/create/rendererAssets/common"
988
+ ),
989
+ features
990
+ });
991
+ }
992
+ return taskLog.success("Forkbook configuration generated", { showLog: !0 }), {
993
+ configDir: storybookConfigFolder,
994
+ storybookCommand: _options.storybookCommand,
995
+ shouldRunDev: _options.shouldRunDev
996
+ };
997
+ }
998
+
999
+ // src/create/commands/GeneratorExecutionCommand.ts
1000
+ var GeneratorExecutionCommand = class {
1001
+ /** Execute generator for the detected project type */
1002
+ constructor(dependencyCollector, jsPackageManager, addonService = new AddonService(), telemetryService = new TelemetryService()) {
1003
+ this.dependencyCollector = dependencyCollector;
1004
+ this.jsPackageManager = jsPackageManager;
1005
+ this.addonService = addonService;
1006
+ this.telemetryService = telemetryService;
1007
+ /** Execute the project-specific generator */
1008
+ this.executeProjectGenerator = async ({
1009
+ projectType,
1010
+ frameworkInfo,
1011
+ options,
1012
+ selectedFeatures,
1013
+ language
1014
+ }) => {
1015
+ let generator = generatorRegistry.get(projectType);
1016
+ if (!generator)
1017
+ throw new Error(`No generator found for project type: ${projectType}`);
1018
+ let npmOptions = {
1019
+ type: "devDependencies",
1020
+ skipInstall: options.skipInstall
1021
+ }, generatorModule = generator, frameworkOptions = await generatorModule.configure(this.jsPackageManager, {
1022
+ framework: frameworkInfo.framework,
1023
+ renderer: frameworkInfo.renderer,
1024
+ builder: frameworkInfo.builder,
1025
+ language,
1026
+ storybookVersionSpecifier: options.storybookVersionSpecifier,
1027
+ telemetryService: this.telemetryService,
1028
+ linkable: !!options.linkable,
1029
+ features: selectedFeatures,
1030
+ dependencyCollector: this.dependencyCollector,
1031
+ yes: options.yes
1032
+ }), generatorOptions = {
1033
+ language,
1034
+ builder: frameworkInfo.builder,
1035
+ framework: frameworkInfo.framework,
1036
+ renderer: frameworkInfo.renderer,
1037
+ storybookVersionSpecifier: options.storybookVersionSpecifier,
1038
+ linkable: !!options.linkable,
1039
+ yes: !!options.yes,
1040
+ projectType,
1041
+ features: selectedFeatures,
1042
+ dependencyCollector: this.dependencyCollector
1043
+ }, postInstall2 = generatorModule.postInstall ? async () => {
1044
+ await generatorModule.postInstall?.({ packageManager: this.jsPackageManager });
1045
+ } : void 0;
1046
+ if (frameworkOptions.skipGenerator)
1047
+ return generatorModule.postConfigure && await generatorModule.postConfigure({ packageManager: this.jsPackageManager }), {
1048
+ shouldRunDev: frameworkOptions.shouldRunDev,
1049
+ storybookCommand: frameworkOptions.storybookCommand,
1050
+ extraAddons: [],
1051
+ postInstall: postInstall2
1052
+ };
1053
+ let extraAddons = this.addonService.getAddonsForFeatures(selectedFeatures), generatorResult = await baseGenerator(
1054
+ this.jsPackageManager,
1055
+ npmOptions,
1056
+ generatorOptions,
1057
+ {
1058
+ ...frameworkOptions,
1059
+ extraAddons: [...frameworkOptions.extraAddons ?? [], ...extraAddons]
1060
+ }
1061
+ );
1062
+ return generatorModule.postConfigure && await generatorModule.postConfigure({ packageManager: this.jsPackageManager }), {
1063
+ ...generatorResult,
1064
+ extraAddons,
1065
+ postInstall: postInstall2
1066
+ };
1067
+ };
1068
+ }
1069
+ async execute({
1070
+ projectType,
1071
+ options,
1072
+ frameworkInfo,
1073
+ selectedFeatures,
1074
+ language
1075
+ }) {
1076
+ let { postInstall: postInstall2, ...generatorResult } = await this.executeProjectGenerator({
1077
+ projectType,
1078
+ frameworkInfo,
1079
+ options,
1080
+ selectedFeatures,
1081
+ language
1082
+ });
1083
+ return {
1084
+ ...generatorResult,
1085
+ configDir: "configDir" in generatorResult ? generatorResult.configDir : void 0,
1086
+ storybookCommand: generatorResult.storybookCommand !== void 0 ? generatorResult.storybookCommand : this.jsPackageManager.getRunCommand("forkbook"),
1087
+ /**
1088
+ * Hook to run after dependencies are installed. Optional — only the generators that need to do
1089
+ * something after `installDependencies` will set this.
1090
+ */
1091
+ postInstall: postInstall2
1092
+ };
1093
+ }
1094
+ }, executeGeneratorExecution = ({
1095
+ dependencyCollector,
1096
+ packageManager,
1097
+ ...options
1098
+ }) => new GeneratorExecutionCommand(dependencyCollector, packageManager).execute(options);
1099
+
1100
+ // src/create/commands/AddonConfigurationCommand.ts
1101
+ import { AddonVitestService as AddonVitestService2 } from "@aussieljk/forkbook/internal/cli";
1102
+ import { CLI_COLORS as CLI_COLORS2, logger as logger9, prompt as prompt6 } from "@aussieljk/forkbook/internal/node-logger";
1103
+ import { ErrorCollector } from "@aussieljk/forkbook/internal/telemetry";
1104
+ import { dedent as dedent7 } from "ts-dedent";
1105
+ var ADDON_INSTALLATION_INSTRUCTIONS = {
1106
+ "@aussieljk/forkbook/addon-vitest": "https://storybook.js.org/docs/writing-tests/integrations/vitest-addon#manual-setup-advanced"
1107
+ }, AddonConfigurationCommand = class {
1108
+ constructor(packageManager, commandOptions, addonVitestService = new AddonVitestService2(packageManager), telemetryService = new TelemetryService()) {
1109
+ this.packageManager = packageManager;
1110
+ this.commandOptions = commandOptions;
1111
+ this.addonVitestService = addonVitestService;
1112
+ this.telemetryService = telemetryService;
1113
+ }
1114
+ /** Execute addon configuration */
1115
+ async execute({
1116
+ addons,
1117
+ configDir
1118
+ }) {
1119
+ if (!configDir || addons.length === 0)
1120
+ return { status: "success" };
1121
+ try {
1122
+ let { hasFailures, addonResults } = await this.configureAddons(configDir, addons);
1123
+ if (addonResults.has("@aussieljk/forkbook/addon-vitest")) {
1124
+ let { result } = await this.addonVitestService.installPlaywright({
1125
+ yes: this.commandOptions.yes,
1126
+ useRemotePkg: !!this.commandOptions.skipInstall
1127
+ });
1128
+ await this.telemetryService.trackPlaywrightPromptDecision(result);
1129
+ }
1130
+ return hasFailures && this.logManualAddonInstructions(
1131
+ addons.filter((addon) => addonResults.get(addon)?.result === "failed")
1132
+ ), { status: hasFailures ? "failed" : "success" };
1133
+ } catch (e) {
1134
+ return logger9.error("Unexpected error during addon configuration:"), logger9.error(e), { status: "failed" };
1135
+ }
1136
+ }
1137
+ getAddonsWithInstructions(addons) {
1138
+ return addons.filter((addon) => ADDON_INSTALLATION_INSTRUCTIONS[addon]);
1139
+ }
1140
+ logManualAddonInstructions(addons) {
1141
+ let addonsWithInstructions = this.getAddonsWithInstructions(addons);
1142
+ addonsWithInstructions.length > 0 && logger9.warn(dedent7`
1143
+ The following addons couldn't be configured:
1144
+
1145
+ ${addonsWithInstructions.map((addon) => {
1146
+ let manualInstructionLink = ADDON_INSTALLATION_INSTRUCTIONS[addon];
1147
+ return `- ${addon}: ${manualInstructionLink}`;
1148
+ }).join(`
1149
+ `)}
1150
+
1151
+ ${addonsWithInstructions.length > 0 ? "Please follow each addon's configuration instructions manually." : ""}
1152
+ `);
1153
+ }
1154
+ /** Configure test addons */
1155
+ async configureAddons(configDir, addons) {
1156
+ let { postinstallAddon } = await import("./postinstallAddon-GYGMWDL6.js"), task = prompt6.taskLog({
1157
+ id: "configure-addons",
1158
+ title: "Configuring addons..."
1159
+ }), addonResults = /* @__PURE__ */ new Map();
1160
+ for (let addon of addons)
1161
+ try {
1162
+ task.message(`Configuring ${addon}...`);
1163
+ let options = {
1164
+ packageManager: this.packageManager.type,
1165
+ configDir,
1166
+ yes: !0,
1167
+ skipInstall: !0,
1168
+ // Dependencies were installed in the preceding init step (unless the
1169
+ // user opted out), so nested `storybook` invocations can run the local
1170
+ // binary instead of fetching an ephemeral copy via dlx/npx.
1171
+ useRemotePkg: !!this.commandOptions.skipInstall,
1172
+ skipDependencyManagement: !0,
1173
+ logger: logger9,
1174
+ prompt: prompt6
1175
+ };
1176
+ addon === "@aussieljk/forkbook/addon-vitest" ? await postInstall(options) : await postinstallAddon(addon, options), task.message(`${addon} configured
1177
+ `), addonResults.set(addon, null);
1178
+ } catch (e) {
1179
+ logger9.debug(e), ErrorCollector.addError(e), addonResults.set(addon, e);
1180
+ }
1181
+ let hasFailures = [...addonResults.values()].some((result) => result !== null);
1182
+ return hasFailures ? task.error("Failed to configure addons") : task.success("Addons configured successfully"), addons.forEach((addon, index) => {
1183
+ let error = addonResults.get(addon);
1184
+ logger9.log(CLI_COLORS2.muted(error ? `\u274C ${addon}` : `\u2705 ${addon}`), {
1185
+ spacing: index === 0 ? 1 : 0
1186
+ });
1187
+ }), { hasFailures, addonResults };
1188
+ }
1189
+ }, executeAddonConfiguration = ({
1190
+ packageManager,
1191
+ options,
1192
+ ...rest
1193
+ }) => new AddonConfigurationCommand(packageManager, options).execute(rest);
1194
+
1195
+ // src/create/commands/DependencyInstallationCommand.ts
1196
+ import { AddonVitestService as AddonVitestService3 } from "@aussieljk/forkbook/internal/cli";
1197
+ import { logger as logger10, prompt as prompt7 } from "@aussieljk/forkbook/internal/node-logger";
1198
+ import { MinimumReleaseAgeHandledError as MinimumReleaseAgeHandledError2 } from "@aussieljk/forkbook/internal/server-errors";
1199
+ import { ErrorCollector as ErrorCollector2 } from "@aussieljk/forkbook/internal/telemetry";
1200
+ import { Feature as Feature5 } from "@aussieljk/forkbook/internal/types";
1201
+ var DependencyInstallationCommand = class {
1202
+ constructor(dependencyCollector, packageManager, addonVitestService = new AddonVitestService3(packageManager)) {
1203
+ this.dependencyCollector = dependencyCollector;
1204
+ this.packageManager = packageManager;
1205
+ this.addonVitestService = addonVitestService;
1206
+ }
1207
+ /** Execute dependency installation */
1208
+ async execute({
1209
+ skipInstall = !1,
1210
+ selectedFeatures
1211
+ }) {
1212
+ if (await this.collectAddonDependencies(selectedFeatures), !this.dependencyCollector.hasPackages() && skipInstall)
1213
+ return { status: "success" };
1214
+ let { dependencies, devDependencies } = this.dependencyCollector.getAllPackages(), task = prompt7.taskLog({
1215
+ id: "adding-dependencies",
1216
+ title: "Adding dependencies to package.json"
1217
+ });
1218
+ if (dependencies.length > 0 && (task.message(`Adding dependencies:
1219
+ ` + dependencies.map((dep) => `- ${dep}`).join(`
1220
+ `)), await this.packageManager.addDependencies(
1221
+ { type: "dependencies", skipInstall: !0 },
1222
+ dependencies
1223
+ )), devDependencies.length > 0 && (task.message(
1224
+ `Adding devDependencies:
1225
+ ` + devDependencies.map((dep) => `- ${dep}`).join(`
1226
+ `)
1227
+ ), await this.packageManager.addDependencies(
1228
+ { type: "devDependencies", skipInstall: !0 },
1229
+ devDependencies
1230
+ )), task.success("Dependencies added to package.json", { showLog: !0 }), !skipInstall && this.dependencyCollector.hasPackages())
1231
+ try {
1232
+ await this.packageManager.installDependencies();
1233
+ } catch (err) {
1234
+ if (err instanceof MinimumReleaseAgeHandledError2)
1235
+ throw err;
1236
+ return ErrorCollector2.addError(err), { status: "failed" };
1237
+ }
1238
+ return { status: "success" };
1239
+ }
1240
+ /**
1241
+ * Collect addon dependencies (the caller adds them to package.json and installs them afterwards).
1242
+ * For pnpm catalog workspaces this also registers the derived entries in pnpm-workspace.yaml so
1243
+ * the subsequent install can resolve their `catalog:` specifiers.
1244
+ */
1245
+ async collectAddonDependencies(selectedFeatures) {
1246
+ try {
1247
+ if (selectedFeatures.has(Feature5.TEST)) {
1248
+ let vitestDeps = await this.addonVitestService.collectDependencies();
1249
+ this.dependencyCollector.addDevDependencies(vitestDeps);
1250
+ }
1251
+ } catch (err) {
1252
+ logger10.warn(`Failed to collect addon dependencies: ${err}`);
1253
+ }
1254
+ }
1255
+ }, executeDependencyInstallation = ({
1256
+ dependencyCollector,
1257
+ packageManager,
1258
+ ...props
1259
+ }) => new DependencyInstallationCommand(dependencyCollector, packageManager).execute(props);
1260
+
1261
+ // src/create/commands/FinalizationCommand.ts
1262
+ import fs from "node:fs/promises";
1263
+ import { getProjectRoot as getProjectRoot3 } from "@aussieljk/forkbook/internal/common";
1264
+ import { CLI_COLORS as CLI_COLORS3, logTracker, logger as logger11 } from "@aussieljk/forkbook/internal/node-logger";
1265
+ import { ErrorCollector as ErrorCollector3 } from "@aussieljk/forkbook/internal/telemetry";
1266
+ import { dedent as dedent8 } from "ts-dedent";
1267
+ var FinalizationCommand = class {
1268
+ constructor(options) {
1269
+ this.options = options;
1270
+ }
1271
+ /** Execute finalization steps */
1272
+ async execute({ storybookCommand }) {
1273
+ await this.updateGitignore(), ErrorCollector3.getErrors().length > 0 ? await this.printFailureMessage(storybookCommand) : this.printSuccessMessage(storybookCommand);
1274
+ }
1275
+ /** Update .gitignore with Forkbook-specific entries */
1276
+ async updateGitignore() {
1277
+ let foundGitIgnoreFile = up(".gitignore"), rootDirectory = getProjectRoot3();
1278
+ if (!foundGitIgnoreFile || !foundGitIgnoreFile.includes(rootDirectory))
1279
+ return;
1280
+ let contents = await fs.readFile(foundGitIgnoreFile, "utf-8"), hasStorybookLog = contents.includes("*storybook.log"), hasStorybookStatic = contents.includes("storybook-static"), linesToAdd = [
1281
+ hasStorybookLog ? "" : "*storybook.log",
1282
+ hasStorybookStatic ? "" : "storybook-static"
1283
+ ].filter(Boolean).join(`
1284
+ `);
1285
+ linesToAdd && await fs.appendFile(foundGitIgnoreFile, `
1286
+ ${linesToAdd}
1287
+ `);
1288
+ }
1289
+ async printFailureMessage(storybookCommand) {
1290
+ logger11.warn(
1291
+ "Forkbook setup completed, but some non-blocking errors occurred. Please check the log file below for details."
1292
+ ), this.printNextSteps(storybookCommand);
1293
+ try {
1294
+ let logFile = await logTracker.writeToFile(this.options.logfile);
1295
+ logger11.warn(`Debug logs are written to: ${logFile}`);
1296
+ } catch {
1297
+ }
1298
+ }
1299
+ getSetupSkillPromptText() {
1300
+ return `Run \`${this.options.setupSkillCommand}\` and follow its instructions precisely.`;
1301
+ }
1302
+ printSuccessMessage(storybookCommand) {
1303
+ this.options.showAgentFollowUp ? logger11.step(
1304
+ CLI_COLORS3.storybook(
1305
+ dedent8`Forkbook is installed but is not entirely set up yet.
1306
+ To finish setting up, now run \`${this.options.setupSkillCommand}\` and follow its instructions precisely.`
1307
+ )
1308
+ ) : logger11.step(CLI_COLORS3.success("Forkbook was successfully installed in your project!")), this.printNextSteps(storybookCommand);
1309
+ }
1310
+ printNextSteps(storybookCommand) {
1311
+ storybookCommand && logger11.log(`To run Forkbook, run ${CLI_COLORS3.cta(storybookCommand)}. CTRL+C to stop.`), this.options.showAiInstructions ? logger11.log(dedent8`
1312
+ Official documentation reference: ${CLI_COLORS3.cta("https://storybook.js.org/llms.txt")}
1313
+ `) : logger11.log(dedent8`
1314
+ Want to learn more about Forkbook? ${CLI_COLORS3.cta("https://storybook.js.org/")}
1315
+ Having trouble or want to chat? ${CLI_COLORS3.cta("https://discord.gg/storybook/")}
1316
+ `), this.options.showAiInstructions && logger11.step(dedent8`To finalize setting up with AI, paste this prompt to your AI agent:
1317
+
1318
+ ${CLI_COLORS3.storybook(this.getSetupSkillPromptText())}
1319
+ `);
1320
+ }
1321
+ }, executeFinalization = ({
1322
+ logfile,
1323
+ showAgentFollowUp,
1324
+ showAiInstructions,
1325
+ setupSkillCommand,
1326
+ ...params
1327
+ }) => new FinalizationCommand({
1328
+ logfile,
1329
+ showAgentFollowUp,
1330
+ showAiInstructions,
1331
+ setupSkillCommand
1332
+ }).execute(params);
1333
+
1334
+ // src/create/dependency-collector.ts
1335
+ var DependencyCollector = class {
1336
+ constructor() {
1337
+ this.packages = /* @__PURE__ */ new Map([
1338
+ ["dependencies", /* @__PURE__ */ new Map()],
1339
+ ["devDependencies", /* @__PURE__ */ new Map()]
1340
+ ]);
1341
+ }
1342
+ /** Add development dependencies */
1343
+ addDevDependencies(packageNames) {
1344
+ this.add("devDependencies", packageNames);
1345
+ }
1346
+ /** Add regular dependencies */
1347
+ addDependencies(packageNames) {
1348
+ this.add("dependencies", packageNames);
1349
+ }
1350
+ /** Get all packages across all types */
1351
+ getAllPackages() {
1352
+ return {
1353
+ dependencies: this.getDependencies(),
1354
+ devDependencies: this.getDevDependencies()
1355
+ };
1356
+ }
1357
+ /** Check if collector has any packages */
1358
+ hasPackages() {
1359
+ return this.packages.get("dependencies").size > 0 || this.packages.get("devDependencies").size > 0;
1360
+ }
1361
+ /** Get all version conflicts across all dependency types */
1362
+ getVersionConflicts() {
1363
+ let conflicts = [];
1364
+ for (let [type, typeMap] of this.packages.entries()) {
1365
+ let packageNames = /* @__PURE__ */ new Map();
1366
+ typeMap.forEach((version, name) => {
1367
+ let versions2 = packageNames.get(name) || [];
1368
+ versions2.push(version), packageNames.set(name, versions2);
1369
+ }), packageNames.forEach((versions2, name) => {
1370
+ versions2.length > 1 && new Set(versions2).size > 1 && conflicts.push({
1371
+ packageName: name,
1372
+ existingVersion: versions2[0],
1373
+ newVersion: versions2[versions2.length - 1],
1374
+ type
1375
+ });
1376
+ });
1377
+ }
1378
+ return conflicts;
1379
+ }
1380
+ /** Merge dependencies from another collector */
1381
+ merge(other) {
1382
+ let { dependencies, devDependencies } = other.getAllPackages();
1383
+ this.addDependencies(dependencies), this.addDevDependencies(devDependencies);
1384
+ }
1385
+ /** Validate that all packages have valid version specifiers */
1386
+ validate() {
1387
+ let errors = [];
1388
+ for (let [type, typeMap] of this.packages.entries())
1389
+ typeMap.forEach((version, name) => {
1390
+ (!name || name.trim() === "") && errors.push(`Invalid package name in ${type}: empty or whitespace`), version === "" && errors.push(`Package ${name} in ${type} has empty version`);
1391
+ });
1392
+ return {
1393
+ valid: errors.length === 0,
1394
+ errors
1395
+ };
1396
+ }
1397
+ /** Get count of packages by type */
1398
+ getPackageCount(type) {
1399
+ return type ? this.packages.get(type).size : this.packages.get("dependencies").size + this.packages.get("devDependencies").size;
1400
+ }
1401
+ /**
1402
+ * Add packages to the collector
1403
+ *
1404
+ * @param type - The dependency type (dependencies or devDependencies)
1405
+ * @param packageNames - Array of package names, optionally with version specifiers (e.g.,
1406
+ * 'react@18.0.0')
1407
+ */
1408
+ add(type, packageNames) {
1409
+ let typeMap = this.packages.get(type);
1410
+ for (let pkg of packageNames) {
1411
+ let { name, version } = this.parsePackage(pkg);
1412
+ typeMap.has(name) ? version && typeMap.set(name, version) : typeMap.set(name, version || "latest");
1413
+ }
1414
+ }
1415
+ /** Get all packages with their versions for a specific type */
1416
+ getPackages(type) {
1417
+ let typeMap = this.packages.get(type);
1418
+ return Array.from(typeMap.entries()).map(
1419
+ ([name, version]) => version === "latest" ? name : `${name}@${version}`
1420
+ );
1421
+ }
1422
+ /** Get all development dependencies */
1423
+ getDevDependencies() {
1424
+ return this.getPackages("devDependencies");
1425
+ }
1426
+ /** Get all regular dependencies */
1427
+ getDependencies() {
1428
+ return this.getPackages("dependencies");
1429
+ }
1430
+ /**
1431
+ * Parse a package string into name and version
1432
+ *
1433
+ * @param pkg - Package string (e.g., 'react@18.0.0' or 'react')
1434
+ */
1435
+ parsePackage(pkg) {
1436
+ let scopedMatch = pkg.match(/^(@[^@]+\/[^@]+)(?:@(.+))?$/);
1437
+ if (scopedMatch)
1438
+ return {
1439
+ name: scopedMatch[1],
1440
+ version: scopedMatch[2]
1441
+ };
1442
+ let regularMatch = pkg.match(/^([^@]+)(?:@(.+))?$/);
1443
+ return regularMatch ? {
1444
+ name: regularMatch[1],
1445
+ version: regularMatch[2]
1446
+ } : { name: pkg };
1447
+ }
1448
+ };
1449
+
1450
+ // src/create/generators/NEXTJS/index.ts
1451
+ import { existsSync as existsSync2 } from "node:fs";
1452
+ import { join as join2 } from "node:path";
1453
+ import { ProjectType as ProjectType2 } from "@aussieljk/forkbook/internal/cli";
1454
+ import {
1455
+ SupportedBuilder as SupportedBuilder2,
1456
+ SupportedFramework as SupportedFramework3,
1457
+ SupportedRenderer as SupportedRenderer2
1458
+ } from "@aussieljk/forkbook/internal/types";
1459
+ var NEXTJS_default = {
1460
+ metadata: {
1461
+ projectType: ProjectType2.NEXTJS,
1462
+ renderer: SupportedRenderer2.REACT,
1463
+ framework: SupportedFramework3.NEXTJS_VITE,
1464
+ builderOverride: SupportedBuilder2.VITE
1465
+ },
1466
+ configure: async () => {
1467
+ let staticDir;
1468
+ return existsSync2(join2(process.cwd(), "public")) && (staticDir = "public"), {
1469
+ staticDir,
1470
+ extraPackages: ["vite"]
1471
+ };
1472
+ }
1473
+ };
1474
+
1475
+ // src/create/generators/REACT/index.ts
1476
+ import { ProjectType as ProjectType3 } from "@aussieljk/forkbook/internal/cli";
1477
+ import { SupportedLanguage as SupportedLanguage4, SupportedRenderer as SupportedRenderer3 } from "@aussieljk/forkbook/internal/types";
1478
+ var REACT_default = {
1479
+ metadata: {
1480
+ projectType: ProjectType3.REACT,
1481
+ renderer: SupportedRenderer3.REACT
1482
+ },
1483
+ configure: async (packageManager, { language }) => ({
1484
+ extraPackages: language === SupportedLanguage4.JAVASCRIPT ? ["prop-types"] : []
1485
+ })
1486
+ };
1487
+
1488
+ // src/create/generators/REACT_NATIVE/index.ts
1489
+ import { join as join4 } from "node:path";
1490
+ import { ProjectType as ProjectType4, copyTemplateFiles as copyTemplateFiles2 } from "@aussieljk/forkbook/internal/cli";
1491
+ import { executeCommand as executeCommand2 } from "@aussieljk/forkbook/internal/common";
1492
+ import { CLI_COLORS as CLI_COLORS4, logger as logger13, prompt as prompt9 } from "@aussieljk/forkbook/internal/node-logger";
1493
+ import {
1494
+ SupportedBuilder as SupportedBuilder3,
1495
+ SupportedLanguage as SupportedLanguage6,
1496
+ SupportedRenderer as SupportedRenderer4
1497
+ } from "@aussieljk/forkbook/internal/types";
1498
+ import { dedent as dedent9 } from "ts-dedent";
1499
+
1500
+ // src/create/generators/REACT_NATIVE/generateEntrypoint.ts
1501
+ import { mkdir as mkdir2, readFile, writeFile as writeFile2 } from "node:fs/promises";
1502
+ import path, { join as join3 } from "node:path";
1503
+ import { SupportedLanguage as SupportedLanguage5 } from "@aussieljk/forkbook/internal/types";
1504
+ var ENTRYPOINT_TEMPLATE_DIR = join3(
1505
+ resolvePackageDir("@aussieljk/forkbook"),
1506
+ "assets/create/templates/react-native"
1507
+ ), getEntrypointExtension = (language) => language === SupportedLanguage5.TYPESCRIPT ? "ts" : "js", getEntrypointTemplatePath = (templateVariant = "default") => join3(ENTRYPOINT_TEMPLATE_DIR, templateVariant === "expo" ? "index.expo.js" : "index.js"), generateReactNativeEntrypoint = async ({
1508
+ language,
1509
+ templateVariant = "default",
1510
+ cwd = process.cwd()
1511
+ }) => {
1512
+ let extension = getEntrypointExtension(language), templatePath = getEntrypointTemplatePath(templateVariant), targetDir = path.join(cwd, RN_STORYBOOK_DIR), targetPath = path.join(targetDir, `index.${extension}`), templateContents = await readFile(templatePath, "utf-8");
1513
+ return await mkdir2(targetDir, { recursive: !0 }), await writeFile2(targetPath, templateContents, "utf-8"), {
1514
+ targetPath,
1515
+ extension
1516
+ };
1517
+ };
1518
+
1519
+ // src/create/generators/REACT_NATIVE/generateScripts.ts
1520
+ var STORYBOOK_ENV_ASSIGNMENT = "STORYBOOK_ENABLED=true", STORYBOOK_ENV_PREFIX = `cross-env ${STORYBOOK_ENV_ASSIGNMENT}`, STORYBOOK_ENV_PATTERN = /(?:^|\s)STORYBOOK_ENABLED=/, CROSS_ENV_PREFIX_PATTERN = /^(cross-env(?:-shell)?\s+)/, withStorybookEnv = (scriptValue) => {
1521
+ let normalizedScriptValue = scriptValue.trim();
1522
+ return STORYBOOK_ENV_PATTERN.test(normalizedScriptValue) ? normalizedScriptValue : CROSS_ENV_PREFIX_PATTERN.test(normalizedScriptValue) ? normalizedScriptValue.replace(
1523
+ CROSS_ENV_PREFIX_PATTERN,
1524
+ `$1${STORYBOOK_ENV_ASSIGNMENT} `
1525
+ ) : `${STORYBOOK_ENV_PREFIX} ${normalizedScriptValue}`.trim();
1526
+ }, deriveStorybookPlatformScripts = (scripts) => {
1527
+ let scriptsToAdd = {}, missingBaseScripts = [], iosScript = typeof scripts?.ios == "string" ? scripts.ios.trim() : "";
1528
+ iosScript ? scriptsToAdd["storybook:ios"] = withStorybookEnv(iosScript) : missingBaseScripts.push("ios");
1529
+ let androidScript = typeof scripts?.android == "string" ? scripts.android.trim() : "";
1530
+ return androidScript ? scriptsToAdd["storybook:android"] = withStorybookEnv(androidScript) : missingBaseScripts.push("android"), { scriptsToAdd, missingBaseScripts };
1531
+ };
1532
+
1533
+ // src/create/generators/REACT_NATIVE/metroConfig.ts
1534
+ import { access, readFile as readFile2, writeFile as writeFile3 } from "node:fs/promises";
1535
+ import path2 from "node:path";
1536
+ import { parser, recast, types as t } from "@aussieljk/forkbook/internal/babel";
1537
+ import { logger as logger12, prompt as prompt8 } from "@aussieljk/forkbook/internal/node-logger";
1538
+ var METRO_CONFIG_CANDIDATES = ["metro.config.ts", "metro.config.js", "metro.config.cjs"], METRO_SETUP_DOCS_LINK = "https://storybookjs.github.io/react-native/docs/intro/configuration/metro-configuration", METRO_FALLBACK_COMMENT_MARKER = "storybook-react-native-metro-codemod-fallback", EXPO_CREATE_METRO_COMMAND = {
1539
+ command: "expo",
1540
+ args: ["customize", "metro.config.js"]
1541
+ }, STORYBOOK_PACKAGE_PATTERNS = [
1542
+ "'@storybook/",
1543
+ // @storybook/* scoped packages (single-quoted)
1544
+ '"@storybook/',
1545
+ // @storybook/* scoped packages (double-quoted)
1546
+ "'storybook'",
1547
+ // bare 'storybook' package specifier
1548
+ '"storybook"',
1549
+ // bare "storybook" package specifier
1550
+ "'storybook/",
1551
+ // storybook/* sub-path (single-quoted)
1552
+ '"storybook/'
1553
+ // storybook/* sub-path (double-quoted)
1554
+ ], hasStorybookPackage = (value) => value === "storybook" || value.startsWith("@storybook/") || value.startsWith("storybook/"), isAstNode = (value) => !!value && typeof value == "object" && "type" in value, getRequirePackageFromCallExpression = (callExpression) => {
1555
+ if (t.isIdentifier(callExpression.callee, { name: "require" })) {
1556
+ let [firstArgument] = callExpression.arguments;
1557
+ return t.isStringLiteral(firstArgument) ? firstArgument.value : null;
1558
+ }
1559
+ if (t.isMemberExpression(callExpression.callee) && t.isCallExpression(callExpression.callee.object)) {
1560
+ let objectCall = callExpression.callee.object;
1561
+ if (!t.isIdentifier(objectCall.callee, { name: "require" }))
1562
+ return null;
1563
+ let [firstArgument] = objectCall.arguments;
1564
+ return t.isStringLiteral(firstArgument) ? firstArgument.value : null;
1565
+ }
1566
+ return null;
1567
+ }, statementContainsStorybookCall = (statement) => {
1568
+ let visited = /* @__PURE__ */ new WeakSet(), queue = [statement];
1569
+ for (; queue.length > 0; ) {
1570
+ let current = queue.pop();
1571
+ if (!(!current || typeof current != "object") && !visited.has(current)) {
1572
+ if (visited.add(current), isAstNode(current) && t.isCallExpression(current)) {
1573
+ let packageName = getRequirePackageFromCallExpression(current);
1574
+ if (packageName && hasStorybookPackage(packageName))
1575
+ return !0;
1576
+ }
1577
+ if (Array.isArray(current)) {
1578
+ queue.push(...current);
1579
+ continue;
1580
+ }
1581
+ for (let value of Object.values(current))
1582
+ value && (typeof value == "object" || Array.isArray(value)) && queue.push(value);
1583
+ }
1584
+ }
1585
+ return !1;
1586
+ }, isModuleExportsTarget = (left) => t.isMemberExpression(left) && t.isIdentifier(left.object, { name: "module" }) && t.isIdentifier(left.property, { name: "exports" }), isWithStorybookCall = (node, withStorybookLocalName) => t.isCallExpression(node) && t.isIdentifier(node.callee, { name: withStorybookLocalName }), parseConfig = (source) => recast.parse(source, {
1587
+ parser: {
1588
+ parse(code) {
1589
+ return parser.parse(code, {
1590
+ sourceType: "unambiguous",
1591
+ plugins: ["jsx", "typescript", "decorators-legacy", "classProperties"]
1592
+ });
1593
+ }
1594
+ }
1595
+ }), usesEsmSyntax = (program) => program.body.some(
1596
+ (node) => t.isImportDeclaration(node) || t.isExportDefaultDeclaration(node) || t.isExportNamedDeclaration(node) || t.isExportAllDeclaration(node)
1597
+ ), containsStorybookImport = (source) => {
1598
+ try {
1599
+ let ast = parseConfig(source);
1600
+ for (let statement of ast.program.body)
1601
+ if (t.isImportDeclaration(statement) && hasStorybookPackage(statement.source.value) || t.isExportNamedDeclaration(statement) && statement.source && hasStorybookPackage(statement.source.value) || statementContainsStorybookCall(statement))
1602
+ return !0;
1603
+ } catch {
1604
+ return STORYBOOK_PACKAGE_PATTERNS.some((pattern) => source.includes(pattern));
1605
+ }
1606
+ return !1;
1607
+ }, hasWithStorybookBinding = (program) => {
1608
+ for (let statement of program.body) {
1609
+ if (t.isImportDeclaration(statement) && statement.source.value === "@storybook/react-native/withStorybook") {
1610
+ let withStorybookSpecifier = statement.specifiers.find(
1611
+ (specifier) => t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported, { name: "withStorybook" })
1612
+ );
1613
+ if (withStorybookSpecifier && t.isImportSpecifier(withStorybookSpecifier))
1614
+ return withStorybookSpecifier.local.name;
1615
+ }
1616
+ if (t.isVariableDeclaration(statement))
1617
+ for (let declaration of statement.declarations) {
1618
+ if (!t.isObjectPattern(declaration.id) || !t.isCallExpression(declaration.init) || !t.isIdentifier(declaration.init.callee, { name: "require" }))
1619
+ continue;
1620
+ let [firstArgument] = declaration.init.arguments;
1621
+ if (t.isStringLiteral(firstArgument) && firstArgument.value === "@storybook/react-native/withStorybook") {
1622
+ for (let property of declaration.id.properties)
1623
+ if (t.isObjectProperty(property) && t.isIdentifier(property.key, { name: "withStorybook" }) && t.isIdentifier(property.value))
1624
+ return property.value.name;
1625
+ }
1626
+ }
1627
+ }
1628
+ }, getBodyInsertionIndex = (program) => {
1629
+ for (let i = 0; i < program.body.length; i++) {
1630
+ let statement = program.body[i];
1631
+ if (!(t.isExpressionStatement(statement) && t.isStringLiteral(statement.expression)))
1632
+ return i;
1633
+ }
1634
+ return program.body.length;
1635
+ }, shiftFileLeadingComments = (fromNode, toNode) => {
1636
+ let from = fromNode, to = toNode, isFileLeading = (c) => typeof c.start == "number" && c.start === 0;
1637
+ if (Array.isArray(from.comments)) {
1638
+ let fileLeading = from.comments.filter((c) => c.leading && isFileLeading(c));
1639
+ fileLeading.length > 0 && (to.comments = [...fileLeading, ...to.comments ?? []], from.comments = from.comments.filter((c) => !(c.leading && isFileLeading(c))));
1640
+ }
1641
+ if (Array.isArray(from.leadingComments)) {
1642
+ let fileLeading = from.leadingComments.filter(isFileLeading);
1643
+ fileLeading.length > 0 && (to.leadingComments = [...fileLeading, ...to.leadingComments ?? []], from.leadingComments = from.leadingComments.filter((c) => !isFileLeading(c)));
1644
+ }
1645
+ }, injectWithStorybookImport = (program, useEsmImport) => {
1646
+ if (useEsmImport) {
1647
+ let importDeclaration = t.importDeclaration(
1648
+ [t.importSpecifier(t.identifier("withStorybook"), t.identifier("withStorybook"))],
1649
+ t.stringLiteral("@storybook/react-native/withStorybook")
1650
+ ), lastImportIndex = [...program.body].reverse().findIndex((statement) => t.isImportDeclaration(statement));
1651
+ if (lastImportIndex === -1) {
1652
+ let insertAt2 = getBodyInsertionIndex(program), nodeAtInsert2 = program.body[insertAt2];
1653
+ nodeAtInsert2 && shiftFileLeadingComments(nodeAtInsert2, importDeclaration), program.body.splice(insertAt2, 0, importDeclaration);
1654
+ return;
1655
+ }
1656
+ let insertAfter = program.body.length - lastImportIndex;
1657
+ program.body.splice(insertAfter, 0, importDeclaration);
1658
+ return;
1659
+ }
1660
+ let requireDeclaration = t.variableDeclaration("const", [
1661
+ t.variableDeclarator(
1662
+ t.objectPattern([
1663
+ t.objectProperty(t.identifier("withStorybook"), t.identifier("withStorybook"), !1, !0)
1664
+ ]),
1665
+ t.callExpression(t.identifier("require"), [
1666
+ t.stringLiteral("@storybook/react-native/withStorybook")
1667
+ ])
1668
+ )
1669
+ ]), insertAt = getBodyInsertionIndex(program), nodeAtInsert = program.body[insertAt];
1670
+ nodeAtInsert && shiftFileLeadingComments(nodeAtInsert, requireDeclaration), program.body.splice(insertAt, 0, requireDeclaration);
1671
+ }, prependMetroFallbackComment = (source) => source.includes(METRO_FALLBACK_COMMENT_MARKER) ? source : `/**
1672
+ * ${METRO_FALLBACK_COMMENT_MARKER}
1673
+ * Storybook could not automatically update this Metro config file.
1674
+ * Please follow the manual setup instructions:
1675
+ * ${METRO_SETUP_DOCS_LINK}
1676
+ */
1677
+ ${source}`, transformMetroConfigSource = (source, filePath) => {
1678
+ let ast = parseConfig(source), program = ast.program, withStorybookLocalName = hasWithStorybookBinding(program) ?? "withStorybook", matchedExport = !1, changed = !1;
1679
+ for (let statement of program.body) {
1680
+ if (t.isExpressionStatement(statement) && t.isAssignmentExpression(statement.expression)) {
1681
+ if (!isModuleExportsTarget(statement.expression.left))
1682
+ continue;
1683
+ if (matchedExport = !0, isWithStorybookCall(statement.expression.right, withStorybookLocalName))
1684
+ return { action: "already-configured" };
1685
+ statement.expression.right = t.callExpression(t.identifier(withStorybookLocalName), [
1686
+ statement.expression.right
1687
+ ]), changed = !0;
1688
+ continue;
1689
+ }
1690
+ if (t.isExportDefaultDeclaration(statement)) {
1691
+ if (matchedExport = !0, t.isFunctionDeclaration(statement.declaration)) {
1692
+ let functionExpression = t.functionExpression(
1693
+ statement.declaration.id,
1694
+ statement.declaration.params,
1695
+ statement.declaration.body,
1696
+ statement.declaration.generator,
1697
+ statement.declaration.async
1698
+ );
1699
+ functionExpression.returnType = statement.declaration.returnType ?? null, functionExpression.typeParameters = statement.declaration.typeParameters ?? null, statement.declaration = t.callExpression(t.identifier(withStorybookLocalName), [
1700
+ functionExpression
1701
+ ]), changed = !0;
1702
+ continue;
1703
+ }
1704
+ if (!t.isExpression(statement.declaration))
1705
+ return { action: "unsupported" };
1706
+ if (isWithStorybookCall(statement.declaration, withStorybookLocalName))
1707
+ return { action: "already-configured" };
1708
+ statement.declaration = t.callExpression(t.identifier(withStorybookLocalName), [
1709
+ statement.declaration
1710
+ ]), changed = !0;
1711
+ }
1712
+ }
1713
+ if (!matchedExport)
1714
+ return { action: "unsupported" };
1715
+ if (!changed)
1716
+ return { action: "already-configured" };
1717
+ if (!hasWithStorybookBinding(program)) {
1718
+ let shouldUseEsmImport = usesEsmSyntax(program) || filePath.endsWith(".mjs");
1719
+ injectWithStorybookImport(program, shouldUseEsmImport);
1720
+ }
1721
+ return {
1722
+ action: "updated",
1723
+ code: recast.print(ast, {
1724
+ quote: "single",
1725
+ trailingComma: !0,
1726
+ tabWidth: 2,
1727
+ wrapColumn: 100
1728
+ }).code
1729
+ };
1730
+ }, pathExists2 = async (value) => {
1731
+ try {
1732
+ return await access(value), !0;
1733
+ } catch {
1734
+ return !1;
1735
+ }
1736
+ }, detectMetroCandidates = async () => {
1737
+ let candidates = [];
1738
+ for (let fileName of METRO_CONFIG_CANDIDATES) {
1739
+ let absolutePath = path2.resolve(process.cwd(), fileName);
1740
+ await pathExists2(absolutePath) && candidates.push(absolutePath);
1741
+ }
1742
+ return candidates;
1743
+ }, createExpoMetroConfigHelper = async (packageManager) => {
1744
+ try {
1745
+ return await packageManager.runPackageCommand({
1746
+ args: [EXPO_CREATE_METRO_COMMAND.command, ...EXPO_CREATE_METRO_COMMAND.args],
1747
+ cwd: process.cwd()
1748
+ }), !0;
1749
+ } catch (error) {
1750
+ return logger12.warn(`Failed to create Expo Metro config automatically: ${String(error)}`), !1;
1751
+ }
1752
+ }, resolveMetroConfigPath = async ({
1753
+ packageManager,
1754
+ yes
1755
+ }) => {
1756
+ let candidates = await detectMetroCandidates();
1757
+ if (candidates.length === 0 && packageManager.getDependencyVersion("expo") && await createExpoMetroConfigHelper(packageManager) && (candidates = await detectMetroCandidates()), candidates.length === 1)
1758
+ return candidates[0];
1759
+ if (candidates.length > 1) {
1760
+ if (yes)
1761
+ return logger12.warn(
1762
+ `Multiple Metro config files detected. Non-interactive mode selected ${path2.relative(
1763
+ process.cwd(),
1764
+ candidates[0]
1765
+ )}.`
1766
+ ), candidates[0];
1767
+ let selected = await prompt8.select({
1768
+ message: "Multiple Metro config files found. Which one should Storybook update?",
1769
+ options: candidates.map((candidate) => ({
1770
+ label: path2.relative(process.cwd(), candidate),
1771
+ value: candidate
1772
+ }))
1773
+ });
1774
+ return String(selected);
1775
+ }
1776
+ if (yes)
1777
+ return null;
1778
+ let answer = await prompt8.text({
1779
+ message: "No Metro config file was found. Enter the path to your Metro config file to update, or leave blank to skip."
1780
+ }), normalized = String(answer || "").trim();
1781
+ if (!normalized)
1782
+ return null;
1783
+ let resolved = path2.isAbsolute(normalized) ? normalized : path2.resolve(process.cwd(), normalized.replace(/^\.\//, ""));
1784
+ return await pathExists2(resolved) ? resolved : (logger12.warn(`Provided Metro config path does not exist: ${normalized}`), null);
1785
+ }, runMetroCodemodOrFallback = async ({
1786
+ packageManager,
1787
+ yes
1788
+ }) => {
1789
+ let filePath = await resolveMetroConfigPath({ packageManager, yes });
1790
+ if (!filePath)
1791
+ return {
1792
+ status: "skipped-missing-file",
1793
+ notes: ["No Metro config file was selected for automatic modification."]
1794
+ };
1795
+ let source = await readFile2(filePath, "utf-8");
1796
+ if (containsStorybookImport(source))
1797
+ return {
1798
+ status: "skipped-existing-storybook-import",
1799
+ filePath,
1800
+ notes: ["Storybook import detected in Metro config; leaving file unchanged."]
1801
+ };
1802
+ try {
1803
+ let transformResult = transformMetroConfigSource(source, filePath);
1804
+ if (transformResult.action === "already-configured")
1805
+ return {
1806
+ status: "already-configured",
1807
+ filePath,
1808
+ notes: ["Metro config already appears to be wrapped with withStorybook."]
1809
+ };
1810
+ if (transformResult.action === "unsupported") {
1811
+ let fallbackSource = prependMetroFallbackComment(source);
1812
+ return fallbackSource !== source && await writeFile3(filePath, fallbackSource, "utf-8"), {
1813
+ status: "fallback-commented",
1814
+ filePath,
1815
+ notes: ["Could not apply automated codemod; added guidance comment at top of file."]
1816
+ };
1817
+ }
1818
+ return transformResult.code !== source && await writeFile3(filePath, transformResult.code, "utf-8"), {
1819
+ status: "updated",
1820
+ filePath,
1821
+ notes: ["Metro config was updated with withStorybook wrapper."]
1822
+ };
1823
+ } catch (error) {
1824
+ let fallbackSource = prependMetroFallbackComment(source);
1825
+ return fallbackSource !== source && await writeFile3(filePath, fallbackSource, "utf-8"), {
1826
+ status: "fallback-commented",
1827
+ filePath,
1828
+ notes: [`Metro codemod encountered an error: ${String(error)}`]
1829
+ };
1830
+ }
1831
+ };
1832
+
1833
+ // src/create/generators/REACT_NATIVE/index.ts
1834
+ var lastMetroCodemodResult, lastScriptDerivationResult, detectReactNativeEntrypointTemplateVariant = (allDependencies) => allDependencies.expo || allDependencies["expo-router"] ? "expo" : "default", fixExpoDependencyVersions = async () => {
1835
+ let task = prompt9.taskLog({
1836
+ id: "expo-install-fix",
1837
+ title: "Aligning Expo SDK dependency versions with `npx expo install --fix`"
1838
+ });
1839
+ try {
1840
+ let result = await executeCommand2({
1841
+ command: "npx",
1842
+ args: ["expo", "install", "--fix"],
1843
+ stdio: "pipe"
1844
+ });
1845
+ result.stdout && task.message(String(result.stdout)), task.success("Expo SDK dependency versions aligned", { showLog: !0 });
1846
+ } catch (err) {
1847
+ let message = err instanceof Error ? err.message : String(err);
1848
+ task.error("Could not run `npx expo install --fix` automatically"), logger13.warn(
1849
+ dedent9`
1850
+ Could not automatically align Expo SDK package versions.
1851
+
1852
+ To avoid runtime warnings such as "Native module is null, cannot access legacy storage",
1853
+ run the following command in your project root:
1854
+
1855
+ ${CLI_COLORS4.cta("npx expo install --fix")}
1856
+
1857
+ Reason: ${message}
1858
+ `
1859
+ );
1860
+ }
1861
+ }, REACT_NATIVE_default = {
1862
+ metadata: {
1863
+ projectType: ProjectType4.REACT_NATIVE,
1864
+ renderer: SupportedRenderer4.REACT,
1865
+ builderOverride: SupportedBuilder3.VITE,
1866
+ framework: null
1867
+ },
1868
+ configure: async (packageManager, context) => {
1869
+ let missingReactDom = !packageManager.getDependencyVersion("react-dom"), reactVersion = packageManager.getDependencyVersion("react"), dependencyCollector = context.dependencyCollector, peerDependencies = [
1870
+ "react-native-safe-area-context",
1871
+ "@react-native-async-storage/async-storage",
1872
+ "@expo/ui",
1873
+ "expo-symbols"
1874
+ ].filter((dep) => !packageManager.getDependencyVersion(dep)), existingScripts = packageManager.primaryPackageJson.packageJson.scripts, scriptDerivationResult = deriveStorybookPlatformScripts(
1875
+ existingScripts
1876
+ );
1877
+ lastScriptDerivationResult = scriptDerivationResult;
1878
+ let needsCrossEnv = Object.keys(scriptDerivationResult.scriptsToAdd).length > 0 && !packageManager.getDependencyVersion("cross-env"), packagesToResolve = [
1879
+ ...peerDependencies,
1880
+ ...needsCrossEnv ? ["cross-env"] : [],
1881
+ "@storybook/addon-ondevice-controls",
1882
+ "@storybook/addon-ondevice-actions",
1883
+ "@storybook/react-native",
1884
+ "@storybook/react-native-ui-lite",
1885
+ "storybook"
1886
+ ], packages = [
1887
+ ...await packageManager.getVersionedPackages(packagesToResolve, {
1888
+ storybookVersionSpecifier: context.storybookVersionSpecifier
1889
+ }),
1890
+ ...missingReactDom && reactVersion ? [`react-dom@${reactVersion}`] : []
1891
+ ];
1892
+ if (dependencyCollector.addDependencies(packages), packageManager.addScripts({
1893
+ ...scriptDerivationResult.scriptsToAdd
1894
+ }), context.framework == null) {
1895
+ let { packageJson, operationDir } = packageManager.primaryPackageJson;
1896
+ applyPreviewImportsMap(packageJson, join4(RN_STORYBOOK_DIR, "preview.tsx"), operationDir) && packageManager.writePackageJson(packageJson, operationDir);
1897
+ }
1898
+ await copyTemplateFiles2({
1899
+ packageManager,
1900
+ templateLocation: SupportedRenderer4.REACT_NATIVE,
1901
+ language: SupportedLanguage6.TYPESCRIPT,
1902
+ destination: RN_STORYBOOK_DIR,
1903
+ features: context.features
1904
+ }), await generateReactNativeEntrypoint({ language: context.language }), lastMetroCodemodResult = await runMetroCodemodOrFallback({
1905
+ packageManager,
1906
+ yes: !!context.yes
1907
+ });
1908
+ let templateVariant = detectReactNativeEntrypointTemplateVariant(packageManager.getAllDependencies());
1909
+ return await generateReactNativeEntrypoint({
1910
+ language: context.language,
1911
+ templateVariant
1912
+ }), {
1913
+ // Signal to skip baseGenerator by returning minimal config
1914
+ storybookConfigFolder: RN_STORYBOOK_DIR,
1915
+ skipGenerator: !0,
1916
+ storybookCommand: null,
1917
+ shouldRunDev: !1
1918
+ // React Native is started via platform scripts (see postConfigure), not `storybook dev`
1919
+ };
1920
+ },
1921
+ postInstall: async ({ packageManager }) => {
1922
+ detectReactNativeEntrypointTemplateVariant(packageManager.getAllDependencies()) === "expo" && await fixExpoDependencyVersions();
1923
+ },
1924
+ postConfigure: ({ packageManager }) => {
1925
+ let platformRunGuidance = (() => {
1926
+ let scriptNames = Object.keys(lastScriptDerivationResult?.scriptsToAdd ?? {});
1927
+ return scriptNames.length === 0 ? "No platform launch scripts could be generated automatically." : scriptNames.map((scriptName) => packageManager.getRunCommand(scriptName)).join(`
1928
+ `);
1929
+ })(), scriptWarningSummary = (() => {
1930
+ let missing = lastScriptDerivationResult?.missingBaseScripts ?? [];
1931
+ return missing.length === 0 ? null : `Could not infer ${missing.join(", ")} app scripts from package.json. To launch Storybook manually, set STORYBOOK_ENABLED=true when running your app scripts.`;
1932
+ })(), metroCodemodSummary = lastMetroCodemodResult ? lastMetroCodemodResult.status === "updated" ? "Metro config was updated automatically with withStorybook(...)." : lastMetroCodemodResult.status === "already-configured" ? "Metro config already appears to be configured for Storybook." : lastMetroCodemodResult.status === "skipped-existing-storybook-import" ? "Metro config already contains Storybook imports, so auto-modification was skipped." : lastMetroCodemodResult.status === "fallback-commented" ? "Metro config could not be transformed automatically; guidance was added to your Metro config file." : "No Metro config file was selected; please update Metro manually." : "Metro config could not be evaluated automatically.", metroStatus = lastMetroCodemodResult?.status, showWithStorybookManualSnippet = !lastMetroCodemodResult || metroStatus === "fallback-commented" || metroStatus === "skipped-missing-file", mayNeedFollowUp = !!scriptWarningSummary || showWithStorybookManualSnippet;
1933
+ logger13.log(dedent9`
1934
+ ${CLI_COLORS4.success("Storybook for React Native has been configured.")}
1935
+
1936
+ ${mayNeedFollowUp ? `${CLI_COLORS4.info("If anything below could not be applied automatically, follow the guidance or the docs link.")}
1937
+ ` : ""}
1938
+ Storybook run scripts:
1939
+
1940
+ ${CLI_COLORS4.cta(" " + platformRunGuidance + " ")}
1941
+
1942
+ Metro config status:
1943
+
1944
+ ${CLI_COLORS4.info(" " + metroCodemodSummary + " ")}
1945
+
1946
+ ${showWithStorybookManualSnippet ? dedent9`
1947
+ If your Metro config still needs wiring, wrap the default export with withStorybook:
1948
+
1949
+ ${CLI_COLORS4.info(" const { withStorybook } = require('@storybook/react-native/withStorybook'); ")}
1950
+ ${CLI_COLORS4.info(" module.exports = withStorybook(defaultConfig); ")}
1951
+ ` : ""}
1952
+ ${scriptWarningSummary ? `${CLI_COLORS4.warning(scriptWarningSummary)}
1953
+ ` : ""}
1954
+
1955
+ For more details go to:
1956
+ ${METRO_SETUP_DOCS_LINK}
1957
+ `);
1958
+ }
1959
+ };
1960
+
1961
+ // src/create/generators/registerGenerators.ts
1962
+ var setOfGenerators = /* @__PURE__ */ new Set([
1963
+ REACT_default,
1964
+ REACT_NATIVE_default,
1965
+ NEXTJS_default
1966
+ ]);
1967
+ function registerAllGenerators() {
1968
+ setOfGenerators.forEach((generator) => {
1969
+ generatorRegistry.register(generator);
1970
+ });
1971
+ }
1972
+
1973
+ // src/create/initiate.ts
1974
+ async function checkFeatureSupport(packageManager, framework, builder, renderer) {
1975
+ return {
1976
+ isTestFeatureAvailable: (await new FeatureCompatibilityService(packageManager).validateTestFeatureCompatibility(
1977
+ framework,
1978
+ builder,
1979
+ process.cwd()
1980
+ )).compatible,
1981
+ isAiAvailable: supportsSkills(renderer, framework),
1982
+ isAiSetupAvailable: supportsAiSetup(renderer, builder, framework)
1983
+ };
1984
+ }
1985
+ async function doInitiate(options) {
1986
+ options.agent && (options.yes = !0);
1987
+ let telemetryService = new TelemetryService();
1988
+ registerAllGenerators();
1989
+ let dependencyCollector = new DependencyCollector(), { packageManager, isEmptyProject } = await executePreflightCheck(options), { projectType, language } = await executeProjectDetection(packageManager, options), { framework, builder, renderer } = await executeFrameworkDetection(
1990
+ projectType,
1991
+ packageManager,
1992
+ options
1993
+ ), { isTestFeatureAvailable, isAiAvailable, isAiSetupAvailable } = await checkFeatureSupport(
1994
+ packageManager,
1995
+ framework,
1996
+ builder,
1997
+ renderer
1998
+ ), { selectedFeatures } = await executeUserPreferences({
1999
+ options,
2000
+ framework,
2001
+ builder,
2002
+ renderer,
2003
+ isTestFeatureAvailable,
2004
+ // Skip AI feature recommendation when scaffolding into an empty directory,
2005
+ // since the user hasn't yet committed to a project setup where AI tooling adds value.
2006
+ isAiAvailable: isAiAvailable && !isEmptyProject,
2007
+ isAiSetupAvailable
2008
+ });
2009
+ selectedFeatures.has(Feature6.AI) && !isAiAvailable && (logger14.warn(
2010
+ "The AI features are not available for this framework yet, so the Forkbook skills are not installed."
2011
+ ), selectedFeatures.delete(Feature6.AI));
2012
+ let { configDir, storybookCommand, shouldRunDev, extraAddons, postInstall: postInstall2 } = await executeGeneratorExecution({
2013
+ projectType,
2014
+ packageManager,
2015
+ frameworkInfo: { builder, framework, renderer },
2016
+ options,
2017
+ dependencyCollector,
2018
+ selectedFeatures,
2019
+ language
2020
+ }), dependencyInstallationResult = await executeDependencyInstallation({
2021
+ packageManager,
2022
+ dependencyCollector,
2023
+ skipInstall: !!options.skipInstall,
2024
+ selectedFeatures
2025
+ });
2026
+ if (dependencyCollector = null, postInstall2 && !options.skipInstall && dependencyInstallationResult.status === "success")
2027
+ try {
2028
+ await postInstall2();
2029
+ } catch (err) {
2030
+ logger14.warn(`Post-install step failed: ${err instanceof Error ? err.message : String(err)}`);
2031
+ }
2032
+ await executeAddonConfiguration({
2033
+ packageManager,
2034
+ addons: extraAddons,
2035
+ configDir,
2036
+ options
2037
+ });
2038
+ let hasAiFeature = selectedFeatures.has(Feature6.AI);
2039
+ return hasAiFeature && await telemetryService.trackSkills(
2040
+ await installSkills({ packageManager, source: "ai-feature" })
2041
+ ), configDir && isAiSetupAvailable && (await cache.set("ai-init-opt-in", {
2042
+ timestamp: Date.now(),
2043
+ configDir: resolve3(configDir),
2044
+ answer: hasAiFeature
2045
+ }).catch(() => {
2046
+ }), await telemetry4("ai-init-opt-in", {
2047
+ answer: hasAiFeature
2048
+ }).catch(() => {
2049
+ })), await executeFinalization({
2050
+ showAgentFollowUp: !!options.agent && hasAiFeature && isAiSetupAvailable,
2051
+ showAiInstructions: hasAiFeature && isAiSetupAvailable,
2052
+ logfile: options.logfile,
2053
+ storybookCommand,
2054
+ setupSkillCommand: packageManager.getPackageCommand(["forkbook", "skills", "setup"])
2055
+ }), await telemetryService.trackInitWithContext(projectType, selectedFeatures, configDir), {
2056
+ shouldRunDev: !!options.dev && !options.skipInstall && shouldRunDev !== !1 && dependencyInstallationResult.status === "success",
2057
+ packageManager,
2058
+ storybookCommand
2059
+ };
2060
+ }
2061
+ var handleCommandFailure = async (logFilePath) => {
2062
+ let logFile = await logTracker2.writeToFile(logFilePath);
2063
+ logger14.error("Forkbook encountered an error during initialization"), logger14.log(`Debug logs are written to: ${logFile}`), logger14.outro("Forkbook exited with an error"), process.exit(1);
2064
+ };
2065
+ async function initiate(options) {
2066
+ let initiateResult = await withTelemetry(
2067
+ "init",
2068
+ {
2069
+ cliOptions: options,
2070
+ printError: (err) => !err.handled && logger14.error(err),
2071
+ // enable telemetry if nothing else specified in env var or CLI options
2072
+ fallbackTelemetryState: !0
2073
+ },
2074
+ async () => {
2075
+ let result = await doInitiate(options);
2076
+ return logger14.outro(""), result;
2077
+ }
2078
+ ).catch(() => handleCommandFailure(options.logfile));
2079
+ !options.agent && initiateResult?.shouldRunDev && await runStorybookDev(initiateResult);
2080
+ }
2081
+ async function runStorybookDev(result) {
2082
+ let { packageManager, storybookCommand } = result;
2083
+ if (storybookCommand)
2084
+ try {
2085
+ let parts = storybookCommand.split(" ");
2086
+ packageManager.type === "npm" && parts.push("--silent"), (packageManager.type === PackageManagerName2.NPM || packageManager.type === PackageManagerName2.BUN) && parts.push("--");
2087
+ let defaultPort = 6006, availablePort = await getServerPort(defaultPort);
2088
+ availablePort !== defaultPort && parts.push("-p", `${availablePort}`), parts.push("--quiet");
2089
+ let [command, ...args] = [...parts];
2090
+ await executeCommand3({
2091
+ command,
2092
+ args,
2093
+ stdio: "inherit"
2094
+ });
2095
+ } catch {
2096
+ }
2097
+ }
2098
+
2099
+ export {
2100
+ doInitiate,
2101
+ initiate
2102
+ };