@salla.sa/twilight-theme-engine 1.0.0-beta.4
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/README.md +165 -0
- package/dist/AddToCartForm-HOWNKCKX.js +304 -0
- package/dist/AddToCartForm-HOWNKCKX.js.map +1 -0
- package/dist/BlogAuthorPage-W3BZIJHJ.js +101 -0
- package/dist/BlogAuthorPage-W3BZIJHJ.js.map +1 -0
- package/dist/BlogCategoryPage-AIAJ5JBR.js +101 -0
- package/dist/BlogCategoryPage-AIAJ5JBR.js.map +1 -0
- package/dist/BlogPage-4BYF2EQW.js +190 -0
- package/dist/BlogPage-4BYF2EQW.js.map +1 -0
- package/dist/BlogSinglePage-AMNAUMWW.js +187 -0
- package/dist/BlogSinglePage-AMNAUMWW.js.map +1 -0
- package/dist/BlogTagPage-ELG2H5N5.js +101 -0
- package/dist/BlogTagPage-ELG2H5N5.js.map +1 -0
- package/dist/BrandsPage-ZSO3PYAV.js +127 -0
- package/dist/BrandsPage-ZSO3PYAV.js.map +1 -0
- package/dist/Breadcrumb-N32QFMVK.js +152 -0
- package/dist/Breadcrumb-N32QFMVK.js.map +1 -0
- package/dist/CartItem-SGTGOTEC.js +171 -0
- package/dist/CartItem-SGTGOTEC.js.map +1 -0
- package/dist/CartSummary-OKDGVSX2.js +236 -0
- package/dist/CartSummary-OKDGVSX2.js.map +1 -0
- package/dist/Copyright-F3HLYXFJ.js +9 -0
- package/dist/Copyright-F3HLYXFJ.js.map +1 -0
- package/dist/CurrencySymbol-TARAYUOT.js +11 -0
- package/dist/CurrencySymbol-TARAYUOT.js.map +1 -0
- package/dist/CustomerLayout-LB4E2LHT.js +68 -0
- package/dist/CustomerLayout-LB4E2LHT.js.map +1 -0
- package/dist/ErrorPage-TK4U3ENF.js +6 -0
- package/dist/ErrorPage-TK4U3ENF.js.map +1 -0
- package/dist/Footer-UVCSKTW3.js +39 -0
- package/dist/Footer-UVCSKTW3.js.map +1 -0
- package/dist/GoogleTag-4LHWC365.js +52 -0
- package/dist/GoogleTag-4LHWC365.js.map +1 -0
- package/dist/Header-BF6SPZJC.js +15 -0
- package/dist/Header-BF6SPZJC.js.map +1 -0
- package/dist/ImageModal-WLJM3WIE.js +41 -0
- package/dist/ImageModal-WLJM3WIE.js.map +1 -0
- package/dist/LoyaltyPage-X4PHPUFC.js +188 -0
- package/dist/LoyaltyPage-X4PHPUFC.js.map +1 -0
- package/dist/MainMenu-R3EWTNNC.js +91 -0
- package/dist/MainMenu-R3EWTNNC.js.map +1 -0
- package/dist/MasterLayout-5JLM7IMW.js +39 -0
- package/dist/MasterLayout-5JLM7IMW.js.map +1 -0
- package/dist/MobileMenu-QXESUQXC.js +175 -0
- package/dist/MobileMenu-QXESUQXC.js.map +1 -0
- package/dist/NoContent-PBGESHBJ.js +21 -0
- package/dist/NoContent-PBGESHBJ.js.map +1 -0
- package/dist/NotificationsPage-V6UIPDJD.js +84 -0
- package/dist/NotificationsPage-V6UIPDJD.js.map +1 -0
- package/dist/OrderSinglePage-ZMEKPLE3.js +441 -0
- package/dist/OrderSinglePage-ZMEKPLE3.js.map +1 -0
- package/dist/OrdersPage-EAATVPYK.js +184 -0
- package/dist/OrdersPage-EAATVPYK.js.map +1 -0
- package/dist/PageSingle-Y6ARZ5LS.js +28 -0
- package/dist/PageSingle-Y6ARZ5LS.js.map +1 -0
- package/dist/PreOrderNotification-ZVTGNV7K.js +23 -0
- package/dist/PreOrderNotification-ZVTGNV7K.js.map +1 -0
- package/dist/PriceQuoteButton-RAAPL4N4.js +26 -0
- package/dist/PriceQuoteButton-RAAPL4N4.js.map +1 -0
- package/dist/ProductDetails-KTY4ZSFM.js +194 -0
- package/dist/ProductDetails-KTY4ZSFM.js.map +1 -0
- package/dist/ProfilePage-6SK34MDJ.js +64 -0
- package/dist/ProfilePage-6SK34MDJ.js.map +1 -0
- package/dist/RenderWhenVisible-TR7G2KUC.js +50 -0
- package/dist/RenderWhenVisible-TR7G2KUC.js.map +1 -0
- package/dist/SeoCartWidget-XF4GEJK7.js +109 -0
- package/dist/SeoCartWidget-XF4GEJK7.js.map +1 -0
- package/dist/SettingsPage-DPYARBPO.js +51 -0
- package/dist/SettingsPage-DPYARBPO.js.map +1 -0
- package/dist/SiftSnippet-X74S5KDO.js +29 -0
- package/dist/SiftSnippet-X74S5KDO.js.map +1 -0
- package/dist/StoreClosedNotification-KSB2GPEZ.js +91 -0
- package/dist/StoreClosedNotification-KSB2GPEZ.js.map +1 -0
- package/dist/Testimonials-MZCVP66E.js +26 -0
- package/dist/Testimonials-MZCVP66E.js.map +1 -0
- package/dist/TestimonialsPage-4OFS5Z4V.js +77 -0
- package/dist/TestimonialsPage-4OFS5Z4V.js.map +1 -0
- package/dist/ThankYouPage-C7PA3RJP.js +236 -0
- package/dist/ThankYouPage-C7PA3RJP.js.map +1 -0
- package/dist/TwilightBundles-5F2H75VV.js +46 -0
- package/dist/TwilightBundles-5F2H75VV.js.map +1 -0
- package/dist/WalletPage-66XGZKO7.js +189 -0
- package/dist/WalletPage-66XGZKO7.js.map +1 -0
- package/dist/WidgetHead-FXEPCB23.js +7 -0
- package/dist/WidgetHead-FXEPCB23.js.map +1 -0
- package/dist/WishlistPage-7ZZYHBSZ.js +144 -0
- package/dist/WishlistPage-7ZZYHBSZ.js.map +1 -0
- package/dist/ambient/salla-components.d.ts +312 -0
- package/dist/ambient/virtual-modules.d.ts +22 -0
- package/dist/api/apps.d.ts +28 -0
- package/dist/api/apps.d.ts.map +1 -0
- package/dist/api/apps.js +26 -0
- package/dist/api/apps.js.map +1 -0
- package/dist/api/blog.d.ts +61 -0
- package/dist/api/blog.d.ts.map +1 -0
- package/dist/api/brands.d.ts +25 -0
- package/dist/api/brands.d.ts.map +1 -0
- package/dist/api/brands.js +40 -0
- package/dist/api/brands.js.map +1 -0
- package/dist/api/cart.d.ts +21 -0
- package/dist/api/cart.d.ts.map +1 -0
- package/dist/api/cart.js +40 -0
- package/dist/api/cart.js.map +1 -0
- package/dist/api/category.d.ts +31 -0
- package/dist/api/category.d.ts.map +1 -0
- package/dist/api/category.js +40 -0
- package/dist/api/category.js.map +1 -0
- package/dist/api/client.d.ts +17 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +7 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/home.d.ts +15 -0
- package/dist/api/home.d.ts.map +1 -0
- package/dist/api/home.js +8 -0
- package/dist/api/home.js.map +1 -0
- package/dist/api/loyalty.d.ts +25 -0
- package/dist/api/loyalty.d.ts.map +1 -0
- package/dist/api/loyalty.js +40 -0
- package/dist/api/loyalty.js.map +1 -0
- package/dist/api/menu.d.ts +16 -0
- package/dist/api/menu.d.ts.map +1 -0
- package/dist/api/menu.js +8 -0
- package/dist/api/menu.js.map +1 -0
- package/dist/api/notification.d.ts +26 -0
- package/dist/api/notification.d.ts.map +1 -0
- package/dist/api/order.d.ts +74 -0
- package/dist/api/order.d.ts.map +1 -0
- package/dist/api/order.js +40 -0
- package/dist/api/order.js.map +1 -0
- package/dist/api/page.d.ts +16 -0
- package/dist/api/page.d.ts.map +1 -0
- package/dist/api/page.js +40 -0
- package/dist/api/page.js.map +1 -0
- package/dist/api/product.d.ts +80 -0
- package/dist/api/product.d.ts.map +1 -0
- package/dist/api/product.js +40 -0
- package/dist/api/product.js.map +1 -0
- package/dist/api/profile.d.ts +9 -0
- package/dist/api/profile.d.ts.map +1 -0
- package/dist/api/profile.js +23 -0
- package/dist/api/profile.js.map +1 -0
- package/dist/api/store.d.ts +46 -0
- package/dist/api/store.d.ts.map +1 -0
- package/dist/api/store.js +8 -0
- package/dist/api/store.js.map +1 -0
- package/dist/api/translations.d.ts +15 -0
- package/dist/api/translations.d.ts.map +1 -0
- package/dist/api/translations.js +8 -0
- package/dist/api/translations.js.map +1 -0
- package/dist/api/types.d.ts +54 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +3 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/user.d.ts +15 -0
- package/dist/api/user.d.ts.map +1 -0
- package/dist/api/user.js +8 -0
- package/dist/api/user.js.map +1 -0
- package/dist/api/wallet.d.ts +30 -0
- package/dist/api/wallet.d.ts.map +1 -0
- package/dist/api/wishlist.d.ts +25 -0
- package/dist/api/wishlist.d.ts.map +1 -0
- package/dist/chunk-25SSLQAJ.js +67 -0
- package/dist/chunk-25SSLQAJ.js.map +1 -0
- package/dist/chunk-2FU6CVSB.js +18 -0
- package/dist/chunk-2FU6CVSB.js.map +1 -0
- package/dist/chunk-2KF5JJU6.js +169 -0
- package/dist/chunk-2KF5JJU6.js.map +1 -0
- package/dist/chunk-2TB2LTL2.js +103 -0
- package/dist/chunk-2TB2LTL2.js.map +1 -0
- package/dist/chunk-3DCZJDDK.js +10 -0
- package/dist/chunk-3DCZJDDK.js.map +1 -0
- package/dist/chunk-3UHSMGPY.js +145 -0
- package/dist/chunk-3UHSMGPY.js.map +1 -0
- package/dist/chunk-4EQEYRZ7.js +65 -0
- package/dist/chunk-4EQEYRZ7.js.map +1 -0
- package/dist/chunk-562ZMVI3.js +592 -0
- package/dist/chunk-562ZMVI3.js.map +1 -0
- package/dist/chunk-5Q6PFLDN.js +20 -0
- package/dist/chunk-5Q6PFLDN.js.map +1 -0
- package/dist/chunk-6B6VCCMC.js +28 -0
- package/dist/chunk-6B6VCCMC.js.map +1 -0
- package/dist/chunk-6BZ5TKEV.js +44 -0
- package/dist/chunk-6BZ5TKEV.js.map +1 -0
- package/dist/chunk-6NBBXERE.js +24 -0
- package/dist/chunk-6NBBXERE.js.map +1 -0
- package/dist/chunk-6Q5BFHFA.js +88 -0
- package/dist/chunk-6Q5BFHFA.js.map +1 -0
- package/dist/chunk-6YX4RS55.js +33 -0
- package/dist/chunk-6YX4RS55.js.map +1 -0
- package/dist/chunk-7LP7D75V.js +14 -0
- package/dist/chunk-7LP7D75V.js.map +1 -0
- package/dist/chunk-A5ZRUAMT.js +16 -0
- package/dist/chunk-A5ZRUAMT.js.map +1 -0
- package/dist/chunk-B3EFOE57.js +32 -0
- package/dist/chunk-B3EFOE57.js.map +1 -0
- package/dist/chunk-BT6HEEAP.js +31 -0
- package/dist/chunk-BT6HEEAP.js.map +1 -0
- package/dist/chunk-BVSJPBJ6.js +26 -0
- package/dist/chunk-BVSJPBJ6.js.map +1 -0
- package/dist/chunk-BWFBVXT3.js +13 -0
- package/dist/chunk-BWFBVXT3.js.map +1 -0
- package/dist/chunk-CW625T2E.js +62 -0
- package/dist/chunk-CW625T2E.js.map +1 -0
- package/dist/chunk-DFMO5KBU.js +67 -0
- package/dist/chunk-DFMO5KBU.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +10 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-EQ5ZGAVR.js +89 -0
- package/dist/chunk-EQ5ZGAVR.js.map +1 -0
- package/dist/chunk-FBFPH5BB.js +34 -0
- package/dist/chunk-FBFPH5BB.js.map +1 -0
- package/dist/chunk-G7ALL4BC.js +52 -0
- package/dist/chunk-G7ALL4BC.js.map +1 -0
- package/dist/chunk-GBWCXUPD.js +99 -0
- package/dist/chunk-GBWCXUPD.js.map +1 -0
- package/dist/chunk-GLM3RPCP.js +1167 -0
- package/dist/chunk-GLM3RPCP.js.map +1 -0
- package/dist/chunk-GN34LCTG.js +92 -0
- package/dist/chunk-GN34LCTG.js.map +1 -0
- package/dist/chunk-GO34DE35.js +247 -0
- package/dist/chunk-GO34DE35.js.map +1 -0
- package/dist/chunk-HOSHJBPS.js +52 -0
- package/dist/chunk-HOSHJBPS.js.map +1 -0
- package/dist/chunk-I5Z4NJBB.js +17 -0
- package/dist/chunk-I5Z4NJBB.js.map +1 -0
- package/dist/chunk-J37AYLWL.js +66 -0
- package/dist/chunk-J37AYLWL.js.map +1 -0
- package/dist/chunk-KCKHA75V.js +19 -0
- package/dist/chunk-KCKHA75V.js.map +1 -0
- package/dist/chunk-KIPZQN3Y.js +158 -0
- package/dist/chunk-KIPZQN3Y.js.map +1 -0
- package/dist/chunk-LBUMC5PB.js +34 -0
- package/dist/chunk-LBUMC5PB.js.map +1 -0
- package/dist/chunk-LSDIFHXZ.js +80 -0
- package/dist/chunk-LSDIFHXZ.js.map +1 -0
- package/dist/chunk-M6ICEIWY.js +25 -0
- package/dist/chunk-M6ICEIWY.js.map +1 -0
- package/dist/chunk-MTONGOJD.js +42 -0
- package/dist/chunk-MTONGOJD.js.map +1 -0
- package/dist/chunk-MXQCE3KA.js +173 -0
- package/dist/chunk-MXQCE3KA.js.map +1 -0
- package/dist/chunk-N5RSKJP4.js +65 -0
- package/dist/chunk-N5RSKJP4.js.map +1 -0
- package/dist/chunk-N7CCSGZF.js +3 -0
- package/dist/chunk-N7CCSGZF.js.map +1 -0
- package/dist/chunk-NBHI5X36.js +27 -0
- package/dist/chunk-NBHI5X36.js.map +1 -0
- package/dist/chunk-NSX6XPDU.js +673 -0
- package/dist/chunk-NSX6XPDU.js.map +1 -0
- package/dist/chunk-O2UOV5RK.js +32 -0
- package/dist/chunk-O2UOV5RK.js.map +1 -0
- package/dist/chunk-OZTGUF7K.js +66 -0
- package/dist/chunk-OZTGUF7K.js.map +1 -0
- package/dist/chunk-Q3VACSSR.js +21 -0
- package/dist/chunk-Q3VACSSR.js.map +1 -0
- package/dist/chunk-QTDGM2SO.js +123 -0
- package/dist/chunk-QTDGM2SO.js.map +1 -0
- package/dist/chunk-QYL5OHAV.js +70 -0
- package/dist/chunk-QYL5OHAV.js.map +1 -0
- package/dist/chunk-RH32IGQD.js +372 -0
- package/dist/chunk-RH32IGQD.js.map +1 -0
- package/dist/chunk-RUHSV4Z6.js +12 -0
- package/dist/chunk-RUHSV4Z6.js.map +1 -0
- package/dist/chunk-RYBA3JDM.js +33 -0
- package/dist/chunk-RYBA3JDM.js.map +1 -0
- package/dist/chunk-SBIXBX6J.js +29 -0
- package/dist/chunk-SBIXBX6J.js.map +1 -0
- package/dist/chunk-SSRNIBVV.js +75 -0
- package/dist/chunk-SSRNIBVV.js.map +1 -0
- package/dist/chunk-SVZOWI7E.js +51 -0
- package/dist/chunk-SVZOWI7E.js.map +1 -0
- package/dist/chunk-SYHTMNYF.js +89 -0
- package/dist/chunk-SYHTMNYF.js.map +1 -0
- package/dist/chunk-T72DAX7R.js +65 -0
- package/dist/chunk-T72DAX7R.js.map +1 -0
- package/dist/chunk-TCSNNCRH.js +23 -0
- package/dist/chunk-TCSNNCRH.js.map +1 -0
- package/dist/chunk-TQLEQSXE.js +48 -0
- package/dist/chunk-TQLEQSXE.js.map +1 -0
- package/dist/chunk-TRUQDEMI.js +14 -0
- package/dist/chunk-TRUQDEMI.js.map +1 -0
- package/dist/chunk-TZ3E5BN4.js +91 -0
- package/dist/chunk-TZ3E5BN4.js.map +1 -0
- package/dist/chunk-TZ4YD5CU.js +16 -0
- package/dist/chunk-TZ4YD5CU.js.map +1 -0
- package/dist/chunk-U7HAK5U7.js +105 -0
- package/dist/chunk-U7HAK5U7.js.map +1 -0
- package/dist/chunk-UE3BUFZI.js +16 -0
- package/dist/chunk-UE3BUFZI.js.map +1 -0
- package/dist/chunk-UIX3W2PN.js +56 -0
- package/dist/chunk-UIX3W2PN.js.map +1 -0
- package/dist/chunk-VVRYP6IL.js +61 -0
- package/dist/chunk-VVRYP6IL.js.map +1 -0
- package/dist/chunk-VVZNW5CB.js +49 -0
- package/dist/chunk-VVZNW5CB.js.map +1 -0
- package/dist/chunk-XHGF75TM.js +133 -0
- package/dist/chunk-XHGF75TM.js.map +1 -0
- package/dist/chunk-XUI3TRXF.js +26 -0
- package/dist/chunk-XUI3TRXF.js.map +1 -0
- package/dist/chunk-YCYTBRYB.js +30 -0
- package/dist/chunk-YCYTBRYB.js.map +1 -0
- package/dist/chunk-YMVLYYLU.js +25 -0
- package/dist/chunk-YMVLYYLU.js.map +1 -0
- package/dist/chunk-Z653O7MX.js +10 -0
- package/dist/chunk-Z653O7MX.js.map +1 -0
- package/dist/chunk-ZCH7W7DZ.js +30 -0
- package/dist/chunk-ZCH7W7DZ.js.map +1 -0
- package/dist/components/Component.d.ts +8 -0
- package/dist/components/Component.d.ts.map +1 -0
- package/dist/components/ComponentRegistry.d.ts +19 -0
- package/dist/components/ComponentRegistry.d.ts.map +1 -0
- package/dist/components/cart/CartItem.d.ts +8 -0
- package/dist/components/cart/CartItem.d.ts.map +1 -0
- package/dist/components/cart/CartSummary.d.ts +12 -0
- package/dist/components/cart/CartSummary.d.ts.map +1 -0
- package/dist/components/cart/PreOrderNotification.d.ts +2 -0
- package/dist/components/cart/PreOrderNotification.d.ts.map +1 -0
- package/dist/components/cart/PriceQuoteButton.d.ts +2 -0
- package/dist/components/cart/PriceQuoteButton.d.ts.map +1 -0
- package/dist/components/cart/SeoCartWidget.d.ts +34 -0
- package/dist/components/cart/SeoCartWidget.d.ts.map +1 -0
- package/dist/components/cart/index.d.ts +4 -0
- package/dist/components/cart/index.d.ts.map +1 -0
- package/dist/components/cart/index.js +4 -0
- package/dist/components/cart/index.js.map +1 -0
- package/dist/components/cart/lazy.d.ts +8 -0
- package/dist/components/cart/lazy.d.ts.map +1 -0
- package/dist/components/collapse/Collapse.d.ts +51 -0
- package/dist/components/collapse/Collapse.d.ts.map +1 -0
- package/dist/components/collapse/index.d.ts +36 -0
- package/dist/components/collapse/index.d.ts.map +1 -0
- package/dist/components/collapse/index.js +44 -0
- package/dist/components/collapse/index.js.map +1 -0
- package/dist/components/common/Breadcrumb.d.ts +7 -0
- package/dist/components/common/Breadcrumb.d.ts.map +1 -0
- package/dist/components/common/BreadcrumbJsonLd.d.ts +8 -0
- package/dist/components/common/BreadcrumbJsonLd.d.ts.map +1 -0
- package/dist/components/common/BreadcrumbTrail.d.ts +8 -0
- package/dist/components/common/BreadcrumbTrail.d.ts.map +1 -0
- package/dist/components/common/CurrencySymbol.d.ts +8 -0
- package/dist/components/common/CurrencySymbol.d.ts.map +1 -0
- package/dist/components/common/DeferredData.d.ts +20 -0
- package/dist/components/common/DeferredData.d.ts.map +1 -0
- package/dist/components/common/ErrorPage.d.ts +18 -0
- package/dist/components/common/ErrorPage.d.ts.map +1 -0
- package/dist/components/common/Image.d.ts +28 -0
- package/dist/components/common/Image.d.ts.map +1 -0
- package/dist/components/common/Link.d.ts +21 -0
- package/dist/components/common/Link.d.ts.map +1 -0
- package/dist/components/common/Link.types.d.ts +82 -0
- package/dist/components/common/Link.types.d.ts.map +1 -0
- package/dist/components/common/NoContent.d.ts +9 -0
- package/dist/components/common/NoContent.d.ts.map +1 -0
- package/dist/components/common/RenderWhenVisible.d.ts +23 -0
- package/dist/components/common/RenderWhenVisible.d.ts.map +1 -0
- package/dist/components/common/index.d.ts +11 -0
- package/dist/components/common/index.d.ts.map +1 -0
- package/dist/components/common/index.js +6 -0
- package/dist/components/common/index.js.map +1 -0
- package/dist/components/common/lazy.d.ts +13 -0
- package/dist/components/common/lazy.d.ts.map +1 -0
- package/dist/components/common/types.d.ts +7 -0
- package/dist/components/common/types.d.ts.map +1 -0
- package/dist/components/defineComponent.d.ts +11 -0
- package/dist/components/defineComponent.d.ts.map +1 -0
- package/dist/components/drawer/Drawer.d.ts +53 -0
- package/dist/components/drawer/Drawer.d.ts.map +1 -0
- package/dist/components/drawer/index.d.ts +32 -0
- package/dist/components/drawer/index.d.ts.map +1 -0
- package/dist/components/drawer/index.js +40 -0
- package/dist/components/drawer/index.js.map +1 -0
- package/dist/components/dropdown/Dropdown.d.ts +63 -0
- package/dist/components/dropdown/Dropdown.d.ts.map +1 -0
- package/dist/components/dropdown/index.d.ts +34 -0
- package/dist/components/dropdown/index.d.ts.map +1 -0
- package/dist/components/dropdown/index.js +67 -0
- package/dist/components/dropdown/index.js.map +1 -0
- package/dist/components/home/BundleComponent.d.ts +9 -0
- package/dist/components/home/BundleComponent.d.ts.map +1 -0
- package/dist/components/home/ComponentErrorBoundary.d.ts +22 -0
- package/dist/components/home/ComponentErrorBoundary.d.ts.map +1 -0
- package/dist/components/home/FeaturedProductsStyle1.d.ts +26 -0
- package/dist/components/home/FeaturedProductsStyle1.d.ts.map +1 -0
- package/dist/components/home/FeaturedProductsStyle2.d.ts +25 -0
- package/dist/components/home/FeaturedProductsStyle2.d.ts.map +1 -0
- package/dist/components/home/FeaturedProductsStyle3.d.ts +20 -0
- package/dist/components/home/FeaturedProductsStyle3.d.ts.map +1 -0
- package/dist/components/home/FixedBanner.d.ts +16 -0
- package/dist/components/home/FixedBanner.d.ts.map +1 -0
- package/dist/components/home/FixedProducts.d.ts +18 -0
- package/dist/components/home/FixedProducts.d.ts.map +1 -0
- package/dist/components/home/HomePageRenderer.d.ts +37 -0
- package/dist/components/home/HomePageRenderer.d.ts.map +1 -0
- package/dist/components/home/ParallaxBackground.d.ts +17 -0
- package/dist/components/home/ParallaxBackground.d.ts.map +1 -0
- package/dist/components/home/PhotosSlider.d.ts +16 -0
- package/dist/components/home/PhotosSlider.d.ts.map +1 -0
- package/dist/components/home/ProductsSlider.d.ts +25 -0
- package/dist/components/home/ProductsSlider.d.ts.map +1 -0
- package/dist/components/home/SquarePhotos.d.ts +21 -0
- package/dist/components/home/SquarePhotos.d.ts.map +1 -0
- package/dist/components/home/StoreFeatures.d.ts +9 -0
- package/dist/components/home/StoreFeatures.d.ts.map +1 -0
- package/dist/components/home/Testimonials.d.ts +15 -0
- package/dist/components/home/Testimonials.d.ts.map +1 -0
- package/dist/components/home/Youtube.d.ts +9 -0
- package/dist/components/home/Youtube.d.ts.map +1 -0
- package/dist/components/home/index.d.ts +9 -0
- package/dist/components/home/index.d.ts.map +1 -0
- package/dist/components/home/index.js +43 -0
- package/dist/components/home/index.js.map +1 -0
- package/dist/components/home/lazy.d.ts +14 -0
- package/dist/components/home/lazy.d.ts.map +1 -0
- package/dist/components/home/register.d.ts +4 -0
- package/dist/components/home/register.d.ts.map +1 -0
- package/dist/components/home/types.d.ts +6 -0
- package/dist/components/home/types.d.ts.map +1 -0
- package/dist/components/layout/Copyright.d.ts +8 -0
- package/dist/components/layout/Copyright.d.ts.map +1 -0
- package/dist/components/layout/CustomerLayout.d.ts +8 -0
- package/dist/components/layout/CustomerLayout.d.ts.map +1 -0
- package/dist/components/layout/Footer.d.ts +2 -0
- package/dist/components/layout/Footer.d.ts.map +1 -0
- package/dist/components/layout/Header.d.ts +7 -0
- package/dist/components/layout/Header.d.ts.map +1 -0
- package/dist/components/layout/MasterLayout.d.ts +3 -0
- package/dist/components/layout/MasterLayout.d.ts.map +1 -0
- package/dist/components/layout/WidgetHead.d.ts +21 -0
- package/dist/components/layout/WidgetHead.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +5 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +25 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/layout/lazy.d.ts +11 -0
- package/dist/components/layout/lazy.d.ts.map +1 -0
- package/dist/components/layout/types.d.ts +10 -0
- package/dist/components/layout/types.d.ts.map +1 -0
- package/dist/components/modal/ImageModal.d.ts +37 -0
- package/dist/components/modal/ImageModal.d.ts.map +1 -0
- package/dist/components/modal/Modal.d.ts +78 -0
- package/dist/components/modal/Modal.d.ts.map +1 -0
- package/dist/components/modal/index.d.ts +30 -0
- package/dist/components/modal/index.d.ts.map +1 -0
- package/dist/components/modal/index.js +5 -0
- package/dist/components/modal/index.js.map +1 -0
- package/dist/components/modal/lazy.d.ts +7 -0
- package/dist/components/modal/lazy.d.ts.map +1 -0
- package/dist/components/navigation/MainMenu.d.ts +2 -0
- package/dist/components/navigation/MainMenu.d.ts.map +1 -0
- package/dist/components/navigation/MobileMenu.d.ts +6 -0
- package/dist/components/navigation/MobileMenu.d.ts.map +1 -0
- package/dist/components/navigation/index.d.ts +3 -0
- package/dist/components/navigation/index.d.ts.map +1 -0
- package/dist/components/navigation/lazy.d.ts +7 -0
- package/dist/components/navigation/lazy.d.ts.map +1 -0
- package/dist/components/product/AddToCartForm.d.ts +12 -0
- package/dist/components/product/AddToCartForm.d.ts.map +1 -0
- package/dist/components/product/ProductCard.d.ts +16 -0
- package/dist/components/product/ProductCard.d.ts.map +1 -0
- package/dist/components/product/ProductDetails.d.ts +8 -0
- package/dist/components/product/ProductDetails.d.ts.map +1 -0
- package/dist/components/product/ProductGallery.d.ts +7 -0
- package/dist/components/product/ProductGallery.d.ts.map +1 -0
- package/dist/components/product/index.d.ts +8 -0
- package/dist/components/product/index.d.ts.map +1 -0
- package/dist/components/product/index.js +41 -0
- package/dist/components/product/index.js.map +1 -0
- package/dist/components/product/lazy.d.ts +3 -0
- package/dist/components/product/lazy.d.ts.map +1 -0
- package/dist/components/store/StoreClosedNotification.d.ts +17 -0
- package/dist/components/store/StoreClosedNotification.d.ts.map +1 -0
- package/dist/components/store/index.d.ts +3 -0
- package/dist/components/store/index.d.ts.map +1 -0
- package/dist/components/store/lazy.d.ts +3 -0
- package/dist/components/store/lazy.d.ts.map +1 -0
- package/dist/components/toast/Toaster.d.ts +8 -0
- package/dist/components/toast/Toaster.d.ts.map +1 -0
- package/dist/components/toast/index.d.ts +4 -0
- package/dist/components/toast/index.d.ts.map +1 -0
- package/dist/components/toast/index.js +5 -0
- package/dist/components/toast/index.js.map +1 -0
- package/dist/components/toast/types.d.ts +27 -0
- package/dist/components/toast/types.d.ts.map +1 -0
- package/dist/components/toast/useToast.d.ts +5 -0
- package/dist/components/toast/useToast.d.ts.map +1 -0
- package/dist/components/tracking/GoogleTag.d.ts +13 -0
- package/dist/components/tracking/GoogleTag.d.ts.map +1 -0
- package/dist/components/tracking/SiftSnippet.d.ts +16 -0
- package/dist/components/tracking/SiftSnippet.d.ts.map +1 -0
- package/dist/components/tracking/TwilightBundles.d.ts +11 -0
- package/dist/components/tracking/TwilightBundles.d.ts.map +1 -0
- package/dist/components/tracking/index.d.ts +5 -0
- package/dist/components/tracking/index.d.ts.map +1 -0
- package/dist/components/tracking/lazy.d.ts +5 -0
- package/dist/components/tracking/lazy.d.ts.map +1 -0
- package/dist/components/useComponent.d.ts +4 -0
- package/dist/components/useComponent.d.ts.map +1 -0
- package/dist/contexts/CartContext.d.ts +34 -0
- package/dist/contexts/CartContext.d.ts.map +1 -0
- package/dist/contexts/ProductContext.d.ts +34 -0
- package/dist/contexts/ProductContext.d.ts.map +1 -0
- package/dist/contexts/index.d.ts +3 -0
- package/dist/contexts/index.d.ts.map +1 -0
- package/dist/document-class-PLK3HUM6.js +21 -0
- package/dist/document-class-PLK3HUM6.js.map +1 -0
- package/dist/dom/document.d.ts +26 -0
- package/dist/dom/document.d.ts.map +1 -0
- package/dist/dom/index.d.ts +24 -0
- package/dist/dom/index.d.ts.map +1 -0
- package/dist/dom.d.ts +1 -0
- package/dist/dom.js +18 -0
- package/dist/dom.js.map +1 -0
- package/dist/eslint/index.d.ts +17 -0
- package/dist/eslint/index.d.ts.map +1 -0
- package/dist/eslint/index.js +86 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/hooks/HookRegistry.d.ts +47 -0
- package/dist/hooks/HookRegistry.d.ts.map +1 -0
- package/dist/hooks/HookRegistry.js +4 -0
- package/dist/hooks/HookRegistry.js.map +1 -0
- package/dist/hooks/HookSlot.d.ts +96 -0
- package/dist/hooks/HookSlot.d.ts.map +1 -0
- package/dist/hooks/HookSlot.js +6 -0
- package/dist/hooks/HookSlot.js.map +1 -0
- package/dist/hooks/index.d.ts +27 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +39 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registerDefaultHooks.d.ts +18 -0
- package/dist/hooks/registerDefaultHooks.d.ts.map +1 -0
- package/dist/hooks/types.d.ts +100 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/useAsset.d.ts +26 -0
- package/dist/hooks/useAsset.d.ts.map +1 -0
- package/dist/hooks/useAsset.js +5 -0
- package/dist/hooks/useAsset.js.map +1 -0
- package/dist/hooks/useAsyncFn.d.ts +68 -0
- package/dist/hooks/useAsyncFn.d.ts.map +1 -0
- package/dist/hooks/useAsyncFn.js +4 -0
- package/dist/hooks/useAsyncFn.js.map +1 -0
- package/dist/hooks/useBlogLike.d.ts +7 -0
- package/dist/hooks/useBlogLike.d.ts.map +1 -0
- package/dist/hooks/useBlogLike.js +7 -0
- package/dist/hooks/useBlogLike.js.map +1 -0
- package/dist/hooks/useBreadcrumbs.d.ts +3 -0
- package/dist/hooks/useBreadcrumbs.d.ts.map +1 -0
- package/dist/hooks/useComments.d.ts +36 -0
- package/dist/hooks/useComments.d.ts.map +1 -0
- package/dist/hooks/useComments.js +4 -0
- package/dist/hooks/useComments.js.map +1 -0
- package/dist/hooks/useCoupon.d.ts +66 -0
- package/dist/hooks/useCoupon.d.ts.map +1 -0
- package/dist/hooks/useCoupon.js +5 -0
- package/dist/hooks/useCoupon.js.map +1 -0
- package/dist/hooks/useDate.d.ts +24 -0
- package/dist/hooks/useDate.d.ts.map +1 -0
- package/dist/hooks/useDocumentClass.d.ts +42 -0
- package/dist/hooks/useDocumentClass.d.ts.map +1 -0
- package/dist/hooks/useDocumentClass.js +5 -0
- package/dist/hooks/useDocumentClass.js.map +1 -0
- package/dist/hooks/useGtm.d.ts +38 -0
- package/dist/hooks/useGtm.d.ts.map +1 -0
- package/dist/hooks/useHook.d.ts +24 -0
- package/dist/hooks/useHook.d.ts.map +1 -0
- package/dist/hooks/useHook.js +5 -0
- package/dist/hooks/useHook.js.map +1 -0
- package/dist/hooks/useIsClient.d.ts +7 -0
- package/dist/hooks/useIsClient.d.ts.map +1 -0
- package/dist/hooks/useMoney.d.ts +26 -0
- package/dist/hooks/useMoney.d.ts.map +1 -0
- package/dist/hooks/useMoney.js +39 -0
- package/dist/hooks/useMoney.js.map +1 -0
- package/dist/hooks/useNumber.d.ts +24 -0
- package/dist/hooks/useNumber.d.ts.map +1 -0
- package/dist/hooks/useOpeningHours.d.ts +28 -0
- package/dist/hooks/useOpeningHours.d.ts.map +1 -0
- package/dist/hooks/usePageConfig.d.ts +44 -0
- package/dist/hooks/usePageConfig.d.ts.map +1 -0
- package/dist/hooks/useProduct.d.ts +47 -0
- package/dist/hooks/useProduct.d.ts.map +1 -0
- package/dist/hooks/useProduct.js +4 -0
- package/dist/hooks/useProduct.js.map +1 -0
- package/dist/hooks/useStore.d.ts +36 -0
- package/dist/hooks/useStore.d.ts.map +1 -0
- package/dist/hooks/useStore.js +39 -0
- package/dist/hooks/useStore.js.map +1 -0
- package/dist/hooks/useTheme.d.ts +41 -0
- package/dist/hooks/useTheme.d.ts.map +1 -0
- package/dist/hooks/useTheme.js +5 -0
- package/dist/hooks/useTheme.js.map +1 -0
- package/dist/hooks/useUser.d.ts +8 -0
- package/dist/hooks/useUser.d.ts.map +1 -0
- package/dist/hooks/useUser.js +9 -0
- package/dist/hooks/useUser.js.map +1 -0
- package/dist/hooks/useWishlist.d.ts +5 -0
- package/dist/hooks/useWishlist.d.ts.map +1 -0
- package/dist/hooks/useWishlist.js +5 -0
- package/dist/hooks/useWishlist.js.map +1 -0
- package/dist/i18n.d.ts +1 -0
- package/dist/i18n.js +5 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/analytics/gtm.d.ts +38 -0
- package/dist/lib/analytics/gtm.d.ts.map +1 -0
- package/dist/lib/services/index.d.ts +1 -0
- package/dist/lib/services/index.d.ts.map +1 -0
- package/dist/navigation-N4H65RUN.js +17 -0
- package/dist/navigation-N4H65RUN.js.map +1 -0
- package/dist/navigation-YCYHW4MK.js +10 -0
- package/dist/navigation-YCYHW4MK.js.map +1 -0
- package/dist/nextjs/document-class.d.ts +92 -0
- package/dist/nextjs/document-class.d.ts.map +1 -0
- package/dist/nextjs/head.d.ts +36 -0
- package/dist/nextjs/head.d.ts.map +1 -0
- package/dist/nextjs/index.d.ts +29 -0
- package/dist/nextjs/index.d.ts.map +1 -0
- package/dist/nextjs/link.d.ts +14 -0
- package/dist/nextjs/link.d.ts.map +1 -0
- package/dist/nextjs/navigation.d.ts +9 -0
- package/dist/nextjs/navigation.d.ts.map +1 -0
- package/dist/nextjs/router.d.ts +15 -0
- package/dist/nextjs/router.d.ts.map +1 -0
- package/dist/nextjs.d.ts +1 -0
- package/dist/nextjs.js +22 -0
- package/dist/nextjs.js.map +1 -0
- package/dist/not-found-BJ3VK5VJ.js +69 -0
- package/dist/not-found-BJ3VK5VJ.js.map +1 -0
- package/dist/providers/DocumentClassProvider.d.ts +56 -0
- package/dist/providers/DocumentClassProvider.d.ts.map +1 -0
- package/dist/providers/DocumentSyncRegistry.d.ts +20 -0
- package/dist/providers/DocumentSyncRegistry.d.ts.map +1 -0
- package/dist/providers/LinkProvider.d.ts +34 -0
- package/dist/providers/LinkProvider.d.ts.map +1 -0
- package/dist/providers/NavigationProvider.d.ts +223 -0
- package/dist/providers/NavigationProvider.d.ts.map +1 -0
- package/dist/providers/TwilightProvider.d.ts +7 -0
- package/dist/providers/TwilightProvider.d.ts.map +1 -0
- package/dist/providers/i18n-factory.d.ts +17 -0
- package/dist/providers/i18n-factory.d.ts.map +1 -0
- package/dist/providers/i18n.d.ts +31 -0
- package/dist/providers/i18n.d.ts.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/locale-constants.d.ts +17 -0
- package/dist/providers/locale-constants.d.ts.map +1 -0
- package/dist/providers/salla-sdk.types.d.ts +352 -0
- package/dist/providers/salla-sdk.types.d.ts.map +1 -0
- package/dist/providers/twilight-context.d.ts +4 -0
- package/dist/providers/twilight-context.d.ts.map +1 -0
- package/dist/providers/twilight-init.d.ts +24 -0
- package/dist/providers/twilight-init.d.ts.map +1 -0
- package/dist/providers/twilight-theme.d.ts +9 -0
- package/dist/providers/twilight-theme.d.ts.map +1 -0
- package/dist/providers/twilight.types.d.ts +95 -0
- package/dist/providers/twilight.types.d.ts.map +1 -0
- package/dist/router/context.d.ts +3 -0
- package/dist/router/context.d.ts.map +1 -0
- package/dist/router/index.d.ts +4 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/route-ids.d.ts +37 -0
- package/dist/router/route-ids.d.ts.map +1 -0
- package/dist/routes/account/index.d.ts +8 -0
- package/dist/routes/account/index.d.ts.map +1 -0
- package/dist/routes/account/notifications/NotificationsPage.d.ts +3 -0
- package/dist/routes/account/notifications/NotificationsPage.d.ts.map +1 -0
- package/dist/routes/account/notifications/index.d.ts +17 -0
- package/dist/routes/account/notifications/index.d.ts.map +1 -0
- package/dist/routes/account/notifications/loader.d.ts +5 -0
- package/dist/routes/account/notifications/loader.d.ts.map +1 -0
- package/dist/routes/account/notifications/types.d.ts +17 -0
- package/dist/routes/account/notifications/types.d.ts.map +1 -0
- package/dist/routes/account/orders/OrderSinglePage.d.ts +3 -0
- package/dist/routes/account/orders/OrderSinglePage.d.ts.map +1 -0
- package/dist/routes/account/orders/OrdersPage.d.ts +3 -0
- package/dist/routes/account/orders/OrdersPage.d.ts.map +1 -0
- package/dist/routes/account/orders/index.d.ts +35 -0
- package/dist/routes/account/orders/index.d.ts.map +1 -0
- package/dist/routes/account/orders/loader.d.ts +11 -0
- package/dist/routes/account/orders/loader.d.ts.map +1 -0
- package/dist/routes/account/orders/types.d.ts +22 -0
- package/dist/routes/account/orders/types.d.ts.map +1 -0
- package/dist/routes/account/orders.d.ts +1 -0
- package/dist/routes/account/orders.js +42 -0
- package/dist/routes/account/orders.js.map +1 -0
- package/dist/routes/account/profile/ProfilePage.d.ts +3 -0
- package/dist/routes/account/profile/ProfilePage.d.ts.map +1 -0
- package/dist/routes/account/profile/index.d.ts +17 -0
- package/dist/routes/account/profile/index.d.ts.map +1 -0
- package/dist/routes/account/profile/loader.d.ts +5 -0
- package/dist/routes/account/profile/loader.d.ts.map +1 -0
- package/dist/routes/account/profile/types.d.ts +5 -0
- package/dist/routes/account/profile/types.d.ts.map +1 -0
- package/dist/routes/account/settings/SettingsPage.d.ts +3 -0
- package/dist/routes/account/settings/SettingsPage.d.ts.map +1 -0
- package/dist/routes/account/settings/index.d.ts +17 -0
- package/dist/routes/account/settings/index.d.ts.map +1 -0
- package/dist/routes/account/settings/loader.d.ts +5 -0
- package/dist/routes/account/settings/loader.d.ts.map +1 -0
- package/dist/routes/account/settings/types.d.ts +5 -0
- package/dist/routes/account/settings/types.d.ts.map +1 -0
- package/dist/routes/account/types.d.ts +300 -0
- package/dist/routes/account/types.d.ts.map +1 -0
- package/dist/routes/account/wallet/WalletPage.d.ts +3 -0
- package/dist/routes/account/wallet/WalletPage.d.ts.map +1 -0
- package/dist/routes/account/wallet/index.d.ts +16 -0
- package/dist/routes/account/wallet/index.d.ts.map +1 -0
- package/dist/routes/account/wallet/loader.d.ts +4 -0
- package/dist/routes/account/wallet/loader.d.ts.map +1 -0
- package/dist/routes/account/wallet/types.d.ts +11 -0
- package/dist/routes/account/wallet/types.d.ts.map +1 -0
- package/dist/routes/account/wishlist/WishlistPage.d.ts +3 -0
- package/dist/routes/account/wishlist/WishlistPage.d.ts.map +1 -0
- package/dist/routes/account/wishlist/index.d.ts +16 -0
- package/dist/routes/account/wishlist/index.d.ts.map +1 -0
- package/dist/routes/account/wishlist/loader.d.ts +4 -0
- package/dist/routes/account/wishlist/loader.d.ts.map +1 -0
- package/dist/routes/account/wishlist/types.d.ts +9 -0
- package/dist/routes/account/wishlist/types.d.ts.map +1 -0
- package/dist/routes/account.d.ts +1 -0
- package/dist/routes/account.js +253 -0
- package/dist/routes/account.js.map +1 -0
- package/dist/routes/blog/BlogAuthorPage.d.ts +3 -0
- package/dist/routes/blog/BlogAuthorPage.d.ts.map +1 -0
- package/dist/routes/blog/BlogCategoryPage.d.ts +3 -0
- package/dist/routes/blog/BlogCategoryPage.d.ts.map +1 -0
- package/dist/routes/blog/BlogPage.d.ts +3 -0
- package/dist/routes/blog/BlogPage.d.ts.map +1 -0
- package/dist/routes/blog/BlogSinglePage.d.ts +3 -0
- package/dist/routes/blog/BlogSinglePage.d.ts.map +1 -0
- package/dist/routes/blog/BlogTagPage.d.ts +3 -0
- package/dist/routes/blog/BlogTagPage.d.ts.map +1 -0
- package/dist/routes/blog/components.d.ts +14 -0
- package/dist/routes/blog/components.d.ts.map +1 -0
- package/dist/routes/blog/index.d.ts +76 -0
- package/dist/routes/blog/index.d.ts.map +1 -0
- package/dist/routes/blog/loader.d.ts +16 -0
- package/dist/routes/blog/loader.d.ts.map +1 -0
- package/dist/routes/blog/types.d.ts +92 -0
- package/dist/routes/blog/types.d.ts.map +1 -0
- package/dist/routes/blog.d.ts +1 -0
- package/dist/routes/blog.js +303 -0
- package/dist/routes/blog.js.map +1 -0
- package/dist/routes/brands/BrandsPage.d.ts +5 -0
- package/dist/routes/brands/BrandsPage.d.ts.map +1 -0
- package/dist/routes/brands/index.d.ts +20 -0
- package/dist/routes/brands/index.d.ts.map +1 -0
- package/dist/routes/brands/loader.d.ts +3 -0
- package/dist/routes/brands/loader.d.ts.map +1 -0
- package/dist/routes/brands/types.d.ts +32 -0
- package/dist/routes/brands/types.d.ts.map +1 -0
- package/dist/routes/brands.d.ts +1 -0
- package/dist/routes/brands.js +92 -0
- package/dist/routes/brands.js.map +1 -0
- package/dist/routes/cart/CartPage.d.ts +3 -0
- package/dist/routes/cart/CartPage.d.ts.map +1 -0
- package/dist/routes/cart/index.d.ts +20 -0
- package/dist/routes/cart/index.d.ts.map +1 -0
- package/dist/routes/cart/loader.d.ts +8 -0
- package/dist/routes/cart/loader.d.ts.map +1 -0
- package/dist/routes/cart/types.d.ts +6 -0
- package/dist/routes/cart/types.d.ts.map +1 -0
- package/dist/routes/cart.d.ts +1 -0
- package/dist/routes/cart.js +168 -0
- package/dist/routes/cart.js.map +1 -0
- package/dist/routes/home/HomePage.d.ts +5 -0
- package/dist/routes/home/HomePage.d.ts.map +1 -0
- package/dist/routes/home/index.d.ts +22 -0
- package/dist/routes/home/index.d.ts.map +1 -0
- package/dist/routes/home/loader.d.ts +12 -0
- package/dist/routes/home/loader.d.ts.map +1 -0
- package/dist/routes/home/types.d.ts +10 -0
- package/dist/routes/home/types.d.ts.map +1 -0
- package/dist/routes/home.d.ts +1 -0
- package/dist/routes/home.js +46 -0
- package/dist/routes/home.js.map +1 -0
- package/dist/routes/index.d.ts +20 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +40 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/lazy.d.ts +23 -0
- package/dist/routes/lazy.d.ts.map +1 -0
- package/dist/routes/loyalty/LoyaltyPage.d.ts +3 -0
- package/dist/routes/loyalty/LoyaltyPage.d.ts.map +1 -0
- package/dist/routes/loyalty/index.d.ts +19 -0
- package/dist/routes/loyalty/index.d.ts.map +1 -0
- package/dist/routes/loyalty/loader.d.ts +3 -0
- package/dist/routes/loyalty/loader.d.ts.map +1 -0
- package/dist/routes/loyalty/types.d.ts +96 -0
- package/dist/routes/loyalty/types.d.ts.map +1 -0
- package/dist/routes/loyalty.d.ts +1 -0
- package/dist/routes/loyalty.js +73 -0
- package/dist/routes/loyalty.js.map +1 -0
- package/dist/routes/not-found.d.ts +15 -0
- package/dist/routes/not-found.d.ts.map +1 -0
- package/dist/routes/page/PageSingle.d.ts +3 -0
- package/dist/routes/page/PageSingle.d.ts.map +1 -0
- package/dist/routes/page/index.d.ts +21 -0
- package/dist/routes/page/index.d.ts.map +1 -0
- package/dist/routes/page/loader.d.ts +6 -0
- package/dist/routes/page/loader.d.ts.map +1 -0
- package/dist/routes/page/types.d.ts +32 -0
- package/dist/routes/page/types.d.ts.map +1 -0
- package/dist/routes/page.d.ts +1 -0
- package/dist/routes/page.js +97 -0
- package/dist/routes/page.js.map +1 -0
- package/dist/routes/product/ProductPage.d.ts +3 -0
- package/dist/routes/product/ProductPage.d.ts.map +1 -0
- package/dist/routes/product/index.d.ts +21 -0
- package/dist/routes/product/index.d.ts.map +1 -0
- package/dist/routes/product/loader.d.ts +6 -0
- package/dist/routes/product/loader.d.ts.map +1 -0
- package/dist/routes/product/types.d.ts +6 -0
- package/dist/routes/product/types.d.ts.map +1 -0
- package/dist/routes/product-listing/ProductListPage.d.ts +13 -0
- package/dist/routes/product-listing/ProductListPage.d.ts.map +1 -0
- package/dist/routes/product-listing/index.d.ts +16 -0
- package/dist/routes/product-listing/index.d.ts.map +1 -0
- package/dist/routes/product-listing/loader.d.ts +3 -0
- package/dist/routes/product-listing/loader.d.ts.map +1 -0
- package/dist/routes/product-listing/types.d.ts +71 -0
- package/dist/routes/product-listing/types.d.ts.map +1 -0
- package/dist/routes/product-listing.d.ts +1 -0
- package/dist/routes/product-listing.js +516 -0
- package/dist/routes/product-listing.js.map +1 -0
- package/dist/routes/product.d.ts +1 -0
- package/dist/routes/product.js +225 -0
- package/dist/routes/product.js.map +1 -0
- package/dist/routes/root/beforeLoad.d.ts +21 -0
- package/dist/routes/root/beforeLoad.d.ts.map +1 -0
- package/dist/routes/root/head.d.ts +5 -0
- package/dist/routes/root/head.d.ts.map +1 -0
- package/dist/routes/root/index.d.ts +3 -0
- package/dist/routes/root/index.d.ts.map +1 -0
- package/dist/routes/seo-redirects.d.ts +19 -0
- package/dist/routes/seo-redirects.d.ts.map +1 -0
- package/dist/routes/seo-redirects.js +40 -0
- package/dist/routes/seo-redirects.js.map +1 -0
- package/dist/routes/testimonials/TestimonialsPage.d.ts +3 -0
- package/dist/routes/testimonials/TestimonialsPage.d.ts.map +1 -0
- package/dist/routes/testimonials/index.d.ts +19 -0
- package/dist/routes/testimonials/index.d.ts.map +1 -0
- package/dist/routes/testimonials/loader.d.ts +5 -0
- package/dist/routes/testimonials/loader.d.ts.map +1 -0
- package/dist/routes/testimonials/types.d.ts +5 -0
- package/dist/routes/testimonials/types.d.ts.map +1 -0
- package/dist/routes/testimonials.d.ts +1 -0
- package/dist/routes/testimonials.js +49 -0
- package/dist/routes/testimonials.js.map +1 -0
- package/dist/routes/thank-you/ThankYouPage.d.ts +3 -0
- package/dist/routes/thank-you/ThankYouPage.d.ts.map +1 -0
- package/dist/routes/thank-you/index.d.ts +20 -0
- package/dist/routes/thank-you/index.d.ts.map +1 -0
- package/dist/routes/thank-you/loader.d.ts +5 -0
- package/dist/routes/thank-you/loader.d.ts.map +1 -0
- package/dist/routes/thank-you/types.d.ts +14 -0
- package/dist/routes/thank-you/types.d.ts.map +1 -0
- package/dist/routes/thank-you.d.ts +1 -0
- package/dist/routes/thank-you.js +95 -0
- package/dist/routes/thank-you.js.map +1 -0
- package/dist/routes/types.d.ts +36 -0
- package/dist/routes/types.d.ts.map +1 -0
- package/dist/sentry/client.d.ts +6 -0
- package/dist/sentry/client.d.ts.map +1 -0
- package/dist/sentry/client.js +17 -0
- package/dist/sentry/client.js.map +1 -0
- package/dist/sentry/server.d.ts +10 -0
- package/dist/sentry/server.d.ts.map +1 -0
- package/dist/sentry/server.js +16 -0
- package/dist/sentry/server.js.map +1 -0
- package/dist/skeleton.d.ts +4 -0
- package/dist/skeleton.d.ts.map +1 -0
- package/dist/skeleton.js +47 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/tanstack/document-class.d.ts +44 -0
- package/dist/tanstack/document-class.d.ts.map +1 -0
- package/dist/tanstack/head.d.ts +24 -0
- package/dist/tanstack/head.d.ts.map +1 -0
- package/dist/tanstack/index.d.ts +28 -0
- package/dist/tanstack/index.d.ts.map +1 -0
- package/dist/tanstack/link.d.ts +18 -0
- package/dist/tanstack/link.d.ts.map +1 -0
- package/dist/tanstack/middleware/earlyHints.d.ts +3 -0
- package/dist/tanstack/middleware/earlyHints.d.ts.map +1 -0
- package/dist/tanstack/middleware/twilight.d.ts +7 -0
- package/dist/tanstack/middleware/twilight.d.ts.map +1 -0
- package/dist/tanstack/navigation.d.ts +13 -0
- package/dist/tanstack/navigation.d.ts.map +1 -0
- package/dist/tanstack/router.d.ts +85 -0
- package/dist/tanstack/router.d.ts.map +1 -0
- package/dist/tanstack/templates/account-layout.d.ts +8 -0
- package/dist/tanstack/templates/account-layout.d.ts.map +1 -0
- package/dist/tanstack/templates/index.d.ts +4 -0
- package/dist/tanstack/templates/index.d.ts.map +1 -0
- package/dist/tanstack/templates/locale-wrapper.d.ts +15 -0
- package/dist/tanstack/templates/locale-wrapper.d.ts.map +1 -0
- package/dist/tanstack/templates/redirect.d.ts +6 -0
- package/dist/tanstack/templates/redirect.d.ts.map +1 -0
- package/dist/tanstack.d.ts +1 -0
- package/dist/tanstack.js +137 -0
- package/dist/tanstack.js.map +1 -0
- package/dist/twilight/context.d.ts +46 -0
- package/dist/twilight/context.d.ts.map +1 -0
- package/dist/twilight/index.d.ts +3 -0
- package/dist/twilight/index.d.ts.map +1 -0
- package/dist/types/hooks.d.ts +58 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/index.d.ts +724 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/apply-theme.d.ts +3 -0
- package/dist/utils/apply-theme.d.ts.map +1 -0
- package/dist/utils/asset.d.ts +27 -0
- package/dist/utils/asset.d.ts.map +1 -0
- package/dist/utils/baseHead.d.ts +23 -0
- package/dist/utils/baseHead.d.ts.map +1 -0
- package/dist/utils/baseHead.js +5 -0
- package/dist/utils/baseHead.js.map +1 -0
- package/dist/utils/breadcrumb.d.ts +5 -0
- package/dist/utils/breadcrumb.d.ts.map +1 -0
- package/dist/utils/cdn-image.d.ts +5 -0
- package/dist/utils/cdn-image.d.ts.map +1 -0
- package/dist/utils/color.d.ts +34 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/cookies.d.ts +16 -0
- package/dist/utils/cookies.d.ts.map +1 -0
- package/dist/utils/device.d.ts +19 -0
- package/dist/utils/device.d.ts.map +1 -0
- package/dist/utils/document-class.d.ts +67 -0
- package/dist/utils/document-class.d.ts.map +1 -0
- package/dist/utils/errors.d.ts +4 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/head.d.ts +100 -0
- package/dist/utils/head.d.ts.map +1 -0
- package/dist/utils/head.js +4 -0
- package/dist/utils/head.js.map +1 -0
- package/dist/utils/index.d.ts +22 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +15 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/number.d.ts +21 -0
- package/dist/utils/number.d.ts.map +1 -0
- package/dist/utils/salla-plural.d.ts +14 -0
- package/dist/utils/salla-plural.d.ts.map +1 -0
- package/dist/utils/sanitize.d.ts +2 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/sdk-events.d.ts +25 -0
- package/dist/utils/sdk-events.d.ts.map +1 -0
- package/dist/utils/sdk-helpers.d.ts +30 -0
- package/dist/utils/sdk-helpers.d.ts.map +1 -0
- package/dist/utils/sort-options.d.ts +8 -0
- package/dist/utils/sort-options.d.ts.map +1 -0
- package/dist/vite/adapters/index.d.ts +18 -0
- package/dist/vite/adapters/index.d.ts.map +1 -0
- package/dist/vite/adapters/nextjs.adapter.d.ts +12 -0
- package/dist/vite/adapters/nextjs.adapter.d.ts.map +1 -0
- package/dist/vite/adapters/tanstack.adapter.d.ts +71 -0
- package/dist/vite/adapters/tanstack.adapter.d.ts.map +1 -0
- package/dist/vite/index.d.ts +6 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +2193 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/plugins/best-practices/best-practices.plugin.d.ts +4 -0
- package/dist/vite/plugins/best-practices/best-practices.plugin.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/hooks-registry.d.ts +27 -0
- package/dist/vite/plugins/best-practices/hooks-registry.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/reporter.d.ts +4 -0
- package/dist/vite/plugins/best-practices/reporter.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/index.d.ts +4 -0
- package/dist/vite/plugins/best-practices/rules/index.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/no-deep-component-import.d.ts +3 -0
- package/dist/vite/plugins/best-practices/rules/no-deep-component-import.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/no-direct-product-card-import.d.ts +3 -0
- package/dist/vite/plugins/best-practices/rules/no-direct-product-card-import.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/no-img-without-dimensions.d.ts +3 -0
- package/dist/vite/plugins/best-practices/rules/no-img-without-dimensions.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/no-manual-dom.d.ts +3 -0
- package/dist/vite/plugins/best-practices/rules/no-manual-dom.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/no-window-location-reload.d.ts +3 -0
- package/dist/vite/plugins/best-practices/rules/no-window-location-reload.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/rules/require-page-hooks.d.ts +16 -0
- package/dist/vite/plugins/best-practices/rules/require-page-hooks.d.ts.map +1 -0
- package/dist/vite/plugins/best-practices/types.d.ts +34 -0
- package/dist/vite/plugins/best-practices/types.d.ts.map +1 -0
- package/dist/vite/plugins/package-aliases.plugin.d.ts +3 -0
- package/dist/vite/plugins/package-aliases.plugin.d.ts.map +1 -0
- package/dist/vite/plugins/salla-hydration.plugin.d.ts +12 -0
- package/dist/vite/plugins/salla-hydration.plugin.d.ts.map +1 -0
- package/dist/vite/plugins/theme-translations.plugin.d.ts +20 -0
- package/dist/vite/plugins/theme-translations.plugin.d.ts.map +1 -0
- package/dist/vite/twilight-react.d.ts +22 -0
- package/dist/vite/twilight-react.d.ts.map +1 -0
- package/dist/vite/types.d.ts +110 -0
- package/dist/vite/types.d.ts.map +1 -0
- package/package.json +474 -0
|
@@ -0,0 +1,2193 @@
|
|
|
1
|
+
import { tanstackHeadAdapter } from '../chunk-6Q5BFHFA.js';
|
|
2
|
+
import { nextjsHeadAdapter } from '../chunk-HOSHJBPS.js';
|
|
3
|
+
import { setHeadAdapter } from '../chunk-B3EFOE57.js';
|
|
4
|
+
import { RouteId } from '../chunk-MTONGOJD.js';
|
|
5
|
+
import '../chunk-KIPZQN3Y.js';
|
|
6
|
+
import '../chunk-T72DAX7R.js';
|
|
7
|
+
import '../chunk-DGUM43GV.js';
|
|
8
|
+
import { readdir, readFile } from 'fs/promises';
|
|
9
|
+
import { dirname, resolve, relative, join, basename, sep } from 'path';
|
|
10
|
+
import { parseSync } from 'oxc-parser';
|
|
11
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, statSync } from 'fs';
|
|
12
|
+
import { createHash } from 'crypto';
|
|
13
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
14
|
+
import Module, { createRequire } from 'module';
|
|
15
|
+
import { transformSync } from 'esbuild';
|
|
16
|
+
|
|
17
|
+
// src/vite/plugins/salla-hydration.plugin.ts
|
|
18
|
+
var TAG_START_RE = /<(?:salla|custom)-[a-z][a-z0-9-]*/g;
|
|
19
|
+
function webHydrationPlugin() {
|
|
20
|
+
return {
|
|
21
|
+
name: "twilight:web-hydration",
|
|
22
|
+
enforce: "pre",
|
|
23
|
+
transform(code, id) {
|
|
24
|
+
if (!/\.[jt]sx$/.test(id)) return null;
|
|
25
|
+
if (!/<(?:salla|custom)-[a-z]/.test(code)) return null;
|
|
26
|
+
let result = "";
|
|
27
|
+
let lastIndex = 0;
|
|
28
|
+
TAG_START_RE.lastIndex = 0;
|
|
29
|
+
let match;
|
|
30
|
+
while ((match = TAG_START_RE.exec(code)) !== null) {
|
|
31
|
+
const tagStart = match.index;
|
|
32
|
+
const afterTag = tagStart + match[0].length;
|
|
33
|
+
let i = afterTag;
|
|
34
|
+
let braceDepth = 0;
|
|
35
|
+
let closingPos = -1;
|
|
36
|
+
let isSelfClosing = false;
|
|
37
|
+
while (i < code.length) {
|
|
38
|
+
const ch = code[i];
|
|
39
|
+
if (ch === "{") {
|
|
40
|
+
braceDepth++;
|
|
41
|
+
} else if (ch === "}") {
|
|
42
|
+
braceDepth--;
|
|
43
|
+
} else if (braceDepth === 0 && ch === ">") {
|
|
44
|
+
isSelfClosing = i > 0 && code[i - 1] === "/";
|
|
45
|
+
closingPos = i;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
i++;
|
|
49
|
+
}
|
|
50
|
+
if (closingPos === -1) break;
|
|
51
|
+
const propsSlice = code.slice(afterTag, isSelfClosing ? closingPos - 1 : closingPos);
|
|
52
|
+
if (propsSlice.includes("suppressHydrationWarning")) {
|
|
53
|
+
TAG_START_RE.lastIndex = closingPos + 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const insertPos = isSelfClosing ? closingPos - 1 : closingPos;
|
|
57
|
+
result += code.slice(lastIndex, insertPos) + " suppressHydrationWarning";
|
|
58
|
+
lastIndex = insertPos;
|
|
59
|
+
TAG_START_RE.lastIndex = closingPos + 1;
|
|
60
|
+
}
|
|
61
|
+
if (lastIndex === 0) return null;
|
|
62
|
+
result += code.slice(lastIndex);
|
|
63
|
+
return { code: result };
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
var VIRTUAL_ID = "virtual:twilight/theme-translations";
|
|
68
|
+
var RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
69
|
+
function themeTranslationsPlugin(localesDir) {
|
|
70
|
+
let resolvedLocalesDir;
|
|
71
|
+
return {
|
|
72
|
+
name: "twilight:translations",
|
|
73
|
+
configResolved(config) {
|
|
74
|
+
if (localesDir) {
|
|
75
|
+
resolvedLocalesDir = resolve(config.root, localesDir);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
resolveId(id) {
|
|
79
|
+
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
80
|
+
},
|
|
81
|
+
async load(id) {
|
|
82
|
+
if (id !== RESOLVED_ID) return;
|
|
83
|
+
if (!resolvedLocalesDir) return "export default {};";
|
|
84
|
+
try {
|
|
85
|
+
const files = await readdir(resolvedLocalesDir);
|
|
86
|
+
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
87
|
+
if (jsonFiles.length === 0) return "export default {};";
|
|
88
|
+
const entries = [];
|
|
89
|
+
for (const file of jsonFiles) {
|
|
90
|
+
const locale = basename(file, ".json");
|
|
91
|
+
const content = await readFile(join(resolvedLocalesDir, file), "utf-8");
|
|
92
|
+
const data = JSON.parse(content);
|
|
93
|
+
entries.push(` '${locale}.trans': ${JSON.stringify(data)}`);
|
|
94
|
+
}
|
|
95
|
+
return `export default {
|
|
96
|
+
${entries.join(",\n")}
|
|
97
|
+
};
|
|
98
|
+
`;
|
|
99
|
+
} catch {
|
|
100
|
+
return "export default {};";
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
configureServer(server) {
|
|
104
|
+
if (!resolvedLocalesDir) return;
|
|
105
|
+
server.watcher.add(join(resolvedLocalesDir, "*.json"));
|
|
106
|
+
server.watcher.on("change", (file) => {
|
|
107
|
+
if (file.startsWith(resolvedLocalesDir) && file.endsWith(".json")) {
|
|
108
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
109
|
+
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
server.watcher.on("add", (file) => {
|
|
113
|
+
if (file.startsWith(resolvedLocalesDir) && file.endsWith(".json")) {
|
|
114
|
+
const mod = server.moduleGraph.getModuleById(RESOLVED_ID);
|
|
115
|
+
if (mod) server.moduleGraph.invalidateModule(mod);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/vite/plugins/best-practices/rules/no-deep-component-import.ts
|
|
123
|
+
var COMPONENT_FOLDERS = [
|
|
124
|
+
"common",
|
|
125
|
+
"cart",
|
|
126
|
+
"product",
|
|
127
|
+
"layout",
|
|
128
|
+
"home",
|
|
129
|
+
"modal",
|
|
130
|
+
"drawer",
|
|
131
|
+
"dropdown",
|
|
132
|
+
"collapse",
|
|
133
|
+
"toast",
|
|
134
|
+
"navigation"
|
|
135
|
+
];
|
|
136
|
+
var FOLDERS_PATTERN = COMPONENT_FOLDERS.join("|");
|
|
137
|
+
var DEEP_IMPORT_RE = new RegExp(
|
|
138
|
+
`(?:import|from)\\s+.*['"](?:\\.\\.\\/)+(${FOLDERS_PATTERN})\\/([^'"]+)['"]`,
|
|
139
|
+
"g"
|
|
140
|
+
);
|
|
141
|
+
var noDeepComponentImport = {
|
|
142
|
+
name: "no-deep-component-import",
|
|
143
|
+
description: "Enforce imports from barrel exports (index.ts) to preserve lazy loading.",
|
|
144
|
+
severity: "warn",
|
|
145
|
+
check(context) {
|
|
146
|
+
const violations = [];
|
|
147
|
+
const lines = context.code.split("\n");
|
|
148
|
+
for (let i = 0; i < lines.length; i++) {
|
|
149
|
+
const line = lines[i];
|
|
150
|
+
if (!line.includes("import") && !line.includes("from")) continue;
|
|
151
|
+
DEEP_IMPORT_RE.lastIndex = 0;
|
|
152
|
+
let match;
|
|
153
|
+
while ((match = DEEP_IMPORT_RE.exec(line)) !== null) {
|
|
154
|
+
const folder = match[1];
|
|
155
|
+
violations.push({
|
|
156
|
+
rule: "no-deep-component-import",
|
|
157
|
+
message: `Deep import into '${folder}/' bypasses the barrel export and breaks lazy loading.`,
|
|
158
|
+
line: i + 1,
|
|
159
|
+
recommendation: `Import from '../${folder}' (barrel export) instead of '../${folder}/${match[2]}'.`
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return violations;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// src/vite/plugins/best-practices/rules/no-window-location-reload.ts
|
|
168
|
+
var RELOAD_RE = /window\s*\.\s*location\s*\.\s*reload\s*\(/g;
|
|
169
|
+
var noWindowLocationReload = {
|
|
170
|
+
name: "no-window-location-reload",
|
|
171
|
+
description: "Disallow window.location.reload() in React components.",
|
|
172
|
+
severity: "error",
|
|
173
|
+
check(context) {
|
|
174
|
+
const violations = [];
|
|
175
|
+
const lines = context.code.split("\n");
|
|
176
|
+
for (let i = 0; i < lines.length; i++) {
|
|
177
|
+
const line = lines[i];
|
|
178
|
+
RELOAD_RE.lastIndex = 0;
|
|
179
|
+
if (RELOAD_RE.test(line)) {
|
|
180
|
+
violations.push({
|
|
181
|
+
rule: "no-window-location-reload",
|
|
182
|
+
message: "window.location.reload() forces a full page reload, discarding React state.",
|
|
183
|
+
line: i + 1,
|
|
184
|
+
recommendation: "Use React state for empty-state handling, React key prop to remount components, or router.invalidate() to refetch loaders."
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return violations;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// src/vite/plugins/best-practices/rules/no-manual-dom.ts
|
|
193
|
+
var DOM_METHODS = [
|
|
194
|
+
{ pattern: /document\s*\.\s*querySelector\s*\(/g, name: "document.querySelector()" },
|
|
195
|
+
{ pattern: /document\s*\.\s*querySelectorAll\s*\(/g, name: "document.querySelectorAll()" },
|
|
196
|
+
{ pattern: /document\s*\.\s*getElementById\s*\(/g, name: "document.getElementById()" },
|
|
197
|
+
{
|
|
198
|
+
pattern: /document\s*\.\s*getElementsByClassName\s*\(/g,
|
|
199
|
+
name: "document.getElementsByClassName()"
|
|
200
|
+
},
|
|
201
|
+
{ pattern: /\.classList\s*\.\s*(?:add|remove|toggle)\s*\(/g, name: "classList manipulation" }
|
|
202
|
+
];
|
|
203
|
+
var noManualDom = {
|
|
204
|
+
name: "no-manual-dom",
|
|
205
|
+
description: "Disallow direct DOM manipulation in React components.",
|
|
206
|
+
severity: "warn",
|
|
207
|
+
check(context) {
|
|
208
|
+
const violations = [];
|
|
209
|
+
const lines = context.code.split("\n");
|
|
210
|
+
for (let i = 0; i < lines.length; i++) {
|
|
211
|
+
const line = lines[i];
|
|
212
|
+
if (!line.includes("document") && !line.includes("classList")) continue;
|
|
213
|
+
for (const method of DOM_METHODS) {
|
|
214
|
+
method.pattern.lastIndex = 0;
|
|
215
|
+
if (method.pattern.test(line)) {
|
|
216
|
+
violations.push({
|
|
217
|
+
rule: "no-manual-dom",
|
|
218
|
+
message: `${method.name} performs direct DOM manipulation outside React's control.`,
|
|
219
|
+
line: i + 1,
|
|
220
|
+
recommendation: "Use useRef() for element access and React state/clsx() for class toggling."
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return violations;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// src/vite/plugins/best-practices/rules/no-img-without-dimensions.ts
|
|
230
|
+
var IMG_TAG_RE = /<img\s([^>]*?)\/?>/gi;
|
|
231
|
+
var noImgWithoutDimensions = {
|
|
232
|
+
name: "no-img-without-dimensions",
|
|
233
|
+
description: "Require width and height on <img> elements to prevent layout shifts (CLS).",
|
|
234
|
+
severity: "info",
|
|
235
|
+
check(context) {
|
|
236
|
+
if (!/\.[jt]sx$/.test(context.id)) return [];
|
|
237
|
+
const violations = [];
|
|
238
|
+
const lines = context.code.split("\n");
|
|
239
|
+
for (let i = 0; i < lines.length; i++) {
|
|
240
|
+
const line = lines[i];
|
|
241
|
+
if (!line.includes("<img")) continue;
|
|
242
|
+
IMG_TAG_RE.lastIndex = 0;
|
|
243
|
+
let match;
|
|
244
|
+
while ((match = IMG_TAG_RE.exec(line)) !== null) {
|
|
245
|
+
const attrs = match[1];
|
|
246
|
+
const hasWidth = /\bwidth\s*[={]/.test(attrs);
|
|
247
|
+
const hasHeight = /\bheight\s*[={]/.test(attrs);
|
|
248
|
+
if (!hasWidth || !hasHeight) {
|
|
249
|
+
violations.push({
|
|
250
|
+
rule: "no-img-without-dimensions",
|
|
251
|
+
message: "<img> without explicit width/height causes layout shifts (CLS).",
|
|
252
|
+
line: i + 1,
|
|
253
|
+
recommendation: "Add width and height attributes, or use the <Image> component which handles this automatically."
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return violations;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/vite/plugins/best-practices/rules/no-direct-product-card-import.ts
|
|
263
|
+
var DIRECT_PRODUCT_CARD_IMPORT_RE = /(?:import|from)\s+.*['"](?:\.\.\/)+product\/ProductCard['"]/g;
|
|
264
|
+
var ALLOWED_PATHS = ["/ProductCard.tsx", "/ProductCard.test.tsx", ".test.", ".spec."];
|
|
265
|
+
var noDirectProductCardImport = {
|
|
266
|
+
name: "no-direct-product-card-import",
|
|
267
|
+
description: "Prevent direct imports of ProductCard to ensure registry override works correctly.",
|
|
268
|
+
severity: "error",
|
|
269
|
+
check(context) {
|
|
270
|
+
const violations = [];
|
|
271
|
+
if (ALLOWED_PATHS.some((path) => context.relativeId.includes(path))) {
|
|
272
|
+
return violations;
|
|
273
|
+
}
|
|
274
|
+
const lines = context.code.split("\n");
|
|
275
|
+
for (let i = 0; i < lines.length; i++) {
|
|
276
|
+
const line = lines[i];
|
|
277
|
+
if (!line.includes("import") && !line.includes("from")) continue;
|
|
278
|
+
DIRECT_PRODUCT_CARD_IMPORT_RE.lastIndex = 0;
|
|
279
|
+
if (DIRECT_PRODUCT_CARD_IMPORT_RE.test(line)) {
|
|
280
|
+
violations.push({
|
|
281
|
+
rule: "no-direct-product-card-import",
|
|
282
|
+
message: `Direct import of ProductCard bypasses the registry override mechanism.`,
|
|
283
|
+
line: i + 1,
|
|
284
|
+
recommendation: `Import ProductCard from barrel export '../product' or use registry override to customize.`
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return violations;
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
// src/vite/plugins/best-practices/hooks-registry.ts
|
|
293
|
+
var ROUTE_HOOK_MAP = [
|
|
294
|
+
// Product Page
|
|
295
|
+
{
|
|
296
|
+
pattern: /ProductPage|product\.tsx$/,
|
|
297
|
+
routeType: "product",
|
|
298
|
+
expectedHooks: [
|
|
299
|
+
{ hook: "product:start", severity: "warn" },
|
|
300
|
+
{ hook: "product:details.start", severity: "warn" },
|
|
301
|
+
{ hook: "product:details.end", severity: "warn" },
|
|
302
|
+
{ hook: "product:single.description.start", severity: "warn" },
|
|
303
|
+
{ hook: "product:single.description", severity: "warn" },
|
|
304
|
+
{ hook: "product:single.description.end", severity: "warn" },
|
|
305
|
+
{ hook: "product:single.form.start", severity: "warn" },
|
|
306
|
+
{ hook: "product:single.form.end", severity: "warn" },
|
|
307
|
+
{ hook: "product:related.start", severity: "warn" },
|
|
308
|
+
{ hook: "product:related.end", severity: "warn" },
|
|
309
|
+
{ hook: "product:end", severity: "warn" }
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
// Cart Page
|
|
313
|
+
{
|
|
314
|
+
pattern: /CartPage|cart\.tsx$/,
|
|
315
|
+
routeType: "cart",
|
|
316
|
+
expectedHooks: [
|
|
317
|
+
{ hook: "cart:start", severity: "warn" },
|
|
318
|
+
{ hook: "cart:items.start", severity: "warn" },
|
|
319
|
+
{ hook: "cart:items.end", severity: "warn" },
|
|
320
|
+
{ hook: "cart:summary.start", severity: "warn" },
|
|
321
|
+
{ hook: "cart:summary.end", severity: "warn" },
|
|
322
|
+
{ hook: "cart:submit.start", severity: "warn" },
|
|
323
|
+
{ hook: "cart:submit.end", severity: "warn" },
|
|
324
|
+
{ hook: "cart:end", severity: "warn" }
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
// Home Page
|
|
328
|
+
{
|
|
329
|
+
pattern: /routes\/home\/HomePage\.tsx$/,
|
|
330
|
+
routeType: "home",
|
|
331
|
+
expectedHooks: [
|
|
332
|
+
{ hook: "home:start", severity: "warn" },
|
|
333
|
+
{ hook: "home:content", severity: "warn" },
|
|
334
|
+
{ hook: "home:end", severity: "warn" }
|
|
335
|
+
]
|
|
336
|
+
},
|
|
337
|
+
// Blog Index
|
|
338
|
+
{
|
|
339
|
+
pattern: /BlogPage|blog\.tsx$/,
|
|
340
|
+
routeType: "blog",
|
|
341
|
+
expectedHooks: [
|
|
342
|
+
{ hook: "blog:start", severity: "warn" },
|
|
343
|
+
{ hook: "blog:items.start", severity: "warn" },
|
|
344
|
+
{ hook: "blog:items.end", severity: "warn" },
|
|
345
|
+
{ hook: "blog:end", severity: "warn" }
|
|
346
|
+
]
|
|
347
|
+
},
|
|
348
|
+
// Blog Single
|
|
349
|
+
{
|
|
350
|
+
pattern: /BlogSinglePage/,
|
|
351
|
+
routeType: "blog-single",
|
|
352
|
+
expectedHooks: [
|
|
353
|
+
{ hook: "blog:single.start", severity: "warn" },
|
|
354
|
+
{ hook: "blog:single.end", severity: "warn" },
|
|
355
|
+
{ hook: "blog:single.related.start", severity: "warn" },
|
|
356
|
+
{ hook: "blog:single.related.end", severity: "warn" }
|
|
357
|
+
]
|
|
358
|
+
},
|
|
359
|
+
// Blog Category
|
|
360
|
+
{
|
|
361
|
+
pattern: /BlogCategoryPage/,
|
|
362
|
+
routeType: "blog-category",
|
|
363
|
+
expectedHooks: [
|
|
364
|
+
{ hook: "blog:category.start", severity: "warn" },
|
|
365
|
+
{ hook: "blog:category.end", severity: "warn" }
|
|
366
|
+
]
|
|
367
|
+
},
|
|
368
|
+
// Blog Tag
|
|
369
|
+
{
|
|
370
|
+
pattern: /BlogTagPage/,
|
|
371
|
+
routeType: "blog-tag",
|
|
372
|
+
expectedHooks: [
|
|
373
|
+
{ hook: "blog:tag.start", severity: "warn" },
|
|
374
|
+
{ hook: "blog:tag.end", severity: "warn" }
|
|
375
|
+
]
|
|
376
|
+
},
|
|
377
|
+
// Blog Author
|
|
378
|
+
{
|
|
379
|
+
pattern: /BlogAuthorPage/,
|
|
380
|
+
routeType: "blog-author",
|
|
381
|
+
expectedHooks: [
|
|
382
|
+
{ hook: "blog:author.start", severity: "warn" },
|
|
383
|
+
{ hook: "blog:author.end", severity: "warn" }
|
|
384
|
+
]
|
|
385
|
+
},
|
|
386
|
+
// Product Listing
|
|
387
|
+
{
|
|
388
|
+
pattern: /ProductListPage\.tsx$/,
|
|
389
|
+
routeType: "product-listing",
|
|
390
|
+
expectedHooks: [
|
|
391
|
+
{ hook: "product:list.start", severity: "warn" },
|
|
392
|
+
{ hook: "product:list.items.start", severity: "warn" },
|
|
393
|
+
{ hook: "product:list.items.end", severity: "warn" },
|
|
394
|
+
{ hook: "product:list.end", severity: "warn" }
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
// Brands
|
|
398
|
+
{
|
|
399
|
+
pattern: /BrandsPage\.tsx$/,
|
|
400
|
+
routeType: "brands",
|
|
401
|
+
expectedHooks: [
|
|
402
|
+
{ hook: "brands:index.items.start", severity: "warn" },
|
|
403
|
+
{ hook: "brands:index.items.end", severity: "warn" }
|
|
404
|
+
]
|
|
405
|
+
},
|
|
406
|
+
// Thank You
|
|
407
|
+
{
|
|
408
|
+
pattern: /ThankYouPage\.tsx$/,
|
|
409
|
+
routeType: "thank-you",
|
|
410
|
+
expectedHooks: [
|
|
411
|
+
{ hook: "thank-you:start", severity: "warn" },
|
|
412
|
+
{ hook: "thank-you:items.start", severity: "warn" },
|
|
413
|
+
{ hook: "thank-you:items.end", severity: "warn" },
|
|
414
|
+
{ hook: "thank-you:end", severity: "warn" }
|
|
415
|
+
]
|
|
416
|
+
},
|
|
417
|
+
// Not Found
|
|
418
|
+
{
|
|
419
|
+
pattern: /not-found/,
|
|
420
|
+
routeType: "not-found",
|
|
421
|
+
expectedHooks: [
|
|
422
|
+
{ hook: "notfound:start", severity: "warn" },
|
|
423
|
+
{ hook: "notfound:content", severity: "warn" },
|
|
424
|
+
{ hook: "notfound:end", severity: "warn" }
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
// Account - Profile
|
|
428
|
+
{
|
|
429
|
+
pattern: /ProfilePage\.tsx$/,
|
|
430
|
+
routeType: "customer-profile",
|
|
431
|
+
expectedHooks: [
|
|
432
|
+
{ hook: "customer:profile.start", severity: "warn" },
|
|
433
|
+
{ hook: "customer:profile.form.start", severity: "warn" },
|
|
434
|
+
{ hook: "customer:profile.form.end", severity: "warn" },
|
|
435
|
+
{ hook: "customer:profile.end", severity: "warn" }
|
|
436
|
+
]
|
|
437
|
+
},
|
|
438
|
+
// Account - Orders
|
|
439
|
+
{
|
|
440
|
+
pattern: /OrdersPage\.tsx$/,
|
|
441
|
+
routeType: "customer-orders",
|
|
442
|
+
expectedHooks: [
|
|
443
|
+
{ hook: "customer:orders.index.items.start", severity: "warn" },
|
|
444
|
+
{ hook: "customer:orders.index.items.end", severity: "warn" }
|
|
445
|
+
]
|
|
446
|
+
},
|
|
447
|
+
// Account - Order Single
|
|
448
|
+
{
|
|
449
|
+
pattern: /OrderSinglePage\.tsx$/,
|
|
450
|
+
routeType: "customer-order-single",
|
|
451
|
+
expectedHooks: [
|
|
452
|
+
{ hook: "customer:orders.single.details.start", severity: "warn" },
|
|
453
|
+
{ hook: "customer:orders.single.details.end", severity: "warn" }
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
// Account - Notifications
|
|
457
|
+
{
|
|
458
|
+
pattern: /NotificationsPage\.tsx$/,
|
|
459
|
+
routeType: "customer-notifications",
|
|
460
|
+
expectedHooks: [
|
|
461
|
+
{ hook: "customer:notifications.items.start", severity: "warn" },
|
|
462
|
+
{ hook: "customer:notifications.items.end", severity: "warn" }
|
|
463
|
+
]
|
|
464
|
+
},
|
|
465
|
+
// Account - Wallet
|
|
466
|
+
{
|
|
467
|
+
pattern: /WalletPage\.tsx$/,
|
|
468
|
+
routeType: "customer-wallet",
|
|
469
|
+
expectedHooks: [
|
|
470
|
+
{ hook: "customer:wallet.transactions.start", severity: "warn" },
|
|
471
|
+
{ hook: "customer:wallet.transactions.end", severity: "warn" }
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
// Account - Settings
|
|
475
|
+
{
|
|
476
|
+
pattern: /SettingsPage\.tsx$/,
|
|
477
|
+
routeType: "customer-settings",
|
|
478
|
+
expectedHooks: [
|
|
479
|
+
{ hook: "customer:settings.start", severity: "warn" },
|
|
480
|
+
{ hook: "customer:settings.end", severity: "warn" }
|
|
481
|
+
]
|
|
482
|
+
},
|
|
483
|
+
// Account - Wishlist
|
|
484
|
+
{
|
|
485
|
+
pattern: /WishlistPage\.tsx$/,
|
|
486
|
+
routeType: "customer-wishlist",
|
|
487
|
+
expectedHooks: [
|
|
488
|
+
{ hook: "customer:wishlist.items.start", severity: "warn" },
|
|
489
|
+
{ hook: "customer:wishlist.items.end", severity: "warn" }
|
|
490
|
+
]
|
|
491
|
+
}
|
|
492
|
+
];
|
|
493
|
+
function getExpectedHooks(filePath) {
|
|
494
|
+
for (const entry of ROUTE_HOOK_MAP) {
|
|
495
|
+
if (entry.pattern.test(filePath)) {
|
|
496
|
+
return entry.expectedHooks;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/vite/plugins/best-practices/rules/require-page-hooks.ts
|
|
503
|
+
var HOOK_NAME_ENUM_TO_STRING = {
|
|
504
|
+
BODY_START: "body:start",
|
|
505
|
+
BODY_END: "body:end",
|
|
506
|
+
BODY_INNER: "body:inner",
|
|
507
|
+
HEAD_START: "head:start",
|
|
508
|
+
HEAD_END: "head:end",
|
|
509
|
+
HEAD_INNER: "head:inner",
|
|
510
|
+
HEADER_START: "header:start",
|
|
511
|
+
HEADER_END: "header:end",
|
|
512
|
+
FOOTER_START: "footer:start",
|
|
513
|
+
FOOTER_END: "footer:end",
|
|
514
|
+
PRODUCT_DESCRIPTION_START: "product:single.description.start",
|
|
515
|
+
PRODUCT_DESCRIPTION: "product:single.description",
|
|
516
|
+
PRODUCT_DESCRIPTION_END: "product:single.description.end",
|
|
517
|
+
PRODUCT_FORM_START: "product:single.form.start",
|
|
518
|
+
PRODUCT_FORM_END: "product:single.form.end",
|
|
519
|
+
CART_ITEMS_START: "cart:items.start",
|
|
520
|
+
CART_ITEMS_END: "cart:items.end",
|
|
521
|
+
CART_SUMMARY_START: "cart:summary.start",
|
|
522
|
+
CART_SUMMARY_END: "cart:summary.end",
|
|
523
|
+
SEARCH_START: "search:start",
|
|
524
|
+
SEARCH_ITEMS_START: "search:items.start",
|
|
525
|
+
SEARCH_ITEMS_END: "search:items.end",
|
|
526
|
+
SEARCH_END: "search:end",
|
|
527
|
+
HOMEPAGE_SLIDER: "homepage:slider",
|
|
528
|
+
HOMEPAGE_BANNERS: "homepage:banners",
|
|
529
|
+
HOMEPAGE_FEATURED: "homepage:featured"
|
|
530
|
+
};
|
|
531
|
+
function isNodeModules(path) {
|
|
532
|
+
return path.includes("node_modules");
|
|
533
|
+
}
|
|
534
|
+
function isLocalImport(importPath) {
|
|
535
|
+
return importPath.startsWith(".") || importPath.startsWith("/");
|
|
536
|
+
}
|
|
537
|
+
function importsThemeEngineRoutes(code) {
|
|
538
|
+
const importRegex = /import\s+.*\s+from\s+['"]@salla\.sa\/twilight-theme-engine\/routes\/[^'"]+['"]/;
|
|
539
|
+
return importRegex.test(code);
|
|
540
|
+
}
|
|
541
|
+
function resolveImportPath(importer, importPath) {
|
|
542
|
+
const dir = dirname(importer);
|
|
543
|
+
const resolved = resolve(dir, importPath);
|
|
544
|
+
if (existsSync(resolved)) {
|
|
545
|
+
try {
|
|
546
|
+
if (statSync(resolved).isFile()) {
|
|
547
|
+
return resolved;
|
|
548
|
+
}
|
|
549
|
+
} catch {
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
for (const ext of [".ts", ".tsx", ".js", ".jsx"]) {
|
|
553
|
+
const withExt = resolved + ext;
|
|
554
|
+
if (existsSync(withExt)) return withExt;
|
|
555
|
+
}
|
|
556
|
+
for (const index of ["index.ts", "index.tsx", "index.js", "index.jsx"]) {
|
|
557
|
+
const indexPath = resolve(resolved, index);
|
|
558
|
+
if (existsSync(indexPath)) return indexPath;
|
|
559
|
+
}
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
function extractHookNameFromAttrValue(attrValue) {
|
|
563
|
+
if (!attrValue || typeof attrValue !== "object") return null;
|
|
564
|
+
const value = attrValue;
|
|
565
|
+
if ((value.type === "Literal" || value.type === "StringLiteral") && typeof value.value === "string") {
|
|
566
|
+
return value.value;
|
|
567
|
+
}
|
|
568
|
+
if (value.type === "JSXExpressionContainer") {
|
|
569
|
+
const expr = value.expression;
|
|
570
|
+
if (expr?.type === "MemberExpression") {
|
|
571
|
+
const object = expr.object;
|
|
572
|
+
const property = expr.property;
|
|
573
|
+
if (object?.type === "Identifier" && object.name === "HookName" && property?.type === "Identifier" && typeof property.name === "string") {
|
|
574
|
+
return HOOK_NAME_ENUM_TO_STRING[property.name] || null;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
function extractHooksFromAst(node, hooks) {
|
|
581
|
+
if (!node || typeof node !== "object") return;
|
|
582
|
+
const obj = node;
|
|
583
|
+
if (obj.type === "JSXElement") {
|
|
584
|
+
const opening = obj.openingElement;
|
|
585
|
+
if (opening && typeof opening === "object") {
|
|
586
|
+
const name = opening.name;
|
|
587
|
+
if (name?.type === "JSXIdentifier" && name.name === "HookSlot") {
|
|
588
|
+
const attributes = opening.attributes;
|
|
589
|
+
if (Array.isArray(attributes)) {
|
|
590
|
+
for (const attr of attributes) {
|
|
591
|
+
if (attr && typeof attr === "object") {
|
|
592
|
+
const attrObj = attr;
|
|
593
|
+
if (attrObj.type === "JSXAttribute") {
|
|
594
|
+
const attrName = attrObj.name;
|
|
595
|
+
if (attrName?.type === "JSXIdentifier" && attrName.name === "name") {
|
|
596
|
+
const hookName = extractHookNameFromAttrValue(attrObj.value);
|
|
597
|
+
if (hookName) hooks.add(hookName);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (obj.type === "CallExpression") {
|
|
607
|
+
const callee = obj.callee;
|
|
608
|
+
if (callee?.type === "MemberExpression") {
|
|
609
|
+
const object = callee.object;
|
|
610
|
+
const property = callee.property;
|
|
611
|
+
if (object?.type === "Identifier" && object.name === "hookRegistry" && property?.type === "Identifier" && property.name === "register") {
|
|
612
|
+
const args = obj.arguments;
|
|
613
|
+
if (Array.isArray(args) && args.length > 0) {
|
|
614
|
+
const firstArg = args[0];
|
|
615
|
+
const expr = firstArg.expression || firstArg;
|
|
616
|
+
if ((expr?.type === "Literal" || expr?.type === "StringLiteral") && typeof expr.value === "string") {
|
|
617
|
+
hooks.add(expr.value);
|
|
618
|
+
} else if (expr?.type === "MemberExpression") {
|
|
619
|
+
const argObject = expr.object;
|
|
620
|
+
const argProperty = expr.property;
|
|
621
|
+
if (argObject?.type === "Identifier" && argObject.name === "HookName" && argProperty?.type === "Identifier" && typeof argProperty.name === "string") {
|
|
622
|
+
const hookName = HOOK_NAME_ENUM_TO_STRING[argProperty.name];
|
|
623
|
+
if (hookName) hooks.add(hookName);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
for (const key of Object.keys(obj)) {
|
|
631
|
+
if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
|
|
632
|
+
const child = obj[key];
|
|
633
|
+
if (Array.isArray(child)) {
|
|
634
|
+
for (const item of child) {
|
|
635
|
+
extractHooksFromAst(item, hooks);
|
|
636
|
+
}
|
|
637
|
+
} else if (typeof child === "object" && child !== null) {
|
|
638
|
+
extractHooksFromAst(child, hooks);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
function findDynamicImportsInNode(node, filePath, visited, hooks) {
|
|
643
|
+
if (!node || typeof node !== "object") return;
|
|
644
|
+
const obj = node;
|
|
645
|
+
if (obj.type === "ImportExpression") {
|
|
646
|
+
const source = obj.source;
|
|
647
|
+
if ((source?.type === "Literal" || source?.type === "StringLiteral") && typeof source.value === "string") {
|
|
648
|
+
const importPath = source.value;
|
|
649
|
+
if (isLocalImport(importPath)) {
|
|
650
|
+
const resolved = resolveImportPath(filePath, importPath);
|
|
651
|
+
if (resolved) {
|
|
652
|
+
const nestedHooks = findHooksInFile(resolved, visited);
|
|
653
|
+
for (const hook of nestedHooks) {
|
|
654
|
+
hooks.add(hook);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
for (const key of Object.keys(obj)) {
|
|
661
|
+
if (key === "loc" || key === "range" || key === "start" || key === "end") continue;
|
|
662
|
+
const child = obj[key];
|
|
663
|
+
if (Array.isArray(child)) {
|
|
664
|
+
for (const item of child) {
|
|
665
|
+
findDynamicImportsInNode(item, filePath, visited, hooks);
|
|
666
|
+
}
|
|
667
|
+
} else if (typeof child === "object" && child !== null) {
|
|
668
|
+
findDynamicImportsInNode(child, filePath, visited, hooks);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
function findHooksInFile(filePath, visited = /* @__PURE__ */ new Set()) {
|
|
673
|
+
if (visited.has(filePath)) return /* @__PURE__ */ new Set();
|
|
674
|
+
if (isNodeModules(filePath)) return /* @__PURE__ */ new Set();
|
|
675
|
+
visited.add(filePath);
|
|
676
|
+
const hooks = /* @__PURE__ */ new Set();
|
|
677
|
+
try {
|
|
678
|
+
const code = readFileSync(filePath, "utf-8");
|
|
679
|
+
const ast = parseSync(filePath, code, {
|
|
680
|
+
sourceType: "module",
|
|
681
|
+
preserveParens: false
|
|
682
|
+
});
|
|
683
|
+
extractHooksFromAst(ast.program, hooks);
|
|
684
|
+
const body = ast.program?.body;
|
|
685
|
+
if (Array.isArray(body)) {
|
|
686
|
+
for (const stmt of body) {
|
|
687
|
+
if (stmt && typeof stmt === "object") {
|
|
688
|
+
const stmtObj = stmt;
|
|
689
|
+
if (stmtObj.type === "ImportDeclaration") {
|
|
690
|
+
const source = stmtObj.source;
|
|
691
|
+
if ((source?.type === "Literal" || source?.type === "StringLiteral") && typeof source.value === "string") {
|
|
692
|
+
const importPath = source.value;
|
|
693
|
+
if (isLocalImport(importPath)) {
|
|
694
|
+
const resolved = resolveImportPath(filePath, importPath);
|
|
695
|
+
if (resolved) {
|
|
696
|
+
const nestedHooks = findHooksInFile(resolved, visited);
|
|
697
|
+
for (const hook of nestedHooks) {
|
|
698
|
+
hooks.add(hook);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
if (stmtObj.type === "ExportNamedDeclaration") {
|
|
705
|
+
const source = stmtObj.source;
|
|
706
|
+
if (source && (source.type === "Literal" || source.type === "StringLiteral") && typeof source.value === "string") {
|
|
707
|
+
const importPath = source.value;
|
|
708
|
+
if (isLocalImport(importPath)) {
|
|
709
|
+
const resolved = resolveImportPath(filePath, importPath);
|
|
710
|
+
if (resolved) {
|
|
711
|
+
const nestedHooks = findHooksInFile(resolved, visited);
|
|
712
|
+
for (const hook of nestedHooks) {
|
|
713
|
+
hooks.add(hook);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
findDynamicImportsInNode(stmtObj, filePath, visited, hooks);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
} catch {
|
|
724
|
+
}
|
|
725
|
+
return hooks;
|
|
726
|
+
}
|
|
727
|
+
function getLineForHook(code, hookName) {
|
|
728
|
+
const lines = code.split("\n");
|
|
729
|
+
for (let i = 0; i < lines.length; i++) {
|
|
730
|
+
if (lines[i].includes(hookName)) {
|
|
731
|
+
return i + 1;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
return 1;
|
|
735
|
+
}
|
|
736
|
+
var requirePageHooks = {
|
|
737
|
+
name: "require-page-hooks",
|
|
738
|
+
description: "Ensure route files include expected HookSlot or hookRegistry entries for customization.",
|
|
739
|
+
severity: "warn",
|
|
740
|
+
check(context) {
|
|
741
|
+
const violations = [];
|
|
742
|
+
const expectedHooks = getExpectedHooks(context.relativeId);
|
|
743
|
+
if (!expectedHooks) return violations;
|
|
744
|
+
if (importsThemeEngineRoutes(context.code)) {
|
|
745
|
+
return violations;
|
|
746
|
+
}
|
|
747
|
+
let foundHooks;
|
|
748
|
+
try {
|
|
749
|
+
foundHooks = findHooksInFile(context.id);
|
|
750
|
+
} catch {
|
|
751
|
+
foundHooks = /* @__PURE__ */ new Set();
|
|
752
|
+
}
|
|
753
|
+
if (foundHooks.size === 0) {
|
|
754
|
+
try {
|
|
755
|
+
const ast = parseSync(context.id, context.code, {
|
|
756
|
+
sourceType: "module",
|
|
757
|
+
preserveParens: false
|
|
758
|
+
});
|
|
759
|
+
extractHooksFromAst(ast.program, foundHooks);
|
|
760
|
+
} catch {
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
for (const expected of expectedHooks) {
|
|
764
|
+
if (!foundHooks.has(expected.hook)) {
|
|
765
|
+
violations.push({
|
|
766
|
+
rule: "require-page-hooks",
|
|
767
|
+
message: `Missing expected hook '${expected.hook}' in ${context.relativeId}`,
|
|
768
|
+
line: getLineForHook(context.code, "HookSlot") || 1,
|
|
769
|
+
recommendation: `Add <HookSlot name="${expected.hook}" /> or hookRegistry.register('${expected.hook}', ...) to enable theme customization.`
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return violations;
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
// src/vite/plugins/best-practices/rules/index.ts
|
|
778
|
+
var builtinRules = [
|
|
779
|
+
noDeepComponentImport,
|
|
780
|
+
noWindowLocationReload,
|
|
781
|
+
noManualDom,
|
|
782
|
+
noImgWithoutDimensions,
|
|
783
|
+
noDirectProductCardImport,
|
|
784
|
+
requirePageHooks
|
|
785
|
+
];
|
|
786
|
+
|
|
787
|
+
// src/vite/plugins/best-practices/reporter.ts
|
|
788
|
+
var COLORS = {
|
|
789
|
+
reset: "\x1B[0m",
|
|
790
|
+
red: "\x1B[31m",
|
|
791
|
+
yellow: "\x1B[33m",
|
|
792
|
+
cyan: "\x1B[36m",
|
|
793
|
+
dim: "\x1B[2m",
|
|
794
|
+
bold: "\x1B[1m",
|
|
795
|
+
green: "\x1B[32m"
|
|
796
|
+
};
|
|
797
|
+
var SEVERITY_LABEL = {
|
|
798
|
+
error: `${COLORS.red}ERROR${COLORS.reset}`,
|
|
799
|
+
warn: `${COLORS.yellow}WARN${COLORS.reset}`,
|
|
800
|
+
info: `${COLORS.cyan}INFO${COLORS.reset}`
|
|
801
|
+
};
|
|
802
|
+
var SEVERITY_ICON = {
|
|
803
|
+
error: `${COLORS.red}\u2718${COLORS.reset}`,
|
|
804
|
+
warn: `${COLORS.yellow}\u26A0${COLORS.reset}`,
|
|
805
|
+
info: `${COLORS.cyan}\u2139${COLORS.reset}`
|
|
806
|
+
};
|
|
807
|
+
function formatViolation(violation, severity, relativeId) {
|
|
808
|
+
const loc = `${COLORS.dim}${relativeId}:${violation.line}${COLORS.reset}`;
|
|
809
|
+
const icon = SEVERITY_ICON[severity];
|
|
810
|
+
const label = SEVERITY_LABEL[severity];
|
|
811
|
+
const rule = `${COLORS.dim}(${violation.rule})${COLORS.reset}`;
|
|
812
|
+
return [
|
|
813
|
+
` ${icon} ${label} ${rule}`,
|
|
814
|
+
` ${loc}`,
|
|
815
|
+
` ${violation.message}`,
|
|
816
|
+
` ${COLORS.green}\u2192 ${violation.recommendation}${COLORS.reset}`
|
|
817
|
+
].join("\n");
|
|
818
|
+
}
|
|
819
|
+
function formatSummary(errors, warnings, infos) {
|
|
820
|
+
const parts = [];
|
|
821
|
+
if (errors > 0) parts.push(`${COLORS.red}${errors} error(s)${COLORS.reset}`);
|
|
822
|
+
if (warnings > 0) parts.push(`${COLORS.yellow}${warnings} warning(s)${COLORS.reset}`);
|
|
823
|
+
if (infos > 0) parts.push(`${COLORS.cyan}${infos} info(s)${COLORS.reset}`);
|
|
824
|
+
return `${COLORS.bold}[twilight:best-practices]${COLORS.reset} ${parts.join(", ")}`;
|
|
825
|
+
}
|
|
826
|
+
var fileHashCache = /* @__PURE__ */ new Map();
|
|
827
|
+
function hash(content) {
|
|
828
|
+
return createHash("md5").update(content).digest("hex");
|
|
829
|
+
}
|
|
830
|
+
function matchesGlob(id, patterns) {
|
|
831
|
+
return patterns.some((p) => {
|
|
832
|
+
if (/[\\^$|+?(){}[\]\\\\]/.test(p)) return false;
|
|
833
|
+
const regex = new RegExp(
|
|
834
|
+
"^" + p.replace(/\./g, "\\.").replace(/\*\*/g, "\0GLOBSTAR\0").replace(/\*/g, "[^/]*").replace(/\0GLOBSTAR\0/g, ".*") + "$"
|
|
835
|
+
);
|
|
836
|
+
return regex.test(id);
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
function bestPracticesPlugin(options = {}) {
|
|
840
|
+
const {
|
|
841
|
+
include = ["**/*.ts", "**/*.tsx"],
|
|
842
|
+
exclude = ["**/node_modules/**", "**/dist/**", "**/*.d.ts", "**/.twilight/**"],
|
|
843
|
+
disabledRules = [],
|
|
844
|
+
severityOverrides = {},
|
|
845
|
+
browserConsole = false
|
|
846
|
+
} = options;
|
|
847
|
+
const enabledRules = builtinRules.filter((r) => !disabledRules.includes(r.name));
|
|
848
|
+
let projectRoot = "";
|
|
849
|
+
return {
|
|
850
|
+
name: "twilight:best-practices",
|
|
851
|
+
apply: "build",
|
|
852
|
+
enforce: "pre",
|
|
853
|
+
configResolved(config) {
|
|
854
|
+
projectRoot = config.root;
|
|
855
|
+
},
|
|
856
|
+
transform(code, id) {
|
|
857
|
+
if (!/\.[jt]sx?$/.test(id)) return null;
|
|
858
|
+
const relativeId = relative(projectRoot, id);
|
|
859
|
+
if (!matchesGlob(relativeId, include)) return null;
|
|
860
|
+
if (matchesGlob(relativeId, exclude)) return null;
|
|
861
|
+
const h = hash(code);
|
|
862
|
+
if (fileHashCache.get(id) === h) return null;
|
|
863
|
+
fileHashCache.set(id, h);
|
|
864
|
+
const context = { code, id, relativeId };
|
|
865
|
+
const allViolations = [];
|
|
866
|
+
for (const rule of enabledRules) {
|
|
867
|
+
const severity = severityOverrides[rule.name] ?? rule.severity;
|
|
868
|
+
const violations = rule.check(context);
|
|
869
|
+
for (const v of violations) {
|
|
870
|
+
allViolations.push({ violation: v, severity });
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
if (allViolations.length === 0) return null;
|
|
874
|
+
const counts = { error: 0, warn: 0, info: 0 };
|
|
875
|
+
const lines = [];
|
|
876
|
+
for (const { violation, severity } of allViolations) {
|
|
877
|
+
counts[severity]++;
|
|
878
|
+
lines.push(formatViolation(violation, severity, relativeId));
|
|
879
|
+
}
|
|
880
|
+
console.error("\n" + lines.join("\n"));
|
|
881
|
+
console.error(formatSummary(counts.error, counts.warn, counts.info) + "\n");
|
|
882
|
+
if (browserConsole && allViolations.length > 0) {
|
|
883
|
+
const consoleStatements = allViolations.map(({ violation, severity }) => {
|
|
884
|
+
const method = severity === "error" ? "error" : severity === "warn" ? "warn" : "info";
|
|
885
|
+
const msg = `[twilight:${violation.rule}] ${violation.message}\\n \u2192 ${violation.recommendation}\\n at ${relativeId}:${violation.line}`;
|
|
886
|
+
return `console.${method}(${JSON.stringify(msg)});`;
|
|
887
|
+
}).join("\n");
|
|
888
|
+
return {
|
|
889
|
+
code: code + "\n" + consoleStatements,
|
|
890
|
+
map: null
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
return null;
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
function findEngineSrc(startDir) {
|
|
898
|
+
let dir = startDir;
|
|
899
|
+
for (let i = 0; i < 6; i++) {
|
|
900
|
+
const candidate = resolve(dir, "src");
|
|
901
|
+
if (existsSync(resolve(candidate, "index.ts"))) return candidate;
|
|
902
|
+
dir = resolve(dir, "..");
|
|
903
|
+
}
|
|
904
|
+
return null;
|
|
905
|
+
}
|
|
906
|
+
var engineSrc = findEngineSrc(dirname(fileURLToPath(import.meta.url)));
|
|
907
|
+
var PKG = "@salla.sa/twilight-theme-engine";
|
|
908
|
+
var ESCAPED_PKG = PKG.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
909
|
+
var SAFE_SUBPATH = /^[a-zA-Z0-9/_-]+$/;
|
|
910
|
+
function pkgPattern(subpath) {
|
|
911
|
+
if (subpath && !SAFE_SUBPATH.test(subpath))
|
|
912
|
+
throw new Error(`Invalid package subpath: ${subpath}`);
|
|
913
|
+
return new RegExp(`^${ESCAPED_PKG}${subpath ? "/" + subpath : ""}$`);
|
|
914
|
+
}
|
|
915
|
+
var ALIASES = !engineSrc ? [] : [
|
|
916
|
+
{ find: pkgPattern("i18n"), replacement: resolve(engineSrc, "providers/i18n.ts") },
|
|
917
|
+
{ find: pkgPattern("hooks"), replacement: resolve(engineSrc, "hooks/index.ts") },
|
|
918
|
+
{
|
|
919
|
+
find: pkgPattern("hooks/useAsyncFn"),
|
|
920
|
+
replacement: resolve(engineSrc, "hooks/useAsyncFn.ts")
|
|
921
|
+
},
|
|
922
|
+
{ find: pkgPattern("hooks/useStore"), replacement: resolve(engineSrc, "hooks/useStore.ts") },
|
|
923
|
+
{ find: pkgPattern("hooks/useTheme"), replacement: resolve(engineSrc, "hooks/useTheme.ts") },
|
|
924
|
+
{ find: pkgPattern("hooks/useMoney"), replacement: resolve(engineSrc, "hooks/useMoney.tsx") },
|
|
925
|
+
{ find: pkgPattern("hooks/useAsset"), replacement: resolve(engineSrc, "hooks/useAsset.ts") },
|
|
926
|
+
{
|
|
927
|
+
find: pkgPattern("hooks/useProduct"),
|
|
928
|
+
replacement: resolve(engineSrc, "hooks/useProduct.ts")
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
find: pkgPattern("hooks/useDocumentClass"),
|
|
932
|
+
replacement: resolve(engineSrc, "hooks/useDocumentClass.ts")
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
find: pkgPattern("hooks/useCoupon"),
|
|
936
|
+
replacement: resolve(engineSrc, "hooks/useCoupon.ts")
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
find: pkgPattern("hooks/useWishlist"),
|
|
940
|
+
replacement: resolve(engineSrc, "hooks/useWishlist.ts")
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
find: pkgPattern("hooks/useBlogLike"),
|
|
944
|
+
replacement: resolve(engineSrc, "hooks/useBlogLike.ts")
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
find: pkgPattern("hooks/useComments"),
|
|
948
|
+
replacement: resolve(engineSrc, "hooks/useComments.ts")
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
find: pkgPattern("hooks/HookRegistry"),
|
|
952
|
+
replacement: resolve(engineSrc, "hooks/HookRegistry.ts")
|
|
953
|
+
},
|
|
954
|
+
{ find: pkgPattern("hooks/HookSlot"), replacement: resolve(engineSrc, "hooks/HookSlot.tsx") },
|
|
955
|
+
{ find: pkgPattern("hooks/useHook"), replacement: resolve(engineSrc, "hooks/useHook.ts") },
|
|
956
|
+
{ find: pkgPattern("hooks/useGtm"), replacement: resolve(engineSrc, "hooks/useGtm.ts") },
|
|
957
|
+
{ find: pkgPattern("contexts"), replacement: resolve(engineSrc, "contexts/index.ts") },
|
|
958
|
+
{ find: pkgPattern("utils"), replacement: resolve(engineSrc, "utils/index.ts") },
|
|
959
|
+
{ find: pkgPattern("utils/baseHead"), replacement: resolve(engineSrc, "utils/baseHead.ts") },
|
|
960
|
+
{ find: pkgPattern("utils/head"), replacement: resolve(engineSrc, "utils/head.ts") },
|
|
961
|
+
{ find: pkgPattern("types"), replacement: resolve(engineSrc, "types/index.ts") },
|
|
962
|
+
{ find: pkgPattern("types/hooks"), replacement: resolve(engineSrc, "types/hooks.ts") },
|
|
963
|
+
{ find: pkgPattern("eslint"), replacement: resolve(engineSrc, "eslint/index.ts") },
|
|
964
|
+
{ find: pkgPattern("vite"), replacement: resolve(engineSrc, "vite/index.ts") },
|
|
965
|
+
{ find: pkgPattern("routes"), replacement: resolve(engineSrc, "routes/index.ts") },
|
|
966
|
+
{ find: pkgPattern("routes/home"), replacement: resolve(engineSrc, "routes/home/index.tsx") },
|
|
967
|
+
{ find: pkgPattern("routes/cart"), replacement: resolve(engineSrc, "routes/cart/index.tsx") },
|
|
968
|
+
{
|
|
969
|
+
find: pkgPattern("routes/product"),
|
|
970
|
+
replacement: resolve(engineSrc, "routes/product/index.tsx")
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
find: pkgPattern("routes/product-listing"),
|
|
974
|
+
replacement: resolve(engineSrc, "routes/product-listing/index.tsx")
|
|
975
|
+
},
|
|
976
|
+
{ find: pkgPattern("routes/blog"), replacement: resolve(engineSrc, "routes/blog/index.tsx") },
|
|
977
|
+
{
|
|
978
|
+
find: pkgPattern("routes/brands"),
|
|
979
|
+
replacement: resolve(engineSrc, "routes/brands/index.tsx")
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
find: pkgPattern("routes/account"),
|
|
983
|
+
replacement: resolve(engineSrc, "routes/account/index.tsx")
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
find: pkgPattern("routes/account/orders"),
|
|
987
|
+
replacement: resolve(engineSrc, "routes/account/orders/index.tsx")
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
find: pkgPattern("routes/loyalty"),
|
|
991
|
+
replacement: resolve(engineSrc, "routes/loyalty/index.tsx")
|
|
992
|
+
},
|
|
993
|
+
{ find: pkgPattern("routes/page"), replacement: resolve(engineSrc, "routes/page/index.tsx") },
|
|
994
|
+
{
|
|
995
|
+
find: pkgPattern("routes/testimonials"),
|
|
996
|
+
replacement: resolve(engineSrc, "routes/testimonials/index.tsx")
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
find: pkgPattern("routes/thank-you"),
|
|
1000
|
+
replacement: resolve(engineSrc, "routes/thank-you/index.tsx")
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
find: pkgPattern("routes/seo-redirects"),
|
|
1004
|
+
replacement: resolve(engineSrc, "routes/seo-redirects.ts")
|
|
1005
|
+
},
|
|
1006
|
+
{ find: pkgPattern("skeleton"), replacement: resolve(engineSrc, "skeleton.ts") },
|
|
1007
|
+
{ find: pkgPattern("tanstack"), replacement: resolve(engineSrc, "tanstack/index.ts") },
|
|
1008
|
+
{ find: pkgPattern("nextjs"), replacement: resolve(engineSrc, "nextjs/index.ts") },
|
|
1009
|
+
{ find: pkgPattern("dom"), replacement: resolve(engineSrc, "dom/index.ts") },
|
|
1010
|
+
{
|
|
1011
|
+
find: pkgPattern("components/modal"),
|
|
1012
|
+
replacement: resolve(engineSrc, "components/modal/index.ts")
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
find: pkgPattern("components/drawer"),
|
|
1016
|
+
replacement: resolve(engineSrc, "components/drawer/index.ts")
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
find: pkgPattern("components/dropdown"),
|
|
1020
|
+
replacement: resolve(engineSrc, "components/dropdown/index.ts")
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
find: pkgPattern("components/collapse"),
|
|
1024
|
+
replacement: resolve(engineSrc, "components/collapse/index.ts")
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
find: pkgPattern("components/toast"),
|
|
1028
|
+
replacement: resolve(engineSrc, "components/toast/index.ts")
|
|
1029
|
+
},
|
|
1030
|
+
{
|
|
1031
|
+
find: pkgPattern("components/cart"),
|
|
1032
|
+
replacement: resolve(engineSrc, "components/cart/index.ts")
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
find: pkgPattern("components/product"),
|
|
1036
|
+
replacement: resolve(engineSrc, "components/product/index.ts")
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
find: pkgPattern("components/layout"),
|
|
1040
|
+
replacement: resolve(engineSrc, "components/layout/index.ts")
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
find: pkgPattern("components/home"),
|
|
1044
|
+
replacement: resolve(engineSrc, "components/home/index.ts")
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
find: pkgPattern("components/common"),
|
|
1048
|
+
replacement: resolve(engineSrc, "components/common/index.ts")
|
|
1049
|
+
},
|
|
1050
|
+
{ find: pkgPattern("modal"), replacement: resolve(engineSrc, "components/modal/index.ts") },
|
|
1051
|
+
{ find: pkgPattern("drawer"), replacement: resolve(engineSrc, "components/drawer/index.ts") },
|
|
1052
|
+
{
|
|
1053
|
+
find: pkgPattern("dropdown"),
|
|
1054
|
+
replacement: resolve(engineSrc, "components/dropdown/index.ts")
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
find: pkgPattern("collapse"),
|
|
1058
|
+
replacement: resolve(engineSrc, "components/collapse/index.ts")
|
|
1059
|
+
},
|
|
1060
|
+
{ find: pkgPattern("toast"), replacement: resolve(engineSrc, "components/toast/index.ts") },
|
|
1061
|
+
{ find: pkgPattern("cart"), replacement: resolve(engineSrc, "components/cart/index.ts") },
|
|
1062
|
+
{
|
|
1063
|
+
find: pkgPattern("product"),
|
|
1064
|
+
replacement: resolve(engineSrc, "components/product/index.ts")
|
|
1065
|
+
},
|
|
1066
|
+
{ find: pkgPattern("layout"), replacement: resolve(engineSrc, "components/layout/index.ts") },
|
|
1067
|
+
{ find: pkgPattern("home"), replacement: resolve(engineSrc, "components/home/index.ts") },
|
|
1068
|
+
{ find: pkgPattern("common"), replacement: resolve(engineSrc, "components/common/index.ts") },
|
|
1069
|
+
{ find: pkgPattern("providers"), replacement: resolve(engineSrc, "providers/index.ts") },
|
|
1070
|
+
{ find: pkgPattern("api/types"), replacement: resolve(engineSrc, "api/types.ts") },
|
|
1071
|
+
{ find: pkgPattern("api/client"), replacement: resolve(engineSrc, "api/client.ts") },
|
|
1072
|
+
{ find: pkgPattern("api/store"), replacement: resolve(engineSrc, "api/store.ts") },
|
|
1073
|
+
{
|
|
1074
|
+
find: pkgPattern("api/translations"),
|
|
1075
|
+
replacement: resolve(engineSrc, "api/translations.ts")
|
|
1076
|
+
},
|
|
1077
|
+
{ find: pkgPattern("api/cart"), replacement: resolve(engineSrc, "api/cart.ts") },
|
|
1078
|
+
{ find: pkgPattern("api/product"), replacement: resolve(engineSrc, "api/product.ts") },
|
|
1079
|
+
{ find: pkgPattern("api/home"), replacement: resolve(engineSrc, "api/home.ts") },
|
|
1080
|
+
{ find: pkgPattern("api/brands"), replacement: resolve(engineSrc, "api/brands.ts") },
|
|
1081
|
+
{ find: pkgPattern("api/loyalty"), replacement: resolve(engineSrc, "api/loyalty.ts") },
|
|
1082
|
+
{ find: pkgPattern("api/order"), replacement: resolve(engineSrc, "api/order.ts") },
|
|
1083
|
+
{ find: pkgPattern("api/category"), replacement: resolve(engineSrc, "api/category.ts") },
|
|
1084
|
+
{ find: pkgPattern("api/page"), replacement: resolve(engineSrc, "api/page.ts") },
|
|
1085
|
+
{ find: pkgPattern("api/menu"), replacement: resolve(engineSrc, "api/menu.ts") },
|
|
1086
|
+
{
|
|
1087
|
+
find: pkgPattern("api/notification"),
|
|
1088
|
+
replacement: resolve(engineSrc, "api/notification.ts")
|
|
1089
|
+
},
|
|
1090
|
+
{ find: pkgPattern("api/wishlist"), replacement: resolve(engineSrc, "api/wishlist.ts") },
|
|
1091
|
+
{ find: pkgPattern("api/profile"), replacement: resolve(engineSrc, "api/profile.ts") },
|
|
1092
|
+
{
|
|
1093
|
+
find: pkgPattern("tracking"),
|
|
1094
|
+
replacement: resolve(engineSrc, "components/tracking/index.ts")
|
|
1095
|
+
},
|
|
1096
|
+
{ find: pkgPattern("store"), replacement: resolve(engineSrc, "components/store/index.ts") },
|
|
1097
|
+
{ find: pkgPattern(""), replacement: resolve(engineSrc, "index.ts") }
|
|
1098
|
+
];
|
|
1099
|
+
function packageAliasesPlugin() {
|
|
1100
|
+
return {
|
|
1101
|
+
name: "twilight:package-aliases",
|
|
1102
|
+
enforce: "pre",
|
|
1103
|
+
config() {
|
|
1104
|
+
return {
|
|
1105
|
+
resolve: {
|
|
1106
|
+
alias: ALIASES
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
// src/tanstack/templates/locale-wrapper.ts
|
|
1114
|
+
function getLocaleWrapperTemplate(baseRoutesImport) {
|
|
1115
|
+
const mainPkg = baseRoutesImport.replace(/\/routes$/, "");
|
|
1116
|
+
return `// @auto-generated
|
|
1117
|
+
// @ts-nocheck \u2014 params types are generated by TanStack Router on pnpm dev
|
|
1118
|
+
import { createFileRoute, Outlet, redirect } from '@tanstack/react-router';
|
|
1119
|
+
import { FALLBACK_LOCALE, isLocale } from '${baseRoutesImport}';
|
|
1120
|
+
import { store } from '${mainPkg}/api/store';
|
|
1121
|
+
|
|
1122
|
+
export const Route = createFileRoute('/{-$locale}')({
|
|
1123
|
+
beforeLoad: ({ params, location }) => {
|
|
1124
|
+
const { locale } = params;
|
|
1125
|
+
if (!locale) return;
|
|
1126
|
+
if (!isLocale(locale)) {
|
|
1127
|
+
throw redirect({ to: \`/\${FALLBACK_LOCALE}\${location.pathname}\`, replace: true });
|
|
1128
|
+
}
|
|
1129
|
+
},
|
|
1130
|
+
loader: async ({ params, context, location }) => {
|
|
1131
|
+
const settings = await context.queryClient.ensureQueryData(store.queries.settings());
|
|
1132
|
+
const isMultilingual = settings?.store?.settings?.is_multilingual ?? true;
|
|
1133
|
+
|
|
1134
|
+
if (!isMultilingual && params.locale) {
|
|
1135
|
+
throw redirect({
|
|
1136
|
+
to: location.pathname.slice(\`/\${params.locale}\`.length) || '/',
|
|
1137
|
+
replace: true,
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
if (isMultilingual && !params.locale) {
|
|
1141
|
+
throw redirect({ to: \`/\${FALLBACK_LOCALE}\${location.pathname}\`, replace: true });
|
|
1142
|
+
}
|
|
1143
|
+
},
|
|
1144
|
+
component: () => <Outlet />,
|
|
1145
|
+
});
|
|
1146
|
+
`;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
// src/tanstack/templates/redirect.ts
|
|
1150
|
+
function getRedirectTemplate(baseRoutesImport) {
|
|
1151
|
+
return `// @auto-generated
|
|
1152
|
+
// @ts-nocheck \u2014 params types are generated by TanStack Router on pnpm dev
|
|
1153
|
+
import { createFileRoute, redirect } from '@tanstack/react-router';
|
|
1154
|
+
import { FALLBACK_LOCALE } from '${baseRoutesImport}';
|
|
1155
|
+
|
|
1156
|
+
type RedirectType =
|
|
1157
|
+
| 'products'
|
|
1158
|
+
| 'categories'
|
|
1159
|
+
| 'brands'
|
|
1160
|
+
| 'pages'
|
|
1161
|
+
| 'blog_articles'
|
|
1162
|
+
| 'blog_categories'
|
|
1163
|
+
| 'products_tags'
|
|
1164
|
+
| 'reviews_link'
|
|
1165
|
+
| 'book_now';
|
|
1166
|
+
|
|
1167
|
+
export const Route = createFileRoute('/{-$locale}/redirect/$type/$id')({
|
|
1168
|
+
loader: async ({ params }) => {
|
|
1169
|
+
const { type, id } = params;
|
|
1170
|
+
const locale = params.locale || FALLBACK_LOCALE;
|
|
1171
|
+
|
|
1172
|
+
let redirectPath: string;
|
|
1173
|
+
const slug = '-';
|
|
1174
|
+
|
|
1175
|
+
switch (type as RedirectType) {
|
|
1176
|
+
case 'products':
|
|
1177
|
+
redirectPath = \`/\${locale}/\${slug}/p\${id}\`;
|
|
1178
|
+
break;
|
|
1179
|
+
case 'categories':
|
|
1180
|
+
redirectPath = \`/\${locale}/\${slug}/c\${id}\`;
|
|
1181
|
+
break;
|
|
1182
|
+
case 'brands':
|
|
1183
|
+
redirectPath = \`/\${locale}/brands/\${id}\`;
|
|
1184
|
+
break;
|
|
1185
|
+
case 'pages':
|
|
1186
|
+
redirectPath = \`/\${locale}/page-\${id}\`;
|
|
1187
|
+
break;
|
|
1188
|
+
case 'blog_articles':
|
|
1189
|
+
redirectPath = \`/\${locale}/blog/\${slug}/a-\${id}\`;
|
|
1190
|
+
break;
|
|
1191
|
+
case 'blog_categories':
|
|
1192
|
+
redirectPath = \`/\${locale}/blog/\${slug}/c-\${id}\`;
|
|
1193
|
+
break;
|
|
1194
|
+
case 'products_tags':
|
|
1195
|
+
redirectPath = \`/\${locale}/\${slug}/tag-\${id}\`;
|
|
1196
|
+
break;
|
|
1197
|
+
case 'book_now':
|
|
1198
|
+
redirectPath = \`/\${locale}/landing/\${id}\`;
|
|
1199
|
+
break;
|
|
1200
|
+
case 'reviews_link':
|
|
1201
|
+
default:
|
|
1202
|
+
redirectPath = \`/\${locale}\`;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
throw redirect({ to: redirectPath });
|
|
1206
|
+
},
|
|
1207
|
+
});
|
|
1208
|
+
`;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
// src/tanstack/templates/account-layout.ts
|
|
1212
|
+
function getAccountLayoutTemplate(baseRoutesImport) {
|
|
1213
|
+
const mainPkg = baseRoutesImport.replace(/\/routes$/, "");
|
|
1214
|
+
return `// @auto-generated
|
|
1215
|
+
// @ts-nocheck \u2014 params types are generated by TanStack Router on pnpm dev
|
|
1216
|
+
import { createFileRoute, Outlet, useMatches } from '@tanstack/react-router';
|
|
1217
|
+
import { useComponent } from '${mainPkg}';
|
|
1218
|
+
import { CustomerLayout } from '${mainPkg}/components/layout';
|
|
1219
|
+
import { CustomerLayoutSkeleton } from '${mainPkg}/skeleton';
|
|
1220
|
+
|
|
1221
|
+
const ACCOUNT_LAYOUT_PENDING_KEY = 'account:layout-pending';
|
|
1222
|
+
|
|
1223
|
+
function AccountLayoutComponent() {
|
|
1224
|
+
const matches = useMatches();
|
|
1225
|
+
const page = matches.reduceRight(
|
|
1226
|
+
(found, m) => found ?? (m.loaderData?.page ? m.loaderData.page : null),
|
|
1227
|
+
null,
|
|
1228
|
+
);
|
|
1229
|
+
|
|
1230
|
+
return (
|
|
1231
|
+
<CustomerLayout page={page}>
|
|
1232
|
+
<Outlet />
|
|
1233
|
+
</CustomerLayout>
|
|
1234
|
+
);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function AccountLayoutPendingComponent() {
|
|
1238
|
+
const AccountLayoutPending = useComponent(ACCOUNT_LAYOUT_PENDING_KEY);
|
|
1239
|
+
return AccountLayoutPending ? <AccountLayoutPending /> : <CustomerLayoutSkeleton />;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
export const Route = createFileRoute('/{-$locale}/account')({
|
|
1243
|
+
component: AccountLayoutComponent,
|
|
1244
|
+
pendingComponent: AccountLayoutPendingComponent,
|
|
1245
|
+
});
|
|
1246
|
+
`;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/vite/adapters/tanstack.adapter.ts
|
|
1250
|
+
var DEFAULT_ROUTES_DIR = "./app/routes";
|
|
1251
|
+
var DEFAULT_ROUTES_FILE = "./app/routes.ts";
|
|
1252
|
+
var DEFAULT_ROOT_ROUTE = "__root.tsx";
|
|
1253
|
+
var DEFAULT_BASE_ROUTES = [
|
|
1254
|
+
// Core routes
|
|
1255
|
+
{
|
|
1256
|
+
path: "/",
|
|
1257
|
+
file: "index.tsx",
|
|
1258
|
+
factory: "createHomeRouteConfig",
|
|
1259
|
+
id: RouteId.INDEX,
|
|
1260
|
+
isIndex: true
|
|
1261
|
+
},
|
|
1262
|
+
{ path: "/cart", file: "cart.tsx", factory: "createCartRouteConfig", id: RouteId.CART },
|
|
1263
|
+
{ path: "/search", file: "search.tsx", factory: "createSearchRouteConfig", id: RouteId.SEARCH },
|
|
1264
|
+
// Product listing routes
|
|
1265
|
+
{
|
|
1266
|
+
path: "/latest-products",
|
|
1267
|
+
file: "latest-products.tsx",
|
|
1268
|
+
factory: "createLatestProductsRouteConfig",
|
|
1269
|
+
id: RouteId.PRODUCT_INDEX_LATEST
|
|
1270
|
+
},
|
|
1271
|
+
{
|
|
1272
|
+
path: "/most-sales-products",
|
|
1273
|
+
file: "most-sales-products.tsx",
|
|
1274
|
+
factory: "createMostSalesProductsRouteConfig",
|
|
1275
|
+
id: RouteId.PRODUCT_INDEX_SALES
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
path: "/offers",
|
|
1279
|
+
file: "offers.tsx",
|
|
1280
|
+
factory: "createOffersRouteConfig",
|
|
1281
|
+
id: RouteId.PRODUCT_INDEX_OFFERS
|
|
1282
|
+
},
|
|
1283
|
+
// Blog routes
|
|
1284
|
+
{ path: "/blog", file: "blog.tsx", factory: "createBlogRouteConfig", id: RouteId.BLOG_INDEX },
|
|
1285
|
+
{
|
|
1286
|
+
path: "/blog/author/$id",
|
|
1287
|
+
file: "blog_.author.$id.tsx",
|
|
1288
|
+
factory: "createBlogAuthorRouteConfig",
|
|
1289
|
+
id: RouteId.BLOG_INDEX_AUTHOR
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
path: "/blog/$slug/a-{$id}",
|
|
1293
|
+
file: "blog_.$slug.a-$id.tsx",
|
|
1294
|
+
factory: "createBlogSingleRouteConfig",
|
|
1295
|
+
id: RouteId.BLOG_SINGLE
|
|
1296
|
+
},
|
|
1297
|
+
{
|
|
1298
|
+
path: "/blog/$slug/c-{$id}",
|
|
1299
|
+
file: "blog_.$slug.c-$id.tsx",
|
|
1300
|
+
factory: "createBlogCategoryRouteConfig",
|
|
1301
|
+
id: RouteId.BLOG_INDEX_CATEGORY
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
path: "/blog/$slug/tag-{$id}",
|
|
1305
|
+
file: "blog_.$slug.tag-$id.tsx",
|
|
1306
|
+
factory: "createBlogTagRouteConfig",
|
|
1307
|
+
id: RouteId.BLOG_INDEX_TAG
|
|
1308
|
+
},
|
|
1309
|
+
// Brands routes
|
|
1310
|
+
{
|
|
1311
|
+
path: "/brands",
|
|
1312
|
+
file: "brands.tsx",
|
|
1313
|
+
factory: "createBrandsRouteConfig",
|
|
1314
|
+
id: RouteId.BRANDS_INDEX
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
path: "/brands/$id",
|
|
1318
|
+
file: "brands.$id.tsx",
|
|
1319
|
+
factory: "createBrandSingleRouteConfig",
|
|
1320
|
+
id: RouteId.BRANDS_SINGLE
|
|
1321
|
+
},
|
|
1322
|
+
// Tag routes
|
|
1323
|
+
{
|
|
1324
|
+
path: "/tags/$id",
|
|
1325
|
+
file: "tags.$id.tsx",
|
|
1326
|
+
factory: "createTagRouteConfig",
|
|
1327
|
+
id: RouteId.PRODUCT_INDEX_TAG
|
|
1328
|
+
},
|
|
1329
|
+
// Customer routes
|
|
1330
|
+
{
|
|
1331
|
+
path: "/account",
|
|
1332
|
+
file: "account.tsx",
|
|
1333
|
+
factory: "createAccountLayoutConfig",
|
|
1334
|
+
id: RouteId.CUSTOMER_LAYOUT,
|
|
1335
|
+
isLayout: true
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
path: "/account/profile",
|
|
1339
|
+
file: "account.profile.tsx",
|
|
1340
|
+
factory: "createProfileRouteConfig",
|
|
1341
|
+
id: RouteId.CUSTOMER_PROFILE
|
|
1342
|
+
},
|
|
1343
|
+
{
|
|
1344
|
+
path: "/account/wishlist",
|
|
1345
|
+
file: "account.wishlist.tsx",
|
|
1346
|
+
factory: "createWishlistRouteConfig",
|
|
1347
|
+
id: RouteId.CUSTOMER_WISHLIST
|
|
1348
|
+
},
|
|
1349
|
+
{
|
|
1350
|
+
path: "/account/wallet",
|
|
1351
|
+
file: "account.wallet.tsx",
|
|
1352
|
+
factory: "createWalletRouteConfig",
|
|
1353
|
+
id: RouteId.CUSTOMER_WALLET
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
path: "/account/notifications",
|
|
1357
|
+
file: "account.notifications.tsx",
|
|
1358
|
+
factory: "createNotificationsRouteConfig",
|
|
1359
|
+
id: RouteId.CUSTOMER_NOTIFICATIONS
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
path: "/account/settings",
|
|
1363
|
+
file: "account.settings.tsx",
|
|
1364
|
+
factory: "createSettingsRouteConfig",
|
|
1365
|
+
id: RouteId.CUSTOMER_SETTINGS
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
path: "/account/orders",
|
|
1369
|
+
file: "account.orders.tsx",
|
|
1370
|
+
factory: "createOrdersRouteConfig",
|
|
1371
|
+
id: RouteId.CUSTOMER_ORDERS_INDEX
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
path: "/account/orders/$id",
|
|
1375
|
+
file: "account.orders.$id.tsx",
|
|
1376
|
+
factory: "createOrderSingleRouteConfig",
|
|
1377
|
+
id: RouteId.CUSTOMER_ORDERS_SINGLE
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
path: "/pending-orders",
|
|
1381
|
+
file: "pending-orders.tsx",
|
|
1382
|
+
factory: "createPendingOrdersRedirectConfig",
|
|
1383
|
+
id: RouteId.CUSTOMER_ORDERS_INDEX_PENDING
|
|
1384
|
+
},
|
|
1385
|
+
// Other routes
|
|
1386
|
+
{
|
|
1387
|
+
path: "/loyalty",
|
|
1388
|
+
file: "loyalty.tsx",
|
|
1389
|
+
factory: "createLoyaltyRouteConfig",
|
|
1390
|
+
id: RouteId.LOYALTY
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
path: "/testimonials",
|
|
1394
|
+
file: "testimonials.tsx",
|
|
1395
|
+
factory: "createTestimonialsRouteConfig",
|
|
1396
|
+
id: RouteId.TESTIMONIALS
|
|
1397
|
+
},
|
|
1398
|
+
{
|
|
1399
|
+
path: "/thank-you/$orderId",
|
|
1400
|
+
file: "thank-you.$orderId.tsx",
|
|
1401
|
+
factory: "createThankYouRouteConfig",
|
|
1402
|
+
id: RouteId.THANK_YOU
|
|
1403
|
+
},
|
|
1404
|
+
// SEO-friendly slug routes
|
|
1405
|
+
{
|
|
1406
|
+
path: "/$slug/c{$id}",
|
|
1407
|
+
file: "$slug.c$id.tsx",
|
|
1408
|
+
factory: "createSlugCategoryRouteConfig",
|
|
1409
|
+
id: RouteId.PRODUCT_INDEX
|
|
1410
|
+
},
|
|
1411
|
+
{
|
|
1412
|
+
path: "/$slug/p{$id}",
|
|
1413
|
+
file: "$slug.p$id.tsx",
|
|
1414
|
+
factory: "createSlugProductRouteConfig",
|
|
1415
|
+
id: RouteId.PRODUCT_SINGLE
|
|
1416
|
+
},
|
|
1417
|
+
{
|
|
1418
|
+
path: "/$slug/brand-{$id}",
|
|
1419
|
+
file: "$slug.brand-$id.tsx",
|
|
1420
|
+
factory: "createSlugBrandRedirectConfig",
|
|
1421
|
+
id: RouteId.BRANDS_SINGLE
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
path: "/$slug/tag-{$id}",
|
|
1425
|
+
file: "$slug.tag-$id.tsx",
|
|
1426
|
+
factory: "createSlugTagRouteConfig",
|
|
1427
|
+
id: RouteId.PRODUCT_INDEX_TAG
|
|
1428
|
+
},
|
|
1429
|
+
{
|
|
1430
|
+
path: "/$slug/page-{$id}",
|
|
1431
|
+
file: "$slug.page-$id.tsx",
|
|
1432
|
+
factory: "createSlugPageRouteConfig",
|
|
1433
|
+
id: RouteId.PAGE_SINGLE
|
|
1434
|
+
}
|
|
1435
|
+
];
|
|
1436
|
+
function loadRoutesFile(filePath) {
|
|
1437
|
+
if (!existsSync(filePath)) return [];
|
|
1438
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
1439
|
+
let code;
|
|
1440
|
+
try {
|
|
1441
|
+
const result = transformSync(raw, {
|
|
1442
|
+
loader: "ts",
|
|
1443
|
+
format: "cjs",
|
|
1444
|
+
target: "node18"
|
|
1445
|
+
});
|
|
1446
|
+
code = result.code;
|
|
1447
|
+
} catch (err) {
|
|
1448
|
+
console.warn(`[twilight-react:tanstack] Failed to transpile ${basename(filePath)}:`, err);
|
|
1449
|
+
return [];
|
|
1450
|
+
}
|
|
1451
|
+
const projectRequire = createRequire(resolve(process.cwd(), "package.json"));
|
|
1452
|
+
let exported;
|
|
1453
|
+
try {
|
|
1454
|
+
const m = new Module(filePath);
|
|
1455
|
+
m.filename = filePath;
|
|
1456
|
+
m.paths = Module._nodeModulePaths(dirname(filePath));
|
|
1457
|
+
m.require = projectRequire;
|
|
1458
|
+
m._compile(code, filePath);
|
|
1459
|
+
exported = m.exports;
|
|
1460
|
+
} catch (err) {
|
|
1461
|
+
console.warn(`[twilight-react:tanstack] Failed to evaluate ${basename(filePath)}:`, err);
|
|
1462
|
+
return [];
|
|
1463
|
+
}
|
|
1464
|
+
if (!Array.isArray(exported.routes)) return [];
|
|
1465
|
+
const routes = [];
|
|
1466
|
+
for (const node of exported.routes) {
|
|
1467
|
+
if (!node || typeof node !== "object" || !node.file) continue;
|
|
1468
|
+
if (node.type === "index") {
|
|
1469
|
+
routes.push({
|
|
1470
|
+
path: "/",
|
|
1471
|
+
file: node.file,
|
|
1472
|
+
factory: `createCustomRoute_${node.file.replace(/[^a-zA-Z0-9]/g, "_")}`,
|
|
1473
|
+
isIndex: true
|
|
1474
|
+
});
|
|
1475
|
+
} else if (node.type === "route" && node.path) {
|
|
1476
|
+
routes.push({
|
|
1477
|
+
path: node.path,
|
|
1478
|
+
file: node.file,
|
|
1479
|
+
factory: `createCustomRoute_${node.file.replace(/[^a-zA-Z0-9]/g, "_")}`
|
|
1480
|
+
});
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
if (routes.length > 0) {
|
|
1484
|
+
console.log(
|
|
1485
|
+
`[twilight-react:tanstack] Loaded ${routes.length} custom route(s) from ${basename(filePath)}`
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
return routes;
|
|
1489
|
+
}
|
|
1490
|
+
var FACTORY_TO_MODULE = {
|
|
1491
|
+
createHomeRouteConfig: "Home",
|
|
1492
|
+
createCartRouteConfig: "Cart",
|
|
1493
|
+
// All product listing routes use the unified ProductListing module
|
|
1494
|
+
createSearchRouteConfig: "ProductListing",
|
|
1495
|
+
createLatestProductsRouteConfig: "ProductListing",
|
|
1496
|
+
createMostSalesProductsRouteConfig: "ProductListing",
|
|
1497
|
+
createOffersRouteConfig: "ProductListing",
|
|
1498
|
+
createSlugCategoryRouteConfig: "ProductListing",
|
|
1499
|
+
createSlugTagRouteConfig: "ProductListing",
|
|
1500
|
+
createTagRouteConfig: "ProductListing",
|
|
1501
|
+
createBrandSingleRouteConfig: "ProductListing",
|
|
1502
|
+
createBlogRouteConfig: "Blog",
|
|
1503
|
+
createBlogSingleRouteConfig: "BlogSingle",
|
|
1504
|
+
createBlogAuthorRouteConfig: "BlogAuthorRoute",
|
|
1505
|
+
createBlogCategoryRouteConfig: "BlogCategoryRoute",
|
|
1506
|
+
createBlogTagRouteConfig: "BlogTagRoute",
|
|
1507
|
+
createBrandsRouteConfig: "Brands",
|
|
1508
|
+
createProfileRouteConfig: "Profile",
|
|
1509
|
+
createWishlistRouteConfig: "Wishlist",
|
|
1510
|
+
createWalletRouteConfig: "Wallet",
|
|
1511
|
+
createNotificationsRouteConfig: "Notifications",
|
|
1512
|
+
createSettingsRouteConfig: "Settings",
|
|
1513
|
+
createOrdersRouteConfig: "Orders",
|
|
1514
|
+
createOrderSingleRouteConfig: "OrderSingle",
|
|
1515
|
+
createAccountLayoutConfig: "AccountLayout",
|
|
1516
|
+
createLoyaltyRouteConfig: "Loyalty",
|
|
1517
|
+
createTestimonialsRouteConfig: "Testimonials",
|
|
1518
|
+
createThankYouRouteConfig: "ThankYou",
|
|
1519
|
+
// Other routes
|
|
1520
|
+
createSlugProductRouteConfig: "Product",
|
|
1521
|
+
createSlugPageRouteConfig: "PageSingle",
|
|
1522
|
+
// SEO slug redirect (redirect-only, no component)
|
|
1523
|
+
createSlugBrandRedirectConfig: "slugBrandRedirect",
|
|
1524
|
+
// Pending orders redirect
|
|
1525
|
+
createPendingOrdersRedirectConfig: "pendingOrdersRedirect"
|
|
1526
|
+
};
|
|
1527
|
+
var REDIRECT_ONLY_MODULES = /* @__PURE__ */ new Set(["slugBrandRedirect", "pendingOrdersRedirect"]);
|
|
1528
|
+
var MODULE_SUBPATH = {
|
|
1529
|
+
Home: "home",
|
|
1530
|
+
Cart: "cart",
|
|
1531
|
+
ProductListing: "product-listing",
|
|
1532
|
+
Blog: "blog",
|
|
1533
|
+
BlogSingle: "blog",
|
|
1534
|
+
BlogAuthorRoute: "blog",
|
|
1535
|
+
BlogCategoryRoute: "blog",
|
|
1536
|
+
BlogTagRoute: "blog",
|
|
1537
|
+
Brands: "brands",
|
|
1538
|
+
BrandSingle: "brands",
|
|
1539
|
+
Profile: "account",
|
|
1540
|
+
Wishlist: "account",
|
|
1541
|
+
Wallet: "account",
|
|
1542
|
+
Notifications: "account",
|
|
1543
|
+
Settings: "account",
|
|
1544
|
+
Orders: "account/orders",
|
|
1545
|
+
OrderSingle: "account/orders",
|
|
1546
|
+
Loyalty: "loyalty",
|
|
1547
|
+
PageSingle: "page",
|
|
1548
|
+
Testimonials: "testimonials",
|
|
1549
|
+
ThankYou: "thank-you",
|
|
1550
|
+
Product: "product",
|
|
1551
|
+
slugBrandRedirect: "seo-redirects",
|
|
1552
|
+
pendingOrdersRedirect: "seo-redirects"
|
|
1553
|
+
};
|
|
1554
|
+
var MODULE_LOADER_TYPE = {
|
|
1555
|
+
Home: "HomeLoaderData",
|
|
1556
|
+
Cart: "CartPageProps",
|
|
1557
|
+
ProductListing: "ProductListLoaderData",
|
|
1558
|
+
Blog: "BlogPageProps",
|
|
1559
|
+
BlogSingle: "BlogSinglePageProps",
|
|
1560
|
+
BlogAuthorRoute: "BlogAuthorLoaderData",
|
|
1561
|
+
BlogCategoryRoute: "BlogCategoryLoaderData",
|
|
1562
|
+
BlogTagRoute: "BlogTagLoaderData",
|
|
1563
|
+
Brands: "BrandsPageProps",
|
|
1564
|
+
BrandSingle: "ProductListLoaderData",
|
|
1565
|
+
Profile: "ProfilePageProps",
|
|
1566
|
+
Wishlist: "WishlistPageProps",
|
|
1567
|
+
Wallet: "WalletPageProps",
|
|
1568
|
+
Notifications: "NotificationsPageProps",
|
|
1569
|
+
Settings: "SettingsPageProps",
|
|
1570
|
+
Orders: "OrdersPageProps",
|
|
1571
|
+
OrderSingle: "OrderSinglePageProps",
|
|
1572
|
+
Loyalty: "LoyaltyPageProps",
|
|
1573
|
+
PageSingle: "PageSingleProps",
|
|
1574
|
+
Testimonials: "TestimonialsPageProps",
|
|
1575
|
+
ThankYou: "ThankYouPageProps",
|
|
1576
|
+
Product: "ProductPageProps"
|
|
1577
|
+
};
|
|
1578
|
+
var PAGINATED_MODULES = /* @__PURE__ */ new Set(["Wishlist"]);
|
|
1579
|
+
var PAGINATED_NO_LOCALE = /* @__PURE__ */ new Set(["Wallet"]);
|
|
1580
|
+
var SORT_PAGINATED_MODULES = /* @__PURE__ */ new Set(["ProductListing"]);
|
|
1581
|
+
var SORT_PAGINATED_FACTORIES = /* @__PURE__ */ new Set([
|
|
1582
|
+
"createSearchRouteConfig",
|
|
1583
|
+
"createSlugTagRouteConfig",
|
|
1584
|
+
"createTagRouteConfig",
|
|
1585
|
+
"createBrandSingleRouteConfig"
|
|
1586
|
+
]);
|
|
1587
|
+
var DEFERRED_ROUTES = /* @__PURE__ */ new Set();
|
|
1588
|
+
var STATUS_FILTERED_MODULES = /* @__PURE__ */ new Set(["Orders"]);
|
|
1589
|
+
var MODULE_PENDING_SKELETON = {
|
|
1590
|
+
Home: "HomeSkeleton",
|
|
1591
|
+
Product: "ProductDetailSkeleton",
|
|
1592
|
+
Blog: "BlogSkeleton",
|
|
1593
|
+
BlogSingle: "BlogSkeleton",
|
|
1594
|
+
BlogAuthorRoute: "BlogSkeleton",
|
|
1595
|
+
BlogCategoryRoute: "BlogSkeleton",
|
|
1596
|
+
BlogTagRoute: "BlogSkeleton",
|
|
1597
|
+
Cart: "CartSkeleton",
|
|
1598
|
+
Profile: "CustomerPageSkeleton",
|
|
1599
|
+
Wishlist: "CustomerPageSkeleton",
|
|
1600
|
+
Wallet: "CustomerPageSkeleton",
|
|
1601
|
+
Notifications: "CustomerPageSkeleton",
|
|
1602
|
+
Settings: "CustomerPageSkeleton",
|
|
1603
|
+
Orders: "CustomerPageSkeleton",
|
|
1604
|
+
OrderSingle: "CustomerPageSkeleton"
|
|
1605
|
+
};
|
|
1606
|
+
var FACTORY_LOADER_PARAMS = {
|
|
1607
|
+
// /$slug/c{$id} → category.loader({ id }) — slug is SEO-only, not used by loader
|
|
1608
|
+
createSlugCategoryRouteConfig: { id: "id" },
|
|
1609
|
+
// /$slug/p{$id} → product.loader({ id })
|
|
1610
|
+
createSlugProductRouteConfig: { id: "id" },
|
|
1611
|
+
// /$slug/tag-{$id} → productListLoader({ source: 'tags', id })
|
|
1612
|
+
createSlugTagRouteConfig: { id: "id" },
|
|
1613
|
+
// /$slug/page-{$id} → pageSingle.loader({ id }) — slug is SEO-only, not used by loader
|
|
1614
|
+
createSlugPageRouteConfig: { id: "id" },
|
|
1615
|
+
// /tags/$id → productListLoader({ source: 'tags', id })
|
|
1616
|
+
createTagRouteConfig: { id: "id" },
|
|
1617
|
+
// /brands/$id → productListLoader({ source: 'brands', id })
|
|
1618
|
+
createBrandSingleRouteConfig: { id: "id" }
|
|
1619
|
+
};
|
|
1620
|
+
var FACTORY_STATIC_PARAMS = {
|
|
1621
|
+
createLatestProductsRouteConfig: {
|
|
1622
|
+
source: "latest",
|
|
1623
|
+
title: "Latest Products",
|
|
1624
|
+
slug: "latest-products"
|
|
1625
|
+
},
|
|
1626
|
+
createMostSalesProductsRouteConfig: {
|
|
1627
|
+
source: "sales",
|
|
1628
|
+
title: "Most Sales Products",
|
|
1629
|
+
slug: "most-sales-products"
|
|
1630
|
+
},
|
|
1631
|
+
createOffersRouteConfig: {
|
|
1632
|
+
source: "offers",
|
|
1633
|
+
title: "Offers",
|
|
1634
|
+
slug: "offers"
|
|
1635
|
+
}
|
|
1636
|
+
};
|
|
1637
|
+
function getParamMapping(routePath, factory) {
|
|
1638
|
+
if (factory && FACTORY_LOADER_PARAMS[factory]) {
|
|
1639
|
+
const mapping = FACTORY_LOADER_PARAMS[factory];
|
|
1640
|
+
const entries = Object.entries(mapping).map(
|
|
1641
|
+
([loaderParam, urlParam]) => `${loaderParam}: params.${urlParam}`
|
|
1642
|
+
);
|
|
1643
|
+
if (factory === "createTagRouteConfig" || factory === "createSlugTagRouteConfig") {
|
|
1644
|
+
return `{ source: 'tags', ${entries.join(", ")} }`;
|
|
1645
|
+
}
|
|
1646
|
+
if (factory === "createBrandSingleRouteConfig") {
|
|
1647
|
+
return `{ source: 'brands', ${entries.join(", ")} }`;
|
|
1648
|
+
}
|
|
1649
|
+
return `{ ${entries.join(", ")} }`;
|
|
1650
|
+
}
|
|
1651
|
+
const paramMatches = routePath.match(/\$([a-zA-Z]+)/g);
|
|
1652
|
+
if (!paramMatches || paramMatches.length === 0) return "";
|
|
1653
|
+
const params = paramMatches.map((match) => {
|
|
1654
|
+
const paramName = match.slice(1);
|
|
1655
|
+
return `${paramName}: params.${paramName}`;
|
|
1656
|
+
});
|
|
1657
|
+
return `{ ${params.join(", ")} }`;
|
|
1658
|
+
}
|
|
1659
|
+
function toTanstackRoutePath(route) {
|
|
1660
|
+
if (route.isIndex) return "/{-$locale}/";
|
|
1661
|
+
return `/{-$locale}${route.path}`;
|
|
1662
|
+
}
|
|
1663
|
+
function generateRouteFileContent(route, baseImport) {
|
|
1664
|
+
const routePath = route.isIndex ? "/" : route.path;
|
|
1665
|
+
const tanstackRoutePath = toTanstackRoutePath(route);
|
|
1666
|
+
const moduleName = FACTORY_TO_MODULE[route.factory];
|
|
1667
|
+
if (moduleName) {
|
|
1668
|
+
const hasParams = routePath.includes("$");
|
|
1669
|
+
const paramMapping = getParamMapping(routePath, route.factory);
|
|
1670
|
+
const isRedirectOnly = REDIRECT_ONLY_MODULES.has(moduleName);
|
|
1671
|
+
const subpath = MODULE_SUBPATH[moduleName];
|
|
1672
|
+
const moduleImport = subpath ? `${baseImport}/${subpath}` : baseImport;
|
|
1673
|
+
if (route.factory === "createSlugBrandRedirectConfig") {
|
|
1674
|
+
const loaderImport = "slugBrandRedirectLoader";
|
|
1675
|
+
const redirectParamMapping = paramMapping ? paramMapping.replace(/\s*}$/, ", locale: params.locale }") : "{ locale: params.locale }";
|
|
1676
|
+
const loaderCall2 = `({ params }) =>
|
|
1677
|
+
${loaderImport}({
|
|
1678
|
+
params: ${redirectParamMapping},
|
|
1679
|
+
})`;
|
|
1680
|
+
return `// @auto-generated
|
|
1681
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1682
|
+
import { ${loaderImport} } from '${baseImport}/seo-redirects';
|
|
1683
|
+
|
|
1684
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1685
|
+
loader: ${loaderCall2},
|
|
1686
|
+
});
|
|
1687
|
+
`;
|
|
1688
|
+
}
|
|
1689
|
+
if (route.factory === "createPendingOrdersRedirectConfig") {
|
|
1690
|
+
const loaderImport = "pendingOrdersRedirectLoader";
|
|
1691
|
+
return `// @auto-generated
|
|
1692
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1693
|
+
import { ${loaderImport} } from '${baseImport}/seo-redirects';
|
|
1694
|
+
|
|
1695
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1696
|
+
loader: ({ params }) =>
|
|
1697
|
+
${loaderImport}({
|
|
1698
|
+
params: { locale: params.locale },
|
|
1699
|
+
}),
|
|
1700
|
+
});
|
|
1701
|
+
`;
|
|
1702
|
+
}
|
|
1703
|
+
const loaderType = MODULE_LOADER_TYPE[moduleName];
|
|
1704
|
+
const typeImport = loaderType ? `
|
|
1705
|
+
import type { ${loaderType} } from '${moduleImport}';` : "";
|
|
1706
|
+
const extraTypeImport = "";
|
|
1707
|
+
const importName = moduleName;
|
|
1708
|
+
const staticParams = route.factory ? FACTORY_STATIC_PARAMS[route.factory] : void 0;
|
|
1709
|
+
const loaderCall = staticParams ? `({ params }) => ${importName}.loader({ params: ${JSON.stringify(staticParams)}, locale: params.locale })` : hasParams ? `({ params }) => ${importName}.loader({ params: ${paramMapping}, locale: params.locale })` : `({ params }) => ${importName}.loader({ locale: params.locale })`;
|
|
1710
|
+
if (isRedirectOnly) {
|
|
1711
|
+
return `// @auto-generated
|
|
1712
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1713
|
+
import { ${importName} } from '${moduleImport}';
|
|
1714
|
+
|
|
1715
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1716
|
+
loader: ${loaderCall},
|
|
1717
|
+
});
|
|
1718
|
+
`;
|
|
1719
|
+
}
|
|
1720
|
+
if (route.factory === "createSearchRouteConfig") {
|
|
1721
|
+
const componentFn2 = loaderType ? `function ${importName}Component() {
|
|
1722
|
+
const data: ${loaderType} = Route.useLoaderData();
|
|
1723
|
+
return <${importName}.Component {...data} />;
|
|
1724
|
+
}` : `function ${importName}Component() {
|
|
1725
|
+
const data = Route.useLoaderData();
|
|
1726
|
+
return <${importName}.Component {...data} />;
|
|
1727
|
+
}`;
|
|
1728
|
+
return `// @auto-generated
|
|
1729
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1730
|
+
import { ${importName} } from '${moduleImport}';${typeImport}${extraTypeImport}
|
|
1731
|
+
import { withHead } from '${baseImport.replace("/routes", "")}/tanstack';
|
|
1732
|
+
|
|
1733
|
+
/**
|
|
1734
|
+
* Search route configuration with URL query parameter support.
|
|
1735
|
+
* Uses validateSearch for type-safe search params and loaderDeps to pass
|
|
1736
|
+
* them to the loader.
|
|
1737
|
+
*/
|
|
1738
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1739
|
+
validateSearch: (search: Record<string, unknown>) => ({ q: (search.q as string) || '' }),
|
|
1740
|
+
loaderDeps: ({ search }) => ({ q: search.q }),
|
|
1741
|
+
loader: ({ deps, params }): Promise<${loaderType}> =>
|
|
1742
|
+
${importName}.loader({
|
|
1743
|
+
params: { source: 'search' },
|
|
1744
|
+
search: { q: deps.q },
|
|
1745
|
+
locale: params.locale,
|
|
1746
|
+
}),
|
|
1747
|
+
head: withHead(${importName}),
|
|
1748
|
+
component: ${importName}Component,
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
/**
|
|
1752
|
+
* Search page component.
|
|
1753
|
+
* Uses Route.useLoaderData() to access the data loaded by the route loader,
|
|
1754
|
+
* following React best practices for data fetching in route components.
|
|
1755
|
+
*/
|
|
1756
|
+
${componentFn2}
|
|
1757
|
+
`;
|
|
1758
|
+
}
|
|
1759
|
+
const isDeferred = DEFERRED_ROUTES.has(moduleName);
|
|
1760
|
+
const PRETTIER_INDENT = 10;
|
|
1761
|
+
const PRETTIER_PRINT_WIDTH = 100;
|
|
1762
|
+
const getTypedLoaderCall = (returnType2, name, args) => {
|
|
1763
|
+
const inline = `({ params }): ${returnType2} => ${name}.loader(${args})`;
|
|
1764
|
+
const lineLength = PRETTIER_INDENT + inline.length + 1;
|
|
1765
|
+
if (lineLength <= PRETTIER_PRINT_WIDTH) {
|
|
1766
|
+
return inline;
|
|
1767
|
+
}
|
|
1768
|
+
return `({ params }): ${returnType2} =>
|
|
1769
|
+
${name}.loader(${args})`;
|
|
1770
|
+
};
|
|
1771
|
+
const returnType = isDeferred ? loaderType : `Promise<${loaderType}>`;
|
|
1772
|
+
const typedLoaderCall = loaderType ? staticParams ? (
|
|
1773
|
+
// Static params routes - expanded object format for Prettier
|
|
1774
|
+
// Each param on its own line with proper nesting
|
|
1775
|
+
`({ params }): ${returnType} =>
|
|
1776
|
+
${importName}.loader({
|
|
1777
|
+
params: {
|
|
1778
|
+
source: '${staticParams.source}',
|
|
1779
|
+
title: '${staticParams.title}',
|
|
1780
|
+
slug: '${staticParams.slug}',
|
|
1781
|
+
},
|
|
1782
|
+
locale: params.locale,
|
|
1783
|
+
})`
|
|
1784
|
+
) : hasParams ? (
|
|
1785
|
+
// Routes with URL params - check if inline fits
|
|
1786
|
+
getTypedLoaderCall(
|
|
1787
|
+
returnType,
|
|
1788
|
+
importName,
|
|
1789
|
+
`{ params: ${paramMapping}, locale: params.locale }`
|
|
1790
|
+
)
|
|
1791
|
+
) : (
|
|
1792
|
+
// Routes without params - check if inline fits
|
|
1793
|
+
getTypedLoaderCall(returnType, importName, "{ locale: params.locale }")
|
|
1794
|
+
) : loaderCall;
|
|
1795
|
+
const skeletonName = MODULE_PENDING_SKELETON[moduleName];
|
|
1796
|
+
const skeletonModulePath = baseImport.replace(/\/routes$/, "/skeleton");
|
|
1797
|
+
const skeletonImport = skeletonName ? `
|
|
1798
|
+
import { ${skeletonName} } from '${skeletonModulePath}';` : "";
|
|
1799
|
+
const pendingLine = skeletonName ? `
|
|
1800
|
+
pendingComponent: () => <${skeletonName} />,` : "";
|
|
1801
|
+
const headImport = `import { withHead } from '${baseImport.replace("/routes", "")}/tanstack';`;
|
|
1802
|
+
const headCallback = route.isIndex ? `withHead(${importName})` : `withHead(${importName})`;
|
|
1803
|
+
const componentFn = isDeferred ? `function ${importName}Component() {
|
|
1804
|
+
const data: ${loaderType} = Route.useLoaderData();
|
|
1805
|
+
return <${importName}.Component components={data.components} />;
|
|
1806
|
+
}` : loaderType ? `function ${importName}Component() {
|
|
1807
|
+
const data: ${loaderType} = Route.useLoaderData();
|
|
1808
|
+
return <${importName}.Component {...data} />;
|
|
1809
|
+
}` : `function ${importName}Component() {
|
|
1810
|
+
const data = Route.useLoaderData();
|
|
1811
|
+
return <${importName}.Component {...data} />;
|
|
1812
|
+
}`;
|
|
1813
|
+
const routeDescription = route.isIndex ? "Home (index) route configuration." : `${importName} route configuration.`;
|
|
1814
|
+
if (SORT_PAGINATED_MODULES.has(moduleName) || SORT_PAGINATED_FACTORIES.has(route.factory)) {
|
|
1815
|
+
const sortLoaderCall = staticParams ? `({ deps, params }): ${returnType} =>
|
|
1816
|
+
${importName}.loader({
|
|
1817
|
+
params: {
|
|
1818
|
+
source: '${staticParams?.source}',
|
|
1819
|
+
title: '${staticParams?.title}',
|
|
1820
|
+
slug: '${staticParams?.slug}',
|
|
1821
|
+
},
|
|
1822
|
+
search: { page: deps.page, sort: deps.sort },
|
|
1823
|
+
locale: params.locale,
|
|
1824
|
+
})` : hasParams ? `({ deps, params }): ${returnType} =>
|
|
1825
|
+
${importName}.loader({
|
|
1826
|
+
params: ${paramMapping},
|
|
1827
|
+
search: { page: deps.page, sort: deps.sort },
|
|
1828
|
+
locale: params.locale,
|
|
1829
|
+
})` : `({ deps, params }): ${returnType} =>
|
|
1830
|
+
${importName}.loader({
|
|
1831
|
+
search: { page: deps.page, sort: deps.sort },
|
|
1832
|
+
locale: params.locale,
|
|
1833
|
+
})`;
|
|
1834
|
+
return `// @auto-generated
|
|
1835
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1836
|
+
import { ${importName} } from '${moduleImport}';${typeImport}${skeletonImport}
|
|
1837
|
+
${headImport}
|
|
1838
|
+
|
|
1839
|
+
/**
|
|
1840
|
+
* ${routeDescription}
|
|
1841
|
+
* Loads page data via loader and renders the ${importName} component.
|
|
1842
|
+
*/
|
|
1843
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1844
|
+
validateSearch: (search: Record<string, unknown>) => {
|
|
1845
|
+
const page = Number(search.page) || 1;
|
|
1846
|
+
const sort = (search.sort as string) || undefined;
|
|
1847
|
+
return { ...(page > 1 ? { page } : {}), ...(sort ? { sort } : {}) };
|
|
1848
|
+
},
|
|
1849
|
+
loaderDeps: ({ search }) => ({ page: search.page, sort: search.sort }),
|
|
1850
|
+
loader: ${sortLoaderCall},
|
|
1851
|
+
head: ${headCallback},${pendingLine}
|
|
1852
|
+
component: ${importName}Component,
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1855
|
+
/**
|
|
1856
|
+
* ${importName} page component.
|
|
1857
|
+
* Uses Route.useLoaderData() to access the data loaded by the route loader,
|
|
1858
|
+
* following React best practices for data fetching in route components.
|
|
1859
|
+
*/
|
|
1860
|
+
${componentFn}
|
|
1861
|
+
`;
|
|
1862
|
+
}
|
|
1863
|
+
if (PAGINATED_MODULES.has(moduleName) || PAGINATED_NO_LOCALE.has(moduleName)) {
|
|
1864
|
+
const isNoLocale = PAGINATED_NO_LOCALE.has(moduleName);
|
|
1865
|
+
const loaderArgs = isNoLocale ? `{ search: { page: deps.page ?? 1 } }` : `{ search: { page: deps.page ?? 1 }, locale: params.locale }`;
|
|
1866
|
+
const loaderDestructuring = isNoLocale ? "{ deps }" : "{ deps, params }";
|
|
1867
|
+
return `// @auto-generated
|
|
1868
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1869
|
+
import { ${importName} } from '${moduleImport}';${typeImport}${skeletonImport}
|
|
1870
|
+
${headImport}
|
|
1871
|
+
|
|
1872
|
+
/**
|
|
1873
|
+
* ${routeDescription}
|
|
1874
|
+
* Loads page data via loader and renders the ${importName} component.
|
|
1875
|
+
*/
|
|
1876
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1877
|
+
validateSearch: (search: Record<string, unknown>) => {
|
|
1878
|
+
const page = Number(search.page) || 1;
|
|
1879
|
+
return page > 1 ? { page } : {};
|
|
1880
|
+
},
|
|
1881
|
+
loaderDeps: ({ search }) => ({ page: search.page }),
|
|
1882
|
+
loader: (${loaderDestructuring}): ${returnType} =>
|
|
1883
|
+
${importName}.loader(${loaderArgs}),
|
|
1884
|
+
head: ${headCallback},${pendingLine}
|
|
1885
|
+
component: ${importName}Component,
|
|
1886
|
+
});
|
|
1887
|
+
|
|
1888
|
+
/**
|
|
1889
|
+
* ${importName} page component.
|
|
1890
|
+
* Uses Route.useLoaderData() to access the data loaded by the route loader,
|
|
1891
|
+
* following React best practices for data fetching in route components.
|
|
1892
|
+
*/
|
|
1893
|
+
${componentFn}
|
|
1894
|
+
`;
|
|
1895
|
+
}
|
|
1896
|
+
if (STATUS_FILTERED_MODULES.has(moduleName)) {
|
|
1897
|
+
return `// @auto-generated
|
|
1898
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1899
|
+
import { ${importName} } from '${moduleImport}';${typeImport}${skeletonImport}
|
|
1900
|
+
${headImport}
|
|
1901
|
+
|
|
1902
|
+
/**
|
|
1903
|
+
* ${routeDescription}
|
|
1904
|
+
* Loads page data via loader and renders the ${importName} component.
|
|
1905
|
+
*/
|
|
1906
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1907
|
+
validateSearch: (search: Record<string, unknown>) => {
|
|
1908
|
+
const status = (search.status as string) || undefined;
|
|
1909
|
+
return status ? { status } : {};
|
|
1910
|
+
},
|
|
1911
|
+
loaderDeps: ({ search }) => ({ status: search.status }),
|
|
1912
|
+
loader: ({ deps, params }): ${returnType} =>
|
|
1913
|
+
${importName}.loader({ search: { status: deps.status }, locale: params.locale }),
|
|
1914
|
+
head: ${headCallback},${pendingLine}
|
|
1915
|
+
component: ${importName}Component,
|
|
1916
|
+
});
|
|
1917
|
+
|
|
1918
|
+
/**
|
|
1919
|
+
* ${importName} page component.
|
|
1920
|
+
* Uses Route.useLoaderData() to access the data loaded by the route loader,
|
|
1921
|
+
* following React best practices for data fetching in route components.
|
|
1922
|
+
*/
|
|
1923
|
+
${componentFn}
|
|
1924
|
+
`;
|
|
1925
|
+
}
|
|
1926
|
+
return `// @auto-generated
|
|
1927
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1928
|
+
import { ${importName} } from '${moduleImport}';${typeImport}${extraTypeImport}${skeletonImport}
|
|
1929
|
+
${headImport}
|
|
1930
|
+
|
|
1931
|
+
/**
|
|
1932
|
+
* ${routeDescription}
|
|
1933
|
+
* Loads page data via loader and renders the ${importName} component.
|
|
1934
|
+
*/
|
|
1935
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1936
|
+
loader: ${typedLoaderCall},
|
|
1937
|
+
head: ${headCallback},${pendingLine}
|
|
1938
|
+
component: ${importName}Component,
|
|
1939
|
+
});
|
|
1940
|
+
|
|
1941
|
+
/**
|
|
1942
|
+
* ${importName} page component.
|
|
1943
|
+
* Uses Route.useLoaderData() to access the data loaded by the route loader,
|
|
1944
|
+
* following React best practices for data fetching in route components.
|
|
1945
|
+
*/
|
|
1946
|
+
${componentFn}
|
|
1947
|
+
`;
|
|
1948
|
+
}
|
|
1949
|
+
return `// @auto-generated
|
|
1950
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
1951
|
+
import { ${route.factory} } from '${baseImport}';
|
|
1952
|
+
|
|
1953
|
+
const config = ${route.factory}();
|
|
1954
|
+
export const Route = createFileRoute('${tanstackRoutePath}')({
|
|
1955
|
+
loader: config.Loader,
|
|
1956
|
+
component: () => { const data = Route.useLoaderData(); return <config.Component {...data} />; },
|
|
1957
|
+
});
|
|
1958
|
+
`;
|
|
1959
|
+
}
|
|
1960
|
+
function getEngineTwilightRelPath(routesDir) {
|
|
1961
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
1962
|
+
while (dir !== dirname(dir)) {
|
|
1963
|
+
if (existsSync(join(dir, "package.json"))) break;
|
|
1964
|
+
dir = dirname(dir);
|
|
1965
|
+
}
|
|
1966
|
+
const twilightDir = join(dir, ".twilight");
|
|
1967
|
+
const absRoutes = resolve(routesDir);
|
|
1968
|
+
return relative(absRoutes, twilightDir).split(sep).join("/");
|
|
1969
|
+
}
|
|
1970
|
+
function resolveProjectPkg(projectRoot, pkg, subpath) {
|
|
1971
|
+
const pkgJsonPath = join(projectRoot, "node_modules", pkg, "package.json");
|
|
1972
|
+
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
|
|
1973
|
+
const key = subpath ? `./${subpath}` : ".";
|
|
1974
|
+
const exportEntry = pkgJson.exports?.[key];
|
|
1975
|
+
const rel = typeof exportEntry === "string" ? exportEntry : exportEntry?.import?.default ?? exportEntry?.default ?? exportEntry?.require?.default ?? pkgJson.main;
|
|
1976
|
+
if (!rel)
|
|
1977
|
+
throw new Error(`[twilight-react] Cannot resolve ${pkg}${subpath ? `/${subpath}` : ""}`);
|
|
1978
|
+
return join(projectRoot, "node_modules", pkg, rel);
|
|
1979
|
+
}
|
|
1980
|
+
function buildVirtualRouteConfig(routes, rootRouteFile, routesDir) {
|
|
1981
|
+
try {
|
|
1982
|
+
const projectRequire = createRequire(resolve(process.cwd(), "package.json"));
|
|
1983
|
+
const { rootRoute, index, route } = projectRequire("@tanstack/virtual-file-routes");
|
|
1984
|
+
const accountPrefix = "/account/";
|
|
1985
|
+
const accountLayout = routes.find((r) => r.isLayout && r.path === "/account");
|
|
1986
|
+
const accountChildren = routes.filter((r) => !r.isLayout && r.path.startsWith(accountPrefix));
|
|
1987
|
+
const nonAccountRoutes = routes.filter((r) => !r.isLayout && !r.path.startsWith(accountPrefix));
|
|
1988
|
+
const langChildren = nonAccountRoutes.map((r) => {
|
|
1989
|
+
if (r.isIndex) return index(r.file);
|
|
1990
|
+
const relativePath = r.path.replace(/^\//, "");
|
|
1991
|
+
return route(relativePath, r.file);
|
|
1992
|
+
});
|
|
1993
|
+
if (accountLayout) {
|
|
1994
|
+
const twilightRel2 = getEngineTwilightRelPath(routesDir);
|
|
1995
|
+
const accChildren = accountChildren.map((r) => {
|
|
1996
|
+
const relativePath = r.path.replace(/^\/account\/?/, "");
|
|
1997
|
+
return route(relativePath, r.file);
|
|
1998
|
+
});
|
|
1999
|
+
langChildren.push(route("account", `${twilightRel2}/account.tsx`, accChildren));
|
|
2000
|
+
}
|
|
2001
|
+
const twilightRel = getEngineTwilightRelPath(routesDir);
|
|
2002
|
+
return rootRoute(rootRouteFile, [
|
|
2003
|
+
route("{-$locale}", `${twilightRel}/$locale.tsx`, [
|
|
2004
|
+
...langChildren,
|
|
2005
|
+
// Redirect route - handles /{-$locale}/redirect/{type}/{id} URLs
|
|
2006
|
+
route("redirect/$type/$id", `${twilightRel}/redirect.$type.$id.tsx`)
|
|
2007
|
+
])
|
|
2008
|
+
]);
|
|
2009
|
+
} catch (_error) {
|
|
2010
|
+
console.warn(
|
|
2011
|
+
"[twilight-react:tanstack] @tanstack/virtual-file-routes not found. Please install it."
|
|
2012
|
+
);
|
|
2013
|
+
return void 0;
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
var tanstackAdapter = {
|
|
2017
|
+
name: "tanstack",
|
|
2018
|
+
generateRouteFiles({
|
|
2019
|
+
projectRoot,
|
|
2020
|
+
baseRoutes,
|
|
2021
|
+
baseRoutesImport
|
|
2022
|
+
}) {
|
|
2023
|
+
const routesDir = DEFAULT_ROUTES_DIR;
|
|
2024
|
+
const routesFilePath = resolve(projectRoot, DEFAULT_ROUTES_FILE);
|
|
2025
|
+
const customRoutes = loadRoutesFile(routesFilePath);
|
|
2026
|
+
const routeMap = /* @__PURE__ */ new Map();
|
|
2027
|
+
(baseRoutes ?? DEFAULT_BASE_ROUTES).forEach((r) => routeMap.set(r.path, r));
|
|
2028
|
+
customRoutes.forEach((r) => routeMap.set(r.path, r));
|
|
2029
|
+
const allRoutes = Array.from(routeMap.values());
|
|
2030
|
+
const routesDirPath = resolve(projectRoot, routesDir);
|
|
2031
|
+
if (!existsSync(routesDirPath)) {
|
|
2032
|
+
mkdirSync(routesDirPath, { recursive: true });
|
|
2033
|
+
}
|
|
2034
|
+
const engineRouteFiles = [
|
|
2035
|
+
{
|
|
2036
|
+
name: "$locale.tsx",
|
|
2037
|
+
content: getLocaleWrapperTemplate(baseRoutesImport)
|
|
2038
|
+
},
|
|
2039
|
+
{
|
|
2040
|
+
name: "redirect.$type.$id.tsx",
|
|
2041
|
+
content: getRedirectTemplate(baseRoutesImport)
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
name: "account.tsx",
|
|
2045
|
+
content: getAccountLayoutTemplate(baseRoutesImport)
|
|
2046
|
+
}
|
|
2047
|
+
];
|
|
2048
|
+
let engineRoot = dirname(fileURLToPath(import.meta.url));
|
|
2049
|
+
while (engineRoot !== dirname(engineRoot)) {
|
|
2050
|
+
if (existsSync(join(engineRoot, "package.json"))) break;
|
|
2051
|
+
engineRoot = dirname(engineRoot);
|
|
2052
|
+
}
|
|
2053
|
+
const twilightDir = join(engineRoot, ".twilight");
|
|
2054
|
+
if (!existsSync(twilightDir)) {
|
|
2055
|
+
mkdirSync(twilightDir, { recursive: true });
|
|
2056
|
+
}
|
|
2057
|
+
for (const { name, content } of engineRouteFiles) {
|
|
2058
|
+
const filePath = join(twilightDir, name);
|
|
2059
|
+
if (!existsSync(filePath)) {
|
|
2060
|
+
writeFileSync(filePath, content);
|
|
2061
|
+
} else {
|
|
2062
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
2063
|
+
if (existing !== content) {
|
|
2064
|
+
writeFileSync(filePath, content);
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
for (const route of allRoutes) {
|
|
2069
|
+
if (route.isLayout) continue;
|
|
2070
|
+
const filePath = join(routesDirPath, route.file);
|
|
2071
|
+
const content = generateRouteFileContent(route, baseRoutesImport);
|
|
2072
|
+
if (!existsSync(filePath)) {
|
|
2073
|
+
writeFileSync(filePath, content);
|
|
2074
|
+
console.log(`[twilight-react:tanstack] Created: ${route.file}`);
|
|
2075
|
+
} else {
|
|
2076
|
+
const existing = readFileSync(filePath, "utf-8");
|
|
2077
|
+
if (existing.startsWith("// @auto-generated") && existing !== content) {
|
|
2078
|
+
writeFileSync(filePath, content);
|
|
2079
|
+
console.log(`[twilight-react:tanstack] Updated: ${route.file}`);
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
return allRoutes;
|
|
2084
|
+
},
|
|
2085
|
+
async createPlugins(options) {
|
|
2086
|
+
const {
|
|
2087
|
+
srcDirectory = "app",
|
|
2088
|
+
baseRoutesImport = "@salla.sa/twilight-theme-engine/routes",
|
|
2089
|
+
localesDir
|
|
2090
|
+
} = options;
|
|
2091
|
+
const projectRoot = process.cwd();
|
|
2092
|
+
const allRoutes = tanstackAdapter.generateRouteFiles({ projectRoot, baseRoutesImport });
|
|
2093
|
+
const virtualRouteConfig = buildVirtualRouteConfig(
|
|
2094
|
+
allRoutes,
|
|
2095
|
+
DEFAULT_ROOT_ROUTE,
|
|
2096
|
+
resolve(projectRoot, srcDirectory, "routes")
|
|
2097
|
+
);
|
|
2098
|
+
const routeGeneratorPlugin = {
|
|
2099
|
+
name: "twilight:react",
|
|
2100
|
+
enforce: "pre",
|
|
2101
|
+
config(config) {
|
|
2102
|
+
tanstackAdapter.generateRouteFiles({
|
|
2103
|
+
projectRoot: config.root || projectRoot,
|
|
2104
|
+
baseRoutesImport
|
|
2105
|
+
});
|
|
2106
|
+
return config;
|
|
2107
|
+
}
|
|
2108
|
+
// configureServer(server) {
|
|
2109
|
+
// // Proactively warm up the Cloudflare Worker module graph so the user's
|
|
2110
|
+
// // first browser request is served promptly. Without this, Worker
|
|
2111
|
+
// // compilation is triggered lazily on the first navigation request,
|
|
2112
|
+
// // causing a ~10-15 second blank-page window on cold starts.
|
|
2113
|
+
// server.httpServer?.on('listening', () => {
|
|
2114
|
+
// const address = server.httpServer?.address();
|
|
2115
|
+
// const port =
|
|
2116
|
+
// address && typeof address === 'object' && 'port' in address
|
|
2117
|
+
// ? (address as { port: number }).port
|
|
2118
|
+
// : null;
|
|
2119
|
+
// if (!port) return;
|
|
2120
|
+
// void (async () => {
|
|
2121
|
+
// // Give TanStack Start + Cloudflare plugin time to finish registering
|
|
2122
|
+
// // their middleware before we make the warmup request.
|
|
2123
|
+
// await new Promise<void>((r) => setTimeout(r, 1500));
|
|
2124
|
+
// for (let attempt = 0; attempt < 10; attempt++) {
|
|
2125
|
+
// try {
|
|
2126
|
+
// const ctrl = new AbortController();
|
|
2127
|
+
// const tid = setTimeout(() => ctrl.abort(), 12000);
|
|
2128
|
+
// const resp = await fetch(`http://localhost:${port}/ar`, {
|
|
2129
|
+
// signal: ctrl.signal,
|
|
2130
|
+
// });
|
|
2131
|
+
// clearTimeout(tid);
|
|
2132
|
+
// const text = await resp.text();
|
|
2133
|
+
// // A substantial response means the Worker is compiled and SSR works.
|
|
2134
|
+
// if (text.length > 500) return;
|
|
2135
|
+
// } catch {
|
|
2136
|
+
// // Worker not ready yet — retry
|
|
2137
|
+
// }
|
|
2138
|
+
// await new Promise<void>((r) => setTimeout(r, 2000));
|
|
2139
|
+
// }
|
|
2140
|
+
// })();
|
|
2141
|
+
// });
|
|
2142
|
+
// },
|
|
2143
|
+
};
|
|
2144
|
+
const { tanstackStart } = await import(pathToFileURL(resolveProjectPkg(projectRoot, "@tanstack/react-start", "plugin/vite")).href);
|
|
2145
|
+
const reactMod = await import(pathToFileURL(resolveProjectPkg(projectRoot, "@vitejs/plugin-react")).href);
|
|
2146
|
+
return [
|
|
2147
|
+
tanstackStart({ srcDirectory, router: { virtualRouteConfig } }),
|
|
2148
|
+
reactMod.default(),
|
|
2149
|
+
packageAliasesPlugin(),
|
|
2150
|
+
routeGeneratorPlugin,
|
|
2151
|
+
webHydrationPlugin(),
|
|
2152
|
+
themeTranslationsPlugin(localesDir),
|
|
2153
|
+
bestPracticesPlugin()
|
|
2154
|
+
];
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
|
|
2158
|
+
// src/vite/adapters/nextjs.adapter.ts
|
|
2159
|
+
var nextjsAdapter = {
|
|
2160
|
+
name: "nextjs",
|
|
2161
|
+
generateRouteFiles(_options) {
|
|
2162
|
+
throw new Error("[twilight-react:nextjs] Next.js framework support is not yet implemented");
|
|
2163
|
+
},
|
|
2164
|
+
async createPlugins(_options) {
|
|
2165
|
+
throw new Error("[twilight-react:nextjs] Next.js framework support is not yet implemented");
|
|
2166
|
+
}
|
|
2167
|
+
};
|
|
2168
|
+
|
|
2169
|
+
// src/vite/adapters/index.ts
|
|
2170
|
+
var frameworkAdapters = {
|
|
2171
|
+
tanstack: tanstackAdapter,
|
|
2172
|
+
nextjs: nextjsAdapter
|
|
2173
|
+
};
|
|
2174
|
+
function getFrameworkAdapter(framework) {
|
|
2175
|
+
const adapter = frameworkAdapters[framework];
|
|
2176
|
+
if (!adapter) {
|
|
2177
|
+
throw new Error(`[twilight-react] Unsupported framework: ${framework}`);
|
|
2178
|
+
}
|
|
2179
|
+
return adapter;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// src/vite/twilight-react.ts
|
|
2183
|
+
async function twilightReact(options = {}) {
|
|
2184
|
+
const { framework = "tanstack" } = options;
|
|
2185
|
+
if (framework === "tanstack") setHeadAdapter(tanstackHeadAdapter);
|
|
2186
|
+
else if (framework === "nextjs") setHeadAdapter(nextjsHeadAdapter);
|
|
2187
|
+
return getFrameworkAdapter(framework).createPlugins(options);
|
|
2188
|
+
}
|
|
2189
|
+
var twilight_react_default = twilightReact;
|
|
2190
|
+
|
|
2191
|
+
export { bestPracticesPlugin, twilight_react_default as default, getFrameworkAdapter, nextjsAdapter as nextjs, tanstackAdapter as tanstack, twilightReact };
|
|
2192
|
+
//# sourceMappingURL=index.js.map
|
|
2193
|
+
//# sourceMappingURL=index.js.map
|