@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.
- package/LICENSE +22 -0
- package/README.md +77 -2
- package/assets/addon-vitest/templates/vitest.config.4.template.ts +36 -0
- package/assets/browser/favicon-wrapper.svg +46 -0
- package/assets/browser/favicon.svg +1 -0
- package/assets/browser/nunito-sans-bold-italic.woff2 +0 -0
- package/assets/browser/nunito-sans-bold.woff2 +0 -0
- package/assets/browser/nunito-sans-italic.woff2 +0 -0
- package/assets/browser/nunito-sans-regular.woff2 +0 -0
- package/assets/builder-vite/iframe.html +99 -0
- package/assets/create/rendererAssets/.eslintrc.json +16 -0
- package/assets/create/rendererAssets/common/Configure.mdx +388 -0
- package/assets/create/rendererAssets/common/assets/accessibility.png +0 -0
- package/assets/create/rendererAssets/common/assets/accessibility.svg +1 -0
- package/assets/create/rendererAssets/common/assets/addon-library.png +0 -0
- package/assets/create/rendererAssets/common/assets/assets.png +0 -0
- package/assets/create/rendererAssets/common/assets/avif-test-image.avif +0 -0
- package/assets/create/rendererAssets/common/assets/context.png +0 -0
- package/assets/create/rendererAssets/common/assets/discord.svg +1 -0
- package/assets/create/rendererAssets/common/assets/docs.png +0 -0
- package/assets/create/rendererAssets/common/assets/figma-plugin.png +0 -0
- package/assets/create/rendererAssets/common/assets/github.svg +1 -0
- package/assets/create/rendererAssets/common/assets/share.png +0 -0
- package/assets/create/rendererAssets/common/assets/styling.png +0 -0
- package/assets/create/rendererAssets/common/assets/testing.png +0 -0
- package/assets/create/rendererAssets/common/assets/theming.png +0 -0
- package/assets/create/rendererAssets/common/assets/tutorials.svg +1 -0
- package/assets/create/rendererAssets/common/assets/youtube.svg +1 -0
- package/assets/create/rendererAssets/common/button.css +30 -0
- package/assets/create/rendererAssets/common/header.css +32 -0
- package/assets/create/rendererAssets/common/page.css +68 -0
- package/assets/create/templates/react-native/index.expo.js +20 -0
- package/assets/create/templates/react-native/index.js +25 -0
- package/assets/docs/addon-backgrounds.gif +0 -0
- package/assets/docs/addon-controls-args-annotated.png +0 -0
- package/assets/docs/addon-controls-args-background-color.png +0 -0
- package/assets/docs/addon-controls-args-background-string.png +0 -0
- package/assets/docs/addon-controls-args-docs.png +0 -0
- package/assets/docs/addon-controls-args-logging.png +0 -0
- package/assets/docs/addon-controls-args-no-annotation.png +0 -0
- package/assets/docs/addon-controls-args-reflow-slider.png +0 -0
- package/assets/docs/addon-controls-args-reflow.png +0 -0
- package/assets/docs/addon-controls-args-template.png +0 -0
- package/assets/docs/addon-controls-expanded.png +0 -0
- package/assets/docs/addon-controls-hero.gif +0 -0
- package/assets/docs/addon-controls-install.png +0 -0
- package/assets/docs/hero.gif +0 -0
- package/assets/docs/highlight.png +0 -0
- package/assets/docs/message-reference.png +0 -0
- package/assets/docs/viewport.png +0 -0
- package/assets/react-native/metro-env.d.ts +69 -0
- package/assets/server/addon.tsconfig.json +6 -0
- package/assets/server/base-preview-body.html +116 -0
- package/assets/server/base-preview-head.html +494 -0
- package/assets/server/openBrowser.applescript +94 -0
- package/assets/server/template.ejs +87 -0
- package/dist/.build-stamp +0 -0
- package/dist/_browser-chunks/Color-PCLE2J36.js +1025 -0
- package/dist/_browser-chunks/DocsRenderer-JXND3PVQ.js +10 -0
- package/dist/_browser-chunks/WithTooltip-XSQFTBMB.js +1619 -0
- package/dist/_browser-chunks/chunk-2JDQ35OA.js +247 -0
- package/dist/_browser-chunks/chunk-2JT76G3E.js +104 -0
- package/dist/_browser-chunks/chunk-2MEPHP35.js +17 -0
- package/dist/_browser-chunks/chunk-2SCZVUKW.js +24 -0
- package/dist/_browser-chunks/chunk-46Z7NGAS.js +41 -0
- package/dist/_browser-chunks/chunk-4ATQOMJB.js +30 -0
- package/dist/_browser-chunks/chunk-52CW7FF7.js +49 -0
- package/dist/_browser-chunks/chunk-5I7E4GMO.js +62 -0
- package/dist/_browser-chunks/chunk-5P4QA6MY.js +20 -0
- package/dist/_browser-chunks/chunk-5WMXI5GW.js +816 -0
- package/dist/_browser-chunks/chunk-66OCZ54D.js +2604 -0
- package/dist/_browser-chunks/chunk-6SXYJQST.js +253 -0
- package/dist/_browser-chunks/chunk-AYRF6EJB.js +36 -0
- package/dist/_browser-chunks/chunk-B4AUNNU4.js +156 -0
- package/dist/_browser-chunks/chunk-BCP2FFXF.js +369 -0
- package/dist/_browser-chunks/chunk-C3D4HEFY.js +3396 -0
- package/dist/_browser-chunks/chunk-CFAOWGL7.js +43 -0
- package/dist/_browser-chunks/chunk-CFWWCCZV.js +223 -0
- package/dist/_browser-chunks/chunk-CNED6RYH.js +18 -0
- package/dist/_browser-chunks/chunk-DRQKCCAG.js +136 -0
- package/dist/_browser-chunks/chunk-ECQ75MKQ.js +0 -0
- package/dist/_browser-chunks/chunk-EIYAKDGP.js +302 -0
- package/dist/_browser-chunks/chunk-ENKK74N4.js +12 -0
- package/dist/_browser-chunks/chunk-FENFYI4X.js +698 -0
- package/dist/_browser-chunks/chunk-FJGWSWL5.js +155 -0
- package/dist/_browser-chunks/chunk-FVSEPWWX.js +2810 -0
- package/dist/_browser-chunks/chunk-GNZY6LOW.js +10116 -0
- package/dist/_browser-chunks/chunk-IE4ULIOQ.js +14 -0
- package/dist/_browser-chunks/chunk-IMSF75WX.js +42 -0
- package/dist/_browser-chunks/chunk-IWQGIXJS.js +14 -0
- package/dist/_browser-chunks/chunk-JMC7AIKT.js +108 -0
- package/dist/_browser-chunks/chunk-JPUOQJUI.js +8 -0
- package/dist/_browser-chunks/chunk-JSBKXXXF.js +218 -0
- package/dist/_browser-chunks/chunk-JWSKPMPC.js +73 -0
- package/dist/_browser-chunks/chunk-JYVGARBG.js +2943 -0
- package/dist/_browser-chunks/chunk-KBK7GKBN.js +35 -0
- package/dist/_browser-chunks/chunk-KQ7CRO2B.js +108 -0
- package/dist/_browser-chunks/chunk-LAWXTSXK.js +18 -0
- package/dist/_browser-chunks/chunk-LE2LTDW3.js +14 -0
- package/dist/_browser-chunks/chunk-LEVSOOLQ.js +48 -0
- package/dist/_browser-chunks/chunk-LV5PIKV4.js +93 -0
- package/dist/_browser-chunks/chunk-MDOL7KML.js +56 -0
- package/dist/_browser-chunks/chunk-MFMDGWP6.js +34 -0
- package/dist/_browser-chunks/chunk-MLBOOZL4.js +67 -0
- package/dist/_browser-chunks/chunk-NQUD4B7H.js +91 -0
- package/dist/_browser-chunks/chunk-NULBREPZ.js +43 -0
- package/dist/_browser-chunks/chunk-NZMVUW5T.js +7 -0
- package/dist/_browser-chunks/chunk-OD6IBQCC.js +117 -0
- package/dist/_browser-chunks/chunk-ODVJ3XZJ.js +157 -0
- package/dist/_browser-chunks/chunk-OQWFVDIN.js +386 -0
- package/dist/_browser-chunks/chunk-OVH3USFB.js +20 -0
- package/dist/_browser-chunks/chunk-OZZPSYQR.js +14 -0
- package/dist/_browser-chunks/chunk-P6PK47TQ.js +1970 -0
- package/dist/_browser-chunks/chunk-PFRNG3UC.js +22 -0
- package/dist/_browser-chunks/chunk-PJSMZ27A.js +13 -0
- package/dist/_browser-chunks/chunk-QC4HFS6K.js +41 -0
- package/dist/_browser-chunks/chunk-QDXFODK4.js +274 -0
- package/dist/_browser-chunks/chunk-RBCHTR7C.js +28 -0
- package/dist/_browser-chunks/chunk-RMYQ3QN3.js +294 -0
- package/dist/_browser-chunks/chunk-RNTIV5CE.js +411 -0
- package/dist/_browser-chunks/chunk-RSPAQWVJ.js +80 -0
- package/dist/_browser-chunks/chunk-S6TK43XQ.js +836 -0
- package/dist/_browser-chunks/chunk-SC67XZST.js +18 -0
- package/dist/_browser-chunks/chunk-SFVA4SBT.js +683 -0
- package/dist/_browser-chunks/chunk-SZYFOQMT.js +25 -0
- package/dist/_browser-chunks/chunk-TBJCJXK4.js +18 -0
- package/dist/_browser-chunks/chunk-UMDO3KB7.js +205 -0
- package/dist/_browser-chunks/chunk-V2G23FV7.js +11 -0
- package/dist/_browser-chunks/chunk-V5M7Q4HT.js +88 -0
- package/dist/_browser-chunks/chunk-W5M6NPS3.js +198 -0
- package/dist/_browser-chunks/chunk-W7NE2JXW.js +84 -0
- package/dist/_browser-chunks/chunk-WGVAAM43.js +1110 -0
- package/dist/_browser-chunks/chunk-WHQRNHXD.js +8 -0
- package/dist/_browser-chunks/chunk-WOSOWBCA.js +12 -0
- package/dist/_browser-chunks/chunk-WZ7KR7SH.js +85 -0
- package/dist/_browser-chunks/chunk-YEKO6BHJ.js +20 -0
- package/dist/_browser-chunks/chunk-YI2IBIQS.js +7 -0
- package/dist/_browser-chunks/chunk-YTIT5NA5.js +1966 -0
- package/dist/_browser-chunks/chunk-ZEHRUHTA.js +6 -0
- package/dist/_browser-chunks/chunk-ZTQ5MEJ5.js +203 -0
- package/dist/_browser-chunks/matchers-YLBYSYAF.js +1263 -0
- package/dist/_browser-chunks/react-dom-client-4OHE3QDV.js +9 -0
- package/dist/_node-chunks/attached-runtime-I2G4WLJI.js +282 -0
- package/dist/_node-chunks/builder-manager-VVHYQXCH.js +1661 -0
- package/dist/_node-chunks/chunk-2BUPBPFB.js +82 -0
- package/dist/_node-chunks/chunk-2DSIDINN.js +884 -0
- package/dist/_node-chunks/chunk-2RU7BKEW.js +23 -0
- package/dist/_node-chunks/chunk-34EO2PUT.js +26 -0
- package/dist/_node-chunks/chunk-3BKIBF5S.js +3008 -0
- package/dist/_node-chunks/chunk-3SDUYDXH.js +98 -0
- package/dist/_node-chunks/chunk-3T4ZSNPH.js +662 -0
- package/dist/_node-chunks/chunk-3W7F2B7P.js +79 -0
- package/dist/_node-chunks/chunk-3Y6AAY5H.js +80 -0
- package/dist/_node-chunks/chunk-42UWAGPW.js +1193 -0
- package/dist/_node-chunks/chunk-4FEANXWU.js +1986 -0
- package/dist/_node-chunks/chunk-5DQFEZEA.js +40 -0
- package/dist/_node-chunks/chunk-6KEHV53S.js +1218 -0
- package/dist/_node-chunks/chunk-6LMWA44H.js +3837 -0
- package/dist/_node-chunks/chunk-6YKBRP72.js +20 -0
- package/dist/_node-chunks/chunk-7GUDZVRQ.js +110 -0
- package/dist/_node-chunks/chunk-B5J7Q7J4.js +21 -0
- package/dist/_node-chunks/chunk-BS2WMZMR.js +90 -0
- package/dist/_node-chunks/chunk-BSKFCWQD.js +47 -0
- package/dist/_node-chunks/chunk-BXVYT7SB.js +36 -0
- package/dist/_node-chunks/chunk-CCOTJ4FC.js +688 -0
- package/dist/_node-chunks/chunk-CQKMLL5J.js +33 -0
- package/dist/_node-chunks/chunk-CXRU72ET.js +63 -0
- package/dist/_node-chunks/chunk-DC7DKR5K.js +20 -0
- package/dist/_node-chunks/chunk-DHJFTB4K.js +25 -0
- package/dist/_node-chunks/chunk-DUR55DJJ.js +1094 -0
- package/dist/_node-chunks/chunk-E6YESGLX.js +7032 -0
- package/dist/_node-chunks/chunk-EHUNOMDD.js +52345 -0
- package/dist/_node-chunks/chunk-ET7PWEO7.js +298 -0
- package/dist/_node-chunks/chunk-EWOX7HPJ.js +20 -0
- package/dist/_node-chunks/chunk-F3ZFKBHY.js +844 -0
- package/dist/_node-chunks/chunk-FK7KGTV7.js +26 -0
- package/dist/_node-chunks/chunk-FPZB5OI7.js +35 -0
- package/dist/_node-chunks/chunk-FW2HQUBQ.js +25 -0
- package/dist/_node-chunks/chunk-FY6UXW6G.js +11 -0
- package/dist/_node-chunks/chunk-GEFQN7K3.js +499 -0
- package/dist/_node-chunks/chunk-GRBLDJCR.js +989 -0
- package/dist/_node-chunks/chunk-H32DYT6P.js +87 -0
- package/dist/_node-chunks/chunk-H4PPVMP5.js +23 -0
- package/dist/_node-chunks/chunk-HMP2G23X.js +25 -0
- package/dist/_node-chunks/chunk-ICPBH3E7.js +59 -0
- package/dist/_node-chunks/chunk-IDEL2J23.js +23 -0
- package/dist/_node-chunks/chunk-IK4FGZLR.js +223 -0
- package/dist/_node-chunks/chunk-JDXXX6LB.js +68 -0
- package/dist/_node-chunks/chunk-JGGFYIG5.js +5468 -0
- package/dist/_node-chunks/chunk-JPAZLYJ3.js +29 -0
- package/dist/_node-chunks/chunk-JZOO7GGC.js +48 -0
- package/dist/_node-chunks/chunk-KISMCCP5.js +4744 -0
- package/dist/_node-chunks/chunk-LCK4ZQKG.js +115 -0
- package/dist/_node-chunks/chunk-LO56I6E2.js +132 -0
- package/dist/_node-chunks/chunk-LXBD4UL4.js +104 -0
- package/dist/_node-chunks/chunk-MA24JW6C.js +7162 -0
- package/dist/_node-chunks/chunk-MK2KYAI6.js +5414 -0
- package/dist/_node-chunks/chunk-NDWKJ4CL.js +2102 -0
- package/dist/_node-chunks/chunk-NIBT7XDZ.js +168 -0
- package/dist/_node-chunks/chunk-NPO45IMH.js +33 -0
- package/dist/_node-chunks/chunk-OISX4AGQ.js +414 -0
- package/dist/_node-chunks/chunk-OUW6R7C3.js +26 -0
- package/dist/_node-chunks/chunk-OWNFOGTA.js +194 -0
- package/dist/_node-chunks/chunk-Q7QNUM5H.js +49 -0
- package/dist/_node-chunks/chunk-QEQLR22M.js +1877 -0
- package/dist/_node-chunks/chunk-RRN2V55B.js +45 -0
- package/dist/_node-chunks/chunk-RWFIFGO5.js +144 -0
- package/dist/_node-chunks/chunk-RXNJDRGO.js +209 -0
- package/dist/_node-chunks/chunk-RZMQ7S3L.js +92 -0
- package/dist/_node-chunks/chunk-SIEXZVCR.js +51 -0
- package/dist/_node-chunks/chunk-SLWQNBGO.js +2034 -0
- package/dist/_node-chunks/chunk-SVTBJ7Q3.js +35 -0
- package/dist/_node-chunks/chunk-SWO5CDYU.js +32 -0
- package/dist/_node-chunks/chunk-TD5PLLQG.js +121 -0
- package/dist/_node-chunks/chunk-TEQGGSP7.js +33 -0
- package/dist/_node-chunks/chunk-TFCEV2XX.js +155 -0
- package/dist/_node-chunks/chunk-TFEWM4E3.js +1073 -0
- package/dist/_node-chunks/chunk-TINO74G5.js +21 -0
- package/dist/_node-chunks/chunk-TNJIXE37.js +40 -0
- package/dist/_node-chunks/chunk-TWI4GVH7.js +19 -0
- package/dist/_node-chunks/chunk-U5W53R2J.js +1011 -0
- package/dist/_node-chunks/chunk-UBOGWBEA.js +148 -0
- package/dist/_node-chunks/chunk-UMUBKI6E.js +3787 -0
- package/dist/_node-chunks/chunk-UVINFLGY.js +56 -0
- package/dist/_node-chunks/chunk-V2DY426G.js +1133 -0
- package/dist/_node-chunks/chunk-VLOXOXXE.js +45 -0
- package/dist/_node-chunks/chunk-W4OMYLSP.js +1297 -0
- package/dist/_node-chunks/chunk-WAXVSN3O.js +18 -0
- package/dist/_node-chunks/chunk-WCULS5TP.js +3767 -0
- package/dist/_node-chunks/chunk-WNZ2UMFM.js +153 -0
- package/dist/_node-chunks/chunk-WZJF2OUH.js +74 -0
- package/dist/_node-chunks/chunk-XGIUVY52.js +611 -0
- package/dist/_node-chunks/chunk-XHL2LVBM.js +415 -0
- package/dist/_node-chunks/chunk-XI6B6P47.js +59 -0
- package/dist/_node-chunks/chunk-XLP2ZKXV.js +60 -0
- package/dist/_node-chunks/chunk-YCMRA6RX.js +95 -0
- package/dist/_node-chunks/chunk-YZFWBA5L.js +2700 -0
- package/dist/_node-chunks/chunk-ZMAMXQKP.js +4731 -0
- package/dist/_node-chunks/chunk-ZWBCQ4MJ.js +110 -0
- package/dist/_node-chunks/dist-VTSTZKUB.js +16 -0
- package/dist/_node-chunks/globby-OEMHPBFY.js +2884 -0
- package/dist/_node-chunks/jiti-NFX6UU74.js +3848 -0
- package/dist/_node-chunks/lib-MDVARD7W.js +366 -0
- package/dist/_node-chunks/local-runtime-NTKIN2QT.js +78 -0
- package/dist/_node-chunks/mdx-plugin-MWISDWDQ.js +5680 -0
- package/dist/_node-chunks/monorepo-LIRFMQXE.js +121 -0
- package/dist/_node-chunks/monorepo-optimized-tests-relaxed-limits-no-story-deletion-CPDW4XTW.js +121 -0
- package/dist/_node-chunks/optimized-tests-HDOLR3EY.js +22 -0
- package/dist/_node-chunks/pattern-copy-play-EKHIUAU2.js +807 -0
- package/dist/_node-chunks/postinstallAddon-GYGMWDL6.js +20 -0
- package/dist/_node-chunks/rehype-external-links-BUN3HUCO.js +121 -0
- package/dist/_node-chunks/rehype-slug-PLADX223.js +52 -0
- package/dist/_node-chunks/relaxed-limits-GBHW6KIQ.js +117 -0
- package/dist/_node-chunks/run-KDTIZNSY.js +103 -0
- package/dist/_node-chunks/run-NL66VTNR.js +4532 -0
- package/dist/_node-chunks/session-id-KIIVOQLR.js +23 -0
- package/dist/_node-chunks/setup-MGC7BQO6.js +278 -0
- package/dist/_node-chunks/vitest.config.4.template-JH2THZFG.js +54 -0
- package/dist/actions/decorator.d.ts +7 -0
- package/dist/actions/decorator.js +43 -0
- package/dist/actions/index.d.ts +67 -0
- package/dist/actions/index.js +28 -0
- package/dist/addon-a11y/index.d.ts +52 -0
- package/dist/addon-a11y/index.js +16 -0
- package/dist/addon-a11y/manager.js +1429 -0
- package/dist/addon-a11y/preset.js +18 -0
- package/dist/addon-a11y/preview.d.ts +17 -0
- package/dist/addon-a11y/preview.js +15 -0
- package/dist/addon-docs/blocks.d.ts +1061 -0
- package/dist/addon-docs/blocks.js +2461 -0
- package/dist/addon-docs/index.d.ts +236 -0
- package/dist/addon-docs/index.js +16 -0
- package/dist/addon-docs/manager.js +90 -0
- package/dist/addon-docs/mdx-react-shim.d.ts +1 -0
- package/dist/addon-docs/mdx-react-shim.js +2 -0
- package/dist/addon-docs/preset.js +378 -0
- package/dist/addon-docs/preview.d.ts +4 -0
- package/dist/addon-docs/preview.js +7 -0
- package/dist/addon-links/index.d.ts +22 -0
- package/dist/addon-links/index.js +20 -0
- package/dist/addon-links/manager.js +14 -0
- package/dist/addon-links/preview.d.ts +6 -0
- package/dist/addon-links/preview.js +9 -0
- package/dist/addon-links/react/index.d.ts +25 -0
- package/dist/addon-links/react/index.js +52 -0
- package/dist/addon-mcp/preset.js +1345 -0
- package/dist/addon-mcp/preview.js +29 -0
- package/dist/addon-mcp/tools/preview-stories/preview-stories-app-script.js +1153 -0
- package/dist/addon-ondevice-actions/index.d.ts +4 -0
- package/dist/addon-ondevice-actions/index.js +7 -0
- package/dist/addon-ondevice-actions/register.js +7 -0
- package/dist/addon-ondevice-controls/index.d.ts +6 -0
- package/dist/addon-ondevice-controls/index.js +14 -0
- package/dist/addon-ondevice-controls/register.js +10 -0
- package/dist/addon-pseudo-states/index.d.ts +35 -0
- package/dist/addon-pseudo-states/index.js +15 -0
- package/dist/addon-pseudo-states/manager.js +53 -0
- package/dist/addon-pseudo-states/preview.d.ts +9 -0
- package/dist/addon-pseudo-states/preview.js +10 -0
- package/dist/addon-themes/index.d.ts +80 -0
- package/dist/addon-themes/index.js +104 -0
- package/dist/addon-themes/manager.js +97 -0
- package/dist/addon-themes/postinstall.js +33 -0
- package/dist/addon-themes/preview.d.ts +6 -0
- package/dist/addon-themes/preview.js +8 -0
- package/dist/addon-vitest/constants.d.ts +132 -0
- package/dist/addon-vitest/constants.js +66 -0
- package/dist/addon-vitest/index.d.ts +4 -0
- package/dist/addon-vitest/index.js +8 -0
- package/dist/addon-vitest/manager.js +665 -0
- package/dist/addon-vitest/node/coverage-reporter.js +1284 -0
- package/dist/addon-vitest/node/vitest.js +674 -0
- package/dist/addon-vitest/postinstall.js +24 -0
- package/dist/addon-vitest/preset.js +943 -0
- package/dist/addon-vitest/vitest-plugin/global-setup.js +162 -0
- package/dist/addon-vitest/vitest-plugin/index.d.ts +56 -0
- package/dist/addon-vitest/vitest-plugin/index.js +463 -0
- package/dist/addon-vitest/vitest-plugin/setup-file-with-project-annotations.js +9 -0
- package/dist/addon-vitest/vitest-plugin/setup-file.browser.4.js +20 -0
- package/dist/addon-vitest/vitest-plugin/setup-file.js +50 -0
- package/dist/addon-vitest/vitest-plugin/test-utils.js +128 -0
- package/dist/babel/index.d.ts +2301 -0
- package/dist/babel/index.js +61 -0
- package/dist/backgrounds/index.d.ts +6 -0
- package/dist/backgrounds/index.js +15 -0
- package/dist/bin/core.js +1705 -0
- package/dist/bin/dispatcher.js +43 -0
- package/dist/bin/loader.js +115 -0
- package/dist/builder-vite/index.d.ts +50 -0
- package/dist/builder-vite/index.js +245 -0
- package/dist/builder-vite/preset.js +27 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.js +352 -0
- package/dist/chunk-B2t1tGRh.d.ts +284 -0
- package/dist/chunk-BCoJQE-f.d.ts +602 -0
- package/dist/chunk-BGkgZp-H.d.ts +214 -0
- package/dist/chunk-BTVrWliM.d.ts +115 -0
- package/dist/chunk-BXLImeLy.d.ts +197 -0
- package/dist/chunk-BfBzpgct.d.ts +916 -0
- package/dist/chunk-Bpi2tz-6.d.ts +511 -0
- package/dist/chunk-BxWufQms.d.ts +142 -0
- package/dist/chunk-C-bavsOH.d.ts +34 -0
- package/dist/chunk-C2p5r3Vt.d.ts +13001 -0
- package/dist/chunk-C6PAgHLT.d.ts +12 -0
- package/dist/chunk-CMeX4WRe.d.ts +179 -0
- package/dist/chunk-Ct9xd6IM.d.ts +65 -0
- package/dist/chunk-CwQKNaYL.d.ts +15 -0
- package/dist/chunk-D7DwV41f.d.ts +3622 -0
- package/dist/chunk-DEVFdzxR.d.ts +253 -0
- package/dist/chunk-DaVb55-_.d.ts +124 -0
- package/dist/chunk-DgRNfmj_.d.ts +40 -0
- package/dist/chunk-DoIGKY33.d.ts +666 -0
- package/dist/chunk-Dr3R0DXk.d.ts +40 -0
- package/dist/chunk-DtHByo32.d.ts +55 -0
- package/dist/chunk-Dw1z1Pki.d.ts +933 -0
- package/dist/chunk-DzuY9DXg.d.ts +79 -0
- package/dist/chunk-FjDVzZTj.d.ts +62 -0
- package/dist/chunk-Kt1tW-D1.d.ts +59 -0
- package/dist/chunk-XP8oHzpE.d.ts +6 -0
- package/dist/chunk-gCX81nOr.d.ts +61 -0
- package/dist/chunk-pcFXCimE.d.ts +741 -0
- package/dist/cli/index.d.ts +1174 -0
- package/dist/cli/index.js +5613 -0
- package/dist/cli/skills/content/index.d.ts +72 -0
- package/dist/cli/skills/content/index.js +335 -0
- package/dist/cli/tools/sdk/child-host.d.ts +61 -0
- package/dist/cli/tools/sdk/child-host.js +131 -0
- package/dist/cli/tools/sdk/index.d.ts +137 -0
- package/dist/cli/tools/sdk/index.js +44 -0
- package/dist/cli-commands/bin/index.js +25 -0
- package/dist/client-logger/index.d.ts +31 -0
- package/dist/client-logger/index.js +63 -0
- package/dist/common/index.d.ts +1103 -0
- package/dist/common/index.js +364 -0
- package/dist/components/index.d.ts +1924 -0
- package/dist/components/index.js +13759 -0
- package/dist/core-events/index.d.ts +155 -0
- package/dist/core-events/index.js +136 -0
- package/dist/core-server/index.d.ts +2200 -0
- package/dist/core-server/index.js +4165 -0
- package/dist/core-server/presets/common-manager.css +170 -0
- package/dist/core-server/presets/common-manager.js +4168 -0
- package/dist/core-server/presets/common-override-preset.js +81 -0
- package/dist/core-server/presets/common-preset.js +2187 -0
- package/dist/create/bin/index.js +23 -0
- package/dist/create/index.js +25 -0
- package/dist/csf/csf-utils.d.ts +2 -0
- package/dist/csf/csf-utils.js +19 -0
- package/dist/csf/index.d.ts +7 -0
- package/dist/csf/index.js +2142 -0
- package/dist/csf-tools/index.d.ts +1157 -0
- package/dist/csf-tools/index.js +736 -0
- package/dist/docs-tools/index.d.ts +197 -0
- package/dist/docs-tools/index.js +61 -0
- package/dist/highlight/index.d.ts +10 -0
- package/dist/highlight/index.js +15 -0
- package/dist/instrumenter/index.d.ts +113 -0
- package/dist/instrumenter/index.js +2595 -0
- package/dist/manager/_manager-chunks/globals-runtime-8HkdnU2F.js +6144 -0
- package/dist/manager/_manager-chunks/globals-runtime-BIKBO23x.js +3389 -0
- package/dist/manager/_manager-chunks/globals-runtime-BdGkqNEt.js +45 -0
- package/dist/manager/_manager-chunks/globals-runtime-BmphMP6z.js +1190 -0
- package/dist/manager/_manager-chunks/globals-runtime-BvM-NY2g.js +13307 -0
- package/dist/manager/_manager-chunks/globals-runtime-C02fvgcd.js +9243 -0
- package/dist/manager/_manager-chunks/globals-runtime-DkAPXCvc.js +9766 -0
- package/dist/manager/_manager-chunks/globals-runtime-DpNYC-qi.js +5564 -0
- package/dist/manager/_manager-chunks/globals-runtime-DtcOnYHR.js +5357 -0
- package/dist/manager/_manager-chunks/globals-runtime-DwFqpqya.js +722 -0
- package/dist/manager/_manager-chunks/globals-runtime-FC201B7s.js +6837 -0
- package/dist/manager/_manager-chunks/globals-runtime-Rp_zjGnh.js +121 -0
- package/dist/manager/_manager-chunks/globals-runtime-ZHrQFa3-.js +10463 -0
- package/dist/manager/_manager-chunks/globals-runtime-eLPTIfX-.js +7759 -0
- package/dist/manager/_manager-chunks/globals-runtime-qKvCZHFY.js +4468 -0
- package/dist/manager/_manager-chunks/globals-runtime-sGpNlIJ1.js +5102 -0
- package/dist/manager/_manager-chunks/runtime-B1L9TH89.js +452 -0
- package/dist/manager/_manager-chunks/runtime-BK0zF7FN.js +22 -0
- package/dist/manager/_manager-chunks/runtime-BhkT2CXl.js +1408 -0
- package/dist/manager/_manager-chunks/runtime-Bly6WJLN.js +998 -0
- package/dist/manager/_manager-chunks/runtime-D0UOWx0U.js +979 -0
- package/dist/manager/_manager-chunks/runtime-D94Vq3oR.js +4014 -0
- package/dist/manager/_manager-chunks/runtime-DMig8mT7.js +77 -0
- package/dist/manager/_manager-chunks/runtime-EITvVbkG.js +46 -0
- package/dist/manager/_manager-chunks/runtime-cp5pazY2.js +8936 -0
- package/dist/manager/_manager-chunks/runtime-eDVAYF7N.js +6860 -0
- package/dist/manager/_manager-chunks/runtime-i-PDAHLR.js +2493 -0
- package/dist/manager/globals-runtime.js +2 -0
- package/dist/manager/globals.d.ts +23 -0
- package/dist/manager/globals.js +26 -0
- package/dist/manager/manager-stores.d.ts +2 -0
- package/dist/manager/manager-stores.js +19 -0
- package/dist/manager/runtime.js +2 -0
- package/dist/manager-api/index.d.ts +2 -0
- package/dist/manager-api/index.js +3257 -0
- package/dist/manager-errors.d.ts +89 -0
- package/dist/manager-errors.js +20 -0
- package/dist/mcp/index.d.ts +270 -0
- package/dist/mcp/index.js +305 -0
- package/dist/mocking-utils/index.d.ts +689 -0
- package/dist/mocking-utils/index.js +521 -0
- package/dist/mocking-utils/mocker-runtime.js +1254 -0
- package/dist/nextjs-vite/config/preview.js +3 -0
- package/dist/nextjs-vite/export-mocks/cache/index.d.ts +25 -0
- package/dist/nextjs-vite/export-mocks/cache/index.js +29 -0
- package/dist/nextjs-vite/export-mocks/headers/index.d.ts +37 -0
- package/dist/nextjs-vite/export-mocks/headers/index.js +54 -0
- package/dist/nextjs-vite/export-mocks/link/index.d.ts +9 -0
- package/dist/nextjs-vite/export-mocks/link/index.js +59 -0
- package/dist/nextjs-vite/export-mocks/navigation/index.d.ts +28 -0
- package/dist/nextjs-vite/export-mocks/navigation/index.js +58 -0
- package/dist/nextjs-vite/export-mocks/router/index.d.ts +34 -0
- package/dist/nextjs-vite/export-mocks/router/index.js +63 -0
- package/dist/nextjs-vite/index.d.ts +92 -0
- package/dist/nextjs-vite/index.js +58 -0
- package/dist/nextjs-vite/node/index.d.ts +6 -0
- package/dist/nextjs-vite/node/index.js +20 -0
- package/dist/nextjs-vite/preset.js +648 -0
- package/dist/nextjs-vite/preview.d.ts +20 -0
- package/dist/nextjs-vite/preview.js +11 -0
- package/dist/nextjs-vite/vite-plugin/index.d.ts +6 -0
- package/dist/nextjs-vite/vite-plugin/index.js +19 -0
- package/dist/nextjs-vite-plugin/index.d.ts +28 -0
- package/dist/nextjs-vite-plugin/index.js +923 -0
- package/dist/nextjs-vite-plugin/mocks/storybook.global.js +29 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-context.js +8 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/image-default-loader.js +23 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-image.js +28 -0
- package/dist/nextjs-vite-plugin/plugins/next-image/alias/next-legacy-image.js +17 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/cache/index.js +29 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/dynamic/index.js +40 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/headers/index.js +55 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/link/index.js +63 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/navigation/index.js +71 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/router/index.js +74 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/rsc/server-only.js +7 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/alias/safe-stable-stringify/index.js +13 -0
- package/dist/nextjs-vite-plugin/plugins/next-mocks/compatibility/draft-mode.compat.js +7 -0
- package/dist/node-logger/index.d.ts +495 -0
- package/dist/node-logger/index.js +42 -0
- package/dist/oxc-parser/index.d.ts +99 -0
- package/dist/oxc-parser/index.js +275 -0
- package/dist/oxc-parser/worker.js +37 -0
- package/dist/preview/_chunks/runtime-BIzIdDbb.js +10263 -0
- package/dist/preview/_chunks/runtime-BTPtVY1p.js +1102 -0
- package/dist/preview/_chunks/runtime-BZSnICCg.js +8484 -0
- package/dist/preview/_chunks/runtime-BdGkqNEt.js +45 -0
- package/dist/preview/_chunks/runtime-BwSxqk3t.js +63 -0
- package/dist/preview/_chunks/runtime-CqHxptiK.js +6143 -0
- package/dist/preview/_chunks/runtime-CsV4HZPV.js +5064 -0
- package/dist/preview/_chunks/runtime-CxZK_Ln3.js +284 -0
- package/dist/preview/_chunks/runtime-DZToXfvO.js +9767 -0
- package/dist/preview/_chunks/runtime-DrTjJkPY.js +3872 -0
- package/dist/preview/_chunks/runtime-DuHdxMFA.js +387 -0
- package/dist/preview/_chunks/runtime-iXdo8CR8.js +3635 -0
- package/dist/preview/_chunks/runtime-q3wt0e_N.js +6838 -0
- package/dist/preview/globals.d.ts +16 -0
- package/dist/preview/globals.js +20 -0
- package/dist/preview/runtime.js +6 -0
- package/dist/preview-api/index.d.ts +4 -0
- package/dist/preview-api/index.js +147 -0
- package/dist/preview-errors.d.ts +186 -0
- package/dist/preview-errors.js +56 -0
- package/dist/react/docgen/docgen-worker.js +38 -0
- package/dist/react/entry-preview-argtypes.js +9 -0
- package/dist/react/entry-preview-docs.js +12 -0
- package/dist/react/entry-preview-rsc.js +11 -0
- package/dist/react/entry-preview.js +21 -0
- package/dist/react/index.d.ts +119 -0
- package/dist/react/index.js +26 -0
- package/dist/react/preset.js +301 -0
- package/dist/react/preview.d.ts +2 -0
- package/dist/react/preview.js +11 -0
- package/dist/react-native/bin/get-stories.js +34 -0
- package/dist/react-native/index.d.ts +160 -0
- package/dist/react-native/index.js +1547 -0
- package/dist/react-native/metro/node.d.ts +83 -0
- package/dist/react-native/metro/node.js +21 -0
- package/dist/react-native/metro/withStorybook.d.ts +2269 -0
- package/dist/react-native/metro/withStorybook.js +138 -0
- package/dist/react-native/preview.d.ts +6 -0
- package/dist/react-native/preview.js +20 -0
- package/dist/react-native/scripts/generate.d.ts +22 -0
- package/dist/react-native/scripts/generate.js +18 -0
- package/dist/react-native/stub.js +20 -0
- package/dist/react-native-theming/index.d.ts +175 -0
- package/dist/react-native-theming/index.js +2591 -0
- package/dist/react-native-ui/index.d.ts +130 -0
- package/dist/react-native-ui/index.js +1448 -0
- package/dist/react-native-ui-common/index.d.ts +230 -0
- package/dist/react-native-ui-common/index.js +514 -0
- package/dist/react-vite/index.d.ts +4 -0
- package/dist/react-vite/index.js +8 -0
- package/dist/react-vite/node/index.d.ts +6 -0
- package/dist/react-vite/node/index.js +20 -0
- package/dist/react-vite/preset.d.ts +6 -0
- package/dist/react-vite/preset.js +21 -0
- package/dist/router/index.d.ts +141 -0
- package/dist/router/index.js +1217 -0
- package/dist/server-errors.d.ts +2 -0
- package/dist/server-errors.js +149 -0
- package/dist/shared/open-service/index.d.ts +3 -0
- package/dist/shared/open-service/index.js +115 -0
- package/dist/shared/open-service/services/docgen/worker/docgen-worker.js +75 -0
- package/dist/shared/open-service/toolsets/docs/public.d.ts +1296 -0
- package/dist/shared/open-service/toolsets/docs/public.js +991 -0
- package/dist/telemetry/index.d.ts +314 -0
- package/dist/telemetry/index.js +103 -0
- package/dist/test/index.d.ts +158 -0
- package/dist/test/index.js +19421 -0
- package/dist/theming/create.d.ts +15 -0
- package/dist/theming/create.js +11 -0
- package/dist/theming/index.d.ts +54 -0
- package/dist/theming/index.js +511 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +48 -0
- package/dist/viewport/index.d.ts +275 -0
- package/dist/viewport/index.js +21 -0
- package/package.json +1054 -4
- package/template/nextjs-vite/cli/.eslintrc.json +6 -0
- package/template/nextjs-vite/cli/js/Button.jsx +42 -0
- package/template/nextjs-vite/cli/js/Button.stories.js +49 -0
- package/template/nextjs-vite/cli/js/Configure.mdx +470 -0
- package/template/nextjs-vite/cli/js/Header.jsx +58 -0
- package/template/nextjs-vite/cli/js/Header.stories.js +30 -0
- package/template/nextjs-vite/cli/js/Page.jsx +68 -0
- package/template/nextjs-vite/cli/js/Page.stories.js +28 -0
- package/template/nextjs-vite/cli/ts/Button.stories.ts +54 -0
- package/template/nextjs-vite/cli/ts/Button.tsx +39 -0
- package/template/nextjs-vite/cli/ts/Configure.mdx +446 -0
- package/template/nextjs-vite/cli/ts/Header.stories.ts +34 -0
- package/template/nextjs-vite/cli/ts/Header.tsx +54 -0
- package/template/nextjs-vite/cli/ts/Page.stories.ts +33 -0
- package/template/nextjs-vite/cli/ts/Page.tsx +73 -0
- package/template/react/cli/.eslintrc.json +5 -0
- package/template/react/cli/js/Button.jsx +39 -0
- package/template/react/cli/js/Button.stories.js +49 -0
- package/template/react/cli/js/Header.jsx +56 -0
- package/template/react/cli/js/Header.stories.js +29 -0
- package/template/react/cli/js/Page.jsx +69 -0
- package/template/react/cli/js/Page.stories.js +28 -0
- package/template/react/cli/ts/Button.stories.ts +54 -0
- package/template/react/cli/ts/Button.tsx +37 -0
- package/template/react/cli/ts/Header.stories.ts +34 -0
- package/template/react/cli/ts/Header.tsx +56 -0
- package/template/react/cli/ts/Page.stories.ts +33 -0
- package/template/react/cli/ts/Page.tsx +73 -0
- package/template/react-vite/cli/.eslintrc.json +5 -0
- package/template/react-vite/cli/js/Button.jsx +39 -0
- package/template/react-vite/cli/js/Button.stories.js +49 -0
- package/template/react-vite/cli/js/Header.jsx +56 -0
- package/template/react-vite/cli/js/Header.stories.js +29 -0
- package/template/react-vite/cli/js/Page.jsx +69 -0
- package/template/react-vite/cli/js/Page.stories.js +28 -0
- package/template/react-vite/cli/ts/Button.stories.ts +54 -0
- package/template/react-vite/cli/ts/Button.tsx +37 -0
- package/template/react-vite/cli/ts/Header.stories.ts +34 -0
- package/template/react-vite/cli/ts/Header.tsx +56 -0
- package/template/react-vite/cli/ts/Page.stories.ts +33 -0
- 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
|
+
};
|