@sonordev/site-kit 6.3.6 → 6.5.0
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/agent-manifest.json +8 -2
- package/dist/AnalyticsProvider-44PDLORZ.js +34 -0
- package/dist/{AnalyticsProvider-L3GWK5PO.js.map → AnalyticsProvider-44PDLORZ.js.map} +1 -1
- package/dist/AnalyticsProvider-F6KHEAOX.mjs +13 -0
- package/dist/{AnalyticsProvider-XDVJTAPN.mjs.map → AnalyticsProvider-F6KHEAOX.mjs.map} +1 -1
- package/dist/{ArticleViewTracker-YMGW6ZXB.js → ArticleViewTracker-MGNVIHZ4.js} +6 -6
- package/dist/{ArticleViewTracker-YMGW6ZXB.js.map → ArticleViewTracker-MGNVIHZ4.js.map} +1 -1
- package/dist/{ArticleViewTracker-7AJJTGFY.mjs → ArticleViewTracker-NI4UNSY7.mjs} +5 -5
- package/dist/{ArticleViewTracker-7AJJTGFY.mjs.map → ArticleViewTracker-NI4UNSY7.mjs.map} +1 -1
- package/dist/{ChatWidget-MR64ZLOG.mjs → ChatWidget-XSALHDDW.mjs} +7 -7
- package/dist/{ChatWidget-MR64ZLOG.mjs.map → ChatWidget-XSALHDDW.mjs.map} +1 -1
- package/dist/{ChatWidget-IAYEXLNX.js → ChatWidget-YBXJRR2Z.js} +10 -10
- package/dist/{ChatWidget-IAYEXLNX.js.map → ChatWidget-YBXJRR2Z.js.map} +1 -1
- package/dist/EngageWidget-DUEXPVOY.mjs +13 -0
- package/dist/{EngageWidget-RANSIKC3.mjs.map → EngageWidget-DUEXPVOY.mjs.map} +1 -1
- package/dist/EngageWidget-MDCRS3BN.js +22 -0
- package/dist/{EngageWidget-BF7DH4GO.js.map → EngageWidget-MDCRS3BN.js.map} +1 -1
- package/dist/{FileField-VRKATE4G.js → FileField-AXU6KBSV.js} +6 -6
- package/dist/{FileField-VRKATE4G.js.map → FileField-AXU6KBSV.js.map} +1 -1
- package/dist/{FileField-7ZNQ5BID.mjs → FileField-UTLGR5ZN.mjs} +5 -5
- package/dist/{FileField-7ZNQ5BID.mjs.map → FileField-UTLGR5ZN.mjs.map} +1 -1
- package/dist/{FormSpotlight-QNH7XGYS.mjs → FormSpotlight-NWLCZMOT.mjs} +3 -3
- package/dist/{FormSpotlight-QNH7XGYS.mjs.map → FormSpotlight-NWLCZMOT.mjs.map} +1 -1
- package/dist/{FormSpotlight-VQJ2QWIU.js → FormSpotlight-RR5KJDIH.js} +9 -9
- package/dist/{FormSpotlight-VQJ2QWIU.js.map → FormSpotlight-RR5KJDIH.js.map} +1 -1
- package/dist/{FormStage-3JIN6X6O.js → FormStage-GFNX4GLU.js} +9 -9
- package/dist/{FormStage-3JIN6X6O.js.map → FormStage-GFNX4GLU.js.map} +1 -1
- package/dist/{FormStage-XB4JNFCH.mjs → FormStage-V4XKLI6J.mjs} +3 -3
- package/dist/{FormStage-XB4JNFCH.mjs.map → FormStage-V4XKLI6J.mjs.map} +1 -1
- package/dist/ManagedForm-4AD3LWSC.js +25 -0
- package/dist/{ManagedForm-Q5UFMUBE.js.map → ManagedForm-4AD3LWSC.js.map} +1 -1
- package/dist/ManagedForm-4IWPG6AZ.mjs +16 -0
- package/dist/{ManagedForm-E6F4FLVY.mjs.map → ManagedForm-4IWPG6AZ.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-OEEC3GVY.mjs → ManagedNewsletterForm-ARSY2VHC.mjs} +6 -6
- package/dist/{ManagedNewsletterForm-OEEC3GVY.mjs.map → ManagedNewsletterForm-ARSY2VHC.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-UTNOJ5T4.js → ManagedNewsletterForm-HJZNUABY.js} +7 -7
- package/dist/{ManagedNewsletterForm-UTNOJ5T4.js.map → ManagedNewsletterForm-HJZNUABY.js.map} +1 -1
- package/dist/{SignalCore-PWN5X6FF.mjs → SignalCore-N2LKG4XN.mjs} +5 -5
- package/dist/{SignalCore-PWN5X6FF.mjs.map → SignalCore-N2LKG4XN.mjs.map} +1 -1
- package/dist/{SignalCore-4AUWHMYK.js → SignalCore-P2JUY2BO.js} +11 -11
- package/dist/{SignalCore-4AUWHMYK.js.map → SignalCore-P2JUY2BO.js.map} +1 -1
- package/dist/SitemapSync-KFY4PJ7G.js +19 -0
- package/dist/{SitemapSync-DHJ25PSH.js.map → SitemapSync-KFY4PJ7G.js.map} +1 -1
- package/dist/SitemapSync-UYDL7T4M.mjs +10 -0
- package/dist/{SitemapSync-ZA2MNM63.mjs.map → SitemapSync-UYDL7T4M.mjs.map} +1 -1
- package/dist/analytics/index.js +14 -13
- package/dist/analytics/index.mjs +6 -5
- package/dist/articles/AuthorPage.d.ts +1 -1
- package/dist/articles/AuthorPage.d.ts.map +1 -1
- package/dist/articles/author-schema.d.ts +59 -13
- package/dist/articles/author-schema.d.ts.map +1 -1
- package/dist/articles/index.js +24 -23
- package/dist/articles/index.js.map +1 -1
- package/dist/articles/index.mjs +12 -11
- package/dist/articles/index.mjs.map +1 -1
- package/dist/articles/routes.d.ts +9 -0
- package/dist/articles/routes.d.ts.map +1 -1
- package/dist/articles/server-core.d.ts +5 -2
- package/dist/articles/server-core.d.ts.map +1 -1
- package/dist/articles/server-ui.js +45 -45
- package/dist/articles/server-ui.mjs +8 -8
- package/dist/articles/server.d.ts +5 -2
- package/dist/articles/server.d.ts.map +1 -1
- package/dist/articles/server.js +72 -56
- package/dist/articles/server.mjs +3 -3
- package/dist/articles/types.d.ts +23 -0
- package/dist/articles/types.d.ts.map +1 -1
- package/dist/{chunk-UAOQVHZW.js → chunk-34XL7TVH.js} +4 -4
- package/dist/{chunk-UAOQVHZW.js.map → chunk-34XL7TVH.js.map} +1 -1
- package/dist/chunk-3AOKYAZ2.js +135 -0
- package/dist/chunk-3AOKYAZ2.js.map +1 -0
- package/dist/{chunk-BJKA3XRS.mjs → chunk-3BLKKF67.mjs} +4 -4
- package/dist/{chunk-BJKA3XRS.mjs.map → chunk-3BLKKF67.mjs.map} +1 -1
- package/dist/{chunk-3J5L5DIK.js → chunk-3EAS4PAT.js} +3 -3
- package/dist/{chunk-3J5L5DIK.js.map → chunk-3EAS4PAT.js.map} +1 -1
- package/dist/{chunk-SB4CJX2X.mjs → chunk-42LLFAJQ.mjs} +3 -3
- package/dist/{chunk-SB4CJX2X.mjs.map → chunk-42LLFAJQ.mjs.map} +1 -1
- package/dist/{chunk-ZR43XFUM.js → chunk-55J2KE7D.js} +3 -3
- package/dist/chunk-55J2KE7D.js.map +1 -0
- package/dist/{chunk-VGBUC2JP.js → chunk-5ZMTEK7U.js} +10 -10
- package/dist/{chunk-VGBUC2JP.js.map → chunk-5ZMTEK7U.js.map} +1 -1
- package/dist/{chunk-6DCAMW62.mjs → chunk-6C47333H.mjs} +3 -3
- package/dist/chunk-6C47333H.mjs.map +1 -0
- package/dist/{chunk-E7EV2AHT.js → chunk-6OQYRVMI.js} +9 -9
- package/dist/{chunk-E7EV2AHT.js.map → chunk-6OQYRVMI.js.map} +1 -1
- package/dist/{chunk-UJIKP35G.mjs → chunk-7F66Y4MA.mjs} +4 -4
- package/dist/{chunk-UJIKP35G.mjs.map → chunk-7F66Y4MA.mjs.map} +1 -1
- package/dist/{chunk-6MOGGEY3.mjs → chunk-A2HL22BO.mjs} +3 -3
- package/dist/{chunk-6MOGGEY3.mjs.map → chunk-A2HL22BO.mjs.map} +1 -1
- package/dist/{chunk-7NFSSPGM.js → chunk-AL4Z6VYF.js} +8 -8
- package/dist/{chunk-7NFSSPGM.js.map → chunk-AL4Z6VYF.js.map} +1 -1
- package/dist/{chunk-W46QIVBM.mjs → chunk-B6QPCAEG.mjs} +3 -3
- package/dist/{chunk-W46QIVBM.mjs.map → chunk-B6QPCAEG.mjs.map} +1 -1
- package/dist/{chunk-EB33U2WT.js → chunk-BHZHWXER.js} +131 -71
- package/dist/chunk-BHZHWXER.js.map +1 -0
- package/dist/{chunk-R26FAQWF.mjs → chunk-BNKBRLJK.mjs} +3 -3
- package/dist/{chunk-R26FAQWF.mjs.map → chunk-BNKBRLJK.mjs.map} +1 -1
- package/dist/{chunk-A6UYV475.mjs → chunk-CABEVWKJ.mjs} +4 -24
- package/dist/chunk-CABEVWKJ.mjs.map +1 -0
- package/dist/{chunk-LWCAZDY2.js → chunk-CDRQYJUT.js} +4 -4
- package/dist/{chunk-LWCAZDY2.js.map → chunk-CDRQYJUT.js.map} +1 -1
- package/dist/{chunk-SAOUAIRS.js → chunk-CM4AVKXR.js} +14 -14
- package/dist/{chunk-SAOUAIRS.js.map → chunk-CM4AVKXR.js.map} +1 -1
- package/dist/{chunk-KMONA7CT.mjs → chunk-D3WJMSTB.mjs} +3 -3
- package/dist/{chunk-KMONA7CT.mjs.map → chunk-D3WJMSTB.mjs.map} +1 -1
- package/dist/{chunk-3Q3Y6OQE.mjs → chunk-DWZGW77V.mjs} +4 -4
- package/dist/{chunk-3Q3Y6OQE.mjs.map → chunk-DWZGW77V.mjs.map} +1 -1
- package/dist/{chunk-L6BQIDSZ.mjs → chunk-FPVYKSXE.mjs} +13 -10
- package/dist/chunk-FPVYKSXE.mjs.map +1 -0
- package/dist/{chunk-5XDOBM5S.js → chunk-G2KGHIAP.js} +3 -3
- package/dist/{chunk-5XDOBM5S.js.map → chunk-G2KGHIAP.js.map} +1 -1
- package/dist/chunk-GFSQMK35.mjs +127 -0
- package/dist/chunk-GFSQMK35.mjs.map +1 -0
- package/dist/chunk-GIGUDKLS.mjs +6 -0
- package/dist/{chunk-3V6DIQI7.mjs.map → chunk-GIGUDKLS.mjs.map} +1 -1
- package/dist/{chunk-BJ4T65OK.mjs → chunk-H4TSADY3.mjs} +3 -3
- package/dist/{chunk-BJ4T65OK.mjs.map → chunk-H4TSADY3.mjs.map} +1 -1
- package/dist/{chunk-J4C3JAJF.js → chunk-IO65ROAO.js} +15 -15
- package/dist/{chunk-J4C3JAJF.js.map → chunk-IO65ROAO.js.map} +1 -1
- package/dist/chunk-JCDX37BY.js +58 -0
- package/dist/chunk-JCDX37BY.js.map +1 -0
- package/dist/{chunk-5J4FKRGH.mjs → chunk-MDQLON5R.mjs} +5 -5
- package/dist/{chunk-5J4FKRGH.mjs.map → chunk-MDQLON5R.mjs.map} +1 -1
- package/dist/{chunk-3POB4JKR.js → chunk-MHKD34B4.js} +15 -15
- package/dist/{chunk-3POB4JKR.js.map → chunk-MHKD34B4.js.map} +1 -1
- package/dist/chunk-MXJOKOFK.mjs +51 -0
- package/dist/chunk-MXJOKOFK.mjs.map +1 -0
- package/dist/{chunk-5RNAUYWE.js → chunk-NH2P27MA.js} +4 -27
- package/dist/chunk-NH2P27MA.js.map +1 -0
- package/dist/{chunk-5DZVQW35.mjs → chunk-OFBEBMXN.mjs} +4 -4
- package/dist/{chunk-5DZVQW35.mjs.map → chunk-OFBEBMXN.mjs.map} +1 -1
- package/dist/{chunk-G3L26XQ7.js → chunk-OIPG3EGM.js} +5 -5
- package/dist/{chunk-G3L26XQ7.js.map → chunk-OIPG3EGM.js.map} +1 -1
- package/dist/{chunk-2UZULHI4.js → chunk-OY3PDIB3.js} +10 -10
- package/dist/{chunk-2UZULHI4.js.map → chunk-OY3PDIB3.js.map} +1 -1
- package/dist/{chunk-SNXJXPB6.js → chunk-PFDRQJKJ.js} +13 -13
- package/dist/{chunk-SNXJXPB6.js.map → chunk-PFDRQJKJ.js.map} +1 -1
- package/dist/{chunk-CXYGKK4U.mjs → chunk-PGYOBEPL.mjs} +3 -3
- package/dist/{chunk-CXYGKK4U.mjs.map → chunk-PGYOBEPL.mjs.map} +1 -1
- package/dist/{chunk-TE3YNZVH.js → chunk-PIPGH7GA.js} +4 -4
- package/dist/{chunk-TE3YNZVH.js.map → chunk-PIPGH7GA.js.map} +1 -1
- package/dist/chunk-PURI56RE.js +8 -0
- package/dist/{chunk-6SBRD5KT.js.map → chunk-PURI56RE.js.map} +1 -1
- package/dist/{chunk-X3MY4PL7.mjs → chunk-QAQTDHHT.mjs} +10 -14
- package/dist/chunk-QAQTDHHT.mjs.map +1 -0
- package/dist/{chunk-PMWF5CRL.js → chunk-QCS7NWMA.js} +15 -12
- package/dist/chunk-QCS7NWMA.js.map +1 -0
- package/dist/{chunk-HXHRS3PX.mjs → chunk-RCB6HEHM.mjs} +3 -3
- package/dist/{chunk-HXHRS3PX.mjs.map → chunk-RCB6HEHM.mjs.map} +1 -1
- package/dist/{chunk-ANYCUTS5.js → chunk-RMDH2HMW.js} +3 -3
- package/dist/{chunk-ANYCUTS5.js.map → chunk-RMDH2HMW.js.map} +1 -1
- package/dist/{chunk-NAA5J2JM.js → chunk-RQROZLH3.js} +47 -51
- package/dist/chunk-RQROZLH3.js.map +1 -0
- package/dist/{chunk-X5J3PYZJ.js → chunk-SUGBIEYQ.js} +9 -9
- package/dist/{chunk-X5J3PYZJ.js.map → chunk-SUGBIEYQ.js.map} +1 -1
- package/dist/{chunk-LFF32POH.mjs → chunk-SVCKJ5KH.mjs} +4 -4
- package/dist/{chunk-LFF32POH.mjs.map → chunk-SVCKJ5KH.mjs.map} +1 -1
- package/dist/{chunk-YKZ3EVAQ.mjs → chunk-THO4NS6Z.mjs} +3 -3
- package/dist/{chunk-YKZ3EVAQ.mjs.map → chunk-THO4NS6Z.mjs.map} +1 -1
- package/dist/{chunk-K6ZQVDP4.mjs → chunk-TPEPAHU5.mjs} +3 -3
- package/dist/{chunk-K6ZQVDP4.mjs.map → chunk-TPEPAHU5.mjs.map} +1 -1
- package/dist/{chunk-FRUBUQOH.js → chunk-U577ITSA.js} +5 -5
- package/dist/{chunk-FRUBUQOH.js.map → chunk-U577ITSA.js.map} +1 -1
- package/dist/{chunk-B2NO5QVY.mjs → chunk-UCQDE5UH.mjs} +3 -3
- package/dist/{chunk-B2NO5QVY.mjs.map → chunk-UCQDE5UH.mjs.map} +1 -1
- package/dist/{chunk-KB7SIIVY.mjs → chunk-VA2O5OSV.mjs} +3 -3
- package/dist/{chunk-KB7SIIVY.mjs.map → chunk-VA2O5OSV.mjs.map} +1 -1
- package/dist/{chunk-6I5O5CTL.mjs → chunk-VJTKIKZY.mjs} +128 -68
- package/dist/chunk-VJTKIKZY.mjs.map +1 -0
- package/dist/{chunk-OLVCGOXZ.js → chunk-VUAGR6VL.js} +12 -12
- package/dist/{chunk-OLVCGOXZ.js.map → chunk-VUAGR6VL.js.map} +1 -1
- package/dist/{chunk-PQICWWQW.mjs → chunk-XEOIGCUE.mjs} +5 -5
- package/dist/{chunk-PQICWWQW.mjs.map → chunk-XEOIGCUE.mjs.map} +1 -1
- package/dist/chunk-YMZNEDFP.js +39 -0
- package/dist/chunk-YMZNEDFP.js.map +1 -0
- package/dist/chunk-Z2URIOKG.mjs +36 -0
- package/dist/chunk-Z2URIOKG.mjs.map +1 -0
- package/dist/{chunk-2MEMK5XC.js → chunk-ZXC56JS3.js} +14 -14
- package/dist/{chunk-2MEMK5XC.js.map → chunk-ZXC56JS3.js.map} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.mjs +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/commerce/index.js +59 -58
- package/dist/commerce/index.mjs +7 -6
- package/dist/engage/DesignRenderer.d.ts.map +1 -1
- package/dist/engage/EngageWidget.d.ts.map +1 -1
- package/dist/engage/element-rules.d.ts +39 -0
- package/dist/engage/element-rules.d.ts.map +1 -0
- package/dist/engage/index.js +11 -10
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +8 -7
- package/dist/engage/index.mjs.map +1 -1
- package/dist/fleet/index.js +10 -9
- package/dist/fleet/index.mjs +6 -5
- package/dist/forms/index.js +13 -13
- package/dist/forms/index.mjs +7 -7
- package/dist/forms/server.js +2 -2
- package/dist/forms/server.mjs +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +65 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -10
- package/dist/index.mjs.map +1 -1
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +10 -9
- package/dist/layout/client.mjs +9 -8
- package/dist/layout/index.js +12 -11
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +10 -9
- package/dist/layout/index.mjs.map +1 -1
- package/dist/layout/types.d.ts +6 -0
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/llms/index.d.ts +2 -0
- package/dist/llms/index.d.ts.map +1 -1
- package/dist/llms/index.js +129 -14
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +115 -5
- package/dist/llms/index.mjs.map +1 -1
- package/dist/llms/revalidate.d.ts +3 -0
- package/dist/llms/revalidate.d.ts.map +1 -1
- package/dist/llms/seo-revalidate.d.ts +105 -0
- package/dist/llms/seo-revalidate.d.ts.map +1 -0
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/mcp/transport.d.ts +166 -0
- package/dist/mcp/transport.d.ts.map +1 -0
- package/dist/mcp/transport.js +137 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/mcp/transport.mjs +123 -0
- package/dist/mcp/transport.mjs.map +1 -0
- package/dist/portfolio/contract.d.ts +93 -0
- package/dist/portfolio/contract.d.ts.map +1 -1
- package/dist/portfolio/contract.js +94 -1
- package/dist/portfolio/contract.js.map +1 -1
- package/dist/portfolio/contract.mjs +79 -2
- package/dist/portfolio/contract.mjs.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +7 -6
- package/dist/seo/client.mjs +6 -5
- package/dist/seo/index.js +7 -6
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +6 -5
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/register-sitemap-cli.js +1 -1
- package/dist/seo/register-sitemap-cli.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/build-entries.d.ts +7 -0
- package/dist/shared/build-entries.d.ts.map +1 -1
- package/dist/shared/frame.d.ts +15 -0
- package/dist/shared/frame.d.ts.map +1 -1
- package/dist/shared/request-guards.d.ts +27 -0
- package/dist/shared/request-guards.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.js +3 -3
- package/dist/sitemap/index.mjs +2 -2
- package/dist/sync/index.js +17 -17
- package/dist/sync/index.mjs +4 -4
- package/dist/{writeLLMsTxt-LYYC3ZSN.mjs → writeLLMsTxt-IYJILIU3.mjs} +3 -3
- package/dist/{writeLLMsTxt-XHLHJ5XY.js → writeLLMsTxt-SQG4B63X.js} +4 -4
- package/package.json +24 -21
- package/dist/AnalyticsProvider-L3GWK5PO.js +0 -33
- package/dist/AnalyticsProvider-XDVJTAPN.mjs +0 -12
- package/dist/EngageWidget-BF7DH4GO.js +0 -21
- package/dist/EngageWidget-RANSIKC3.mjs +0 -12
- package/dist/ManagedForm-E6F4FLVY.mjs +0 -16
- package/dist/ManagedForm-Q5UFMUBE.js +0 -25
- package/dist/SitemapSync-DHJ25PSH.js +0 -18
- package/dist/SitemapSync-ZA2MNM63.mjs +0 -9
- package/dist/chunk-3V6DIQI7.mjs +0 -6
- package/dist/chunk-5RNAUYWE.js.map +0 -1
- package/dist/chunk-6DCAMW62.mjs.map +0 -1
- package/dist/chunk-6I5O5CTL.mjs.map +0 -1
- package/dist/chunk-6SBRD5KT.js +0 -8
- package/dist/chunk-A6UYV475.mjs.map +0 -1
- package/dist/chunk-EB33U2WT.js.map +0 -1
- package/dist/chunk-L6BQIDSZ.mjs.map +0 -1
- package/dist/chunk-NAA5J2JM.js.map +0 -1
- package/dist/chunk-PMWF5CRL.js.map +0 -1
- package/dist/chunk-X3MY4PL7.mjs.map +0 -1
- package/dist/chunk-YRCR7WY3.js +0 -65
- package/dist/chunk-YRCR7WY3.js.map +0 -1
- package/dist/chunk-ZL35JCDA.mjs +0 -61
- package/dist/chunk-ZL35JCDA.mjs.map +0 -1
- package/dist/chunk-ZR43XFUM.js.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["getTrackingUrl"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,SAAS,YAAA,GAAe;AACtB,EAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AACJ,EAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,EAAA,GACxC,EAAA;AACJ,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEA,eAAe,OAAU,QAAA,EAAqC;AAC5D,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,YAAA,EAAa;AAExC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAA,CAAQ,MAAM,oCAAoC,CAAA;AAClD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AAMF,IAAA,MAAM,WAAW,MAAM,UAAA;AAAA,MACrB,CAAA,EAAG,MAAM,CAAA,EAAG,QAAQ,CAAA,CAAA;AAAA,MACpB,EAAE,QAAQ,KAAA,EAAM;AAAA,MAChB,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,KACvB;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAC9D,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAcA,eAAsB,eAAA,CACpB,OAAA,GAAkC,EAAC,EACH;AAChC,EAAA,MAAM,SAAS,MAAM,MAAA;AAAA,IACnB;AAAA,GACF;AAEA,EAAA,OAAO,MAAA,EAAQ,cAAc,EAAC;AAChC;AAYO,SAAS,cAAA,CAAe,aAAqB,OAAA,EAAyB;AAC3E,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,GAAA,EAAM,WAAW,IAAI,OAAO,CAAA,CAAA;AAC9C;ACpDO,SAAS,aAAA,GAAqC;AACnD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA,CAAgC,EAAE,CAAA;AACtE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,eAAe,IAAA,GAAO;AACpB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,MAAM,IAAA,GAAO,MAAM,eAAA,EAAgB;AACnC,QAAA,aAAA,CAAc,IAAI,CAAA;AAAA,MACpB,SAAS,GAAA,EAAK;AACZ,QAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,2BAA2B,CAAA;AAAA,MAC3E,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF;AAEA,IAAA,IAAA,EAAK;AAAA,EACP,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AC7BO,SAAS,aAAA,CAAc;AAAA,EAC5B,SAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,UAAA;AAAA,EACA,UAAA,GAAa;AACf,CAAA,EAAuB;AACrB,EAAA,MAAM,EAAE,cAAA,EAAAA,eAAAA,EAAe,GAAI,aAAA,EAAc;AAEzC,EAAA,MAAM,WAAA,uBACH,KAAA,EAAA,EAAI,qBAAA,EAAmB,MAAC,SAAA,EAAU,gBAAA,EAChC,oBAAU,QAAA,mBACT,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAK,SAAA,CAAU,QAAA;AAAA,MACf,KAAK,SAAA,CAAU,IAAA;AAAA,MACf,OAAA,EAAQ;AAAA;AAAA,GACV,uBAEC,MAAA,EAAA,EAAM,QAAA,EAAA,SAAA,CAAU,KAAK,MAAA,CAAO,CAAC,GAAE,CAAA,EAEpC,CAAA;AAGF,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAsB,uBAAmB,IAAA,EAAC,mBAAA,EAAmB,UAAU,EAAA,EAEzE,QAAA,EAAA;AAAA,IAAA,UAAA,GAAa,UAAA,CAAW,SAAS,CAAA,GAAI,WAAA;AAAA,wBAGrC,KAAA,EAAA,EAAI,qBAAA,EAAmB,MAAC,SAAA,EAAU,gBAAA,EAChC,oBAAU,IAAA,EACb,CAAA;AAAA,IAGC,UAAU,WAAA,oBACT,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,MAAM,SAAA,CAAU,WAAA;AAAA,QAChB,MAAA,EAAO,QAAA;AAAA,QACP,GAAA,EAAI,+BAAA;AAAA,QACJ,wBAAA,EAAsB,IAAA;AAAA,QACtB,SAAA,EAAU,mBAAA;AAAA,QACX,QAAA,EAAA;AAAA;AAAA,KAED;AAAA,IAID,cAAc,SAAA,CAAU,MAAA,IAAU,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA,oBAC3D,GAAA,CAAC,KAAA,EAAA,EAAI,uBAAA,EAAqB,MAAC,SAAA,EAAU,kBAAA,EAClC,QAAA,EAAA,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA,KAAA,qBACpB,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAMA,eAAAA,CAAe,SAAA,CAAU,EAAA,EAAI,MAAM,EAAE,CAAA;AAAA,QAC3C,MAAA,EAAO,QAAA;AAAA,QACP,GAAA,EAAI,+BAAA;AAAA,QACJ,sBAAA,EAAoB,IAAA;AAAA,QACpB,iBAAe,KAAA,CAAM,EAAA;AAAA,QACrB,SAAA,EAAU,iBAAA;AAAA,QAET,QAAA,EAAA,KAAA,CAAM;AAAA,OAAA;AAAA,MARF,KAAA,CAAM;AAAA,KAUd,CAAA,EACH;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAsCO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,SAAA,GAAY,EAAA;AAAA,EACZ,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,eAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,SAAA,EAAW,OAAO,cAAA,EAAAA,eAAAA,KAAmB,aAAA,EAAc;AAEvE,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,OAAO,gBAAA,oBAAoB,GAAA,CAAC,KAAA,EAAA,EAAI,yBAAA,EAAuB,MAAC,QAAA,EAAA,uBAAA,EAAqB,CAAA;AAAA,EAC/E;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAO,cAAA,oBAAkB,GAAA,CAAC,KAAA,EAAA,EAAI,uBAAA,EAAqB,MAAE,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,oBAAoB,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,UAAA;AAE/D,EAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AAClC,IAAA,OAAO,cAAA,IAAkB,IAAA;AAAA,EAC3B;AAEA,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,wBAAA,EAAsB,MAC9C,QAAA,EAAA,iBAAA,CAAkB,GAAA;AAAA,IAAI,CAAA,SAAA,KACrB,eAAA,GACI,eAAA,CAAgB,SAAS,CAAA,mBACzB,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QAEC,SAAA;AAAA,QACA;AAAA,OAAA;AAAA,MAFK,SAAA,CAAU;AAAA;AAGjB,GACN,EACF,CAAA;AAEJ","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n // Route through sonorFetch (the canonical transport) — NOT bare fetch — so a\n // stale build-time seed token is transparently refreshed and a 401 triggers\n // one refresh+retry. The credential goes via options.apiKey, never a header:\n // sonorFetch injects the freshest token as x-api-key; a hand-set header would\n // pin the stale seed and 401.\n const response = await sonorFetch(\n `${apiUrl}${endpoint}`,\n { method: 'GET' },\n { apiKey, retries: 0 },\n )\n\n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/affiliates/api.ts","../src/affiliates/useAffiliates.ts","../src/affiliates/AffiliatesWidget.tsx"],"names":["getTrackingUrl"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,SAAS,YAAA,GAAe;AACtB,EAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,sBAAA,GACxC,sBAAA;AACJ,EAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAC5B,MAAA,CAAe,wBAAwB,EAAA,GACxC,EAAA;AACJ,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEA,eAAe,OAAU,QAAA,EAAqC;AAC5D,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAO,GAAI,YAAA,EAAa;AAExC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAA,CAAQ,MAAM,oCAAoC,CAAA;AAClD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AAMF,IAAA,MAAM,WAAW,MAAM,UAAA;AAAA,MACrB,CAAA,EAAG,MAAM,CAAA,EAAG,QAAQ,CAAA,CAAA;AAAA,MACpB,EAAE,QAAQ,KAAA,EAAM;AAAA,MAChB,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAE,KACvB;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAC9D,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,+BAA+B,KAAK,CAAA;AAClD,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAcA,eAAsB,eAAA,CACpB,OAAA,GAAkC,EAAC,EACH;AAChC,EAAA,MAAM,SAAS,MAAM,MAAA;AAAA,IACnB;AAAA,GACF;AAEA,EAAA,OAAO,MAAA,EAAQ,cAAc,EAAC;AAChC;AAYO,SAAS,cAAA,CAAe,aAAqB,OAAA,EAAyB;AAC3E,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,GAAA,EAAM,WAAW,IAAI,OAAO,CAAA,CAAA;AAC9C;ACpDO,SAAS,aAAA,GAAqC;AACnD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA,CAAgC,EAAE,CAAA;AACtE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,IAAI,CAAA;AAC/C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AAEtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,eAAe,IAAA,GAAO;AACpB,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,QAAA,CAAS,IAAI,CAAA;AACb,QAAA,MAAM,IAAA,GAAO,MAAM,eAAA,EAAgB;AACnC,QAAA,aAAA,CAAc,IAAI,CAAA;AAAA,MACpB,SAAS,GAAA,EAAK;AACZ,QAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,2BAA2B,CAAA;AAAA,MAC3E,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF;AAEA,IAAA,IAAA,EAAK;AAAA,EACP,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AC7BO,SAAS,aAAA,CAAc;AAAA,EAC5B,SAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,UAAA;AAAA,EACA,UAAA,GAAa;AACf,CAAA,EAAuB;AACrB,EAAA,MAAM,EAAE,cAAA,EAAAA,eAAAA,EAAe,GAAI,aAAA,EAAc;AAEzC,EAAA,MAAM,WAAA,uBACH,KAAA,EAAA,EAAI,qBAAA,EAAmB,MAAC,SAAA,EAAU,gBAAA,EAChC,oBAAU,QAAA,mBACT,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAK,SAAA,CAAU,QAAA;AAAA,MACf,KAAK,SAAA,CAAU,IAAA;AAAA,MACf,OAAA,EAAQ;AAAA;AAAA,GACV,uBAEC,MAAA,EAAA,EAAM,QAAA,EAAA,SAAA,CAAU,KAAK,MAAA,CAAO,CAAC,GAAE,CAAA,EAEpC,CAAA;AAGF,EAAA,4BACG,KAAA,EAAA,EAAI,SAAA,EAAsB,uBAAmB,IAAA,EAAC,mBAAA,EAAmB,UAAU,EAAA,EAEzE,QAAA,EAAA;AAAA,IAAA,UAAA,GAAa,UAAA,CAAW,SAAS,CAAA,GAAI,WAAA;AAAA,wBAGrC,KAAA,EAAA,EAAI,qBAAA,EAAmB,MAAC,SAAA,EAAU,gBAAA,EAChC,oBAAU,IAAA,EACb,CAAA;AAAA,IAGC,UAAU,WAAA,oBACT,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,MAAM,SAAA,CAAU,WAAA;AAAA,QAChB,MAAA,EAAO,QAAA;AAAA,QACP,GAAA,EAAI,+BAAA;AAAA,QACJ,wBAAA,EAAsB,IAAA;AAAA,QACtB,SAAA,EAAU,mBAAA;AAAA,QACX,QAAA,EAAA;AAAA;AAAA,KAED;AAAA,IAID,cAAc,SAAA,CAAU,MAAA,IAAU,SAAA,CAAU,MAAA,CAAO,SAAS,CAAA,oBAC3D,GAAA,CAAC,KAAA,EAAA,EAAI,uBAAA,EAAqB,MAAC,SAAA,EAAU,kBAAA,EAClC,QAAA,EAAA,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA,KAAA,qBACpB,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAMA,eAAAA,CAAe,SAAA,CAAU,EAAA,EAAI,MAAM,EAAE,CAAA;AAAA,QAC3C,MAAA,EAAO,QAAA;AAAA,QACP,GAAA,EAAI,+BAAA;AAAA,QACJ,sBAAA,EAAoB,IAAA;AAAA,QACpB,iBAAe,KAAA,CAAM,EAAA;AAAA,QACrB,SAAA,EAAU,iBAAA;AAAA,QAET,QAAA,EAAA,KAAA,CAAM;AAAA,OAAA;AAAA,MARF,KAAA,CAAM;AAAA,KAUd,CAAA,EACH;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAsCO,SAAS,gBAAA,CAAiB;AAAA,EAC/B,SAAA,GAAY,EAAA;AAAA,EACZ,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,eAAA;AAAA,EACA;AACF,CAAA,EAA0B;AACxB,EAAA,MAAM,EAAE,UAAA,EAAY,SAAA,EAAW,OAAO,cAAA,EAAAA,eAAAA,KAAmB,aAAA,EAAc;AAEvE,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,OAAO,gBAAA,oBAAoB,GAAA,CAAC,KAAA,EAAA,EAAI,yBAAA,EAAuB,MAAC,QAAA,EAAA,uBAAA,EAAqB,CAAA;AAAA,EAC/E;AAEA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAO,cAAA,oBAAkB,GAAA,CAAC,KAAA,EAAA,EAAI,uBAAA,EAAqB,MAAE,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,EAC7D;AAEA,EAAA,MAAM,oBAAoB,KAAA,GAAQ,UAAA,CAAW,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA,GAAI,UAAA;AAE/D,EAAA,IAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG;AAClC,IAAA,OAAO,cAAA,IAAkB,IAAA;AAAA,EAC3B;AAEA,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAsB,wBAAA,EAAsB,MAC9C,QAAA,EAAA,iBAAA,CAAkB,GAAA;AAAA,IAAI,CAAA,SAAA,KACrB,eAAA,GACI,eAAA,CAAgB,SAAS,CAAA,mBACzB,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QAEC,SAAA;AAAA,QACA;AAAA,OAAA;AAAA,MAFK,SAAA,CAAU;AAAA;AAGjB,GACN,EACF,CAAA;AAEJ","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/affiliates - Affiliates API\n * \n * API functions for fetching affiliate data for client sites.\n * All data goes through Portal API with API key auth - never Supabase directly.\n */\n\nimport { sonorFetch } from '../shared/sonorFetch'\nimport type { Affiliate, AffiliateWithOffers, FetchAffiliatesOptions } from './types'\n\n// ============================================\n// API Config Helpers\n// ============================================\n\nfunction getApiConfig() {\n const apiUrl = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_URL__ || 'https://api.sonor.io'\n : 'https://api.sonor.io'\n const apiKey = typeof window !== 'undefined' \n ? (window as any).__SITE_KIT_API_KEY__ || ''\n : ''\n return { apiUrl, apiKey }\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('[Affiliates] No API key configured')\n return null\n }\n \n try {\n // Route through sonorFetch (the canonical transport) — NOT bare fetch — so a\n // stale build-time seed token is transparently refreshed and a 401 triggers\n // one refresh+retry. The credential goes via options.apiKey, never a header:\n // sonorFetch injects the freshest token as x-api-key; a hand-set header would\n // pin the stale seed and 401.\n const response = await sonorFetch(\n `${apiUrl}${endpoint}`,\n { method: 'GET' },\n { apiKey, retries: 0 },\n )\n\n if (!response.ok) {\n console.error(`[Affiliates] API error: ${response.statusText}`)\n return null\n }\n \n return await response.json()\n } catch (error) {\n console.error('[Affiliates] Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Fetch Affiliates\n// ============================================\n\n/**\n * Fetch all active affiliates for the project\n * \n * @example\n * ```ts\n * const affiliates = await fetchAffiliates()\n * ```\n */\nexport async function fetchAffiliates(\n options: FetchAffiliatesOptions = {}\n): Promise<AffiliateWithOffers[]> {\n const result = await apiGet<{ affiliates: AffiliateWithOffers[] }>(\n '/api/public/affiliates'\n )\n \n return result?.affiliates || []\n}\n\n/**\n * Build a tracking URL for an affiliate offer\n * When clicked, this redirects through our tracking endpoint and then to the destination\n * \n * @example\n * ```ts\n * const trackingUrl = getTrackingUrl(affiliate.id, offer.id)\n * // Returns: https://api.sonor.io/a/{affiliateId}/{offerId}\n * ```\n */\nexport function getTrackingUrl(affiliateId: string, offerId: string): string {\n const { apiUrl } = getApiConfig()\n return `${apiUrl}/a/${affiliateId}/${offerId}`\n}\n","/**\n * @sonordev/site-kit/affiliates - useAffiliates Hook\n * \n * React hook for fetching and displaying affiliates on client sites.\n */\n\n'use client'\n\nimport { useState, useEffect } from 'react'\nimport type { AffiliateWithOffers } from './types'\nimport { fetchAffiliates, getTrackingUrl } from './api'\n\nexport interface UseAffiliatesResult {\n affiliates: AffiliateWithOffers[]\n isLoading: boolean\n error: string | null\n getTrackingUrl: (affiliateId: string, offerId: string) => string\n}\n\n/**\n * Hook to fetch affiliates for display on client sites\n * \n * @example\n * ```tsx\n * function AffiliatesSection() {\n * const { affiliates, isLoading } = useAffiliates()\n * \n * if (isLoading) return <div>Loading...</div>\n * \n * return (\n * <div className=\"grid grid-cols-3 gap-4\">\n * {affiliates.map(affiliate => (\n * <AffiliateCard key={affiliate.id} affiliate={affiliate} />\n * ))}\n * </div>\n * )\n * }\n * ```\n */\nexport function useAffiliates(): UseAffiliatesResult {\n const [affiliates, setAffiliates] = useState<AffiliateWithOffers[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n async function load() {\n try {\n setIsLoading(true)\n setError(null)\n const data = await fetchAffiliates()\n setAffiliates(data)\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load affiliates')\n } finally {\n setIsLoading(false)\n }\n }\n \n load()\n }, [])\n\n return {\n affiliates,\n isLoading,\n error,\n getTrackingUrl,\n }\n}\n","/**\n * @sonordev/site-kit/affiliates - AffiliatesWidget Component\n * \n * Unstyled, headless component for displaying affiliates.\n * Client sites can wrap this or use it directly with their own styling.\n */\n\n'use client'\n\nimport React from 'react'\nimport { useAffiliates } from './useAffiliates'\nimport type { AffiliateWithOffers, AffiliateOffer } from './types'\n\n// ============================================\n// Affiliate Card (Unstyled)\n// ============================================\n\nexport interface AffiliateCardProps {\n affiliate: AffiliateWithOffers\n className?: string\n /** Optional custom render for the logo */\n renderLogo?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Show offers as links below the card */\n showOffers?: boolean\n}\n\n/**\n * Single affiliate card - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * <AffiliateCard \n * affiliate={affiliate}\n * className=\"p-4 bg-white rounded-lg shadow\"\n * showOffers\n * />\n * ```\n */\nexport function AffiliateCard({\n affiliate,\n className = '',\n renderLogo,\n showOffers = false,\n}: AffiliateCardProps) {\n const { getTrackingUrl } = useAffiliates()\n \n const defaultLogo = (\n <div data-affiliate-logo className=\"affiliate-logo\">\n {affiliate.logo_url ? (\n <img \n src={affiliate.logo_url} \n alt={affiliate.name}\n loading=\"lazy\"\n />\n ) : (\n <span>{affiliate.name.charAt(0)}</span>\n )}\n </div>\n )\n\n return (\n <div className={className} data-affiliate-card data-affiliate-id={affiliate.id}>\n {/* Logo */}\n {renderLogo ? renderLogo(affiliate) : defaultLogo}\n \n {/* Name */}\n <div data-affiliate-name className=\"affiliate-name\">\n {affiliate.name}\n </div>\n \n {/* Website link */}\n {affiliate.website_url && (\n <a \n href={affiliate.website_url}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-website\n className=\"affiliate-website\"\n >\n Visit Website\n </a>\n )}\n \n {/* Offers */}\n {showOffers && affiliate.offers && affiliate.offers.length > 0 && (\n <div data-affiliate-offers className=\"affiliate-offers\">\n {affiliate.offers.map(offer => (\n <a\n key={offer.id}\n href={getTrackingUrl(affiliate.id, offer.id)}\n target=\"_blank\"\n rel=\"noopener noreferrer sponsored\"\n data-affiliate-offer\n data-offer-id={offer.id}\n className=\"affiliate-offer\"\n >\n {offer.name}\n </a>\n ))}\n </div>\n )}\n </div>\n )\n}\n\n// ============================================\n// Affiliates Grid (Unstyled)\n// ============================================\n\nexport interface AffiliatesWidgetProps {\n className?: string\n /** Custom loading component */\n loadingComponent?: React.ReactNode\n /** Custom empty state component */\n emptyComponent?: React.ReactNode\n /** Custom error component */\n errorComponent?: React.ReactNode\n /** Show offers on each card */\n showOffers?: boolean\n /** Custom render function for each affiliate */\n renderAffiliate?: (affiliate: AffiliateWithOffers) => React.ReactNode\n /** Maximum number to display */\n limit?: number\n}\n\n/**\n * Display a grid of affiliates - unstyled, bring your own CSS\n * \n * @example\n * ```tsx\n * // Basic usage\n * <AffiliatesWidget className=\"grid grid-cols-3 gap-4\" />\n * \n * // With custom rendering\n * <AffiliatesWidget\n * renderAffiliate={(affiliate) => (\n * <MyCustomCard key={affiliate.id} data={affiliate} />\n * )}\n * />\n * ```\n */\nexport function AffiliatesWidget({\n className = '',\n loadingComponent,\n emptyComponent,\n errorComponent,\n showOffers = false,\n renderAffiliate,\n limit,\n}: AffiliatesWidgetProps) {\n const { affiliates, isLoading, error, getTrackingUrl } = useAffiliates()\n \n if (isLoading) {\n return loadingComponent || <div data-affiliates-loading>Loading affiliates...</div>\n }\n \n if (error) {\n return errorComponent || <div data-affiliates-error>{error}</div>\n }\n \n const displayAffiliates = limit ? affiliates.slice(0, limit) : affiliates\n \n if (displayAffiliates.length === 0) {\n return emptyComponent || null\n }\n \n return (\n <div className={className} data-affiliates-widget>\n {displayAffiliates.map(affiliate => \n renderAffiliate \n ? renderAffiliate(affiliate)\n : <AffiliateCard \n key={affiliate.id} \n affiliate={affiliate} \n showOffers={showOffers}\n />\n )}\n </div>\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteKitClientProviders.d.ts","sourceRoot":"","sources":["../../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"SiteKitClientProviders.d.ts","sourceRoot":"","sources":["../../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,EAAsD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAoBjG,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AA4B1E,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAA;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,YAAY,CAAA;IAC/B,MAAM,CAAC,EAAE,OAAO,GAAG,YAAY,CAAA;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAEhB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,MAAM,EACN,SAAS,EACT,SAAgB,EAChB,MAAa,EACb,MAAc,EACd,WAAmB,EACnB,KAAY,EACZ,KAAY,EACZ,KAAa,GACd,EAAE,2BAA2B,qBAiL7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteKitClientProviders.d.ts","sourceRoot":"","sources":["../../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"SiteKitClientProviders.d.ts","sourceRoot":"","sources":["../../src/layout/SiteKitClientProviders.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,EAAsD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAoBjG,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AA4B1E,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,SAAS,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAA;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,YAAY,CAAA;IAC/B,MAAM,CAAC,EAAE,OAAO,GAAG,YAAY,CAAA;IAC/B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAEhB;AAED,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,MAAM,EACN,SAAS,EACT,SAAgB,EAChB,MAAa,EACb,MAAc,EACd,WAAmB,EACnB,KAAY,EACZ,KAAY,EACZ,KAAa,GACd,EAAE,2BAA2B,qBAiL7B"}
|
package/dist/layout/client.js
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
require('../chunk-
|
|
6
|
-
require('../chunk-
|
|
4
|
+
var chunkQCS7NWMA_js = require('../chunk-QCS7NWMA.js');
|
|
5
|
+
require('../chunk-U577ITSA.js');
|
|
6
|
+
require('../chunk-OY3PDIB3.js');
|
|
7
7
|
require('../chunk-7THQ4UW3.js');
|
|
8
8
|
require('../chunk-HGNSJXWT.js');
|
|
9
|
-
require('../chunk-
|
|
9
|
+
require('../chunk-G2KGHIAP.js');
|
|
10
10
|
require('../chunk-UZKXOZHR.js');
|
|
11
11
|
require('../chunk-SWIKKSKL.js');
|
|
12
12
|
require('../chunk-RC4WWQXR.js');
|
|
13
13
|
require('../chunk-VJMPIRSD.js');
|
|
14
|
-
require('../chunk-
|
|
15
|
-
require('../chunk-
|
|
16
|
-
require('../chunk-
|
|
17
|
-
require('../chunk-
|
|
14
|
+
require('../chunk-NH2P27MA.js');
|
|
15
|
+
require('../chunk-JCDX37BY.js');
|
|
16
|
+
require('../chunk-IO65ROAO.js');
|
|
17
|
+
require('../chunk-PIPGH7GA.js');
|
|
18
|
+
require('../chunk-PURI56RE.js');
|
|
18
19
|
require('../chunk-SNAQBZPT.js');
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
Object.defineProperty(exports, "SiteKitClientProviders", {
|
|
23
24
|
enumerable: true,
|
|
24
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkQCS7NWMA_js.SiteKitClientProviders; }
|
|
25
26
|
});
|
|
26
27
|
//# sourceMappingURL=client.js.map
|
|
27
28
|
//# sourceMappingURL=client.js.map
|
package/dist/layout/client.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
export { SiteKitClientProviders } from '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
2
|
+
export { SiteKitClientProviders } from '../chunk-FPVYKSXE.mjs';
|
|
3
|
+
import '../chunk-VA2O5OSV.mjs';
|
|
4
|
+
import '../chunk-MDQLON5R.mjs';
|
|
5
5
|
import '../chunk-4WCA2HM6.mjs';
|
|
6
6
|
import '../chunk-ZVBLXXNJ.mjs';
|
|
7
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-A2HL22BO.mjs';
|
|
8
8
|
import '../chunk-KZVSB5WE.mjs';
|
|
9
9
|
import '../chunk-ZN4HBK5C.mjs';
|
|
10
10
|
import '../chunk-ZZQAGCSI.mjs';
|
|
11
11
|
import '../chunk-6EDVCUAG.mjs';
|
|
12
|
-
import '../chunk-
|
|
13
|
-
import '../chunk-
|
|
14
|
-
import '../chunk-
|
|
15
|
-
import '../chunk-
|
|
12
|
+
import '../chunk-CABEVWKJ.mjs';
|
|
13
|
+
import '../chunk-MXJOKOFK.mjs';
|
|
14
|
+
import '../chunk-3BLKKF67.mjs';
|
|
15
|
+
import '../chunk-PGYOBEPL.mjs';
|
|
16
|
+
import '../chunk-GIGUDKLS.mjs';
|
|
16
17
|
import '../chunk-BEXTDHO4.mjs';
|
|
17
18
|
//# sourceMappingURL=client.mjs.map
|
|
18
19
|
//# sourceMappingURL=client.mjs.map
|
package/dist/layout/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('../chunk-
|
|
5
|
-
require('../chunk-
|
|
3
|
+
var chunkQCS7NWMA_js = require('../chunk-QCS7NWMA.js');
|
|
4
|
+
require('../chunk-U577ITSA.js');
|
|
5
|
+
require('../chunk-OY3PDIB3.js');
|
|
6
6
|
require('../chunk-7THQ4UW3.js');
|
|
7
7
|
require('../chunk-HGNSJXWT.js');
|
|
8
8
|
var chunkGCPPXUAI_js = require('../chunk-GCPPXUAI.js');
|
|
9
|
-
require('../chunk-
|
|
10
|
-
var
|
|
9
|
+
require('../chunk-G2KGHIAP.js');
|
|
10
|
+
var chunk34XL7TVH_js = require('../chunk-34XL7TVH.js');
|
|
11
11
|
require('../chunk-LVGSOW2F.js');
|
|
12
12
|
var chunkDV2LJYFD_js = require('../chunk-DV2LJYFD.js');
|
|
13
13
|
var chunkO5GHP7UO_js = require('../chunk-O5GHP7UO.js');
|
|
@@ -15,10 +15,11 @@ require('../chunk-UZKXOZHR.js');
|
|
|
15
15
|
require('../chunk-SWIKKSKL.js');
|
|
16
16
|
require('../chunk-RC4WWQXR.js');
|
|
17
17
|
require('../chunk-VJMPIRSD.js');
|
|
18
|
-
require('../chunk-
|
|
19
|
-
require('../chunk-
|
|
20
|
-
require('../chunk-
|
|
21
|
-
require('../chunk-
|
|
18
|
+
require('../chunk-NH2P27MA.js');
|
|
19
|
+
require('../chunk-JCDX37BY.js');
|
|
20
|
+
require('../chunk-IO65ROAO.js');
|
|
21
|
+
require('../chunk-PIPGH7GA.js');
|
|
22
|
+
require('../chunk-PURI56RE.js');
|
|
22
23
|
require('../chunk-SNAQBZPT.js');
|
|
23
24
|
var jsxRuntime = require('react/jsx-runtime');
|
|
24
25
|
|
|
@@ -72,7 +73,7 @@ async function SiteKitLayout({
|
|
|
72
73
|
);
|
|
73
74
|
}
|
|
74
75
|
const apiOrigin = chunkO5GHP7UO_js.resolveApiOrigin(resolvedApiUrl);
|
|
75
|
-
const clientCredential = await
|
|
76
|
+
const clientCredential = await chunk34XL7TVH_js.resolveClientCredential(resolvedApiKey, resolvedApiUrl);
|
|
76
77
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
77
78
|
/* @__PURE__ */ jsxRuntime.jsx("link", { rel: "preconnect", href: apiOrigin, crossOrigin: "anonymous" }),
|
|
78
79
|
/* @__PURE__ */ jsxRuntime.jsx("link", { rel: "dns-prefetch", href: apiOrigin }),
|
|
@@ -80,7 +81,7 @@ async function SiteKitLayout({
|
|
|
80
81
|
managedScripts && /* @__PURE__ */ jsxRuntime.jsx(chunkDV2LJYFD_js.ManagedScripts, { position: "head" }),
|
|
81
82
|
speculation && /* @__PURE__ */ jsxRuntime.jsx(SpeculationRules, { ...typeof speculation === "object" ? speculation : {} }),
|
|
82
83
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
83
|
-
|
|
84
|
+
chunkQCS7NWMA_js.SiteKitClientProviders,
|
|
84
85
|
{
|
|
85
86
|
apiKey: clientCredential,
|
|
86
87
|
apiUrl: resolvedApiUrl,
|
package/dist/layout/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/SpeculationRules.tsx","../../src/layout/SiteKitLayout.tsx"],"names":["jsx","resolveApiOrigin","resolveClientCredential","jsxs","Fragment","ManagedFavicon","ManagedScripts","SiteKitClientProviders"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6BO,SAAS,iBAAiB,EAAE,IAAA,GAAO,aAAa,OAAA,GAAU,IAAG,EAA0B;AAC5F,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,CAAC,IAAI,GAAG;AAAA,MACN;AAAA,QACE,MAAA,EAAQ,UAAA;AAAA,QACR,KAAA,EAAO;AAAA,UACL,GAAA,EAAK;AAAA,YACH,EAAE,cAAc,IAAA,EAAK;AAAA,YACrB,EAAE,GAAA,EAAK,EAAE,YAAA,EAAc,UAAS,EAAE;AAAA,YAClC,EAAE,GAAA,EAAK,EAAE,YAAA,EAAc,UAAS,EAAE;AAAA,YAClC,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,OAAA,MAAY,EAAE,KAAK,EAAE,YAAA,EAAc,OAAA,EAAQ,EAAE,CAAE;AAAA;AAChE,SACF;AAAA,QACA,SAAA,EAAW;AAAA;AACb;AACF,GACF;AAEA,EAAA,uBACEA,cAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,kBAAA;AAAA,MACL,yBAAyB,EAAE,MAAA,EAAQ,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAAE;AAAA,GAC3D;AAEJ;ACsEA,eAAsB,aAAA,CAAc;AAAA,EAClC,QAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA,GAAY,IAAA;AAAA,EACZ,MAAA,GAAS,IAAA;AAAA,EACT,MAAA,GAAS,KAAA;AAAA,EACT,WAAA,GAAc,KAAA;AAAA,EACd,KAAA,GAAQ,IAAA;AAAA,EACR,KAAA,GAAQ,IAAA;AAAA,EACR,OAAA,GAAU,IAAA;AAAA,EACV,cAAA,GAAiB,IAAA;AAAA,EACjB,KAAA,GAAQ,KAAA;AAAA,EACR,qBAAA,GAAwB,KAAA;AAAA,EACxB,WAAA,GAAc;AAChB,CAAA,EAAuB;AAErB,EAAA,MAAM,cAAA,GACJ,MAAA,IACA,OAAA,CAAQ,GAAA,CAAI,aAAA,IACZ,EAAA;AACF,EAAA,MAAM,cAAA,GACJ,MAAA,IACA,OAAA,CAAQ,GAAA,CAAI,aAAA,IACZ,sBAAA;AAEF,EAAA,IAAI,CAAC,kBAAkB,KAAA,EAAO;AAC5B,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAYC,kCAAiB,cAAc,CAAA;AAKjD,EAAA,MAAM,gBAAA,GAAmB,MAAMC,wCAAA,CAAwB,cAAA,EAAgB,cAAc,CAAA;AAErF,EAAA,uBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAJ,eAAC,MAAA,EAAA,EAAK,GAAA,EAAI,cAAa,IAAA,EAAM,SAAA,EAAW,aAAY,WAAA,EAAY,CAAA;AAAA,oBAChEA,cAAAA,CAAC,MAAA,EAAA,EAAK,GAAA,EAAI,cAAA,EAAe,MAAM,SAAA,EAAW,CAAA;AAAA,IAEzC,2BAAWA,cAAAA,CAACK,mCAAe,MAAA,EAAQ,cAAA,EAAgB,QAAQ,cAAA,EAAgB,CAAA;AAAA,IAC3E,cAAA,oBAAkBL,cAAAA,CAACM,+BAAA,EAAA,EAAe,UAAS,MAAA,EAAO,CAAA;AAAA,IAClD,WAAA,oBACCN,cAAAA,CAAC,gBAAA,EAAA,EAAkB,GAAI,OAAO,WAAA,KAAgB,QAAA,GAAW,WAAA,GAAc,EAAC,EAAI,CAAA;AAAA,oBAK9EG,eAAA;AAAA,MAACI,uCAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,gBAAA;AAAA,QACR,MAAA,EAAQ,cAAA;AAAA,QACR,SAAA;AAAA,QACA,SAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA,WAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QACA,KAAA;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,QAAA;AAAA,UACA,qBAAA,mBACCP,cAAAA,CAAC,QAAA,EAAA,EAAO,WAAU,SAAA,EAAU,aAAA,EAAY,MAAA,EACtC,QAAA,kBAAAA,eAAC,GAAA,EAAA,EAAE,IAAA,EAAK,WAAA,EAAY,QAAA,EAAA,UAAA,EAAQ,GAC9B,CAAA,GACE;AAAA;AAAA;AAAA,KACN;AAAA,IAGC,cAAA,oBAAkBA,cAAAA,CAACM,+BAAA,EAAA,EAAe,UAAS,UAAA,EAAW;AAAA,GAAA,EACzD,CAAA;AAEJ","file":"index.js","sourcesContent":["/**\n * SpeculationRules — declarative near-instant navigation for static sites.\n *\n * Emits a `<script type=\"speculationrules\">` telling supporting browsers\n * (Chromium 121+) to prerender same-origin links as the user shows intent\n * (moderate eagerness = hover/mousedown). Non-supporting browsers ignore the\n * tag entirely; there is no JS, no polyfill, no runtime cost — pure\n * progressive enhancement, ideal for the force-static fleet.\n *\n * Server component: renders during SSR, ships as static HTML.\n *\n * Excluded by default: URLs with a query string (often personalized) and\n * obvious non-page paths. Keep exclusions tight — prerendering a page that\n * sets cookies or fires analytics on load double-fires them only if the\n * analytics module ignores prerendering; site-kit analytics defers to\n * post-activation, and Chrome delays most side effects until activation.\n */\n\ninterface SpeculationRulesProps {\n /**\n * 'prerender' (default) renders the next page fully in the background;\n * 'prefetch' only fetches the document. Prefetch is the conservative\n * fallback if a site sees issues with prerender.\n */\n mode?: 'prerender' | 'prefetch'\n /** Additional URL patterns to exclude (speculation rules URL pattern syntax). */\n exclude?: string[]\n}\n\nexport function SpeculationRules({ mode = 'prerender', exclude = [] }: SpeculationRulesProps) {\n const rules = {\n [mode]: [\n {\n source: 'document' as const,\n where: {\n and: [\n { href_matches: '/*' },\n { not: { href_matches: '/*\\\\?*' } },\n { not: { href_matches: '/api/*' } },\n ...exclude.map(pattern => ({ not: { href_matches: pattern } })),\n ],\n },\n eagerness: 'moderate' as const,\n },\n ],\n }\n\n return (\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(rules) }}\n />\n )\n}\n","/**\n * @sonordev/site-kit/layout — SiteKitLayout\n *\n * The master layout component. A single RSC that auto-composes every\n * site-kit feature your layout needs:\n *\n * Server-side (RSC):\n * - ManagedFavicon (link tags from Portal logo)\n * - ManagedScripts position=\"head\" (tracking pixels, analytics tags)\n * - ManagedScripts position=\"body-end\"\n *\n * Client-side (island):\n * - AnalyticsProvider (page views, scroll depth, heatmap, web vitals)\n * - EngageWidget (popups, nudges, chat)\n * - SignalBridge (A/B experiments, behavior tracking)\n * - SitemapSync (keeps Portal seo_pages in sync)\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { SiteKitLayout } from '@sonordev/site-kit/layout'\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <SiteKitLayout>\n * <Header />\n * <main>{children}</main>\n * <Footer />\n * </SiteKitLayout>\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example Opt out of specific features:\n * ```tsx\n * <SiteKitLayout engage={false} signal={false}>\n * {children}\n * </SiteKitLayout>\n * ```\n */\n\nimport * as React from 'react'\nimport { ManagedFavicon } from '../images/ManagedFavicon'\nimport { ManagedScripts } from '../seo/ManagedScripts'\nimport { resolveApiOrigin } from '../server/server-fetch'\nimport { resolveClientCredential } from '../server/mint-site-token'\nimport { SiteKitClientProviders } from './SiteKitClientProviders'\nimport { SpeculationRules } from './SpeculationRules'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\nexport interface SiteKitLayoutProps {\n children: React.ReactNode\n\n /** Portal API key. Defaults to SONOR_API_KEY env var. */\n apiKey?: string\n /** Portal API URL. Defaults to env or https://api.sonor.io */\n apiUrl?: string\n /** Project ID (for Engage chat room routing). Auto-resolved if not provided. */\n projectId?: string\n\n /** Analytics tracking. true (default) | false | config object */\n analytics?: boolean | AnalyticsConfig\n /** Engage widgets (popups, chat). true (default) | false | config object */\n engage?: boolean | EngageConfig\n /** Signal AI (experiments, behavior). false (default) | true | config object */\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. **Default: false.**\n *\n * Sitemap registration is a build-time and server-side job. Build-time\n * `createSitemap` is canonical, and sonor-api's nightly reconciler fetches\n * each host's /sitemap.xml itself, so nothing here needs a visitor.\n *\n * This defaulted to true, and because its throttle lives in sessionStorage\n * and its content hash in localStorage, every first-time visitor, incognito\n * tab and crawler missed both guards and re-POSTed the entire sitemap:\n * upforge.io took ~140 full syncs in a day, queencityriverboats.com ~76.\n * That coupled sitemap traffic to VISITOR COUNT rather than to content\n * changes — exactly backwards — and made every reader pay for platform\n * bookkeeping in bandwidth, XML parsing and an API round-trip.\n *\n * Set true only to re-enable the legacy browser fallback for a site whose\n * build-time registration cannot be made to work.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports this site's kit version + active modules to Sonor\n * once per session so the platform can track version drift. Default: true.\n * Deferred like Analytics; never in the hydration path.\n */\n fleet?: boolean\n /**\n * Defer client modules (Analytics, Engage, SitemapSync) until window load +\n * idle or the first user interaction, keeping their JS and mount work out of\n * the critical hydration path. Default: true. Pass false to restore legacy\n * eager mounting. SignalBridge is never deferred.\n */\n defer?: boolean\n /** ManagedFavicon in <head>. Default: true */\n favicon?: boolean\n /** ManagedScripts (head + body-end). Default: true */\n managedScripts?: boolean\n\n /** Debug mode — logs to console. Default: false */\n debug?: boolean\n /**\n * When true, append a screen-reader-only link to `/llms.txt` after main content.\n * Default false — prefer `buildAiDiscoveryHeaders()` for discovery.\n */\n showLlmsTxtFooterLink?: boolean\n /**\n * Emit a Speculation Rules script prerendering same-origin links on intent\n * (Chromium 121+; other browsers ignore it). Zero JS, static-safe. Default\n * false — opt in per site, or pass { mode: 'prefetch' } for the\n * conservative variant.\n */\n speculation?: boolean | { mode?: 'prerender' | 'prefetch'; exclude?: string[] }\n}\n\nexport async function SiteKitLayout({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n favicon = true,\n managedScripts = true,\n debug = false,\n showLlmsTxtFooterLink = false,\n speculation = false,\n}: SiteKitLayoutProps) {\n // Resolve API config from env (server-side, safe)\n const resolvedApiKey =\n apiKey ??\n process.env.SONOR_API_KEY ??\n ''\n const resolvedApiUrl =\n apiUrl ??\n process.env.SONOR_API_URL ??\n 'https://api.sonor.io'\n\n if (!resolvedApiKey && debug) {\n console.warn(\n '[SiteKitLayout] No API key found. Set SONOR_API_KEY.',\n )\n }\n\n const apiOrigin = resolveApiOrigin(resolvedApiUrl)\n\n // Mint a short-lived client token so the raw key never reaches the browser.\n // Falls back to the raw key if minting is unavailable (older API / transient\n // outage) — the build never breaks. The client refreshes the token as needed.\n const clientCredential = await resolveClientCredential(resolvedApiKey, resolvedApiUrl)\n\n return (\n <>\n <link rel=\"preconnect\" href={apiOrigin} crossOrigin=\"anonymous\" />\n <link rel=\"dns-prefetch\" href={apiOrigin} />\n {/* Server-rendered head components */}\n {favicon && <ManagedFavicon apiKey={resolvedApiKey} apiUrl={resolvedApiUrl} />}\n {managedScripts && <ManagedScripts position=\"head\" />}\n {speculation && (\n <SpeculationRules {...(typeof speculation === 'object' ? speculation : {})} />\n )}\n\n {/* Client-side providers island — receives the minted token (or raw-key\n fallback), never the raw key when minting succeeds. */}\n <SiteKitClientProviders\n apiKey={clientCredential}\n apiUrl={resolvedApiUrl}\n projectId={projectId}\n analytics={analytics}\n engage={engage}\n signal={signal}\n sitemapSync={sitemapSync}\n fleet={fleet}\n defer={defer}\n debug={debug}\n >\n {children}\n {showLlmsTxtFooterLink ? (\n <footer className=\"sr-only\" aria-hidden=\"true\">\n <a href=\"/llms.txt\">llms.txt</a>\n </footer>\n ) : null}\n </SiteKitClientProviders>\n\n {/* Server-rendered body-end scripts */}\n {managedScripts && <ManagedScripts position=\"body-end\" />}\n </>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/layout/SpeculationRules.tsx","../../src/layout/SiteKitLayout.tsx"],"names":["jsx","resolveApiOrigin","resolveClientCredential","jsxs","Fragment","ManagedFavicon","ManagedScripts","SiteKitClientProviders"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * SpeculationRules — declarative near-instant navigation for static sites.\n *\n * Emits a `<script type=\"speculationrules\">` telling supporting browsers\n * (Chromium 121+) to prerender same-origin links as the user shows intent\n * (moderate eagerness = hover/mousedown). Non-supporting browsers ignore the\n * tag entirely; there is no JS, no polyfill, no runtime cost — pure\n * progressive enhancement, ideal for the force-static fleet.\n *\n * Server component: renders during SSR, ships as static HTML.\n *\n * Excluded by default: URLs with a query string (often personalized) and\n * obvious non-page paths. Keep exclusions tight — prerendering a page that\n * sets cookies or fires analytics on load double-fires them only if the\n * analytics module ignores prerendering; site-kit analytics defers to\n * post-activation, and Chrome delays most side effects until activation.\n */\n\ninterface SpeculationRulesProps {\n /**\n * 'prerender' (default) renders the next page fully in the background;\n * 'prefetch' only fetches the document. Prefetch is the conservative\n * fallback if a site sees issues with prerender.\n */\n mode?: 'prerender' | 'prefetch'\n /** Additional URL patterns to exclude (speculation rules URL pattern syntax). */\n exclude?: string[]\n}\n\nexport function SpeculationRules({ mode = 'prerender', exclude = [] }: SpeculationRulesProps) {\n const rules = {\n [mode]: [\n {\n source: 'document' as const,\n where: {\n and: [\n { href_matches: '/*' },\n { not: { href_matches: '/*\\\\?*' } },\n { not: { href_matches: '/api/*' } },\n ...exclude.map(pattern => ({ not: { href_matches: pattern } })),\n ],\n },\n eagerness: 'moderate' as const,\n },\n ],\n }\n\n return (\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(rules) }}\n />\n )\n}\n","/**\n * @sonordev/site-kit/layout — SiteKitLayout\n *\n * The master layout component. A single RSC that auto-composes every\n * site-kit feature your layout needs:\n *\n * Server-side (RSC):\n * - ManagedFavicon (link tags from Portal logo)\n * - ManagedScripts position=\"head\" (tracking pixels, analytics tags)\n * - ManagedScripts position=\"body-end\"\n *\n * Client-side (island):\n * - AnalyticsProvider (page views, scroll depth, heatmap, web vitals)\n * - EngageWidget (popups, nudges, chat)\n * - SignalBridge (A/B experiments, behavior tracking)\n * - SitemapSync (keeps Portal seo_pages in sync)\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { SiteKitLayout } from '@sonordev/site-kit/layout'\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <SiteKitLayout>\n * <Header />\n * <main>{children}</main>\n * <Footer />\n * </SiteKitLayout>\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example Opt out of specific features:\n * ```tsx\n * <SiteKitLayout engage={false} signal={false}>\n * {children}\n * </SiteKitLayout>\n * ```\n */\n\nimport * as React from 'react'\nimport { ManagedFavicon } from '../images/ManagedFavicon'\nimport { ManagedScripts } from '../seo/ManagedScripts'\nimport { resolveApiOrigin } from '../server/server-fetch'\nimport { resolveClientCredential } from '../server/mint-site-token'\nimport { SiteKitClientProviders } from './SiteKitClientProviders'\nimport { SpeculationRules } from './SpeculationRules'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\nexport interface SiteKitLayoutProps {\n children: React.ReactNode\n\n /** Portal API key. Defaults to SONOR_API_KEY env var. */\n apiKey?: string\n /** Portal API URL. Defaults to env or https://api.sonor.io */\n apiUrl?: string\n /** Project ID (for Engage chat room routing). Auto-resolved if not provided. */\n projectId?: string\n\n /** Analytics tracking. true (default) | false | config object */\n analytics?: boolean | AnalyticsConfig\n /** Engage widgets (popups, chat). true (default) | false | config object */\n engage?: boolean | EngageConfig\n /** Signal AI (experiments, behavior). false (default) | true | config object */\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. **Default: false.**\n *\n * Sitemap registration is a build-time and server-side job. Build-time\n * `createSitemap` is canonical, and sonor-api's nightly reconciler fetches\n * each host's /sitemap.xml itself, so nothing here needs a visitor.\n *\n * This defaulted to true, and because its throttle lives in sessionStorage\n * and its content hash in localStorage, every first-time visitor, incognito\n * tab and crawler missed both guards and re-POSTed the entire sitemap:\n * upforge.io took ~140 full syncs in a day, queencityriverboats.com ~76.\n * That coupled sitemap traffic to VISITOR COUNT rather than to content\n * changes — exactly backwards — and made every reader pay for platform\n * bookkeeping in bandwidth, XML parsing and an API round-trip.\n *\n * Set true only to re-enable the legacy browser fallback for a site whose\n * build-time registration cannot be made to work.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports this site's kit version + active modules to Sonor\n * once per session so the platform can track version drift. Default: true.\n * Deferred like Analytics; never in the hydration path.\n */\n fleet?: boolean\n /**\n * Defer client modules (Analytics, Engage, SitemapSync) until window load +\n * idle or the first user interaction, keeping their JS and mount work out of\n * the critical hydration path. Default: true. Pass false to restore legacy\n * eager mounting. SignalBridge is never deferred.\n */\n defer?: boolean\n /** ManagedFavicon in <head>. Default: true */\n favicon?: boolean\n /** ManagedScripts (head + body-end). Default: true */\n managedScripts?: boolean\n\n /** Debug mode — logs to console. Default: false */\n debug?: boolean\n /**\n * When true, append a screen-reader-only link to `/llms.txt` after main content.\n * Default false — prefer `buildAiDiscoveryHeaders()` for discovery.\n */\n showLlmsTxtFooterLink?: boolean\n /**\n * Emit a Speculation Rules script prerendering same-origin links on intent\n * (Chromium 121+; other browsers ignore it). Zero JS, static-safe. Default\n * false — opt in per site, or pass { mode: 'prefetch' } for the\n * conservative variant.\n */\n speculation?: boolean | { mode?: 'prerender' | 'prefetch'; exclude?: string[] }\n}\n\nexport async function SiteKitLayout({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n favicon = true,\n managedScripts = true,\n debug = false,\n showLlmsTxtFooterLink = false,\n speculation = false,\n}: SiteKitLayoutProps) {\n // Resolve API config from env (server-side, safe)\n const resolvedApiKey =\n apiKey ??\n process.env.SONOR_API_KEY ??\n ''\n const resolvedApiUrl =\n apiUrl ??\n process.env.SONOR_API_URL ??\n 'https://api.sonor.io'\n\n if (!resolvedApiKey && debug) {\n console.warn(\n '[SiteKitLayout] No API key found. Set SONOR_API_KEY.',\n )\n }\n\n const apiOrigin = resolveApiOrigin(resolvedApiUrl)\n\n // Mint a short-lived client token so the raw key never reaches the browser.\n // Falls back to the raw key if minting is unavailable (older API / transient\n // outage) — the build never breaks. The client refreshes the token as needed.\n const clientCredential = await resolveClientCredential(resolvedApiKey, resolvedApiUrl)\n\n return (\n <>\n <link rel=\"preconnect\" href={apiOrigin} crossOrigin=\"anonymous\" />\n <link rel=\"dns-prefetch\" href={apiOrigin} />\n {/* Server-rendered head components */}\n {favicon && <ManagedFavicon apiKey={resolvedApiKey} apiUrl={resolvedApiUrl} />}\n {managedScripts && <ManagedScripts position=\"head\" />}\n {speculation && (\n <SpeculationRules {...(typeof speculation === 'object' ? speculation : {})} />\n )}\n\n {/* Client-side providers island — receives the minted token (or raw-key\n fallback), never the raw key when minting succeeds. */}\n <SiteKitClientProviders\n apiKey={clientCredential}\n apiUrl={resolvedApiUrl}\n projectId={projectId}\n analytics={analytics}\n engage={engage}\n signal={signal}\n sitemapSync={sitemapSync}\n fleet={fleet}\n defer={defer}\n debug={debug}\n >\n {children}\n {showLlmsTxtFooterLink ? (\n <footer className=\"sr-only\" aria-hidden=\"true\">\n <a href=\"/llms.txt\">llms.txt</a>\n </footer>\n ) : null}\n </SiteKitClientProviders>\n\n {/* Server-rendered body-end scripts */}\n {managedScripts && <ManagedScripts position=\"body-end\" />}\n </>\n )\n}\n"]}
|
package/dist/layout/index.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { SiteKitClientProviders } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
1
|
+
import { SiteKitClientProviders } from '../chunk-FPVYKSXE.mjs';
|
|
2
|
+
import '../chunk-VA2O5OSV.mjs';
|
|
3
|
+
import '../chunk-MDQLON5R.mjs';
|
|
4
4
|
import '../chunk-4WCA2HM6.mjs';
|
|
5
5
|
import '../chunk-ZVBLXXNJ.mjs';
|
|
6
6
|
import { ManagedFavicon } from '../chunk-CU6OGBKK.mjs';
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import { resolveClientCredential } from '../chunk-
|
|
7
|
+
import '../chunk-A2HL22BO.mjs';
|
|
8
|
+
import { resolveClientCredential } from '../chunk-B6QPCAEG.mjs';
|
|
9
9
|
import '../chunk-BQP6JIE2.mjs';
|
|
10
10
|
import { ManagedScripts } from '../chunk-6PJTLBRR.mjs';
|
|
11
11
|
import { resolveApiOrigin } from '../chunk-6XNEGG5B.mjs';
|
|
@@ -13,10 +13,11 @@ import '../chunk-KZVSB5WE.mjs';
|
|
|
13
13
|
import '../chunk-ZN4HBK5C.mjs';
|
|
14
14
|
import '../chunk-ZZQAGCSI.mjs';
|
|
15
15
|
import '../chunk-6EDVCUAG.mjs';
|
|
16
|
-
import '../chunk-
|
|
17
|
-
import '../chunk-
|
|
18
|
-
import '../chunk-
|
|
19
|
-
import '../chunk-
|
|
16
|
+
import '../chunk-CABEVWKJ.mjs';
|
|
17
|
+
import '../chunk-MXJOKOFK.mjs';
|
|
18
|
+
import '../chunk-3BLKKF67.mjs';
|
|
19
|
+
import '../chunk-PGYOBEPL.mjs';
|
|
20
|
+
import '../chunk-GIGUDKLS.mjs';
|
|
20
21
|
import '../chunk-BEXTDHO4.mjs';
|
|
21
22
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
22
23
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/layout/SpeculationRules.tsx","../../src/layout/SiteKitLayout.tsx"],"names":["jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * SpeculationRules — declarative near-instant navigation for static sites.\n *\n * Emits a `<script type=\"speculationrules\">` telling supporting browsers\n * (Chromium 121+) to prerender same-origin links as the user shows intent\n * (moderate eagerness = hover/mousedown). Non-supporting browsers ignore the\n * tag entirely; there is no JS, no polyfill, no runtime cost — pure\n * progressive enhancement, ideal for the force-static fleet.\n *\n * Server component: renders during SSR, ships as static HTML.\n *\n * Excluded by default: URLs with a query string (often personalized) and\n * obvious non-page paths. Keep exclusions tight — prerendering a page that\n * sets cookies or fires analytics on load double-fires them only if the\n * analytics module ignores prerendering; site-kit analytics defers to\n * post-activation, and Chrome delays most side effects until activation.\n */\n\ninterface SpeculationRulesProps {\n /**\n * 'prerender' (default) renders the next page fully in the background;\n * 'prefetch' only fetches the document. Prefetch is the conservative\n * fallback if a site sees issues with prerender.\n */\n mode?: 'prerender' | 'prefetch'\n /** Additional URL patterns to exclude (speculation rules URL pattern syntax). */\n exclude?: string[]\n}\n\nexport function SpeculationRules({ mode = 'prerender', exclude = [] }: SpeculationRulesProps) {\n const rules = {\n [mode]: [\n {\n source: 'document' as const,\n where: {\n and: [\n { href_matches: '/*' },\n { not: { href_matches: '/*\\\\?*' } },\n { not: { href_matches: '/api/*' } },\n ...exclude.map(pattern => ({ not: { href_matches: pattern } })),\n ],\n },\n eagerness: 'moderate' as const,\n },\n ],\n }\n\n return (\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(rules) }}\n />\n )\n}\n","/**\n * @sonordev/site-kit/layout — SiteKitLayout\n *\n * The master layout component. A single RSC that auto-composes every\n * site-kit feature your layout needs:\n *\n * Server-side (RSC):\n * - ManagedFavicon (link tags from Portal logo)\n * - ManagedScripts position=\"head\" (tracking pixels, analytics tags)\n * - ManagedScripts position=\"body-end\"\n *\n * Client-side (island):\n * - AnalyticsProvider (page views, scroll depth, heatmap, web vitals)\n * - EngageWidget (popups, nudges, chat)\n * - SignalBridge (A/B experiments, behavior tracking)\n * - SitemapSync (keeps Portal seo_pages in sync)\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { SiteKitLayout } from '@sonordev/site-kit/layout'\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <SiteKitLayout>\n * <Header />\n * <main>{children}</main>\n * <Footer />\n * </SiteKitLayout>\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example Opt out of specific features:\n * ```tsx\n * <SiteKitLayout engage={false} signal={false}>\n * {children}\n * </SiteKitLayout>\n * ```\n */\n\nimport * as React from 'react'\nimport { ManagedFavicon } from '../images/ManagedFavicon'\nimport { ManagedScripts } from '../seo/ManagedScripts'\nimport { resolveApiOrigin } from '../server/server-fetch'\nimport { resolveClientCredential } from '../server/mint-site-token'\nimport { SiteKitClientProviders } from './SiteKitClientProviders'\nimport { SpeculationRules } from './SpeculationRules'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\nexport interface SiteKitLayoutProps {\n children: React.ReactNode\n\n /** Portal API key. Defaults to SONOR_API_KEY env var. */\n apiKey?: string\n /** Portal API URL. Defaults to env or https://api.sonor.io */\n apiUrl?: string\n /** Project ID (for Engage chat room routing). Auto-resolved if not provided. */\n projectId?: string\n\n /** Analytics tracking. true (default) | false | config object */\n analytics?: boolean | AnalyticsConfig\n /** Engage widgets (popups, chat). true (default) | false | config object */\n engage?: boolean | EngageConfig\n /** Signal AI (experiments, behavior). false (default) | true | config object */\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. **Default: false.**\n *\n * Sitemap registration is a build-time and server-side job. Build-time\n * `createSitemap` is canonical, and sonor-api's nightly reconciler fetches\n * each host's /sitemap.xml itself, so nothing here needs a visitor.\n *\n * This defaulted to true, and because its throttle lives in sessionStorage\n * and its content hash in localStorage, every first-time visitor, incognito\n * tab and crawler missed both guards and re-POSTed the entire sitemap:\n * upforge.io took ~140 full syncs in a day, queencityriverboats.com ~76.\n * That coupled sitemap traffic to VISITOR COUNT rather than to content\n * changes — exactly backwards — and made every reader pay for platform\n * bookkeeping in bandwidth, XML parsing and an API round-trip.\n *\n * Set true only to re-enable the legacy browser fallback for a site whose\n * build-time registration cannot be made to work.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports this site's kit version + active modules to Sonor\n * once per session so the platform can track version drift. Default: true.\n * Deferred like Analytics; never in the hydration path.\n */\n fleet?: boolean\n /**\n * Defer client modules (Analytics, Engage, SitemapSync) until window load +\n * idle or the first user interaction, keeping their JS and mount work out of\n * the critical hydration path. Default: true. Pass false to restore legacy\n * eager mounting. SignalBridge is never deferred.\n */\n defer?: boolean\n /** ManagedFavicon in <head>. Default: true */\n favicon?: boolean\n /** ManagedScripts (head + body-end). Default: true */\n managedScripts?: boolean\n\n /** Debug mode — logs to console. Default: false */\n debug?: boolean\n /**\n * When true, append a screen-reader-only link to `/llms.txt` after main content.\n * Default false — prefer `buildAiDiscoveryHeaders()` for discovery.\n */\n showLlmsTxtFooterLink?: boolean\n /**\n * Emit a Speculation Rules script prerendering same-origin links on intent\n * (Chromium 121+; other browsers ignore it). Zero JS, static-safe. Default\n * false — opt in per site, or pass { mode: 'prefetch' } for the\n * conservative variant.\n */\n speculation?: boolean | { mode?: 'prerender' | 'prefetch'; exclude?: string[] }\n}\n\nexport async function SiteKitLayout({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n favicon = true,\n managedScripts = true,\n debug = false,\n showLlmsTxtFooterLink = false,\n speculation = false,\n}: SiteKitLayoutProps) {\n // Resolve API config from env (server-side, safe)\n const resolvedApiKey =\n apiKey ??\n process.env.SONOR_API_KEY ??\n ''\n const resolvedApiUrl =\n apiUrl ??\n process.env.SONOR_API_URL ??\n 'https://api.sonor.io'\n\n if (!resolvedApiKey && debug) {\n console.warn(\n '[SiteKitLayout] No API key found. Set SONOR_API_KEY.',\n )\n }\n\n const apiOrigin = resolveApiOrigin(resolvedApiUrl)\n\n // Mint a short-lived client token so the raw key never reaches the browser.\n // Falls back to the raw key if minting is unavailable (older API / transient\n // outage) — the build never breaks. The client refreshes the token as needed.\n const clientCredential = await resolveClientCredential(resolvedApiKey, resolvedApiUrl)\n\n return (\n <>\n <link rel=\"preconnect\" href={apiOrigin} crossOrigin=\"anonymous\" />\n <link rel=\"dns-prefetch\" href={apiOrigin} />\n {/* Server-rendered head components */}\n {favicon && <ManagedFavicon apiKey={resolvedApiKey} apiUrl={resolvedApiUrl} />}\n {managedScripts && <ManagedScripts position=\"head\" />}\n {speculation && (\n <SpeculationRules {...(typeof speculation === 'object' ? speculation : {})} />\n )}\n\n {/* Client-side providers island — receives the minted token (or raw-key\n fallback), never the raw key when minting succeeds. */}\n <SiteKitClientProviders\n apiKey={clientCredential}\n apiUrl={resolvedApiUrl}\n projectId={projectId}\n analytics={analytics}\n engage={engage}\n signal={signal}\n sitemapSync={sitemapSync}\n fleet={fleet}\n defer={defer}\n debug={debug}\n >\n {children}\n {showLlmsTxtFooterLink ? (\n <footer className=\"sr-only\" aria-hidden=\"true\">\n <a href=\"/llms.txt\">llms.txt</a>\n </footer>\n ) : null}\n </SiteKitClientProviders>\n\n {/* Server-rendered body-end scripts */}\n {managedScripts && <ManagedScripts position=\"body-end\" />}\n </>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/layout/SpeculationRules.tsx","../../src/layout/SiteKitLayout.tsx"],"names":["jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * SpeculationRules — declarative near-instant navigation for static sites.\n *\n * Emits a `<script type=\"speculationrules\">` telling supporting browsers\n * (Chromium 121+) to prerender same-origin links as the user shows intent\n * (moderate eagerness = hover/mousedown). Non-supporting browsers ignore the\n * tag entirely; there is no JS, no polyfill, no runtime cost — pure\n * progressive enhancement, ideal for the force-static fleet.\n *\n * Server component: renders during SSR, ships as static HTML.\n *\n * Excluded by default: URLs with a query string (often personalized) and\n * obvious non-page paths. Keep exclusions tight — prerendering a page that\n * sets cookies or fires analytics on load double-fires them only if the\n * analytics module ignores prerendering; site-kit analytics defers to\n * post-activation, and Chrome delays most side effects until activation.\n */\n\ninterface SpeculationRulesProps {\n /**\n * 'prerender' (default) renders the next page fully in the background;\n * 'prefetch' only fetches the document. Prefetch is the conservative\n * fallback if a site sees issues with prerender.\n */\n mode?: 'prerender' | 'prefetch'\n /** Additional URL patterns to exclude (speculation rules URL pattern syntax). */\n exclude?: string[]\n}\n\nexport function SpeculationRules({ mode = 'prerender', exclude = [] }: SpeculationRulesProps) {\n const rules = {\n [mode]: [\n {\n source: 'document' as const,\n where: {\n and: [\n { href_matches: '/*' },\n { not: { href_matches: '/*\\\\?*' } },\n { not: { href_matches: '/api/*' } },\n ...exclude.map(pattern => ({ not: { href_matches: pattern } })),\n ],\n },\n eagerness: 'moderate' as const,\n },\n ],\n }\n\n return (\n <script\n type=\"speculationrules\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(rules) }}\n />\n )\n}\n","/**\n * @sonordev/site-kit/layout — SiteKitLayout\n *\n * The master layout component. A single RSC that auto-composes every\n * site-kit feature your layout needs:\n *\n * Server-side (RSC):\n * - ManagedFavicon (link tags from Portal logo)\n * - ManagedScripts position=\"head\" (tracking pixels, analytics tags)\n * - ManagedScripts position=\"body-end\"\n *\n * Client-side (island):\n * - AnalyticsProvider (page views, scroll depth, heatmap, web vitals)\n * - EngageWidget (popups, nudges, chat)\n * - SignalBridge (A/B experiments, behavior tracking)\n * - SitemapSync (keeps Portal seo_pages in sync)\n *\n * @example\n * ```tsx\n * // app/layout.tsx\n * import { SiteKitLayout } from '@sonordev/site-kit/layout'\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html lang=\"en\">\n * <body>\n * <SiteKitLayout>\n * <Header />\n * <main>{children}</main>\n * <Footer />\n * </SiteKitLayout>\n * </body>\n * </html>\n * )\n * }\n * ```\n *\n * @example Opt out of specific features:\n * ```tsx\n * <SiteKitLayout engage={false} signal={false}>\n * {children}\n * </SiteKitLayout>\n * ```\n */\n\nimport * as React from 'react'\nimport { ManagedFavicon } from '../images/ManagedFavicon'\nimport { ManagedScripts } from '../seo/ManagedScripts'\nimport { resolveApiOrigin } from '../server/server-fetch'\nimport { resolveClientCredential } from '../server/mint-site-token'\nimport { SiteKitClientProviders } from './SiteKitClientProviders'\nimport { SpeculationRules } from './SpeculationRules'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\nexport interface SiteKitLayoutProps {\n children: React.ReactNode\n\n /** Portal API key. Defaults to SONOR_API_KEY env var. */\n apiKey?: string\n /** Portal API URL. Defaults to env or https://api.sonor.io */\n apiUrl?: string\n /** Project ID (for Engage chat room routing). Auto-resolved if not provided. */\n projectId?: string\n\n /** Analytics tracking. true (default) | false | config object */\n analytics?: boolean | AnalyticsConfig\n /** Engage widgets (popups, chat). true (default) | false | config object */\n engage?: boolean | EngageConfig\n /** Signal AI (experiments, behavior). false (default) | true | config object */\n signal?: boolean | SignalConfig\n /**\n * Runtime SitemapSync from the visitor's browser. **Default: false.**\n *\n * Sitemap registration is a build-time and server-side job. Build-time\n * `createSitemap` is canonical, and sonor-api's nightly reconciler fetches\n * each host's /sitemap.xml itself, so nothing here needs a visitor.\n *\n * This defaulted to true, and because its throttle lives in sessionStorage\n * and its content hash in localStorage, every first-time visitor, incognito\n * tab and crawler missed both guards and re-POSTed the entire sitemap:\n * upforge.io took ~140 full syncs in a day, queencityriverboats.com ~76.\n * That coupled sitemap traffic to VISITOR COUNT rather than to content\n * changes — exactly backwards — and made every reader pay for platform\n * bookkeeping in bandwidth, XML parsing and an API round-trip.\n *\n * Set true only to re-enable the legacy browser fallback for a site whose\n * build-time registration cannot be made to work.\n */\n sitemapSync?: boolean\n /**\n * Fleet heartbeat — reports this site's kit version + active modules to Sonor\n * once per session so the platform can track version drift. Default: true.\n * Deferred like Analytics; never in the hydration path.\n */\n fleet?: boolean\n /**\n * Defer client modules (Analytics, Engage, SitemapSync) until window load +\n * idle or the first user interaction, keeping their JS and mount work out of\n * the critical hydration path. Default: true. Pass false to restore legacy\n * eager mounting. SignalBridge is never deferred.\n */\n defer?: boolean\n /** ManagedFavicon in <head>. Default: true */\n favicon?: boolean\n /** ManagedScripts (head + body-end). Default: true */\n managedScripts?: boolean\n\n /** Debug mode — logs to console. Default: false */\n debug?: boolean\n /**\n * When true, append a screen-reader-only link to `/llms.txt` after main content.\n * Default false — prefer `buildAiDiscoveryHeaders()` for discovery.\n */\n showLlmsTxtFooterLink?: boolean\n /**\n * Emit a Speculation Rules script prerendering same-origin links on intent\n * (Chromium 121+; other browsers ignore it). Zero JS, static-safe. Default\n * false — opt in per site, or pass { mode: 'prefetch' } for the\n * conservative variant.\n */\n speculation?: boolean | { mode?: 'prerender' | 'prefetch'; exclude?: string[] }\n}\n\nexport async function SiteKitLayout({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = false,\n fleet = true,\n defer = true,\n favicon = true,\n managedScripts = true,\n debug = false,\n showLlmsTxtFooterLink = false,\n speculation = false,\n}: SiteKitLayoutProps) {\n // Resolve API config from env (server-side, safe)\n const resolvedApiKey =\n apiKey ??\n process.env.SONOR_API_KEY ??\n ''\n const resolvedApiUrl =\n apiUrl ??\n process.env.SONOR_API_URL ??\n 'https://api.sonor.io'\n\n if (!resolvedApiKey && debug) {\n console.warn(\n '[SiteKitLayout] No API key found. Set SONOR_API_KEY.',\n )\n }\n\n const apiOrigin = resolveApiOrigin(resolvedApiUrl)\n\n // Mint a short-lived client token so the raw key never reaches the browser.\n // Falls back to the raw key if minting is unavailable (older API / transient\n // outage) — the build never breaks. The client refreshes the token as needed.\n const clientCredential = await resolveClientCredential(resolvedApiKey, resolvedApiUrl)\n\n return (\n <>\n <link rel=\"preconnect\" href={apiOrigin} crossOrigin=\"anonymous\" />\n <link rel=\"dns-prefetch\" href={apiOrigin} />\n {/* Server-rendered head components */}\n {favicon && <ManagedFavicon apiKey={resolvedApiKey} apiUrl={resolvedApiUrl} />}\n {managedScripts && <ManagedScripts position=\"head\" />}\n {speculation && (\n <SpeculationRules {...(typeof speculation === 'object' ? speculation : {})} />\n )}\n\n {/* Client-side providers island — receives the minted token (or raw-key\n fallback), never the raw key when minting succeeds. */}\n <SiteKitClientProviders\n apiKey={clientCredential}\n apiUrl={resolvedApiUrl}\n projectId={projectId}\n analytics={analytics}\n engage={engage}\n signal={signal}\n sitemapSync={sitemapSync}\n fleet={fleet}\n defer={defer}\n debug={debug}\n >\n {children}\n {showLlmsTxtFooterLink ? (\n <footer className=\"sr-only\" aria-hidden=\"true\">\n <a href=\"/llms.txt\">llms.txt</a>\n </footer>\n ) : null}\n </SiteKitClientProviders>\n\n {/* Server-rendered body-end scripts */}\n {managedScripts && <ManagedScripts position=\"body-end\" />}\n </>\n )\n}\n"]}
|
package/dist/layout/types.d.ts
CHANGED
|
@@ -46,6 +46,12 @@ export interface AnalyticsConfig {
|
|
|
46
46
|
*/
|
|
47
47
|
export interface EngageConfig extends ChatLauncherPlacement {
|
|
48
48
|
chatEnabled?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Show popups and the chat launcher even when this page is framed by
|
|
51
|
+
* another origin (a case study's device frame). Off by default, like
|
|
52
|
+
* analytics' allowInFrame.
|
|
53
|
+
*/
|
|
54
|
+
allowInFrame?: boolean;
|
|
49
55
|
}
|
|
50
56
|
export interface SignalConfig {
|
|
51
57
|
realtime?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/layout/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE5D,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,qBAAqB;IACzD,WAAW,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/layout/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAE5D,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,qBAAqB;IACzD,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B"}
|
package/dist/llms/index.d.ts
CHANGED
|
@@ -30,4 +30,6 @@ export { getLLMsData, getBusinessInfo, getServices, getFAQItems, getPageSummarie
|
|
|
30
30
|
export { writeLLMsTxtToPublic } from './writeLLMsTxt';
|
|
31
31
|
export type { WriteLLMsTxtOptions } from './writeLLMsTxt';
|
|
32
32
|
export { createLlmsRevalidateHandler } from './revalidate';
|
|
33
|
+
export { createSeoRevalidationHandler, parseSeoRevalidationPayload, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, LEGACY_PUBLICATION_PATH, } from './seo-revalidate';
|
|
34
|
+
export type { SeoRevalidationHandlerOptions, SeoRevalidationPayload } from './seo-revalidate';
|
|
33
35
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/llms/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llms/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,YAAY,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,SAAS,CAAA;AAEhB,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,SAAS,CAAA;AAKhB,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,mBAAmB,CAAA;AAK1B,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACrF,YAAY,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAK7G,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,YAAY,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAKvD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AAKnB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,mBAAmB,CAAA;AAK1B,OAAO,EACL,QAAQ,EACR,UAAU,EACV,aAAa,EACb,QAAQ,EACR,OAAO,EACP,aAAa,EACb,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,eAAe,GAChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,EACL,WAAW,EACX,eAAe,EACf,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,OAAO,CAAA;AAKd,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAKzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llms/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,YAAY,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,SAAS,CAAA;AAEhB,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,SAAS,CAAA;AAKhB,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,mBAAmB,CAAA;AAK1B,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACrF,YAAY,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAK7G,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,YAAY,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAA;AAC5E,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAKvD,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AAKnB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,mBAAmB,CAAA;AAK1B,OAAO,EACL,QAAQ,EACR,UAAU,EACV,aAAa,EACb,QAAQ,EACR,OAAO,EACP,aAAa,EACb,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,eAAe,GAChB,MAAM,iBAAiB,CAAA;AAKxB,OAAO,EACL,WAAW,EACX,eAAe,EACf,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,OAAO,CAAA;AAKd,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAKzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,+BAA+B,EAC/B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA"}
|