@sonordev/site-kit 4.1.0 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manifest.json +6 -1
- package/dist/AnalyticsProvider-4BQIFRWP.js +31 -0
- package/dist/{AnalyticsProvider-G5P5RQOA.js.map → AnalyticsProvider-4BQIFRWP.js.map} +1 -1
- package/dist/AnalyticsProvider-EQSG7FGL.mjs +10 -0
- package/dist/{AnalyticsProvider-NGQLQL5N.mjs.map → AnalyticsProvider-EQSG7FGL.mjs.map} +1 -1
- package/dist/ChatWidget-EXJD6YVW.js +20 -0
- package/dist/{ChatWidget-AYKZBKJH.js.map → ChatWidget-EXJD6YVW.js.map} +1 -1
- package/dist/ChatWidget-ZTKWIKXR.mjs +11 -0
- package/dist/{ChatWidget-LPFHRK7U.mjs.map → ChatWidget-ZTKWIKXR.mjs.map} +1 -1
- package/dist/EngageWidget-BJLSXG2V.mjs +9 -0
- package/dist/{EngageWidget-KDE7BYAK.mjs.map → EngageWidget-BJLSXG2V.mjs.map} +1 -1
- package/dist/EngageWidget-HY523XM4.js +18 -0
- package/dist/{EngageWidget-HKPAJAMR.js.map → EngageWidget-HY523XM4.js.map} +1 -1
- package/dist/{FileField-SU4HTY4F.mjs → FileField-5U4FYTLN.mjs} +5 -5
- package/dist/{FileField-SU4HTY4F.mjs.map → FileField-5U4FYTLN.mjs.map} +1 -1
- package/dist/{FileField-DDDNSRMR.js → FileField-FV46FKRM.js} +6 -6
- package/dist/{FileField-DDDNSRMR.js.map → FileField-FV46FKRM.js.map} +1 -1
- package/dist/{FormSpotlight-M4S57VC6.js → FormSpotlight-TUHLSY3O.js} +15 -15
- package/dist/{FormSpotlight-M4S57VC6.js.map → FormSpotlight-TUHLSY3O.js.map} +1 -1
- package/dist/{FormSpotlight-B6TJPNYN.mjs → FormSpotlight-W6BNVKNN.mjs} +3 -3
- package/dist/{FormSpotlight-B6TJPNYN.mjs.map → FormSpotlight-W6BNVKNN.mjs.map} +1 -1
- package/dist/{FormStage-2ASJGNOX.js → FormStage-MNXNKSPP.js} +13 -13
- package/dist/{FormStage-2ASJGNOX.js.map → FormStage-MNXNKSPP.js.map} +1 -1
- package/dist/{FormStage-GH7SA6FQ.mjs → FormStage-NKWP3C2S.mjs} +3 -3
- package/dist/{FormStage-GH7SA6FQ.mjs.map → FormStage-NKWP3C2S.mjs.map} +1 -1
- package/dist/ManagedForm-K4UHRVYV.js +23 -0
- package/dist/{ManagedForm-D2JT3QV3.js.map → ManagedForm-K4UHRVYV.js.map} +1 -1
- package/dist/ManagedForm-M3XW66FH.mjs +14 -0
- package/dist/{ManagedForm-RCC7NEV2.mjs.map → ManagedForm-M3XW66FH.mjs.map} +1 -1
- package/dist/{SignalCore-7H4ZGFZO.js → SignalCore-7PVCUG2S.js} +11 -11
- package/dist/{SignalCore-7H4ZGFZO.js.map → SignalCore-7PVCUG2S.js.map} +1 -1
- package/dist/{SignalCore-36PY3SRB.mjs → SignalCore-S6PCGTHS.mjs} +5 -5
- package/dist/{SignalCore-36PY3SRB.mjs.map → SignalCore-S6PCGTHS.mjs.map} +1 -1
- package/dist/SitemapSync-2HLGUZES.mjs +8 -0
- package/dist/{SitemapSync-HKAG3JU3.mjs.map → SitemapSync-2HLGUZES.mjs.map} +1 -1
- package/dist/SitemapSync-66HQ4SG2.js +17 -0
- package/dist/{SitemapSync-AYVBNCH4.js.map → SitemapSync-66HQ4SG2.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- package/dist/{chunk-7JES77WC.mjs → chunk-2GUDSTNH.mjs} +89 -20
- package/dist/chunk-2GUDSTNH.mjs.map +1 -0
- package/dist/{chunk-LAWESLXJ.js → chunk-2LU7BV5K.js} +29 -19
- package/dist/chunk-2LU7BV5K.js.map +1 -0
- package/dist/{chunk-UTANIZUO.js → chunk-3BXQP54K.js} +3 -3
- package/dist/{chunk-UTANIZUO.js.map → chunk-3BXQP54K.js.map} +1 -1
- package/dist/{chunk-FNOCLT4A.mjs → chunk-4E7NFYL5.mjs} +3 -3
- package/dist/{chunk-FNOCLT4A.mjs.map → chunk-4E7NFYL5.mjs.map} +1 -1
- package/dist/{chunk-HK33JRWA.js → chunk-4MBD6PPV.js} +15 -15
- package/dist/{chunk-HK33JRWA.js.map → chunk-4MBD6PPV.js.map} +1 -1
- package/dist/{chunk-WJJQWAG2.mjs → chunk-4SJITKBL.mjs} +3 -3
- package/dist/{chunk-WJJQWAG2.mjs.map → chunk-4SJITKBL.mjs.map} +1 -1
- package/dist/{chunk-SEH2K6NG.js → chunk-524SIFK7.js} +13 -13
- package/dist/chunk-524SIFK7.js.map +1 -0
- package/dist/{chunk-MKQZVTD3.js → chunk-55FJN7VQ.js} +6 -6
- package/dist/{chunk-MKQZVTD3.js.map → chunk-55FJN7VQ.js.map} +1 -1
- package/dist/{chunk-DCITIONV.js → chunk-645TOMKQ.js} +4 -4
- package/dist/{chunk-DCITIONV.js.map → chunk-645TOMKQ.js.map} +1 -1
- package/dist/{chunk-MXPGAJLM.mjs → chunk-7723NZQW.mjs} +4 -4
- package/dist/{chunk-MXPGAJLM.mjs.map → chunk-7723NZQW.mjs.map} +1 -1
- package/dist/{chunk-2IH5FM2A.js → chunk-7YVFFQWH.js} +14 -14
- package/dist/{chunk-2IH5FM2A.js.map → chunk-7YVFFQWH.js.map} +1 -1
- package/dist/chunk-AAZNH3MA.mjs +23 -0
- package/dist/chunk-AAZNH3MA.mjs.map +1 -0
- package/dist/{chunk-7CYSA5EN.mjs → chunk-BEHHWRZM.mjs} +3 -3
- package/dist/{chunk-7CYSA5EN.mjs.map → chunk-BEHHWRZM.mjs.map} +1 -1
- package/dist/{chunk-3GJBSUVS.js → chunk-BUZSBUYJ.js} +14 -14
- package/dist/{chunk-3GJBSUVS.js.map → chunk-BUZSBUYJ.js.map} +1 -1
- package/dist/chunk-CIM5W3UO.js +26 -0
- package/dist/chunk-CIM5W3UO.js.map +1 -0
- package/dist/{chunk-4ROQDPUE.mjs → chunk-CM5QUX2T.mjs} +3 -3
- package/dist/{chunk-4ROQDPUE.mjs.map → chunk-CM5QUX2T.mjs.map} +1 -1
- package/dist/{chunk-XCCMVJUA.mjs → chunk-D6CPHVMV.mjs} +3 -3
- package/dist/{chunk-XCCMVJUA.mjs.map → chunk-D6CPHVMV.mjs.map} +1 -1
- package/dist/{chunk-L6WWNP2N.js → chunk-DEPDYVUH.js} +5 -5
- package/dist/{chunk-L6WWNP2N.js.map → chunk-DEPDYVUH.js.map} +1 -1
- package/dist/{chunk-VOYLJCHB.js → chunk-F46DCSUI.js} +9 -9
- package/dist/{chunk-VOYLJCHB.js.map → chunk-F46DCSUI.js.map} +1 -1
- package/dist/{chunk-LRHECSZK.js → chunk-HYRKVST7.js} +14 -14
- package/dist/{chunk-LRHECSZK.js.map → chunk-HYRKVST7.js.map} +1 -1
- package/dist/chunk-JA77WXRE.js +30 -0
- package/dist/chunk-JA77WXRE.js.map +1 -0
- package/dist/{chunk-UDHQNYBD.mjs → chunk-K7XOPTOE.mjs} +4 -4
- package/dist/{chunk-UDHQNYBD.mjs.map → chunk-K7XOPTOE.mjs.map} +1 -1
- package/dist/{chunk-S4U44UUD.mjs → chunk-KJSYSRMD.mjs} +3 -3
- package/dist/{chunk-S4U44UUD.mjs.map → chunk-KJSYSRMD.mjs.map} +1 -1
- package/dist/{chunk-A4E6EOU4.mjs → chunk-L4ZLL6TE.mjs} +4 -4
- package/dist/{chunk-A4E6EOU4.mjs.map → chunk-L4ZLL6TE.mjs.map} +1 -1
- package/dist/{chunk-XRQ47XDA.js → chunk-LSW5QBW2.js} +4 -4
- package/dist/{chunk-XRQ47XDA.js.map → chunk-LSW5QBW2.js.map} +1 -1
- package/dist/{chunk-5GAOZTMW.mjs → chunk-MOKM6STG.mjs} +3 -3
- package/dist/{chunk-5GAOZTMW.mjs.map → chunk-MOKM6STG.mjs.map} +1 -1
- package/dist/chunk-NPCWPOCE.mjs +6 -0
- package/dist/{chunk-PKCEJWLD.mjs.map → chunk-NPCWPOCE.mjs.map} +1 -1
- package/dist/{chunk-5JFJJNWS.js → chunk-OB6DNGYK.js} +97 -28
- package/dist/chunk-OB6DNGYK.js.map +1 -0
- package/dist/{chunk-FJ5EMPCK.mjs → chunk-P37FFMOZ.mjs} +9 -9
- package/dist/chunk-P37FFMOZ.mjs.map +1 -0
- package/dist/{chunk-O554YMPI.js → chunk-PLY5AP72.js} +3 -3
- package/dist/{chunk-O554YMPI.js.map → chunk-PLY5AP72.js.map} +1 -1
- package/dist/{chunk-ZDXGB3UC.js → chunk-QQFWEHYU.js} +4 -4
- package/dist/{chunk-ZDXGB3UC.js.map → chunk-QQFWEHYU.js.map} +1 -1
- package/dist/chunk-QZF5NTXQ.mjs +28 -0
- package/dist/chunk-QZF5NTXQ.mjs.map +1 -0
- package/dist/{chunk-G7IMEY5T.mjs → chunk-SED7E3P5.mjs} +4 -4
- package/dist/{chunk-G7IMEY5T.mjs.map → chunk-SED7E3P5.mjs.map} +1 -1
- package/dist/{chunk-GJVC7KKL.mjs → chunk-SS5S43I4.mjs} +18 -8
- package/dist/chunk-SS5S43I4.mjs.map +1 -0
- package/dist/{chunk-VJAUA77N.js → chunk-THBZCEA7.js} +5 -5
- package/dist/{chunk-VJAUA77N.js.map → chunk-THBZCEA7.js.map} +1 -1
- package/dist/{chunk-NTFLRRTQ.js → chunk-TWPLJ27S.js} +7 -7
- package/dist/{chunk-NTFLRRTQ.js.map → chunk-TWPLJ27S.js.map} +1 -1
- package/dist/{chunk-FQ4BDJXG.js → chunk-UEOGMRTL.js} +8 -8
- package/dist/{chunk-FQ4BDJXG.js.map → chunk-UEOGMRTL.js.map} +1 -1
- package/dist/{chunk-NSIRG3C3.js → chunk-UF33ENG6.js} +3 -3
- package/dist/{chunk-NSIRG3C3.js.map → chunk-UF33ENG6.js.map} +1 -1
- package/dist/{chunk-WNUUVBD7.js → chunk-UIKGLLTU.js} +4 -4
- package/dist/{chunk-WNUUVBD7.js.map → chunk-UIKGLLTU.js.map} +1 -1
- package/dist/chunk-UUBW2NJZ.js +8 -0
- package/dist/{chunk-R35CW6MM.js.map → chunk-UUBW2NJZ.js.map} +1 -1
- package/dist/{chunk-2RJ5UHAC.mjs → chunk-W3QLA5MI.mjs} +3 -3
- package/dist/{chunk-2RJ5UHAC.mjs.map → chunk-W3QLA5MI.mjs.map} +1 -1
- package/dist/{chunk-VPBLW4ZN.mjs → chunk-WARTV6ZP.mjs} +4 -4
- package/dist/{chunk-VPBLW4ZN.mjs.map → chunk-WARTV6ZP.mjs.map} +1 -1
- package/dist/{chunk-QYLGVXRX.mjs → chunk-WHHBOYAW.mjs} +4 -4
- package/dist/{chunk-QYLGVXRX.mjs.map → chunk-WHHBOYAW.mjs.map} +1 -1
- package/dist/{chunk-DBZU2TRZ.mjs → chunk-WNK2OK5G.mjs} +3 -3
- package/dist/{chunk-DBZU2TRZ.mjs.map → chunk-WNK2OK5G.mjs.map} +1 -1
- package/dist/{chunk-FYPA5GLS.js → chunk-XBKNPBRB.js} +15 -15
- package/dist/{chunk-FYPA5GLS.js.map → chunk-XBKNPBRB.js.map} +1 -1
- package/dist/{chunk-TH2ANDPK.mjs → chunk-XFVI3SNM.mjs} +3 -3
- package/dist/{chunk-TH2ANDPK.mjs.map → chunk-XFVI3SNM.mjs.map} +1 -1
- package/dist/{chunk-DAGLPS6P.js → chunk-XMZQUC2J.js} +8 -8
- package/dist/{chunk-DAGLPS6P.js.map → chunk-XMZQUC2J.js.map} +1 -1
- package/dist/{chunk-ANTVZSQI.mjs → chunk-YN5WYGHK.mjs} +3 -3
- package/dist/{chunk-ANTVZSQI.mjs.map → chunk-YN5WYGHK.mjs.map} +1 -1
- package/dist/{chunk-LMKDQCU7.mjs → chunk-YV2TG7JR.mjs} +3 -3
- package/dist/{chunk-LMKDQCU7.mjs.map → chunk-YV2TG7JR.mjs.map} +1 -1
- package/dist/{chunk-D7IY27X5.mjs → chunk-ZXVMP6SY.mjs} +3 -3
- package/dist/{chunk-D7IY27X5.mjs.map → chunk-ZXVMP6SY.mjs.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 +56 -56
- package/dist/commerce/index.mjs +5 -5
- package/dist/engage/index.js +10 -10
- package/dist/engage/index.mjs +7 -7
- package/dist/fleet/index.js +8 -8
- package/dist/fleet/index.mjs +4 -4
- package/dist/forms/ManagedForm.d.ts.map +1 -1
- package/dist/forms/index.js +16 -16
- package/dist/forms/index.mjs +9 -9
- package/dist/forms/server.js +10 -10
- package/dist/forms/server.mjs +8 -8
- package/dist/forms/static.js +7 -7
- package/dist/forms/static.mjs +6 -6
- package/dist/forms/tracking-session.d.ts +63 -0
- package/dist/forms/tracking-session.d.ts.map +1 -0
- package/dist/forms/tracking-session.test.d.ts +22 -0
- package/dist/forms/tracking-session.test.d.ts.map +1 -0
- package/dist/forms/useForm.d.ts +11 -0
- package/dist/forms/useForm.d.ts.map +1 -1
- package/dist/forms/useFormTracking.d.ts +6 -1
- package/dist/forms/useFormTracking.d.ts.map +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +67 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -10
- package/dist/index.mjs.map +1 -1
- package/dist/landing/index.d.ts +12 -0
- package/dist/landing/index.d.ts.map +1 -1
- package/dist/landing/index.js +5 -4
- package/dist/landing/index.mjs +2 -1
- package/dist/landing/server-entry.test.d.ts +2 -0
- package/dist/landing/server-entry.test.d.ts.map +1 -0
- package/dist/landing/server.d.ts +32 -0
- package/dist/landing/server.d.ts.map +1 -0
- package/dist/landing/server.js +17 -0
- package/dist/landing/server.js.map +1 -0
- package/dist/landing/server.mjs +4 -0
- package/dist/landing/server.mjs.map +1 -0
- package/dist/layout/SiteKitClientProviders.d.ts +7 -0
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/SiteKitLayout.d.ts +18 -1
- package/dist/layout/SiteKitLayout.d.ts.map +1 -1
- package/dist/layout/client.d.ts +7 -0
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +8 -8
- package/dist/layout/client.mjs +7 -7
- package/dist/layout/index.js +11 -11
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +9 -9
- package/dist/layout/index.mjs.map +1 -1
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +5 -5
- package/dist/seo/index.mjs +4 -4
- 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/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sync/index.js +16 -16
- package/dist/sync/index.mjs +4 -4
- package/dist/types.d.ts +5 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -3
- package/dist/AnalyticsProvider-G5P5RQOA.js +0 -31
- package/dist/AnalyticsProvider-NGQLQL5N.mjs +0 -10
- package/dist/ChatWidget-AYKZBKJH.js +0 -20
- package/dist/ChatWidget-LPFHRK7U.mjs +0 -11
- package/dist/EngageWidget-HKPAJAMR.js +0 -18
- package/dist/EngageWidget-KDE7BYAK.mjs +0 -9
- package/dist/ManagedForm-D2JT3QV3.js +0 -23
- package/dist/ManagedForm-RCC7NEV2.mjs +0 -14
- package/dist/SitemapSync-AYVBNCH4.js +0 -17
- package/dist/SitemapSync-HKAG3JU3.mjs +0 -8
- package/dist/chunk-5JFJJNWS.js.map +0 -1
- package/dist/chunk-7JES77WC.mjs.map +0 -1
- package/dist/chunk-EU2UGO25.js +0 -52
- package/dist/chunk-EU2UGO25.js.map +0 -1
- package/dist/chunk-FJ5EMPCK.mjs.map +0 -1
- package/dist/chunk-GJVC7KKL.mjs.map +0 -1
- package/dist/chunk-IBMOX3YE.mjs +0 -48
- package/dist/chunk-IBMOX3YE.mjs.map +0 -1
- package/dist/chunk-LAWESLXJ.js.map +0 -1
- package/dist/chunk-PKCEJWLD.mjs +0 -6
- package/dist/chunk-R35CW6MM.js +0 -8
- package/dist/chunk-SEH2K6NG.js.map +0 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/landing/contract.ts
|
|
2
|
+
function normalizeCampaignSlug(input) {
|
|
3
|
+
if (!input || typeof input !== "string") return null;
|
|
4
|
+
const slug = input.trim().toLowerCase().replace(/[\s_]+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
5
|
+
return slug || null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/landing/metadata.ts
|
|
9
|
+
function landingPageMetadata(meta = {}) {
|
|
10
|
+
const callerRobots = meta.robots && typeof meta.robots === "object" ? meta.robots : void 0;
|
|
11
|
+
return {
|
|
12
|
+
...meta,
|
|
13
|
+
robots: {
|
|
14
|
+
index: false,
|
|
15
|
+
follow: false,
|
|
16
|
+
...callerRobots
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { landingPageMetadata, normalizeCampaignSlug };
|
|
22
|
+
//# sourceMappingURL=chunk-AAZNH3MA.mjs.map
|
|
23
|
+
//# sourceMappingURL=chunk-AAZNH3MA.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/landing/contract.ts","../src/landing/metadata.ts"],"names":[],"mappings":";AAaO,SAAS,sBAAsB,KAAA,EAAsC;AAC1E,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAU,OAAO,IAAA;AAChD,EAAA,MAAM,IAAA,GAAO,KAAA,CACV,IAAA,EAAK,CACL,WAAA,GACA,OAAA,CAAQ,SAAA,EAAW,GAAG,CAAA,CACtB,OAAA,CAAQ,aAAA,EAAe,EAAE,CAAA,CACzB,OAAA,CAAQ,QAAA,EAAU,GAAG,CAAA,CACrB,OAAA,CAAQ,YAAY,EAAE,CAAA,CACtB,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACd,EAAA,OAAO,IAAA,IAAQ,IAAA;AACjB;;;ACNO,SAAS,mBAAA,CAAoB,IAAA,GAAiB,EAAC,EAAa;AACjE,EAAA,MAAM,YAAA,GACJ,KAAK,MAAA,IAAU,OAAO,KAAK,MAAA,KAAW,QAAA,GAAW,KAAK,MAAA,GAAS,MAAA;AACjE,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,MAAA,EAAQ;AAAA,MACN,KAAA,EAAO,KAAA;AAAA,MACP,MAAA,EAAQ,KAAA;AAAA,MACR,GAAG;AAAA;AACL,GACF;AACF","file":"chunk-AAZNH3MA.mjs","sourcesContent":["/**\n * Landing-page campaign contract.\n *\n * normalizeCampaignSlug is an inlined MIRROR of sonor-api's\n * `src/modules/analytics/utils/campaign.util.ts` (the CANONICAL copy) —\n * keep the function body byte-identical. Both suites assert the same fixed\n * vectors (sonor-api's campaign.util.spec.ts and this package's\n * landing/contract.test.ts), so silent drift fails CI on either side.\n *\n * A slug normalized here always matches the server's canonical form, so the\n * campaign a developer declares in code is exactly the identity the\n * dashboard reports on.\n */\nexport function normalizeCampaignSlug(input?: string | null): string | null {\n if (!input || typeof input !== 'string') return null\n const slug = input\n .trim()\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^a-z0-9-]/g, '')\n .replace(/-{2,}/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80)\n return slug || null\n}\n","import type { Metadata } from 'next'\n\n/**\n * Metadata for a paid-ad landing page: noindex, nofollow by default.\n *\n * This is the RELIABLE noindex mechanism — export it from the landing\n * route so the robots directives render in <head> at SSR:\n *\n * export const metadata = landingPageMetadata({\n * title: 'Spring HVAC Tune-Up | Acme Heating',\n * description: 'Book your $99 spring tune-up.',\n * })\n *\n * The <LandingPage> wrapper also hoists a robots meta tag as belt-and-braces,\n * but body-rendered meta is not honored by all crawlers — always use this\n * helper too. Pass an explicit `robots` object to override the default\n * (e.g. a landing page you deliberately want indexed).\n */\nexport function landingPageMetadata(meta: Metadata = {}): Metadata {\n const callerRobots =\n meta.robots && typeof meta.robots === 'object' ? meta.robots : undefined\n return {\n ...meta,\n robots: {\n index: false,\n follow: false,\n ...callerRobots,\n },\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SITE_KIT_VERSION } from './chunk-
|
|
1
|
+
import { SITE_KIT_VERSION } from './chunk-NPCWPOCE.mjs';
|
|
2
2
|
|
|
3
3
|
// src/shared/siteToken.ts
|
|
4
4
|
var SITE_TOKEN_PREFIX = "st1.";
|
|
@@ -146,5 +146,5 @@ function currentCredential(seed) {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export { configureSiteCredential, credentialBreakerId, currentCredential, getFreshCredential, isSiteToken, isTokenMode, refreshSiteToken };
|
|
149
|
-
//# sourceMappingURL=chunk-
|
|
150
|
-
//# sourceMappingURL=chunk-
|
|
149
|
+
//# sourceMappingURL=chunk-BEHHWRZM.mjs.map
|
|
150
|
+
//# sourceMappingURL=chunk-BEHHWRZM.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/siteToken.ts"],"names":[],"mappings":"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","file":"chunk-7CYSA5EN.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared — Client token manager\n *\n * SiteKitLayout (a server component) no longer ships the raw `sonor_` API key to\n * the browser. Instead it mints a short-lived, project-scoped token server-side\n * and injects THAT. This module is the browser-side lifecycle for that token:\n *\n * - holds the current token (seeded from the injected value)\n * - a static page's seed can be days old and already expired on first view, so\n * it transparently REFRESHES via the public endpoint before first use\n * - dedupes concurrent refreshes (one in-flight request, awaited by all)\n * - persists the freshest token in sessionStorage so navigations within a\n * session don't each re-refresh\n *\n * Everything here is a no-op passthrough when the injected credential is a raw\n * key (a 2.x kit, or the mint-failed fallback) — legacy behavior is unchanged.\n * Fully SSR-safe: on the server there is no refresh, just the seed.\n *\n * The token payload is NOT secret (only its HMAC is unforgeable), so decoding it\n * client-side to read `exp`/`pid` is fine and needs no crypto.\n */\nimport { SITE_KIT_VERSION } from './version'\n\nexport const SITE_TOKEN_PREFIX = 'st1.'\n\n/** Refresh this many ms before expiry, so a request never races the deadline. */\nconst REFRESH_SKEW_MS = 5 * 60_000\nconst REFRESH_TIMEOUT_MS = 6_000\nconst STORAGE_KEY = '__sonor_site_token__'\n\nexport function isSiteToken(credential?: string | null): boolean {\n return typeof credential === 'string' && credential.startsWith(SITE_TOKEN_PREFIX)\n}\n\ninterface DecodedClaims {\n pid?: string\n iat?: number\n exp?: number\n}\n\n/** Decode the (non-secret) token payload. Returns null if not a token / malformed. */\nexport function decodeSiteTokenClaims(token?: string | null): DecodedClaims | null {\n if (!isSiteToken(token)) return null\n const seg = (token as string).split('.')[1]\n if (!seg) return null\n try {\n // base64url → JSON. atob handles standard base64; restore url-safe chars.\n const b64 = seg.replace(/-/g, '+').replace(/_/g, '/')\n const json =\n typeof atob === 'function'\n ? atob(b64)\n : Buffer.from(seg, 'base64url').toString('utf8')\n const claims = JSON.parse(json)\n return typeof claims === 'object' && claims ? claims : null\n } catch {\n return null\n }\n}\n\n/**\n * Stable id for the auth circuit breaker. Tokens rotate, so keying the breaker\n * by the raw value would reset it every refresh — key by the project id encoded\n * in the token instead. Raw keys use a safe prefix.\n */\nexport function credentialBreakerId(credential?: string | null): string {\n if (!credential) return '(anonymous)'\n const claims = decodeSiteTokenClaims(credential)\n if (claims?.pid) return `pid:${claims.pid}`\n return credential.slice(0, 16)\n}\n\ninterface TokenState {\n /** The credential injected by the layout (token or raw key). */\n seed: string | undefined\n /** Whether we're in token mode (seed is a token). */\n isToken: boolean\n /** Base API URL for the refresh endpoint. */\n apiUrl: string\n /** The freshest known token (>= seed). Null in raw-key mode. */\n token: string | null\n /** In-flight refresh, deduped. */\n refreshing: Promise<string | null> | null\n}\n\nfunction initialTokenState(): TokenState {\n return {\n seed: undefined,\n isToken: false,\n apiUrl: 'https://api.sonor.io',\n token: null,\n refreshing: null,\n }\n}\n\n/**\n * Page-wide singleton, keyed on window. Bundlers can (and in the field, do)\n * inline more than one copy of this module into a page — e.g. an app importing\n * site-kit directly while a transpiled component library bundles its own copy.\n * Module-scoped state then splits into per-copy brains: one copy gets\n * configured and refreshes fine while the other keeps sending the stale\n * prerendered seed, 401s, and trips its breaker (\"sonor-auth-paused\" with a\n * working network). Sharing the state object on window gives every copy the\n * same token, the same deduped refresh, and the same breaker. On the server\n * (no window) each module instance keeps private state — there's no refresh\n * lifecycle there anyway.\n */\nconst TOKEN_STATE_KEY = '__SONOR_SITE_TOKEN_STATE__'\n\nconst state: TokenState = (() => {\n if (typeof window === 'undefined') return initialTokenState()\n const w = window as unknown as Record<string, TokenState | undefined>\n return (w[TOKEN_STATE_KEY] ??= initialTokenState())\n})()\n\nfunction readStoredToken(): string | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n return typeof parsed?.token === 'string' ? parsed.token : null\n } catch {\n return null\n }\n}\n\nfunction storeToken(token: string): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ token }))\n } catch {\n /* private mode / disabled storage — memory-only is fine */\n }\n try {\n ;(window as any).__SITE_KIT_API_KEY__ = token\n } catch {\n /* ignore */\n }\n}\n\nfunction tokenExp(token: string | null): number {\n const claims = decodeSiteTokenClaims(token)\n return typeof claims?.exp === 'number' ? claims.exp * 1000 : 0\n}\n\n/**\n * Configure the manager from the layout-injected values. Adopts a fresher token\n * from sessionStorage if a prior page in this session already refreshed.\n */\nexport function configureSiteCredential(opts: {\n credential?: string\n apiUrl?: string\n}): void {\n state.seed = opts.credential\n state.isToken = isSiteToken(opts.credential)\n if (opts.apiUrl) state.apiUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n if (!state.isToken) {\n state.token = null\n return\n }\n\n // configure runs on every render — never downgrade. Keep the freshest of the\n // injected seed, a token stored by an earlier page this session, and whatever\n // an in-flight/prior refresh already put in memory.\n const prior = state.token\n let best = opts.credential ?? null\n const stored = readStoredToken()\n if (stored && tokenExp(stored) > tokenExp(best)) best = stored\n if (prior && tokenExp(prior) > tokenExp(best)) best = prior\n state.token = best\n}\n\nfunction needsRefresh(): boolean {\n if (!state.isToken) return false\n if (!state.token) return true\n return Date.now() >= tokenExp(state.token) - REFRESH_SKEW_MS\n}\n\nasync function doRefresh(): Promise<string | null> {\n const current = state.token\n if (!current) return null\n try {\n const res = await fetch(`${state.apiUrl}/api/public/site-token/refresh`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n // Send the current token as x-api-key too, so the server's key-scoped\n // throttler buckets refreshes by token rather than by shared CDN IP.\n 'x-api-key': current,\n },\n body: JSON.stringify({ token: current }),\n signal:\n typeof AbortSignal !== 'undefined' && AbortSignal.timeout\n ? AbortSignal.timeout(REFRESH_TIMEOUT_MS)\n : undefined,\n })\n if (!res.ok) return null\n const data = await res.json().catch(() => null)\n const next = data?.token\n if (typeof next === 'string' && isSiteToken(next)) {\n state.token = next\n storeToken(next)\n return next\n }\n return null\n } catch {\n return null\n }\n}\n\n/** Refresh now (deduped). Returns the new token, or null on failure. */\nexport function refreshSiteToken(): Promise<string | null> {\n if (!state.isToken) return Promise.resolve(null)\n if (state.refreshing) return state.refreshing\n state.refreshing = doRefresh().finally(() => {\n state.refreshing = null\n })\n return state.refreshing\n}\n\n/**\n * The credential to put on the next request. In token mode, refreshes a stale\n * seed first. In raw-key mode, returns the seed unchanged (legacy passthrough).\n */\nexport async function getFreshCredential(\n seed?: string,\n): Promise<string | undefined> {\n // Unconfigured but handed a token (a component received the prerendered seed\n // as a prop before any provider configured the manager): adopt it so the\n // refresh machinery works instead of replaying a possibly-expired seed.\n if (!state.isToken && isSiteToken(seed)) {\n configureSiteCredential({ credential: seed })\n }\n // A raw key (or nothing configured) — no token machinery.\n if (!state.isToken) return seed ?? state.seed\n if (needsRefresh()) {\n const refreshed = await refreshSiteToken()\n if (refreshed) return refreshed\n // Refresh failed — fall through to whatever we have; the request may 401 and\n // trip the breaker with friendly copy.\n }\n return state.token ?? seed ?? state.seed\n}\n\n/** Whether the given credential is being managed as a token. */\nexport function isTokenMode(): boolean {\n return state.isToken\n}\n\n/**\n * Best-known credential WITHOUT refreshing — for synchronous unload paths\n * (sonorBeacon) that can't await. In token mode returns the freshest token held;\n * in raw-key mode returns the seed.\n */\nexport function currentCredential(seed?: string): string | undefined {\n if (!state.isToken) return seed ?? state.seed\n return state.token ?? seed ?? state.seed\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/shared/siteToken.ts"],"names":[],"mappings":"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","file":"chunk-BEHHWRZM.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared — Client token manager\n *\n * SiteKitLayout (a server component) no longer ships the raw `sonor_` API key to\n * the browser. Instead it mints a short-lived, project-scoped token server-side\n * and injects THAT. This module is the browser-side lifecycle for that token:\n *\n * - holds the current token (seeded from the injected value)\n * - a static page's seed can be days old and already expired on first view, so\n * it transparently REFRESHES via the public endpoint before first use\n * - dedupes concurrent refreshes (one in-flight request, awaited by all)\n * - persists the freshest token in sessionStorage so navigations within a\n * session don't each re-refresh\n *\n * Everything here is a no-op passthrough when the injected credential is a raw\n * key (a 2.x kit, or the mint-failed fallback) — legacy behavior is unchanged.\n * Fully SSR-safe: on the server there is no refresh, just the seed.\n *\n * The token payload is NOT secret (only its HMAC is unforgeable), so decoding it\n * client-side to read `exp`/`pid` is fine and needs no crypto.\n */\nimport { SITE_KIT_VERSION } from './version'\n\nexport const SITE_TOKEN_PREFIX = 'st1.'\n\n/** Refresh this many ms before expiry, so a request never races the deadline. */\nconst REFRESH_SKEW_MS = 5 * 60_000\nconst REFRESH_TIMEOUT_MS = 6_000\nconst STORAGE_KEY = '__sonor_site_token__'\n\nexport function isSiteToken(credential?: string | null): boolean {\n return typeof credential === 'string' && credential.startsWith(SITE_TOKEN_PREFIX)\n}\n\ninterface DecodedClaims {\n pid?: string\n iat?: number\n exp?: number\n}\n\n/** Decode the (non-secret) token payload. Returns null if not a token / malformed. */\nexport function decodeSiteTokenClaims(token?: string | null): DecodedClaims | null {\n if (!isSiteToken(token)) return null\n const seg = (token as string).split('.')[1]\n if (!seg) return null\n try {\n // base64url → JSON. atob handles standard base64; restore url-safe chars.\n const b64 = seg.replace(/-/g, '+').replace(/_/g, '/')\n const json =\n typeof atob === 'function'\n ? atob(b64)\n : Buffer.from(seg, 'base64url').toString('utf8')\n const claims = JSON.parse(json)\n return typeof claims === 'object' && claims ? claims : null\n } catch {\n return null\n }\n}\n\n/**\n * Stable id for the auth circuit breaker. Tokens rotate, so keying the breaker\n * by the raw value would reset it every refresh — key by the project id encoded\n * in the token instead. Raw keys use a safe prefix.\n */\nexport function credentialBreakerId(credential?: string | null): string {\n if (!credential) return '(anonymous)'\n const claims = decodeSiteTokenClaims(credential)\n if (claims?.pid) return `pid:${claims.pid}`\n return credential.slice(0, 16)\n}\n\ninterface TokenState {\n /** The credential injected by the layout (token or raw key). */\n seed: string | undefined\n /** Whether we're in token mode (seed is a token). */\n isToken: boolean\n /** Base API URL for the refresh endpoint. */\n apiUrl: string\n /** The freshest known token (>= seed). Null in raw-key mode. */\n token: string | null\n /** In-flight refresh, deduped. */\n refreshing: Promise<string | null> | null\n}\n\nfunction initialTokenState(): TokenState {\n return {\n seed: undefined,\n isToken: false,\n apiUrl: 'https://api.sonor.io',\n token: null,\n refreshing: null,\n }\n}\n\n/**\n * Page-wide singleton, keyed on window. Bundlers can (and in the field, do)\n * inline more than one copy of this module into a page — e.g. an app importing\n * site-kit directly while a transpiled component library bundles its own copy.\n * Module-scoped state then splits into per-copy brains: one copy gets\n * configured and refreshes fine while the other keeps sending the stale\n * prerendered seed, 401s, and trips its breaker (\"sonor-auth-paused\" with a\n * working network). Sharing the state object on window gives every copy the\n * same token, the same deduped refresh, and the same breaker. On the server\n * (no window) each module instance keeps private state — there's no refresh\n * lifecycle there anyway.\n */\nconst TOKEN_STATE_KEY = '__SONOR_SITE_TOKEN_STATE__'\n\nconst state: TokenState = (() => {\n if (typeof window === 'undefined') return initialTokenState()\n const w = window as unknown as Record<string, TokenState | undefined>\n return (w[TOKEN_STATE_KEY] ??= initialTokenState())\n})()\n\nfunction readStoredToken(): string | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n return typeof parsed?.token === 'string' ? parsed.token : null\n } catch {\n return null\n }\n}\n\nfunction storeToken(token: string): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ token }))\n } catch {\n /* private mode / disabled storage — memory-only is fine */\n }\n try {\n ;(window as any).__SITE_KIT_API_KEY__ = token\n } catch {\n /* ignore */\n }\n}\n\nfunction tokenExp(token: string | null): number {\n const claims = decodeSiteTokenClaims(token)\n return typeof claims?.exp === 'number' ? claims.exp * 1000 : 0\n}\n\n/**\n * Configure the manager from the layout-injected values. Adopts a fresher token\n * from sessionStorage if a prior page in this session already refreshed.\n */\nexport function configureSiteCredential(opts: {\n credential?: string\n apiUrl?: string\n}): void {\n state.seed = opts.credential\n state.isToken = isSiteToken(opts.credential)\n if (opts.apiUrl) state.apiUrl = opts.apiUrl.replace(/\\/+$/, '')\n\n if (!state.isToken) {\n state.token = null\n return\n }\n\n // configure runs on every render — never downgrade. Keep the freshest of the\n // injected seed, a token stored by an earlier page this session, and whatever\n // an in-flight/prior refresh already put in memory.\n const prior = state.token\n let best = opts.credential ?? null\n const stored = readStoredToken()\n if (stored && tokenExp(stored) > tokenExp(best)) best = stored\n if (prior && tokenExp(prior) > tokenExp(best)) best = prior\n state.token = best\n}\n\nfunction needsRefresh(): boolean {\n if (!state.isToken) return false\n if (!state.token) return true\n return Date.now() >= tokenExp(state.token) - REFRESH_SKEW_MS\n}\n\nasync function doRefresh(): Promise<string | null> {\n const current = state.token\n if (!current) return null\n try {\n const res = await fetch(`${state.apiUrl}/api/public/site-token/refresh`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n 'x-sitekit-version': SITE_KIT_VERSION,\n // Send the current token as x-api-key too, so the server's key-scoped\n // throttler buckets refreshes by token rather than by shared CDN IP.\n 'x-api-key': current,\n },\n body: JSON.stringify({ token: current }),\n signal:\n typeof AbortSignal !== 'undefined' && AbortSignal.timeout\n ? AbortSignal.timeout(REFRESH_TIMEOUT_MS)\n : undefined,\n })\n if (!res.ok) return null\n const data = await res.json().catch(() => null)\n const next = data?.token\n if (typeof next === 'string' && isSiteToken(next)) {\n state.token = next\n storeToken(next)\n return next\n }\n return null\n } catch {\n return null\n }\n}\n\n/** Refresh now (deduped). Returns the new token, or null on failure. */\nexport function refreshSiteToken(): Promise<string | null> {\n if (!state.isToken) return Promise.resolve(null)\n if (state.refreshing) return state.refreshing\n state.refreshing = doRefresh().finally(() => {\n state.refreshing = null\n })\n return state.refreshing\n}\n\n/**\n * The credential to put on the next request. In token mode, refreshes a stale\n * seed first. In raw-key mode, returns the seed unchanged (legacy passthrough).\n */\nexport async function getFreshCredential(\n seed?: string,\n): Promise<string | undefined> {\n // Unconfigured but handed a token (a component received the prerendered seed\n // as a prop before any provider configured the manager): adopt it so the\n // refresh machinery works instead of replaying a possibly-expired seed.\n if (!state.isToken && isSiteToken(seed)) {\n configureSiteCredential({ credential: seed })\n }\n // A raw key (or nothing configured) — no token machinery.\n if (!state.isToken) return seed ?? state.seed\n if (needsRefresh()) {\n const refreshed = await refreshSiteToken()\n if (refreshed) return refreshed\n // Refresh failed — fall through to whatever we have; the request may 401 and\n // trip the breaker with friendly copy.\n }\n return state.token ?? seed ?? state.seed\n}\n\n/** Whether the given credential is being managed as a token. */\nexport function isTokenMode(): boolean {\n return state.isToken\n}\n\n/**\n * Best-known credential WITHOUT refreshing — for synchronous unload paths\n * (sonorBeacon) that can't await. In token mode returns the freshest token held;\n * in raw-key mode returns the seed.\n */\nexport function currentCredential(seed?: string): string | undefined {\n if (!state.isToken) return seed ?? state.seed\n return state.token ?? seed ?? state.seed\n}\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var chunkHMFFAUCD_js = require('./chunk-HMFFAUCD.js');
|
|
5
5
|
var chunkRC4WWQXR_js = require('./chunk-RC4WWQXR.js');
|
|
6
|
-
var
|
|
6
|
+
var chunkXBKNPBRB_js = require('./chunk-XBKNPBRB.js');
|
|
7
7
|
var react = require('react');
|
|
8
8
|
var navigation = require('next/navigation');
|
|
9
9
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -101,10 +101,10 @@ function WebVitals({ apiUrl: propApiUrl, apiKey: propApiKey, site: propSite, deb
|
|
|
101
101
|
if (debug2) console.log("[Analytics] Web Vital:", data);
|
|
102
102
|
const endpoint = `${apiUrl}/api/public/analytics/web-vitals`;
|
|
103
103
|
if (viaBeacon) {
|
|
104
|
-
|
|
104
|
+
chunkXBKNPBRB_js.sonorBeacon(endpoint, data, apiKey);
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
|
-
void
|
|
107
|
+
void chunkXBKNPBRB_js.sonorFetch(
|
|
108
108
|
endpoint,
|
|
109
109
|
{
|
|
110
110
|
method: "POST",
|
|
@@ -611,7 +611,7 @@ function AnalyticsProvider({
|
|
|
611
611
|
return;
|
|
612
612
|
}
|
|
613
613
|
try {
|
|
614
|
-
const response = await
|
|
614
|
+
const response = await chunkXBKNPBRB_js.sonorFetch(
|
|
615
615
|
`${apiUrl}/api/public/seo/pages`,
|
|
616
616
|
{ method: "GET", headers: { "Content-Type": "application/json" } },
|
|
617
617
|
{ apiKey }
|
|
@@ -695,7 +695,7 @@ function AnalyticsProvider({
|
|
|
695
695
|
console.log("[Analytics] Page view:", pageView);
|
|
696
696
|
}
|
|
697
697
|
try {
|
|
698
|
-
const response = await
|
|
698
|
+
const response = await chunkXBKNPBRB_js.sonorFetch(
|
|
699
699
|
`${apiUrl}/api/public/analytics/page-view`,
|
|
700
700
|
{
|
|
701
701
|
method: "POST",
|
|
@@ -785,7 +785,7 @@ function AnalyticsProvider({
|
|
|
785
785
|
console.log("[Analytics] Journey step:", sessionData);
|
|
786
786
|
}
|
|
787
787
|
try {
|
|
788
|
-
await
|
|
788
|
+
await chunkXBKNPBRB_js.sonorFetch(
|
|
789
789
|
`${apiUrl}/api/public/analytics/session`,
|
|
790
790
|
{
|
|
791
791
|
method: "POST",
|
|
@@ -810,7 +810,7 @@ function AnalyticsProvider({
|
|
|
810
810
|
previousPageDuration: Math.round((Date.now() - pageEnterTimeRef.current) / 1e3),
|
|
811
811
|
previousPageScrollDepth: currentScrollDepthRef.current
|
|
812
812
|
});
|
|
813
|
-
|
|
813
|
+
chunkXBKNPBRB_js.sonorBeacon(`${apiUrl}/api/public/analytics/session`, payload, apiKey);
|
|
814
814
|
};
|
|
815
815
|
window.addEventListener("pagehide", handleUnload);
|
|
816
816
|
return () => {
|
|
@@ -875,11 +875,11 @@ function AnalyticsProvider({
|
|
|
875
875
|
deviceType: getDeviceType()
|
|
876
876
|
});
|
|
877
877
|
if (useBeacon) {
|
|
878
|
-
|
|
878
|
+
chunkXBKNPBRB_js.sonorBeacon(`${apiUrl}/api/public/analytics/scroll-depth`, payload, apiKey);
|
|
879
879
|
if (debug) console.log("[Analytics] Scroll depth (beacon):", { maxDepth, totalTime });
|
|
880
880
|
} else {
|
|
881
881
|
try {
|
|
882
|
-
await
|
|
882
|
+
await chunkXBKNPBRB_js.sonorFetch(
|
|
883
883
|
`${apiUrl}/api/public/analytics/scroll-depth`,
|
|
884
884
|
{
|
|
885
885
|
method: "POST",
|
|
@@ -957,7 +957,7 @@ function AnalyticsProvider({
|
|
|
957
957
|
if (debug) console.log("[Analytics] Click:", clickData);
|
|
958
958
|
scheduleIdleTask(async () => {
|
|
959
959
|
try {
|
|
960
|
-
await
|
|
960
|
+
await chunkXBKNPBRB_js.sonorFetch(
|
|
961
961
|
`${apiUrl}/api/public/analytics/heatmap-click`,
|
|
962
962
|
{
|
|
963
963
|
method: "POST",
|
|
@@ -1000,7 +1000,7 @@ function AnalyticsProvider({
|
|
|
1000
1000
|
console.log("[Analytics] Event:", event);
|
|
1001
1001
|
}
|
|
1002
1002
|
try {
|
|
1003
|
-
const response = await
|
|
1003
|
+
const response = await chunkXBKNPBRB_js.sonorFetch(
|
|
1004
1004
|
`${apiUrl}/api/public/analytics/event`,
|
|
1005
1005
|
{
|
|
1006
1006
|
method: "POST",
|
|
@@ -1043,7 +1043,7 @@ function AnalyticsProvider({
|
|
|
1043
1043
|
console.log("[Analytics] Conversion:", conversion);
|
|
1044
1044
|
}
|
|
1045
1045
|
try {
|
|
1046
|
-
const response = await
|
|
1046
|
+
const response = await chunkXBKNPBRB_js.sonorFetch(
|
|
1047
1047
|
`${apiUrl}/api/public/analytics/conversion`,
|
|
1048
1048
|
{
|
|
1049
1049
|
method: "POST",
|
|
@@ -1104,5 +1104,5 @@ exports.WebVitals = WebVitals;
|
|
|
1104
1104
|
exports.useAnalytics = useAnalytics;
|
|
1105
1105
|
exports.useAnalyticsOptional = useAnalyticsOptional;
|
|
1106
1106
|
exports.useTrackEvent = useTrackEvent;
|
|
1107
|
-
//# sourceMappingURL=chunk-
|
|
1108
|
-
//# sourceMappingURL=chunk-
|
|
1107
|
+
//# sourceMappingURL=chunk-BUZSBUYJ.js.map
|
|
1108
|
+
//# sourceMappingURL=chunk-BUZSBUYJ.js.map
|