@sonordev/site-kit 5.0.0 → 5.1.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 -5
- package/dist/AnalyticsProvider-2LCSA6G3.mjs +10 -0
- package/dist/{AnalyticsProvider-KCLRFOX6.mjs.map → AnalyticsProvider-2LCSA6G3.mjs.map} +1 -1
- package/dist/AnalyticsProvider-V2U3TQMH.js +31 -0
- package/dist/{AnalyticsProvider-TXM3DRLI.js.map → AnalyticsProvider-V2U3TQMH.js.map} +1 -1
- package/dist/{BlogViewTracker-J6LRGUHU.js → BlogViewTracker-COTPD7WL.js} +6 -6
- package/dist/{BlogViewTracker-J6LRGUHU.js.map → BlogViewTracker-COTPD7WL.js.map} +1 -1
- package/dist/{BlogViewTracker-PZWAWB3O.mjs → BlogViewTracker-HG25ONRP.mjs} +5 -5
- package/dist/{BlogViewTracker-PZWAWB3O.mjs.map → BlogViewTracker-HG25ONRP.mjs.map} +1 -1
- package/dist/ChatWidget-4QUJYFXU.js +20 -0
- package/dist/{ChatWidget-LD54Z2PQ.js.map → ChatWidget-4QUJYFXU.js.map} +1 -1
- package/dist/ChatWidget-RWO7R7EJ.mjs +11 -0
- package/dist/{ChatWidget-PMDPSZXG.mjs.map → ChatWidget-RWO7R7EJ.mjs.map} +1 -1
- package/dist/EngageWidget-LF4AC4QN.mjs +9 -0
- package/dist/{EngageWidget-4CBFRN4Y.mjs.map → EngageWidget-LF4AC4QN.mjs.map} +1 -1
- package/dist/EngageWidget-RSOXB3YM.js +18 -0
- package/dist/{EngageWidget-BF5NMQ5A.js.map → EngageWidget-RSOXB3YM.js.map} +1 -1
- package/dist/{FileField-VXADIOMN.js → FileField-S2GUM3QB.js} +6 -6
- package/dist/{FileField-VXADIOMN.js.map → FileField-S2GUM3QB.js.map} +1 -1
- package/dist/{FileField-FFRHS3XP.mjs → FileField-YJ7DZXC3.mjs} +5 -5
- package/dist/{FileField-FFRHS3XP.mjs.map → FileField-YJ7DZXC3.mjs.map} +1 -1
- package/dist/{FormSpotlight-JG4ZHS56.js → FormSpotlight-7WAXLXZA.js} +15 -15
- package/dist/{FormSpotlight-JG4ZHS56.js.map → FormSpotlight-7WAXLXZA.js.map} +1 -1
- package/dist/{FormSpotlight-KE46EDP5.mjs → FormSpotlight-HLH5LQKI.mjs} +3 -3
- package/dist/{FormSpotlight-KE46EDP5.mjs.map → FormSpotlight-HLH5LQKI.mjs.map} +1 -1
- package/dist/{FormStage-5Z53Z2WY.js → FormStage-LEZYERJB.js} +13 -13
- package/dist/{FormStage-5Z53Z2WY.js.map → FormStage-LEZYERJB.js.map} +1 -1
- package/dist/{FormStage-PZKWEXZE.mjs → FormStage-Q5JW75AF.mjs} +3 -3
- package/dist/{FormStage-PZKWEXZE.mjs.map → FormStage-Q5JW75AF.mjs.map} +1 -1
- package/dist/ManagedForm-H4SEFSAF.js +23 -0
- package/dist/{ManagedForm-E4WHMARH.js.map → ManagedForm-H4SEFSAF.js.map} +1 -1
- package/dist/ManagedForm-U3NFIVEC.mjs +14 -0
- package/dist/{ManagedForm-VU2TKV6J.mjs.map → ManagedForm-U3NFIVEC.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-PG4EX3W6.js → ManagedNewsletterForm-KT2NGUNW.js} +8 -8
- package/dist/{ManagedNewsletterForm-PG4EX3W6.js.map → ManagedNewsletterForm-KT2NGUNW.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-6DET3VGZ.mjs → ManagedNewsletterForm-YKYW7B6P.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-6DET3VGZ.mjs.map → ManagedNewsletterForm-YKYW7B6P.mjs.map} +1 -1
- package/dist/{SignalCore-RZVTLUC2.mjs → SignalCore-2BH5PUGS.mjs} +5 -5
- package/dist/{SignalCore-RZVTLUC2.mjs.map → SignalCore-2BH5PUGS.mjs.map} +1 -1
- package/dist/{SignalCore-TCUVXVMN.js → SignalCore-JM4ODFL2.js} +11 -11
- package/dist/{SignalCore-TCUVXVMN.js.map → SignalCore-JM4ODFL2.js.map} +1 -1
- package/dist/SitemapSync-5CXS2JGB.mjs +8 -0
- package/dist/{SitemapSync-T75NAFB3.mjs.map → SitemapSync-5CXS2JGB.mjs.map} +1 -1
- package/dist/SitemapSync-J4UMJRTO.js +17 -0
- package/dist/{SitemapSync-AJU4DM3G.js.map → SitemapSync-J4UMJRTO.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- package/dist/blog/index.d.ts +9 -5
- package/dist/blog/index.d.ts.map +1 -1
- package/dist/blog/index.js +20 -20
- package/dist/blog/index.mjs +3 -3
- package/dist/blog/server-ui.js +14 -14
- package/dist/blog/server-ui.mjs +2 -2
- package/dist/{chunk-6QQFEJIP.js → chunk-2EJX56YJ.js} +8 -8
- package/dist/{chunk-6QQFEJIP.js.map → chunk-2EJX56YJ.js.map} +1 -1
- package/dist/{chunk-SXPINIJG.mjs → chunk-2XHEUWHV.mjs} +4 -4
- package/dist/{chunk-SXPINIJG.mjs.map → chunk-2XHEUWHV.mjs.map} +1 -1
- package/dist/{chunk-7T4VMXKD.js → chunk-44ZTBQH4.js} +3 -3
- package/dist/{chunk-7T4VMXKD.js.map → chunk-44ZTBQH4.js.map} +1 -1
- package/dist/chunk-4SQ6PROR.mjs +6 -0
- package/dist/{chunk-JPTJGLKS.mjs.map → chunk-4SQ6PROR.mjs.map} +1 -1
- package/dist/{chunk-PPCTL4B5.mjs → chunk-4TU246Q4.mjs} +10 -3
- package/dist/chunk-4TU246Q4.mjs.map +1 -0
- package/dist/{chunk-YSZB2DRX.mjs → chunk-5G2ZRQMO.mjs} +3 -3
- package/dist/{chunk-YSZB2DRX.mjs.map → chunk-5G2ZRQMO.mjs.map} +1 -1
- package/dist/{chunk-FTBABL3T.mjs → chunk-5W56B52Z.mjs} +3 -3
- package/dist/{chunk-FTBABL3T.mjs.map → chunk-5W56B52Z.mjs.map} +1 -1
- package/dist/{chunk-XPAHKYX7.mjs → chunk-6YKNDQYJ.mjs} +3 -3
- package/dist/{chunk-XPAHKYX7.mjs.map → chunk-6YKNDQYJ.mjs.map} +1 -1
- package/dist/{chunk-UV6KQUSL.mjs → chunk-A3VGZAZQ.mjs} +3 -3
- package/dist/{chunk-UV6KQUSL.mjs.map → chunk-A3VGZAZQ.mjs.map} +1 -1
- package/dist/{chunk-JY3KZDEM.js → chunk-ACLBRIYD.js} +3 -3
- package/dist/{chunk-JY3KZDEM.js.map → chunk-ACLBRIYD.js.map} +1 -1
- package/dist/{chunk-MGPHBVOK.js → chunk-ACWGG4VW.js} +9 -9
- package/dist/{chunk-MGPHBVOK.js.map → chunk-ACWGG4VW.js.map} +1 -1
- package/dist/{chunk-J4JXAFSW.mjs → chunk-ADBLBGCQ.mjs} +3 -3
- package/dist/{chunk-J4JXAFSW.mjs.map → chunk-ADBLBGCQ.mjs.map} +1 -1
- package/dist/{chunk-4UHO6DPJ.mjs → chunk-ADOGOLYO.mjs} +4 -4
- package/dist/{chunk-4UHO6DPJ.mjs.map → chunk-ADOGOLYO.mjs.map} +1 -1
- package/dist/{chunk-IX5RAZWX.js → chunk-BGBJSMXT.js} +6 -6
- package/dist/{chunk-IX5RAZWX.js.map → chunk-BGBJSMXT.js.map} +1 -1
- package/dist/{chunk-YVE65W47.mjs → chunk-BUDV7QHH.mjs} +4 -4
- package/dist/{chunk-YVE65W47.mjs.map → chunk-BUDV7QHH.mjs.map} +1 -1
- package/dist/{chunk-3SMG4EXR.mjs → chunk-BVLGJ2CZ.mjs} +3 -3
- package/dist/{chunk-3SMG4EXR.mjs.map → chunk-BVLGJ2CZ.mjs.map} +1 -1
- package/dist/{chunk-OGPS3DKE.js → chunk-CBMHJPR7.js} +5 -5
- package/dist/{chunk-OGPS3DKE.js.map → chunk-CBMHJPR7.js.map} +1 -1
- package/dist/{chunk-VACFVPNF.js → chunk-CGQO7MFO.js} +14 -14
- package/dist/{chunk-VACFVPNF.js.map → chunk-CGQO7MFO.js.map} +1 -1
- package/dist/{chunk-FQ3JQV3M.js → chunk-CKPFETIO.js} +4 -4
- package/dist/{chunk-FQ3JQV3M.js.map → chunk-CKPFETIO.js.map} +1 -1
- package/dist/{chunk-MVJQ4ZA2.mjs → chunk-CYQB5GLU.mjs} +4 -4
- package/dist/{chunk-MVJQ4ZA2.mjs.map → chunk-CYQB5GLU.mjs.map} +1 -1
- package/dist/{chunk-GCZMDY2T.js → chunk-DKRXPXOR.js} +3 -3
- package/dist/{chunk-GCZMDY2T.js.map → chunk-DKRXPXOR.js.map} +1 -1
- package/dist/{chunk-PZE5L2FK.mjs → chunk-DTNNZJYM.mjs} +4 -4
- package/dist/{chunk-PZE5L2FK.mjs.map → chunk-DTNNZJYM.mjs.map} +1 -1
- package/dist/{chunk-HCN2US4M.js → chunk-E3GHVAMK.js} +18 -18
- package/dist/{chunk-HCN2US4M.js.map → chunk-E3GHVAMK.js.map} +1 -1
- package/dist/{chunk-5JNLZRLX.mjs → chunk-EKTMXHBI.mjs} +3 -3
- package/dist/{chunk-5JNLZRLX.mjs.map → chunk-EKTMXHBI.mjs.map} +1 -1
- package/dist/{chunk-LLKXPJSE.js → chunk-EZLK2OQL.js} +7 -7
- package/dist/{chunk-LLKXPJSE.js.map → chunk-EZLK2OQL.js.map} +1 -1
- package/dist/{chunk-BQY3FJ3R.js → chunk-FMOOQKZU.js} +8 -8
- package/dist/{chunk-BQY3FJ3R.js.map → chunk-FMOOQKZU.js.map} +1 -1
- package/dist/{chunk-QI2H5KK6.mjs → chunk-FZISCIJV.mjs} +4 -4
- package/dist/{chunk-QI2H5KK6.mjs.map → chunk-FZISCIJV.mjs.map} +1 -1
- package/dist/{chunk-62ODUWUX.js → chunk-GYAH4KFC.js} +4 -4
- package/dist/{chunk-62ODUWUX.js.map → chunk-GYAH4KFC.js.map} +1 -1
- package/dist/{chunk-JIUVBSQZ.js → chunk-GZVSGQKT.js} +3 -3
- package/dist/{chunk-JIUVBSQZ.js.map → chunk-GZVSGQKT.js.map} +1 -1
- package/dist/{chunk-3FZ76VI5.js → chunk-HPIY7AR3.js} +14 -14
- package/dist/{chunk-3FZ76VI5.js.map → chunk-HPIY7AR3.js.map} +1 -1
- package/dist/{chunk-5OHHYGD6.js → chunk-IQLYFQKZ.js} +15 -15
- package/dist/{chunk-5OHHYGD6.js.map → chunk-IQLYFQKZ.js.map} +1 -1
- package/dist/{chunk-DX6D7HDI.js → chunk-JEI3CSY4.js} +4 -4
- package/dist/{chunk-DX6D7HDI.js.map → chunk-JEI3CSY4.js.map} +1 -1
- package/dist/{chunk-LZY374FB.js → chunk-MCXHQHIX.js} +4 -4
- package/dist/{chunk-LZY374FB.js.map → chunk-MCXHQHIX.js.map} +1 -1
- package/dist/{chunk-FCKL5CF3.mjs → chunk-NIJVVW4G.mjs} +3 -3
- package/dist/{chunk-FCKL5CF3.mjs.map → chunk-NIJVVW4G.mjs.map} +1 -1
- package/dist/{chunk-YGRHEEPX.mjs → chunk-NSTY7ZZA.mjs} +7 -7
- package/dist/{chunk-YGRHEEPX.mjs.map → chunk-NSTY7ZZA.mjs.map} +1 -1
- package/dist/{chunk-HEUCDF3O.mjs → chunk-OAJVITNO.mjs} +3 -3
- package/dist/{chunk-HEUCDF3O.mjs.map → chunk-OAJVITNO.mjs.map} +1 -1
- package/dist/{chunk-SW6KWUNI.mjs → chunk-OTHKWMDB.mjs} +3 -3
- package/dist/{chunk-SW6KWUNI.mjs.map → chunk-OTHKWMDB.mjs.map} +1 -1
- package/dist/{chunk-EISVUD75.mjs → chunk-ROJ25QM3.mjs} +3 -3
- package/dist/{chunk-EISVUD75.mjs.map → chunk-ROJ25QM3.mjs.map} +1 -1
- package/dist/{chunk-FDWDXMJL.mjs → chunk-SXNKLHOX.mjs} +3 -3
- package/dist/{chunk-FDWDXMJL.mjs.map → chunk-SXNKLHOX.mjs.map} +1 -1
- package/dist/{chunk-MPO6TRLS.js → chunk-TAM2D54C.js} +14 -14
- package/dist/{chunk-MPO6TRLS.js.map → chunk-TAM2D54C.js.map} +1 -1
- package/dist/{chunk-MWXBRCM2.mjs → chunk-TECD4AP7.mjs} +3 -3
- package/dist/{chunk-MWXBRCM2.mjs.map → chunk-TECD4AP7.mjs.map} +1 -1
- package/dist/{chunk-AXYKBQVI.mjs → chunk-UMWVTIIZ.mjs} +8 -8
- package/dist/{chunk-AXYKBQVI.mjs.map → chunk-UMWVTIIZ.mjs.map} +1 -1
- package/dist/{chunk-5JQLLF2T.js → chunk-VCNPTLK2.js} +12 -12
- package/dist/{chunk-5JQLLF2T.js.map → chunk-VCNPTLK2.js.map} +1 -1
- package/dist/{chunk-4D2G5ZNP.js → chunk-VIIGOCX4.js} +15 -15
- package/dist/{chunk-4D2G5ZNP.js.map → chunk-VIIGOCX4.js.map} +1 -1
- package/dist/{chunk-QH3WVTEK.mjs → chunk-VWVUYL5J.mjs} +4 -4
- package/dist/{chunk-QH3WVTEK.mjs.map → chunk-VWVUYL5J.mjs.map} +1 -1
- package/dist/{chunk-KWH6RAVY.js → chunk-WMNRTCYY.js} +11 -11
- package/dist/{chunk-KWH6RAVY.js.map → chunk-WMNRTCYY.js.map} +1 -1
- package/dist/{chunk-N3RWPAR5.js → chunk-WZMM57R2.js} +5 -5
- package/dist/{chunk-N3RWPAR5.js.map → chunk-WZMM57R2.js.map} +1 -1
- package/dist/chunk-YPEX4RDE.js +8 -0
- package/dist/{chunk-S65JSRWW.js.map → chunk-YPEX4RDE.js.map} +1 -1
- package/dist/{chunk-UABMMR7U.js → chunk-Z33JXJTJ.js} +10 -3
- package/dist/chunk-Z33JXJTJ.js.map +1 -0
- package/dist/{chunk-UFURXSAI.mjs → chunk-ZFZMN4LT.mjs} +3 -3
- package/dist/{chunk-UFURXSAI.mjs.map → chunk-ZFZMN4LT.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/commerce/server-result.test.d.ts +2 -0
- package/dist/commerce/server-result.test.d.ts.map +1 -0
- package/dist/commerce/server.d.ts +51 -0
- package/dist/commerce/server.d.ts.map +1 -1
- package/dist/commerce/server.js +57 -24
- package/dist/commerce/server.js.map +1 -1
- package/dist/commerce/server.mjs +54 -25
- package/dist/commerce/server.mjs.map +1 -1
- 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/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/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +63 -63
- package/dist/index.mjs +9 -9
- package/dist/layout/client.js +8 -8
- package/dist/layout/client.mjs +7 -7
- package/dist/layout/index.js +10 -10
- package/dist/layout/index.mjs +8 -8
- package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
- package/dist/llms/humanize-industry.d.ts +9 -0
- package/dist/llms/humanize-industry.d.ts.map +1 -0
- package/dist/llms/humanize-industry.test.d.ts +2 -0
- package/dist/llms/humanize-industry.test.d.ts.map +1 -0
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.mjs +2 -2
- 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/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/index.js +2 -2
- package/dist/sitemap/index.mjs +1 -1
- package/dist/sync/index.js +16 -16
- package/dist/sync/index.mjs +4 -4
- package/package.json +1 -1
- package/dist/AnalyticsProvider-KCLRFOX6.mjs +0 -10
- package/dist/AnalyticsProvider-TXM3DRLI.js +0 -31
- package/dist/ChatWidget-LD54Z2PQ.js +0 -20
- package/dist/ChatWidget-PMDPSZXG.mjs +0 -11
- package/dist/EngageWidget-4CBFRN4Y.mjs +0 -9
- package/dist/EngageWidget-BF5NMQ5A.js +0 -18
- package/dist/ManagedForm-E4WHMARH.js +0 -23
- package/dist/ManagedForm-VU2TKV6J.mjs +0 -14
- package/dist/SitemapSync-AJU4DM3G.js +0 -17
- package/dist/SitemapSync-T75NAFB3.mjs +0 -8
- package/dist/chunk-JPTJGLKS.mjs +0 -6
- package/dist/chunk-PPCTL4B5.mjs.map +0 -1
- package/dist/chunk-S65JSRWW.js +0 -8
- package/dist/chunk-UABMMR7U.js.map +0 -1
|
@@ -10,7 +10,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
10
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
11
11
|
|
|
12
12
|
var InteractiveForm = React.lazy(
|
|
13
|
-
() => import('./ManagedForm-
|
|
13
|
+
() => import('./ManagedForm-H4SEFSAF.js').then((m) => ({ default: m.ManagedForm }))
|
|
14
14
|
);
|
|
15
15
|
function FormEnhancer({
|
|
16
16
|
formId,
|
|
@@ -106,5 +106,5 @@ function EnterStyles() {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
exports.FormEnhancer = FormEnhancer;
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
110
|
-
//# sourceMappingURL=chunk-
|
|
109
|
+
//# sourceMappingURL=chunk-44ZTBQH4.js.map
|
|
110
|
+
//# sourceMappingURL=chunk-44ZTBQH4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/forms/FormEnhancer.tsx"],"names":["lazy","useDeferredActivation","useState","jsxs","jsx","Suspense","React","useRef","useEffect"],"mappings":"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","file":"chunk-7T4VMXKD.js","sourcesContent":["'use client'\n\n/**\n * FormEnhancer — the only client code a managed form needs up front.\n *\n * Renders the server-rendered shell (<StaticForm>, passed as `children`) until\n * an idle/first-interaction gate fires, then lazy-imports the interactive form\n * and swaps it in. Everything expensive — validation, conditional logic,\n * spotlight/stage, celebration, momentum — lives behind that dynamic import,\n * so a page ships this boundary and nothing else in its initial chunk set.\n *\n * The shell is a REAL form the whole time (native action + signed token), so\n * the progression is:\n *\n * no JS at all -> shell, submits natively. Works.\n * JS, pre-idle -> shell, submits natively. Works.\n * JS, post-idle -> enhanced form, submits over JSON. Works, with delight.\n * chunk 404s -> shell stays. Works. (Never left blank.)\n *\n * That last line is the invariant to protect: the shell is only removed once\n * the enhancement has actually rendered. Do not \"hide the shell then load\" —\n * a CDN hiccup would leave a visitor staring at an empty box where the form\n * used to be.\n *\n * ── Entrance animation ──────────────────────────────────────────────────\n *\n * Above-the-fold forms upgrade while the visitor is looking at them, so the\n * swap must not pop. The wrapper carries `data-sk-form-mount=\"shell\"` and\n * flips to `\"enhanced\"`, and the enhanced form gets `data-sk-enter` for one\n * frame, so a site can style the transition entirely in CSS:\n *\n * [data-sk-form-mount] { transition: opacity .35s ease }\n * [data-sk-form-mount=\"shell\"] { opacity: .6 }\n *\n * Defaults ship as CSS variables rather than hard-coded values:\n *\n * --sk-form-enter-duration (default 320ms)\n * --sk-form-enter-easing (default cubic-bezier(.22,1,.36,1))\n * --sk-form-enter-distance (default 6px)\n *\n * `enter=\"none\"` opts out entirely; `enter=\"custom\"` emits the data\n * attributes but no site-kit styles, leaving the animation to the site.\n * Every default is collapsed by prefers-reduced-motion.\n */\n\nimport React, { lazy, Suspense, useEffect, useRef, useState } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport type { FormExperience, FormSubmission } from './types'\n\n/** The heavy half. Nothing else in this module may import it statically. */\nconst InteractiveForm = lazy(() =>\n import('./ManagedForm').then((m) => ({ default: m.ManagedForm })),\n)\n\nexport type FormEnterAnimation = 'fade' | 'none' | 'custom'\n\nexport interface FormEnhancerProps {\n formId: string\n /** Server-fetched raw config — hands the enhancement its fields instantly. */\n initialConfig?: Record<string, unknown> | null\n className?: string\n nativeReturnTo?: string\n experience?: FormExperience\n /** Pre-fill field values by slug. See ManagedForm.defaultValues. */\n defaultValues?: Record<string, unknown>\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n /**\n * How the enhanced form arrives. 'fade' (default) crossfades and lifts it\n * into place; 'none' swaps instantly; 'custom' emits the data attributes\n * and no styles so the site owns the animation.\n */\n enter?: FormEnterAnimation\n /**\n * Set false to enhance immediately instead of waiting for idle. Only worth\n * it for a form that is the entire point of the page AND above the fold.\n */\n defer?: boolean\n /** The server-rendered <StaticForm>. Shown until the enhancement mounts. */\n children: React.ReactNode\n}\n\nexport function FormEnhancer({\n formId,\n initialConfig,\n className,\n nativeReturnTo,\n experience,\n defaultValues,\n onSuccess,\n onError,\n enter = 'fade',\n defer = true,\n children,\n}: FormEnhancerProps) {\n const ready = useDeferredActivation(defer)\n // Flipped only after the enhancement has actually committed to the DOM, so\n // the shell never disappears ahead of its replacement.\n const [enhanced, setEnhanced] = useState(false)\n\n return (\n <div\n data-sk-form-mount={enhanced ? 'enhanced' : 'shell'}\n data-sk-part=\"form-mount\"\n style={enter === 'fade' ? FADE_HOST : undefined}\n >\n {enter === 'fade' && <EnterStyles />}\n {ready ? (\n <Suspense fallback={children}>\n <Enhanced onMount={() => setEnhanced(true)} fallback={children}>\n <InteractiveForm\n formId={formId}\n initialConfig={initialConfig}\n className={className}\n nativeReturnTo={nativeReturnTo}\n experience={experience}\n defaultValues={defaultValues}\n onSuccess={onSuccess}\n onError={onError}\n />\n </Enhanced>\n </Suspense>\n ) : (\n children\n )}\n </div>\n )\n}\n\n/**\n * Reports the moment the enhancement is on screen, and keeps the shell\n * rendered if it throws. An error boundary is the difference between \"the\n * fancy version failed\" and \"there is no form on this page\".\n */\nclass Enhanced extends React.Component<\n { onMount: () => void; fallback: React.ReactNode; children: React.ReactNode },\n { failed: boolean }\n> {\n state = { failed: false }\n\n static getDerivedStateFromError() {\n return { failed: true }\n }\n\n componentDidCatch(err: unknown) {\n console.error('[Forms] Enhancement failed; keeping the native form:', err)\n }\n\n componentDidMount() {\n if (!this.state.failed) this.props.onMount()\n }\n\n render() {\n if (this.state.failed) return this.props.fallback\n return <FrameTag>{this.props.children}</FrameTag>\n }\n}\n\n/** Adds data-sk-enter for one frame so a CSS transition has something to run. */\nfunction FrameTag({ children }: { children: React.ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.setAttribute('data-sk-enter', '')\n const id = requestAnimationFrame(() => el.removeAttribute('data-sk-enter'))\n return () => cancelAnimationFrame(id)\n }, [])\n return (\n <div ref={ref} style={{ display: 'contents' }}>\n {children}\n </div>\n )\n}\n\nconst FADE_HOST: React.CSSProperties = {\n transition:\n 'opacity var(--sk-form-enter-duration, 320ms) var(--sk-form-enter-easing, cubic-bezier(.22,1,.36,1))',\n}\n\n/**\n * Scoped to [data-sk-part=\"form-mount\"] so it can never touch a site's own\n * markup. Emitted once per form; identical text dedupes in every browser's\n * style cache and gzips to nothing.\n */\nfunction EnterStyles() {\n return (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: static string, no interpolation\n dangerouslySetInnerHTML={{\n __html: `\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:.55}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"enhanced\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:0;transform:translateY(var(--sk-form-enter-distance,6px))}\n[data-sk-part=\"form-mount\"] [data-sk-enter] *{transition:none!important}\n@media (prefers-reduced-motion: reduce){\n[data-sk-part=\"form-mount\"]{transition:none!important}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:1;transform:none}\n}`,\n }}\n />\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/forms/FormEnhancer.tsx"],"names":["lazy","useDeferredActivation","useState","jsxs","jsx","Suspense","React","useRef","useEffect"],"mappings":"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","file":"chunk-44ZTBQH4.js","sourcesContent":["'use client'\n\n/**\n * FormEnhancer — the only client code a managed form needs up front.\n *\n * Renders the server-rendered shell (<StaticForm>, passed as `children`) until\n * an idle/first-interaction gate fires, then lazy-imports the interactive form\n * and swaps it in. Everything expensive — validation, conditional logic,\n * spotlight/stage, celebration, momentum — lives behind that dynamic import,\n * so a page ships this boundary and nothing else in its initial chunk set.\n *\n * The shell is a REAL form the whole time (native action + signed token), so\n * the progression is:\n *\n * no JS at all -> shell, submits natively. Works.\n * JS, pre-idle -> shell, submits natively. Works.\n * JS, post-idle -> enhanced form, submits over JSON. Works, with delight.\n * chunk 404s -> shell stays. Works. (Never left blank.)\n *\n * That last line is the invariant to protect: the shell is only removed once\n * the enhancement has actually rendered. Do not \"hide the shell then load\" —\n * a CDN hiccup would leave a visitor staring at an empty box where the form\n * used to be.\n *\n * ── Entrance animation ──────────────────────────────────────────────────\n *\n * Above-the-fold forms upgrade while the visitor is looking at them, so the\n * swap must not pop. The wrapper carries `data-sk-form-mount=\"shell\"` and\n * flips to `\"enhanced\"`, and the enhanced form gets `data-sk-enter` for one\n * frame, so a site can style the transition entirely in CSS:\n *\n * [data-sk-form-mount] { transition: opacity .35s ease }\n * [data-sk-form-mount=\"shell\"] { opacity: .6 }\n *\n * Defaults ship as CSS variables rather than hard-coded values:\n *\n * --sk-form-enter-duration (default 320ms)\n * --sk-form-enter-easing (default cubic-bezier(.22,1,.36,1))\n * --sk-form-enter-distance (default 6px)\n *\n * `enter=\"none\"` opts out entirely; `enter=\"custom\"` emits the data\n * attributes but no site-kit styles, leaving the animation to the site.\n * Every default is collapsed by prefers-reduced-motion.\n */\n\nimport React, { lazy, Suspense, useEffect, useRef, useState } from 'react'\nimport { useDeferredActivation } from '../shared/defer'\nimport type { FormExperience, FormSubmission } from './types'\n\n/** The heavy half. Nothing else in this module may import it statically. */\nconst InteractiveForm = lazy(() =>\n import('./ManagedForm').then((m) => ({ default: m.ManagedForm })),\n)\n\nexport type FormEnterAnimation = 'fade' | 'none' | 'custom'\n\nexport interface FormEnhancerProps {\n formId: string\n /** Server-fetched raw config — hands the enhancement its fields instantly. */\n initialConfig?: Record<string, unknown> | null\n className?: string\n nativeReturnTo?: string\n experience?: FormExperience\n /** Pre-fill field values by slug. See ManagedForm.defaultValues. */\n defaultValues?: Record<string, unknown>\n onSuccess?: (submission: FormSubmission) => void\n onError?: (error: Error) => void\n /**\n * How the enhanced form arrives. 'fade' (default) crossfades and lifts it\n * into place; 'none' swaps instantly; 'custom' emits the data attributes\n * and no styles so the site owns the animation.\n */\n enter?: FormEnterAnimation\n /**\n * Set false to enhance immediately instead of waiting for idle. Only worth\n * it for a form that is the entire point of the page AND above the fold.\n */\n defer?: boolean\n /** The server-rendered <StaticForm>. Shown until the enhancement mounts. */\n children: React.ReactNode\n}\n\nexport function FormEnhancer({\n formId,\n initialConfig,\n className,\n nativeReturnTo,\n experience,\n defaultValues,\n onSuccess,\n onError,\n enter = 'fade',\n defer = true,\n children,\n}: FormEnhancerProps) {\n const ready = useDeferredActivation(defer)\n // Flipped only after the enhancement has actually committed to the DOM, so\n // the shell never disappears ahead of its replacement.\n const [enhanced, setEnhanced] = useState(false)\n\n return (\n <div\n data-sk-form-mount={enhanced ? 'enhanced' : 'shell'}\n data-sk-part=\"form-mount\"\n style={enter === 'fade' ? FADE_HOST : undefined}\n >\n {enter === 'fade' && <EnterStyles />}\n {ready ? (\n <Suspense fallback={children}>\n <Enhanced onMount={() => setEnhanced(true)} fallback={children}>\n <InteractiveForm\n formId={formId}\n initialConfig={initialConfig}\n className={className}\n nativeReturnTo={nativeReturnTo}\n experience={experience}\n defaultValues={defaultValues}\n onSuccess={onSuccess}\n onError={onError}\n />\n </Enhanced>\n </Suspense>\n ) : (\n children\n )}\n </div>\n )\n}\n\n/**\n * Reports the moment the enhancement is on screen, and keeps the shell\n * rendered if it throws. An error boundary is the difference between \"the\n * fancy version failed\" and \"there is no form on this page\".\n */\nclass Enhanced extends React.Component<\n { onMount: () => void; fallback: React.ReactNode; children: React.ReactNode },\n { failed: boolean }\n> {\n state = { failed: false }\n\n static getDerivedStateFromError() {\n return { failed: true }\n }\n\n componentDidCatch(err: unknown) {\n console.error('[Forms] Enhancement failed; keeping the native form:', err)\n }\n\n componentDidMount() {\n if (!this.state.failed) this.props.onMount()\n }\n\n render() {\n if (this.state.failed) return this.props.fallback\n return <FrameTag>{this.props.children}</FrameTag>\n }\n}\n\n/** Adds data-sk-enter for one frame so a CSS transition has something to run. */\nfunction FrameTag({ children }: { children: React.ReactNode }) {\n const ref = useRef<HTMLDivElement>(null)\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.setAttribute('data-sk-enter', '')\n const id = requestAnimationFrame(() => el.removeAttribute('data-sk-enter'))\n return () => cancelAnimationFrame(id)\n }, [])\n return (\n <div ref={ref} style={{ display: 'contents' }}>\n {children}\n </div>\n )\n}\n\nconst FADE_HOST: React.CSSProperties = {\n transition:\n 'opacity var(--sk-form-enter-duration, 320ms) var(--sk-form-enter-easing, cubic-bezier(.22,1,.36,1))',\n}\n\n/**\n * Scoped to [data-sk-part=\"form-mount\"] so it can never touch a site's own\n * markup. Emitted once per form; identical text dedupes in every browser's\n * style cache and gzips to nothing.\n */\nfunction EnterStyles() {\n return (\n <style\n // biome-ignore lint/security/noDangerouslySetInnerHtml: static string, no interpolation\n dangerouslySetInnerHTML={{\n __html: `\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:.55}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"enhanced\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:0;transform:translateY(var(--sk-form-enter-distance,6px))}\n[data-sk-part=\"form-mount\"] [data-sk-enter] *{transition:none!important}\n@media (prefers-reduced-motion: reduce){\n[data-sk-part=\"form-mount\"]{transition:none!important}\n[data-sk-part=\"form-mount\"][data-sk-form-mount=\"shell\"]{opacity:1}\n[data-sk-part=\"form-mount\"] [data-sk-enter]{opacity:1;transform:none}\n}`,\n }}\n />\n )\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";AASO,IAAM,gBAAA,GAAmB","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/shared/version.ts"],"names":[],"mappings":";AASO,IAAM,gBAAA,GAAmB","file":"chunk-4SQ6PROR.mjs","sourcesContent":["/**\n * @sonordev/site-kit shared - Package version constant\n *\n * Single source of truth for the version the kit reports at runtime (the\n * x-sitekit-version request header set by sonorFetch). Kept as a plain const\n * so client bundles don't need JSON imports; scripts/verify-dts.cjs asserts\n * it matches package.json at publish time, and version.test.ts asserts it in\n * dev, so it can't silently drift.\n */\nexport const SITE_KIT_VERSION = '5.1.0'\n"]}
|
|
@@ -101,6 +101,13 @@ async function getOptimizedLLMsTxt(options) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// src/llms/humanize-industry.ts
|
|
105
|
+
function humanizeIndustry(industry) {
|
|
106
|
+
const spaced = industry.replace(/[_-]+/g, " ").trim();
|
|
107
|
+
if (!spaced) return industry;
|
|
108
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
104
111
|
// src/llms/generateLLMsTxt.ts
|
|
105
112
|
function mergeLlmsMeta(fallback, primary) {
|
|
106
113
|
if (!primary && !fallback) return void 0;
|
|
@@ -416,7 +423,7 @@ function generateHeaderSection(business, meta, resolvedBaseUrl) {
|
|
|
416
423
|
}
|
|
417
424
|
if (business.industry) {
|
|
418
425
|
lines.push("");
|
|
419
|
-
lines.push(`**Industry:** ${business.industry}`);
|
|
426
|
+
lines.push(`**Industry:** ${humanizeIndustry(business.industry)}`);
|
|
420
427
|
}
|
|
421
428
|
if (business.service_area) {
|
|
422
429
|
lines.push(`**Service Area:** ${business.service_area}`);
|
|
@@ -697,5 +704,5 @@ function atomicWriteSync(filePath, content) {
|
|
|
697
704
|
}
|
|
698
705
|
|
|
699
706
|
export { generateLLMsFullTxt, generateLLMsTxt, getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices, writeLLMsTxtToPublic };
|
|
700
|
-
//# sourceMappingURL=chunk-
|
|
701
|
-
//# sourceMappingURL=chunk-
|
|
707
|
+
//# sourceMappingURL=chunk-4TU246Q4.mjs.map
|
|
708
|
+
//# sourceMappingURL=chunk-4TU246Q4.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/llms/api.ts","../src/llms/humanize-industry.ts","../src/llms/generateLLMsTxt.ts","../src/llms/writeLLMsTxt.ts"],"names":[],"mappings":"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","file":"chunk-4TU246Q4.mjs","sourcesContent":["/**\n * @sonordev/site-kit/llms - API Functions\n * \n * Data fetching for LLM visibility content.\n * Pulls from Signal knowledge base and project data.\n */\n\nimport { cache } from 'react'\nimport { LLM_GEO_CONTRACT_VERSION } from './contract'\nimport { resolveSiteHost } from '../sites/resolve'\nimport type { LLMsDataResponse, LLMBusinessInfo, LLMContactInfo, LLMService, LLMFAQItem, LLMPageSummary } from './types'\n\n// ============================================\n// API Config\n// ============================================\n\nfunction getApiConfig() {\n // Use site-kit globals if available, otherwise fall back to env vars\n const apiUrl = (typeof window !== 'undefined' && (window as any).__SITE_KIT_API_URL__)\n || process.env.SONOR_API_URL\n || 'https://api.sonor.io'\n\n const apiKey = (typeof window !== 'undefined' && (window as any).__SITE_KIT_API_KEY__)\n || process.env.SONOR_API_KEY\n || ''\n \n return { apiUrl, apiKey }\n}\n\n/**\n * Append the sub-site host to an endpoint. `site` scopes every seo_pages read\n * on the Sonor side to THIS host — see `withSite` callers below and the\n * multi-site notes on `getLLMsData`.\n *\n * Resolution (explicit → NEXT_PUBLIC_SITE_URL host → window.location.host) is\n * the shared one from `sites/resolve`, so the value matches what the browser\n * publishes as `__SITE_KIT_SITE__` and what SitemapSync tags rows with.\n */\nfunction withSite(endpoint: string, site?: string): string {\n const host = resolveSiteHost(site)\n if (!host) return endpoint\n return `${endpoint}${endpoint.includes('?') ? '&' : '?'}site=${encodeURIComponent(host)}`\n}\n\nasync function apiGet<T>(endpoint: string): Promise<T | null> {\n const { apiUrl, apiKey } = getApiConfig()\n \n if (!apiKey) {\n console.error('@sonordev/llms: No API key configured. Set SONOR_API_KEY.')\n return null\n }\n \n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n next: { revalidate: 3600 }, // Next.js fetch cache\n } as RequestInit)\n \n if (!response.ok) {\n console.error(`@sonordev/llms: API error: ${response.statusText}`)\n return null\n }\n\n const json = await response.json()\n return json\n } catch (error) {\n console.error('@sonordev/llms: Network error:', error)\n return null\n }\n}\n\n// ============================================\n// Cached Data Fetchers\n// ============================================\n\n/**\n * Fetch all LLM visibility data for a project - cached per request\n * This is the main data source for llms.txt generation\n *\n * @param projectId - Optional project ID (API key identifies project if omitted)\n * @param site - Sub-site host. One Sonor project can host many domains, and\n * seo_pages then holds one row PER HOST for shared paths like `/` and\n * `/terms`. Without this the API returns an arbitrary sibling's row, so a\n * site describes its neighbours instead of itself. Omit to resolve from\n * NEXT_PUBLIC_SITE_URL (the build-time source of truth).\n */\nexport const getLLMsData = cache(async (\n projectId?: string,\n site?: string\n): Promise<LLMsDataResponse | null> => {\n const data = await apiGet<LLMsDataResponse>(withSite(`/api/public/llms/data`, site))\n if (\n data?.meta &&\n data.meta.contract_version != null &&\n data.meta.contract_version !== LLM_GEO_CONTRACT_VERSION &&\n typeof process !== 'undefined' &&\n process.env.NODE_ENV !== 'production'\n ) {\n console.warn(\n `[site-kit/llms] API meta.contract_version (${data.meta.contract_version}) !== site-kit LLM_GEO_CONTRACT_VERSION (${LLM_GEO_CONTRACT_VERSION}).`,\n )\n }\n return data\n})\n\n/**\n * Fetch business info only - cached per request\n */\nexport const getBusinessInfo = cache(async (\n projectId?: string\n): Promise<LLMBusinessInfo | null> => {\n const result = await apiGet<{ business: LLMBusinessInfo }>(`/api/public/llms/business`)\n return result?.business || null\n})\n\n/**\n * Fetch services list - cached per request\n */\nexport const getServices = cache(async (\n projectId?: string,\n site?: string\n): Promise<LLMService[]> => {\n const result = await apiGet<{ services: LLMService[] }>(withSite(`/api/public/llms/services`, site))\n return result?.services || []\n})\n\n/**\n * Fetch FAQ items - cached per request\n */\nexport const getFAQItems = cache(async (\n projectId?: string,\n limit?: number\n): Promise<LLMFAQItem[]> => {\n const endpoint = limit \n ? `/api/public/llms/faq?limit=${limit}`\n : '/api/public/llms/faq'\n const result = await apiGet<{ faq: LLMFAQItem[] }>(endpoint)\n return result?.faq || []\n})\n\n/**\n * Fetch page summaries for sitemap - cached per request\n */\nexport const getPageSummaries = cache(async (\n projectId?: string,\n limit?: number,\n site?: string\n): Promise<LLMPageSummary[]> => {\n const endpoint = limit \n ? `/api/public/llms/pages?limit=${limit}`\n : '/api/public/llms/pages'\n const result = await apiGet<{ pages: LLMPageSummary[] }>(withSite(endpoint, site))\n return result?.pages || []\n})\n\n/**\n * Fetch AI-optimized llms.txt markdown from Portal API (build-time)\n * Used by writeLLMsTxtToPublic for static file generation\n */\nexport async function getOptimizedLLMsTxt(options?: {\n full?: boolean\n /** Matches Portal GET /api/public/llms/txt?publicSummaryOnly=true */\n publicSummaryOnly?: boolean\n /**\n * Sub-site host — scopes the page index to THIS domain on multi-site\n * projects. Omit to resolve from NEXT_PUBLIC_SITE_URL. See getLLMsData.\n */\n site?: string\n apiUrl?: string\n apiKey?: string\n}): Promise<string | null> {\n const apiUrl = options?.apiUrl\n || (typeof process !== 'undefined' && process.env?.SONOR_API_URL)\n || 'https://api.sonor.io'\n const apiKey = options?.apiKey\n || (typeof process !== 'undefined' && process.env?.SONOR_API_KEY)\n || ''\n\n if (!apiKey) {\n console.error('@sonordev/llms: No API key configured for getOptimizedLLMsTxt')\n return null\n }\n\n const params = new URLSearchParams()\n if (options?.full) params.set('full', 'true')\n if (options?.publicSummaryOnly) params.set('publicSummaryOnly', 'true')\n const site = resolveSiteHost(options?.site)\n if (site) params.set('site', site)\n const qs = params.toString()\n const endpoint = `/api/public/llms/txt${qs ? `?${qs}` : ''}`\n\n try {\n const response = await fetch(`${apiUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'text/plain',\n 'x-api-key': apiKey,\n },\n })\n\n if (!response.ok) {\n console.error(`@sonordev/llms: Optimized txt API error: ${response.status} ${response.statusText}`)\n return null\n }\n\n return await response.text()\n } catch (error) {\n console.error('@sonordev/llms: Failed to fetch optimized llms.txt:', error)\n return null\n }\n}\n","/**\n * Turn a stored industry slug into display prose.\n *\n * `business.industry` comes from a fixed enum column (professional_services,\n * home_services, …) and llms.txt is served to AI crawlers verbatim, so\n * printing the raw slug reads as a database leak rather than a description.\n */\nexport function humanizeIndustry(industry: string): string {\n const spaced = industry.replace(/[_-]+/g, ' ').trim()\n if (!spaced) return industry\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n","/**\n * @sonordev/site-kit/llms - llms.txt Generator\n * \n * Generates llms.txt content following the llms.txt specification.\n * https://llmstxt.org/\n * \n * The llms.txt file provides a markdown-formatted overview of a website\n * specifically designed for LLM consumption. It helps AI systems understand\n * what a business does, what services it offers, and how to answer questions.\n */\n\nimport { getLLMsData } from './api'\nimport type {\n GenerateLLMSTxtOptions,\n LLMSTxtContent,\n LLMsDataResponse,\n LLMBusinessInfo,\n LLMContactInfo,\n LLMService,\n LLMFAQItem,\n LLMPageSummary,\n LLMPortfolioItem,\n} from './types'\nimport type { SEOEntity } from '../seo/types'\nimport type { LLMsPayloadMeta } from './contract'\nimport {\n LLM_GEO_CONTRACT_VERSION,\n sanitizeLlmsDisclaimerLine,\n sanitizeLlmsPublicSummary,\n sanitizePrimaryLanguageTag,\n} from './contract'\nimport { humanizeIndustry } from './humanize-industry'\n\nfunction mergeLlmsMeta(\n fallback: LLMsPayloadMeta | null | undefined,\n primary: LLMsPayloadMeta | null | undefined,\n): LLMsPayloadMeta | undefined {\n if (!primary && !fallback) return undefined\n if (!primary) return fallback ?? undefined\n if (!fallback) return primary\n return {\n contract_version: primary.contract_version ?? fallback.contract_version,\n last_updated: primary.last_updated ?? fallback.last_updated ?? null,\n primary_language: primary.primary_language ?? fallback.primary_language ?? null,\n llms_disclaimer: primary.llms_disclaimer ?? fallback.llms_disclaimer ?? null,\n }\n}\n\n/**\n * Single source of truth for the llms.txt link base (site origin).\n * Precedence: explicit `baseUrl` option → Portal/local `business.website` →\n * NEXT_PUBLIC_SITE_URL → SITE_URL. Intentionally never derived from request\n * headers — touching the Request would force the /llms.txt route dynamic and\n * break static prerendering on consumer sites.\n */\nfunction resolveBaseUrl(\n optionBaseUrl: string | undefined,\n businessWebsite: string | undefined | null,\n): string {\n const candidate =\n optionBaseUrl ||\n businessWebsite ||\n process.env.NEXT_PUBLIC_SITE_URL ||\n process.env.SITE_URL ||\n ''\n return candidate.trim().replace(/\\/+$/, '')\n}\n\n/**\n * Merge Portal data with local data. Portal fields take precedence; local fills gaps when Portal is empty.\n */\nfunction mergeLLMsData(\n portal: Partial<LLMsDataResponse> | null,\n local: LLMsDataResponse | null\n): LLMsDataResponse | null {\n if (!local) return portal as LLMsDataResponse | null\n if (!portal) return local\n return {\n meta: mergeLlmsMeta(local.meta, portal.meta),\n business: portal.business ?? local.business,\n contact: portal.contact ?? local.contact,\n services: (portal.services?.length ? portal.services : local.services) ?? [],\n faq: (portal.faq?.length ? portal.faq : local.faq) ?? [],\n pages: (portal.pages?.length ? portal.pages : local.pages) ?? [],\n portfolio: (portal.portfolio?.length ? portal.portfolio : local.portfolio) ?? [],\n }\n}\n\n/**\n * Generate llms.txt content from Portal data\n * \n * @example\n * ```ts\n * // app/llms.txt/route.ts\n * import { generateLLMsTxt } from '@sonordev/site-kit/llms'\n * \n * export async function GET() {\n * const { markdown } = await generateLLMsTxt({\n * projectId: process.env.SONOR_API_KEY!\n * })\n * \n * return new Response(markdown, {\n * headers: { 'Content-Type': 'text/plain; charset=utf-8' }\n * })\n * }\n * ```\n */\nexport async function generateLLMsTxt(\n options: GenerateLLMSTxtOptions\n): Promise<LLMSTxtContent> {\n const {\n projectId,\n baseUrl: baseUrlOption,\n site,\n getLocalData,\n includeBusinessInfo = true,\n includeServices = true,\n includeFAQ = true,\n includePages = true,\n includeContact = true,\n includePortfolio = true,\n includeEntities = true,\n maxFAQItems = 20,\n maxPages = 50,\n maxPortfolioItems = 20,\n maxEntities = 50,\n maxArticlesPerCluster = 5,\n customSections = [],\n optionalPagePaths = [],\n linkToFullLlms = false,\n fullLlmsTxtPath = '/llms-full.txt',\n pageListNotesFromPublicSummaryOnly = false,\n headerPrimaryLanguage,\n headerDisclaimer,\n } = options\n\n // Fetch from Portal first, scoped to THIS sub-site so a multi-site project\n // describes the host being built rather than an arbitrary sibling.\n let data = await getLLMsData(projectId, site)\n\n // Use local data when Portal returns null or empty services\n const useLocal = getLocalData && (!data || !data.services?.length)\n if (useLocal && getLocalData) {\n try {\n const local = await getLocalData()\n data = mergeLLMsData(data ?? null, local)\n } catch (err) {\n console.warn('[site-kit] getLocalData failed:', err)\n }\n }\n \n if (!data) {\n // Return minimal content if no data\n return {\n markdown: '# Website\\n\\n> Information not available.',\n metadata: {\n generated_at: new Date().toISOString(),\n project_id: projectId || '',\n sections: [],\n }\n }\n }\n\n const headerMeta = buildHeaderMeta(\n data.meta,\n headerPrimaryLanguage,\n headerDisclaimer,\n )\n\n const baseUrl = resolveBaseUrl(baseUrlOption, data.business?.website)\n\n const sections: string[] = []\n const sectionNames: string[] = []\n const attemptedSections: string[] = []\n const failedSections: string[] = []\n\n // ========================================\n // Header Section (H1 + blockquote summary)\n // ========================================\n if (includeBusinessInfo && data.business) {\n const header = generateHeaderSection(data.business, headerMeta, baseUrl)\n sections.push(header)\n sectionNames.push('header')\n }\n\n // ========================================\n // About Section\n // ========================================\n if (includeBusinessInfo && data.business?.description) {\n const about = generateAboutSection(data.business)\n sections.push(about)\n sectionNames.push('about')\n }\n\n // ========================================\n // Services Section\n // ========================================\n if (includeServices && data.services?.length > 0) {\n const services = generateServicesSection(data.services)\n sections.push(services)\n sectionNames.push('services')\n }\n\n // ========================================\n // Portfolio / Case Studies Section\n // ========================================\n if (includePortfolio) {\n let portfolioItems = data.portfolio || []\n\n // If LLMs data didn't include portfolio, fetch directly from the portfolio endpoint\n if (portfolioItems.length === 0) {\n attemptedSections.push('portfolio')\n try {\n const apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = process.env.SONOR_API_KEY || ''\n if (apiKey) {\n const response = await fetch(`${apiUrl}/api/public/portfolio/items`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n })\n if (response.ok) {\n const result = await response.json()\n const items = result?.portfolioItems || result?.items || result || []\n portfolioItems = items.filter((item: any) => item.status === 'published')\n }\n }\n } catch (err) {\n console.warn('[site-kit/llms] Portfolio section failed:', err)\n failedSections.push('portfolio')\n }\n }\n\n if (portfolioItems.length > 0) {\n const portfolio = generatePortfolioSection(\n portfolioItems.slice(0, maxPortfolioItems),\n baseUrl\n )\n sections.push(portfolio)\n sectionNames.push('portfolio')\n }\n }\n\n // ========================================\n // Contact Section\n // ========================================\n if (includeContact && data.contact) {\n const contact = generateContactSection(data.contact)\n sections.push(contact)\n sectionNames.push('contact')\n }\n\n // ========================================\n // FAQ Section\n // ========================================\n if (includeFAQ && data.faq?.length > 0) {\n const faq = generateFAQSection(data.faq.slice(0, maxFAQItems))\n sections.push(faq)\n sectionNames.push('faq')\n }\n\n // ========================================\n // Pages Section (sitemap-like index)\n // ========================================\n if (includePages && data.pages?.length > 0) {\n const pages = generatePagesSection(\n data.pages.slice(0, maxPages),\n baseUrl,\n pageListNotesFromPublicSummaryOnly,\n )\n sections.push(pages)\n sectionNames.push('pages')\n }\n\n if (optionalPagePaths.length > 0 && baseUrl) {\n const opt = generateOptionalPagesSection(\n optionalPagePaths,\n data.pages || [],\n baseUrl,\n )\n if (opt) {\n sections.push(opt)\n sectionNames.push('optional')\n }\n }\n\n if (linkToFullLlms && baseUrl) {\n const fullPath = fullLlmsTxtPath.startsWith('/') ? fullLlmsTxtPath : `/${fullLlmsTxtPath}`\n const fullUrl = fullPath.startsWith('http') ? fullPath : `${baseUrl}${fullPath}`\n sections.push(\n `## Full context\\n\\n- [llms-full.txt](${fullUrl}): Expanded page index and FAQ for large-context systems.`,\n )\n sectionNames.push('full-context')\n }\n\n // ========================================\n // Knowledge Graph + Topic Clusters (parallel)\n // ========================================\n {\n type OptionalResult =\n | { kind: 'entities'; entities: SEOEntity[]; primaryEntity: SEOEntity | null }\n | { kind: 'clusters'; clusters: any[] }\n\n const optionalFetches: Promise<OptionalResult | null>[] = []\n\n if (includeEntities) {\n attemptedSections.push('knowledge-graph')\n optionalFetches.push(\n import('../seo/server-api')\n .then(async ({ getEntities, getPrimaryEntity }) => {\n const [entities, primaryEntity] = await Promise.all([\n getEntities().then(e => e.slice(0, maxEntities)),\n getPrimaryEntity(),\n ])\n return { kind: 'entities' as const, entities, primaryEntity }\n })\n .catch((err) => {\n console.warn('[site-kit/llms] Knowledge graph section failed:', err)\n failedSections.push('knowledge-graph')\n return null\n }),\n )\n }\n\n attemptedSections.push('topic-clusters')\n optionalFetches.push(\n import('../blog/server-core')\n .then(async ({ getTopicClusters }) => {\n const clusters = await getTopicClusters()\n return { kind: 'clusters' as const, clusters }\n })\n .catch((err) => {\n console.warn('[site-kit/llms] Topic clusters section failed:', err)\n failedSections.push('topic-clusters')\n return null\n }),\n )\n\n const settled = await Promise.all(optionalFetches)\n\n for (const result of settled) {\n if (!result) continue\n\n if (result.kind === 'entities') {\n if (result.entities.length > 0 || result.primaryEntity) {\n const entitySection = generateEntitySection(result.entities, result.primaryEntity, false)\n sections.push(entitySection)\n sectionNames.push('knowledge-graph')\n }\n }\n\n if (result.kind === 'clusters' && result.clusters.length > 0) {\n const clusterLines: string[] = ['## Topic Clusters', '']\n clusterLines.push('Organized content collections providing comprehensive coverage of key topics.', '')\n for (const cluster of result.clusters) {\n clusterLines.push(`### ${cluster.cluster_name}`)\n clusterLines.push(`Topic: ${cluster.core_topic}`)\n if (cluster.geo_target) clusterLines.push(`Area: ${cluster.geo_target}`)\n clusterLines.push(`Articles: ${cluster.article_count}`)\n if (cluster.target_service_page) {\n clusterLines.push(`Service page: ${baseUrl}${cluster.target_service_page}`)\n }\n\n // Enriched: list pillar page and recent articles\n if (cluster.pillar) {\n const pillarUrl = cluster.pillar.slug ? `${baseUrl}/blog/${cluster.pillar.slug}` : ''\n clusterLines.push(`Pillar: [${cluster.pillar.title || cluster.cluster_name}](${pillarUrl})`)\n }\n const supports = (cluster.supports || []) as any[]\n if (supports.length > 0) {\n const sorted = [...supports]\n .sort((a, b) => (b.published_at || '').localeCompare(a.published_at || ''))\n .slice(0, maxArticlesPerCluster)\n for (const article of sorted) {\n const articleUrl = article.slug ? `${baseUrl}/blog/${article.slug}` : ''\n const dateStr = article.published_at\n ? ` (${new Date(article.published_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })})`\n : ''\n clusterLines.push(`- [${article.title}](${articleUrl})${dateStr}`)\n }\n }\n\n clusterLines.push('')\n }\n sections.push(clusterLines.join('\\n'))\n sectionNames.push('topic-clusters')\n }\n }\n }\n\n // ========================================\n // Custom Sections\n // ========================================\n for (const custom of customSections) {\n sections.push(`## ${custom.title}\\n\\n${custom.content}`)\n sectionNames.push(custom.title.toLowerCase().replace(/\\s+/g, '-'))\n }\n\n return {\n markdown: sections.join('\\n\\n---\\n\\n'),\n metadata: {\n generated_at: new Date().toISOString(),\n project_id: projectId || '',\n sections: sectionNames,\n attempted_sections: attemptedSections.length ? attemptedSections : undefined,\n failed_sections: failedSections.length ? failedSections : undefined,\n }\n }\n}\n\n/**\n * Generate llms-full.txt with comprehensive knowledge dump\n * Use this for AI systems that can handle larger context\n */\nexport async function generateLLMsFullTxt(\n options: GenerateLLMSTxtOptions\n): Promise<LLMSTxtContent> {\n return generateLLMsTxt({\n ...options,\n includeBusinessInfo: true,\n includeServices: true,\n includeFAQ: true,\n includePages: true,\n includeContact: true,\n includePortfolio: true,\n includeEntities: true,\n maxFAQItems: 100,\n maxPages: 200,\n maxPortfolioItems: 50,\n maxEntities: 200,\n })\n}\n\n// ============================================\n// Section Generators\n// ============================================\n\nfunction buildHeaderMeta(\n base: LLMsPayloadMeta | null | undefined,\n primaryLanguageOverride?: string,\n disclaimerOverride?: string,\n): LLMsPayloadMeta | undefined {\n if (primaryLanguageOverride === undefined && disclaimerOverride === undefined) {\n return base ?? undefined\n }\n const merged: LLMsPayloadMeta = {\n contract_version: base?.contract_version ?? LLM_GEO_CONTRACT_VERSION,\n last_updated: base?.last_updated ?? null,\n primary_language: base?.primary_language ?? null,\n llms_disclaimer: base?.llms_disclaimer ?? null,\n }\n if (primaryLanguageOverride !== undefined) {\n const pl = sanitizePrimaryLanguageTag(primaryLanguageOverride)\n merged.primary_language = pl ?? merged.primary_language\n }\n if (disclaimerOverride !== undefined) {\n const d = sanitizeLlmsDisclaimerLine(disclaimerOverride)\n merged.llms_disclaimer = d ?? merged.llms_disclaimer\n }\n return merged\n}\n\nfunction generateHeaderSection(\n business: LLMBusinessInfo,\n meta?: LLMsPayloadMeta | null,\n resolvedBaseUrl?: string,\n): string {\n const lines: string[] = []\n \n // H1 with business name\n lines.push(`# ${business.name}`)\n lines.push('')\n \n // Blockquote summary (per llms.txt spec)\n const summary =\n business.tagline || business.description?.split('.')[0] || business.name\n lines.push(`> ${summary}`)\n if (meta?.last_updated) {\n lines.push(`> Content index last updated: ${meta.last_updated}`)\n }\n if (meta?.primary_language) {\n lines.push(`> Primary language: ${meta.primary_language}`)\n }\n if (meta?.llms_disclaimer) {\n lines.push(`> ${meta.llms_disclaimer}`)\n }\n \n if (business.industry) {\n lines.push('')\n lines.push(`**Industry:** ${humanizeIndustry(business.industry)}`)\n }\n \n if (business.service_area) {\n lines.push(`**Service Area:** ${business.service_area}`)\n }\n \n const website = business.website || resolvedBaseUrl\n if (website) {\n lines.push(`**Website:** ${website}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateAboutSection(business: LLMBusinessInfo): string {\n const lines: string[] = []\n \n lines.push('## About')\n lines.push('')\n lines.push(business.description)\n \n if (business.founded) {\n lines.push('')\n lines.push(`Established: ${business.founded}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateServicesSection(services: LLMService[]): string {\n const lines: string[] = []\n \n lines.push('## Services')\n lines.push('')\n \n for (const service of services) {\n if (service.url) {\n lines.push(`- **[${service.name}](${service.url})**: ${service.description}`)\n } else {\n lines.push(`- **${service.name}**: ${service.description}`)\n }\n }\n\n return lines.join('\\n')\n}\n\nfunction generatePortfolioSection(items: LLMPortfolioItem[], baseUrl: string): string {\n const lines: string[] = []\n\n lines.push('## Portfolio & Case Studies')\n lines.push('')\n\n for (const item of items) {\n const url = item.live_url || (item.slug ? `${baseUrl}/portfolio/${item.slug}` : '')\n\n if (url) {\n lines.push(`### [${item.title}](${url})`)\n } else {\n lines.push(`### ${item.title}`)\n }\n lines.push('')\n\n if (item.description) {\n lines.push(item.description)\n lines.push('')\n }\n\n const meta: string[] = []\n if (item.category) {\n meta.push(`**Category:** ${item.category}`)\n }\n if (item.services?.length) {\n meta.push(`**Services:** ${item.services.join(', ')}`)\n }\n if (item.live_url) {\n meta.push(`**Live Site:** ${item.live_url}`)\n }\n\n if (meta.length > 0) {\n lines.push(meta.join(' | '))\n lines.push('')\n }\n }\n\n return lines.join('\\n').trim()\n}\n\nfunction generateContactSection(contact: LLMContactInfo): string {\n const lines: string[] = []\n \n lines.push('## Contact Information')\n lines.push('')\n \n if (contact.phone) {\n lines.push(`- **Phone:** ${contact.phone}`)\n }\n if (contact.email) {\n lines.push(`- **Email:** ${contact.email}`)\n }\n if (contact.address || contact.city) {\n const addressParts = [\n contact.address,\n contact.city,\n contact.state,\n contact.postal_code,\n contact.country\n ].filter(Boolean)\n lines.push(`- **Address:** ${addressParts.join(', ')}`)\n }\n if (contact.hours) {\n lines.push(`- **Hours:** ${contact.hours}`)\n }\n\n return lines.join('\\n')\n}\n\nfunction generateFAQSection(faq: LLMFAQItem[]): string {\n const lines: string[] = []\n \n lines.push('## Frequently Asked Questions')\n lines.push('')\n \n for (const item of faq) {\n lines.push(`### ${item.question}`)\n lines.push('')\n lines.push(item.answer)\n lines.push('')\n }\n\n return lines.join('\\n').trim()\n}\n\nfunction pageListNote(\n page: LLMPageSummary,\n publicSummaryOnly: boolean,\n): string | undefined {\n const pub = sanitizeLlmsPublicSummary(page.llms_public_summary)\n if (pub) return pub\n if (publicSummaryOnly) return undefined\n if (page.description) return page.description.replace(/[\\[\\]\\r\\n]/g, ' ').trim()\n return undefined\n}\n\nfunction generatePagesSection(\n pages: LLMPageSummary[],\n baseUrl: string,\n publicSummaryOnly: boolean,\n): string {\n const lines: string[] = []\n \n lines.push('## Site Pages')\n lines.push('')\n \n for (const page of pages) {\n const url = page.path.startsWith('http') ? page.path : `${baseUrl}${page.path}`\n const note = pageListNote(page, publicSummaryOnly)\n if (note) {\n lines.push(`- [${page.title}](${url}): ${note}`)\n } else {\n lines.push(`- [${page.title}](${url})`)\n }\n }\n\n return lines.join('\\n')\n}\n\nfunction generateOptionalPagesSection(\n paths: string[],\n pages: LLMPageSummary[],\n baseUrl: string,\n): string | null {\n const normalizedBase = baseUrl.replace(/\\/$/, '')\n const byPath = new Map(pages.map(p => [p.path.replace(/\\/$/, '') || '/', p]))\n const lines: string[] = ['## Optional', '']\n let any = false\n for (const raw of paths) {\n const p = raw.startsWith('/') ? raw : `/${raw}`\n const norm = p.replace(/\\/$/, '') || '/'\n const match = byPath.get(norm) || byPath.get(`${norm}/`)\n const title = match?.title || norm.split('/').filter(Boolean).pop() || norm\n const url = `${normalizedBase}${p.endsWith('/') ? p : `${p}/`}`\n lines.push(`- [${title}](${url})`)\n any = true\n }\n return any ? lines.join('\\n') : null\n}\n\nfunction generateEntitySection(\n entities: SEOEntity[],\n primaryEntity: SEOEntity | null,\n detailed: boolean\n): string {\n const lines: string[] = []\n\n lines.push('## Knowledge Graph')\n lines.push('')\n\n // Primary entity first\n if (primaryEntity) {\n lines.push(`### ${primaryEntity.name} (Primary)`)\n lines.push('')\n lines.push(`- **Type:** ${primaryEntity.entity_type}`)\n if (primaryEntity.schema_type) {\n lines.push(`- **Schema:** ${primaryEntity.schema_type}`)\n }\n if (detailed && primaryEntity.knows_about?.length) {\n lines.push(`- **Knows About:** ${primaryEntity.knows_about.join(', ')}`)\n }\n if (detailed && primaryEntity.same_as?.length) {\n lines.push(`- **Same As:** ${primaryEntity.same_as.join(', ')}`)\n }\n lines.push('')\n }\n\n // Group remaining entities by type\n const grouped = new Map<string, SEOEntity[]>()\n for (const entity of entities) {\n if (primaryEntity && entity.id === primaryEntity.id) continue\n const type = entity.entity_type\n if (!grouped.has(type)) grouped.set(type, [])\n grouped.get(type)!.push(entity)\n }\n\n for (const [type, group] of grouped) {\n const label = type.charAt(0).toUpperCase() + type.slice(1) + 's'\n lines.push(`### ${label}`)\n lines.push('')\n for (const entity of group) {\n if (detailed) {\n lines.push(`- **${entity.name}**`)\n if (entity.knows_about?.length) {\n lines.push(` - Knows About: ${entity.knows_about.join(', ')}`)\n }\n if (entity.same_as?.length) {\n lines.push(` - Same As: ${entity.same_as.join(', ')}`)\n }\n } else {\n lines.push(`- ${entity.name}`)\n }\n }\n lines.push('')\n }\n\n return lines.join('\\n').trim()\n}\n\nexport default generateLLMsTxt\n","/**\n * @sonordev/site-kit/llms - Build-Time Write\n *\n * Fetches AI-optimized llms.txt from Portal API and writes to public/llms.txt\n * at build time. Integrates with sitemap flow when optimizedLLMsTxt is enabled.\n */\n\nimport { writeFileSync, mkdirSync, existsSync, renameSync, unlinkSync } from 'fs'\nimport { join } from 'path'\nimport { getOptimizedLLMsTxt } from './api'\nimport { generateLLMsTxt, generateLLMsFullTxt } from './generateLLMsTxt'\nimport type { LLMsDataResponse, LLMSTxtContent } from './types'\n\nexport interface LLMsCustomSection {\n title: string\n content: string\n}\n\nexport interface WriteLLMsTxtOptions {\n /** Output directory (default: public, relative to cwd) */\n outputDir?: string\n /** Write llms-full.txt as well */\n full?: boolean\n /** Portal API URL */\n apiUrl?: string\n /** Portal API key */\n apiKey?: string\n /** Fallback to non-optimized when API fails */\n fallbackToLocal?: boolean\n /**\n * Sub-site host this build belongs to (e.g. `bd-charlotte.com`). Scopes the\n * page index to THIS domain: one Sonor project can host many domains, and\n * seo_pages then holds one row PER HOST for shared paths like `/` and\n * `/terms`. Without it the API resolves an arbitrary sibling's row, so each\n * build described whichever neighbour happened to sync last. Omit to resolve\n * from NEXT_PUBLIC_SITE_URL via the shared `resolveSiteHost`.\n */\n site?: string\n /** When Portal returns empty services/faq/pages, use this to supply local site data */\n getLocalData?: () => Promise<LLMsDataResponse | null>\n /** Forward to GET /api/public/llms/txt and align local fallback with site-kit strict page notes */\n publicSummaryOnly?: boolean\n /**\n * Site-authored sections appended to llms-full.txt (never llms.txt — that\n * file stays a compact index). Applied on BOTH content paths: appended to\n * the Portal-optimized markdown, and forwarded to the local generator's\n * customSections on fallback. A function form is resolved at write time so\n * sites can build sections from local data (e.g. a verified citation\n * registry → a \"Sourced facts\" section via formatSourcedFactsSection).\n * Sections are only ever appended to real base content — they can never\n * cause a customs-only file to be written.\n */\n customSections?:\n | LLMsCustomSection[]\n | (() => Promise<LLMsCustomSection[] | null> | LLMsCustomSection[] | null)\n}\n\n/**\n * Fetch optimized llms.txt from Portal and write to public/llms.txt\n * Called at build time after sitemap sync (when optimizedLLMsTxt is enabled)\n *\n * Never persists a failure stub: when neither the Portal API nor local data\n * yields real content, the write is skipped entirely so a previously\n * generated (or committed) file keeps serving.\n */\nexport async function writeLLMsTxtToPublic(\n options: WriteLLMsTxtOptions = {}\n): Promise<{ success: boolean; path: string; optimized: boolean }> {\n const {\n outputDir = 'public',\n full = false,\n apiUrl,\n apiKey,\n fallbackToLocal = true,\n site,\n getLocalData,\n publicSummaryOnly,\n customSections,\n } = options\n\n const cwd = typeof process !== 'undefined' ? process.cwd() : '.'\n const outPath = join(cwd, outputDir)\n const llmsPath = join(outPath, 'llms.txt')\n const llmsFullPath = join(outPath, 'llms-full.txt')\n\n // Ensure output directory exists\n if (!existsSync(outPath)) {\n mkdirSync(outPath, { recursive: true })\n }\n\n const apiOptions = { apiUrl, apiKey, publicSummaryOnly, site }\n\n const genOpts = {\n site,\n getLocalData,\n pageListNotesFromPublicSummaryOnly: !!publicSummaryOnly,\n }\n\n // Fetch optimized content\n let markdown = toWritableMarkdown(await getOptimizedLLMsTxt({ ...apiOptions, full: false }))\n let optimized = !!markdown\n\n if (!markdown && fallbackToLocal) {\n console.warn('[site-kit] Optimized llms.txt unavailable, using local generation')\n const result = await generateLLMsTxt(genOpts)\n markdown = toWritableMarkdown(result.markdown, result.metadata)\n }\n\n if (!markdown) {\n console.warn(\n `[site-kit] llms.txt unavailable (Portal fetch failed, no local data) — skipped write, keeping any existing file at ${llmsPath}`\n )\n return { success: false, path: llmsPath, optimized: false }\n }\n\n atomicWriteSync(llmsPath, markdown)\n console.log(`[site-kit] Wrote llms.txt to ${llmsPath}`)\n\n if (full) {\n const sections = await resolveCustomSections(customSections)\n\n let fullMarkdown = toWritableMarkdown(await getOptimizedLLMsTxt({ ...apiOptions, full: true }))\n if (fullMarkdown && sections.length > 0) {\n // Portal path returns finished markdown — append the site's sections.\n fullMarkdown = appendCustomSections(fullMarkdown, sections)\n }\n if (!fullMarkdown && fallbackToLocal) {\n // Local path — the generator appends customSections itself.\n const result = await generateLLMsFullTxt({ ...genOpts, customSections: sections })\n fullMarkdown = toWritableMarkdown(result.markdown, result.metadata)\n }\n if (fullMarkdown) {\n atomicWriteSync(llmsFullPath, fullMarkdown)\n console.log(`[site-kit] Wrote llms-full.txt to ${llmsFullPath}`)\n } else {\n console.warn(\n `[site-kit] llms-full.txt unavailable — skipped write, keeping any existing file at ${llmsFullPath}`\n )\n }\n }\n\n return { success: true, path: llmsPath, optimized }\n}\n\n/**\n * Single source of truth for \"is this real llms.txt content that may be\n * persisted?\" — applied to both the optimized Portal response and the\n * local-generation fallback (llms.txt and llms-full.txt).\n *\n * generateLLMsTxt returns an \"Information not available.\" stub with zero\n * metadata.sections when the Portal fetch and local data both fail. Stubs and\n * empty responses must never reach disk: consumer route handlers serve\n * public/llms.txt with preferStatic, so a single failed build would replace a\n * good file and keep serving the stub to AI crawlers until the next\n * successful build.\n */\nfunction toWritableMarkdown(\n markdown: string | null | undefined,\n metadata?: LLMSTxtContent['metadata'],\n): string | null {\n if (!markdown || !markdown.trim()) return null\n if (metadata && metadata.sections.length === 0) return null\n return markdown\n}\n\n/**\n * Resolve the customSections option (array or factory) defensively: a\n * throwing/rejecting factory or malformed entries must never break the\n * write of the base file — the sections are an enhancement, not a gate.\n */\nasync function resolveCustomSections(\n input: WriteLLMsTxtOptions['customSections'],\n): Promise<LLMsCustomSection[]> {\n if (!input) return []\n try {\n const raw = typeof input === 'function' ? await input() : input\n if (!Array.isArray(raw)) return []\n return raw.filter(\n (s): s is LLMsCustomSection =>\n !!s && typeof s.title === 'string' && !!s.title.trim() &&\n typeof s.content === 'string' && !!s.content.trim(),\n )\n } catch (err) {\n console.warn('[site-kit] llms customSections factory failed — sections skipped:', err)\n return []\n }\n}\n\n/** Append site sections in the generator's own section format. */\nfunction appendCustomSections(markdown: string, sections: LLMsCustomSection[]): string {\n const blocks = sections.map((s) => `## ${s.title}\\n\\n${s.content}`)\n return `${markdown.replace(/\\s+$/, '')}\\n\\n---\\n\\n${blocks.join('\\n\\n---\\n\\n')}\\n`\n}\n\n/**\n * Atomic write: write to .tmp then rename (POSIX atomic).\n * Prevents corrupted files on crash or disk-full.\n */\nfunction atomicWriteSync(filePath: string, content: string): void {\n const tmp = `${filePath}.tmp`\n try {\n writeFileSync(tmp, content, 'utf-8')\n renameSync(tmp, filePath)\n } catch (err) {\n // Clean up temp file on failure\n try { unlinkSync(tmp) } catch { /* ignore */ }\n throw err\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { sonorFetch } from './chunk-
|
|
2
|
+
import { sonorFetch } from './chunk-ADOGOLYO.mjs';
|
|
3
3
|
import { useState, useCallback, useEffect } from 'react';
|
|
4
4
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -521,5 +521,5 @@ async function clearImageSlot(config, slotId, pagePath) {
|
|
|
521
521
|
}
|
|
522
522
|
|
|
523
523
|
export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage };
|
|
524
|
-
//# sourceMappingURL=chunk-
|
|
525
|
-
//# sourceMappingURL=chunk-
|
|
524
|
+
//# sourceMappingURL=chunk-5G2ZRQMO.mjs.map
|
|
525
|
+
//# sourceMappingURL=chunk-5G2ZRQMO.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":[],"mappings":"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","file":"chunk-YSZB2DRX.mjs","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/images/ManagedImage.tsx","../src/images/api.ts"],"names":[],"mappings":"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","file":"chunk-5G2ZRQMO.mjs","sourcesContent":["/**\n * ManagedImage - Portal-managed image component\n * \n * Features:\n * - Fetches images from Portal API via API key (never direct Supabase)\n * - Dev mode: Click to open image picker modal\n * - Supports responsive variants\n * - Automatic focal point handling\n * - Placeholder state for empty slots\n * \n * @example\n * ```tsx\n * <ManagedImage \n * slotId=\"hero-background\"\n * alt=\"Hero background image\"\n * className=\"w-full h-96 object-cover\"\n * />\n * ```\n */\n\n'use client'\n\nimport React, { useState, useEffect, useCallback } from 'react'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ManagedImageData {\n id: string\n slot_id: string\n page_path: string | null\n file_id: string | null\n external_url: string | null\n alt_text: string | null\n title: string | null\n caption: string | null\n focal_point_x: number\n focal_point_y: number\n aspect_ratio: string | null\n public_url?: string\n is_placeholder: boolean\n}\n\nexport interface ImageFile {\n id: string\n filename: string\n storage_path: string\n mime_type: string\n file_size: number\n folder_path: string | null\n public_url?: string\n}\n\nexport interface ManagedImageProps {\n /** API key for Portal API */\n apiKey?: string\n /** API URL (defaults to https://api.sonor.io) */\n apiUrl?: string\n /** Unique slot identifier (e.g., 'hero-background', 'about-team-1') */\n slotId: string\n /** Page path for page-specific slots (defaults to current path) */\n pagePath?: string\n /** Fallback alt text if not set in Portal */\n alt?: string\n /** CSS class names */\n className?: string\n /** Image width */\n width?: number | string\n /** Image height */\n height?: number | string\n /** CSS object-fit property */\n objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n /** Fallback image URL when no image assigned */\n fallback?: string\n /** Custom placeholder component */\n placeholder?: React.ReactNode\n /** Called when image loads */\n onLoad?: () => void\n /** Called on error */\n onError?: (error: Error) => void\n /** Priority loading (Next.js Image optimization) */\n priority?: boolean\n /** Additional styles */\n style?: React.CSSProperties\n /** Enable dev picker even outside dev mode */\n forceDevMode?: boolean\n}\n\n// Check if we're in dev mode\nconst isDevMode = (): boolean => {\n if (typeof window === 'undefined') return false\n return (\n process.env.NODE_ENV === 'development' ||\n window.location.hostname === 'localhost' ||\n window.location.hostname === '127.0.0.1' ||\n window.location.search.includes('uptrade_dev=true')\n )\n}\n\nexport function ManagedImage({\n apiKey = process.env.SONOR_API_KEY,\n apiUrl = process.env.SONOR_API_URL || 'https://api.sonor.io',\n slotId,\n pagePath,\n alt,\n className = '',\n width,\n height,\n objectFit = 'cover',\n fallback,\n placeholder,\n onLoad,\n onError,\n priority,\n style,\n forceDevMode,\n}: ManagedImageProps) {\n const [imageData, setImageData] = useState<ManagedImageData | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<Error | null>(null)\n const [showPicker, setShowPicker] = useState(false)\n const [devMode] = useState(() => forceDevMode || isDevMode())\n\n // Get current page path if not provided\n const currentPath = pagePath ?? (typeof window !== 'undefined' ? window.location.pathname : '/')\n\n // Fetch image data from Portal API\n const fetchImage = useCallback(async () => {\n if (!apiKey || !apiUrl) {\n setLoading(false)\n return\n }\n\n try {\n const params = new URLSearchParams({ page_path: currentPath })\n const res = await sonorFetch(\n `${apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n const data = await res.json()\n setImageData(data.image)\n setError(null)\n } catch (err) {\n // warn, not error: a failed slot fetch must not fail the Lighthouse\n // best-practices errors-in-console audit on every page using this slot.\n console.warn('[ManagedImage] Fetch error:', err)\n setError(err instanceof Error ? err : new Error(String(err)))\n onError?.(err instanceof Error ? err : new Error(String(err)))\n } finally {\n setLoading(false)\n }\n }, [apiKey, apiUrl, slotId, currentPath, onError])\n\n useEffect(() => {\n fetchImage()\n }, [fetchImage])\n\n // Calculate object-position from focal point\n const objectPosition = imageData\n ? `${imageData.focal_point_x}% ${imageData.focal_point_y}%`\n : '50% 50%'\n\n // Get the image URL\n const imageUrl = imageData?.public_url || imageData?.external_url || fallback\n\n // Handle click in dev mode\n const handleClick = (e: React.MouseEvent) => {\n if (devMode) {\n e.preventDefault()\n e.stopPropagation()\n setShowPicker(true)\n }\n }\n\n // Render placeholder state\n if (loading) {\n return (\n <div\n className={`bg-gray-200 animate-pulse ${className}`}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n />\n )\n }\n\n // No image assigned - show placeholder or dev picker hint\n if (!imageUrl) {\n if (placeholder) {\n return <>{placeholder}</>\n }\n\n return (\n <div\n onClick={handleClick}\n className={`\n bg-gray-100 border-2 border-dashed border-gray-300 \n flex items-center justify-center text-gray-400\n ${devMode ? 'cursor-pointer hover:border-blue-400 hover:text-blue-500 hover:bg-blue-50' : ''}\n ${className}\n `}\n style={{\n width: width ?? '100%',\n height: height ?? 200,\n ...style,\n }}\n title={devMode ? `Click to add image for slot: ${slotId}` : undefined}\n >\n <div className=\"text-center p-4\">\n <svg\n className=\"w-12 h-12 mx-auto mb-2\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\n />\n </svg>\n {devMode && (\n <p className=\"text-sm font-medium\">Click to add image</p>\n )}\n <p className=\"text-xs mt-1\">{slotId}</p>\n </div>\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n }\n\n // Render the image\n return (\n <div className=\"relative\" style={{ width, height }}>\n <img\n src={imageUrl}\n alt={imageData?.alt_text || alt || ''}\n title={imageData?.title || undefined}\n data-managed-image=\"true\"\n data-slot-id={slotId}\n data-page-path={currentPath}\n className={className}\n style={{\n objectFit,\n objectPosition,\n width: width ?? '100%',\n height: height ?? 'auto',\n ...style,\n }}\n onLoad={onLoad}\n onError={() => onError?.(new Error('Image failed to load'))}\n loading={priority ? 'eager' : 'lazy'}\n onClick={handleClick}\n />\n\n {/* Dev mode overlay */}\n {devMode && (\n <div\n className=\"absolute inset-0 bg-black/0 hover:bg-black/30 transition-colors cursor-pointer flex items-center justify-center opacity-0 hover:opacity-100\"\n onClick={handleClick}\n >\n <div className=\"bg-white/90 px-3 py-1.5 rounded-lg shadow-lg text-sm font-medium text-gray-700\">\n Edit Image\n </div>\n </div>\n )}\n\n {showPicker && (\n <ImagePickerModal\n slotId={slotId}\n pagePath={currentPath}\n config={{ apiKey, apiUrl }}\n currentImage={imageData}\n onClose={() => setShowPicker(false)}\n onSelect={() => {\n setShowPicker(false)\n fetchImage()\n }}\n />\n )}\n </div>\n )\n}\n\n// ============================================================================\n// IMAGE PICKER MODAL\n// ============================================================================\n\ninterface ImagePickerModalProps {\n slotId: string\n pagePath: string\n config: any\n currentImage?: ManagedImageData | null\n onClose: () => void\n onSelect: () => void\n}\n\nfunction ImagePickerModal({\n slotId,\n pagePath,\n config,\n currentImage,\n onClose,\n onSelect,\n}: ImagePickerModalProps) {\n const [files, setFiles] = useState<ImageFile[]>([])\n const [folders, setFolders] = useState<string[]>([])\n const [currentFolder, setCurrentFolder] = useState<string>('')\n const [search, setSearch] = useState('')\n const [loading, setLoading] = useState(true)\n const [uploading, setUploading] = useState(false)\n const [altText, setAltText] = useState(currentImage?.alt_text || '')\n\n // Fetch available files\n const fetchFiles = useCallback(async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n setLoading(true)\n try {\n const params = new URLSearchParams()\n if (currentFolder) params.set('folder', currentFolder)\n if (search) params.set('search', search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (res.ok) {\n const data = await res.json()\n setFiles(data.files || [])\n setFolders(data.folders || [])\n }\n } catch (err) {\n console.warn('[ImagePicker] Fetch error:', err)\n } finally {\n setLoading(false)\n }\n }, [config?.apiKey, config?.apiUrl, currentFolder, search])\n\n useEffect(() => {\n fetchFiles()\n }, [fetchFiles])\n\n // Select an existing file\n const handleSelectFile = async (file: ImageFile) => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: pagePath,\n file_id: file.id,\n alt_text: altText || file.filename,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Select error:', err)\n }\n }\n\n // Upload new file\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0]\n if (!file || !config?.apiKey || !config?.apiUrl) return\n\n setUploading(true)\n try {\n const formData = new FormData()\n formData.append('file', file)\n formData.append('slot_id', slotId)\n formData.append('page_path', pagePath)\n formData.append('folder', currentFolder || 'Website/Images')\n if (altText) formData.append('alt_text', altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long\n // timeout, no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (res.ok) {\n onSelect()\n }\n } catch (err) {\n console.warn('[ImagePicker] Upload error:', err)\n } finally {\n setUploading(false)\n }\n }\n\n // Clear the slot\n const handleClear = async () => {\n if (!config?.apiKey || !config?.apiUrl) return\n\n try {\n const params = new URLSearchParams({ page_path: pagePath })\n await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n onSelect()\n } catch (err) {\n console.warn('[ImagePicker] Clear error:', err)\n }\n }\n\n return (\n <div\n className=\"fixed inset-0 z-[99999] bg-black/50 flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <div\n className=\"bg-white rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-hidden\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-4 border-b\">\n <div>\n <h2 className=\"text-lg font-semibold\">Select Image</h2>\n <p className=\"text-sm text-gray-500\">Slot: {slotId}</p>\n </div>\n <button\n onClick={onClose}\n className=\"text-gray-400 hover:text-gray-600 p-2\"\n >\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-4 overflow-y-auto\" style={{ maxHeight: 'calc(90vh - 180px)' }}>\n {/* Upload & Search */}\n <div className=\"flex gap-4 mb-4\">\n <div className=\"flex-1\">\n <input\n type=\"text\"\n placeholder=\"Search images...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n <label className=\"px-4 py-2 bg-blue-600 text-white rounded-lg cursor-pointer hover:bg-blue-700 text-sm font-medium flex items-center gap-2\">\n {uploading ? 'Uploading...' : 'Upload New'}\n <input\n type=\"file\"\n accept=\"image/*\"\n onChange={handleUpload}\n disabled={uploading}\n className=\"hidden\"\n />\n </label>\n {currentImage?.file_id && (\n <button\n onClick={handleClear}\n className=\"px-4 py-2 border border-red-200 text-red-600 rounded-lg hover:bg-red-50 text-sm\"\n >\n Remove\n </button>\n )}\n </div>\n\n {/* Alt text input */}\n <div className=\"mb-4\">\n <input\n type=\"text\"\n placeholder=\"Alt text for image...\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n className=\"w-full px-3 py-2 border rounded-lg text-sm\"\n />\n </div>\n\n {/* Folder navigation */}\n {folders.length > 0 && (\n <div className=\"flex gap-2 mb-4 flex-wrap\">\n <button\n onClick={() => setCurrentFolder('')}\n className={`px-3 py-1 text-sm rounded-full ${\n !currentFolder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n All\n </button>\n {folders.map((folder) => (\n <button\n key={folder}\n onClick={() => setCurrentFolder(folder)}\n className={`px-3 py-1 text-sm rounded-full ${\n currentFolder === folder ? 'bg-blue-100 text-blue-700' : 'bg-gray-100 hover:bg-gray-200'\n }`}\n >\n {folder}\n </button>\n ))}\n </div>\n )}\n\n {/* File grid */}\n {loading ? (\n <div className=\"grid grid-cols-4 gap-4\">\n {[...Array(8)].map((_, i) => (\n <div key={i} className=\"aspect-square bg-gray-200 rounded-lg animate-pulse\" />\n ))}\n </div>\n ) : files.length === 0 ? (\n <div className=\"text-center py-12 text-gray-500\">\n <p>No images found</p>\n <p className=\"text-sm mt-1\">Upload a new image to get started</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-4 gap-4\">\n {files.map((file) => (\n <button\n key={file.id}\n onClick={() => handleSelectFile(file)}\n className={`\n aspect-square rounded-lg overflow-hidden border-2 transition-all\n hover:border-blue-400 hover:shadow-lg\n ${currentImage?.file_id === file.id ? 'border-blue-500 ring-2 ring-blue-200' : 'border-gray-200'}\n `}\n >\n <img\n src={file.public_url}\n alt={file.filename}\n className=\"w-full h-full object-cover\"\n />\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t bg-gray-50 flex justify-end\">\n <button\n onClick={onClose}\n className=\"px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg text-sm\"\n >\n Cancel\n </button>\n </div>\n </div>\n </div>\n )\n}\n\nexport default ManagedImage\n","/**\n * Images API functions\n * \n * All functions use Portal API with API key authentication.\n * Never makes direct Supabase calls.\n */\n\nimport type { ManagedImageData, ImageFile } from './ManagedImage'\nimport { sonorFetch } from '../shared/sonorFetch'\n\nexport interface ImageApiConfig {\n apiUrl: string\n apiKey: string\n}\n\n/**\n * Fetch a managed image for a specific slot\n */\nexport async function fetchManagedImage(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ image: ManagedImageData | null; is_placeholder: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Fetch all managed images for the project\n */\nexport async function fetchManagedImages(\n config: ImageApiConfig,\n options?: {\n pagePath?: string\n category?: string\n includePlaceholders?: boolean\n },\n): Promise<{ images: ManagedImageData[] }> {\n const params = new URLSearchParams()\n if (options?.pagePath) params.set('page_path', options.pagePath)\n if (options?.category) params.set('category', options.category)\n if (options?.includePlaceholders) params.set('include_placeholders', 'true')\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch images: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * List available image files in the project\n */\nexport async function listImageFiles(\n config: ImageApiConfig,\n options?: {\n folder?: string\n search?: string\n },\n): Promise<{ files: ImageFile[]; folders: string[] }> {\n const params = new URLSearchParams()\n if (options?.folder) params.set('folder', options.folder)\n if (options?.search) params.set('search', options.search)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/files?${params}`,\n { headers: { 'Content-Type': 'application/json' } },\n { apiKey: config.apiKey },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to list files: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Upload a new image\n */\nexport async function uploadImage(\n config: ImageApiConfig,\n file: File,\n options?: {\n slotId?: string\n pagePath?: string\n folder?: string\n altText?: string\n },\n): Promise<{ file: ImageFile; image?: ManagedImageData }> {\n const formData = new FormData()\n formData.append('file', file)\n if (options?.slotId) formData.append('slot_id', options.slotId)\n if (options?.pagePath) formData.append('page_path', options.pagePath)\n if (options?.folder) formData.append('folder', options.folder)\n if (options?.altText) formData.append('alt_text', options.altText)\n\n // No Content-Type — the browser sets the multipart boundary. Long timeout,\n // no retry: a retried upload would duplicate the file.\n const res = await sonorFetch(`${config.apiUrl}/public/images/upload`, {\n method: 'POST',\n body: formData,\n }, { apiKey: config.apiKey, retries: 0, timeoutMs: 60000 })\n\n if (!res.ok) {\n throw new Error(`Failed to upload image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Assign an existing file to an image slot\n */\nexport async function assignImageToSlot(\n config: ImageApiConfig,\n slotId: string,\n options: {\n fileId?: string\n externalUrl?: string\n pagePath?: string\n altText?: string\n title?: string\n caption?: string\n focalPointX?: number\n focalPointY?: number\n aspectRatio?: string\n },\n): Promise<{ image: ManagedImageData }> {\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n page_path: options.pagePath,\n file_id: options.fileId,\n external_url: options.externalUrl,\n alt_text: options.altText,\n title: options.title,\n caption: options.caption,\n focal_point_x: options.focalPointX,\n focal_point_y: options.focalPointY,\n aspect_ratio: options.aspectRatio,\n }),\n },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to assign image: ${res.status}`)\n }\n\n return res.json()\n}\n\n/**\n * Clear an image from a slot (keeps the file)\n */\nexport async function clearImageSlot(\n config: ImageApiConfig,\n slotId: string,\n pagePath?: string,\n): Promise<{ success: boolean }> {\n const params = new URLSearchParams()\n if (pagePath) params.set('page_path', pagePath)\n\n const res = await sonorFetch(\n `${config.apiUrl}/public/images/slot/${encodeURIComponent(slotId)}?${params}`,\n { method: 'DELETE' },\n { apiKey: config.apiKey, retries: 0 },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to clear slot: ${res.status}`)\n }\n\n return res.json()\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getApiConfig } from './chunk-
|
|
1
|
+
import { getApiConfig } from './chunk-ZFZMN4LT.mjs';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
function HoneypotField({ name, value, onChange }) {
|
|
@@ -56,5 +56,5 @@ function NativeFallbackFields({ config, returnTo }) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export { HoneypotField, NativeFallbackFields, nativeFormProps };
|
|
59
|
-
//# sourceMappingURL=chunk-
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
59
|
+
//# sourceMappingURL=chunk-5W56B52Z.mjs.map
|
|
60
|
+
//# sourceMappingURL=chunk-5W56B52Z.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx"],"mappings":";;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/forms/HoneypotField.tsx","../src/forms/native-fallback.tsx"],"names":["jsx"],"mappings":";;;AAqCO,SAAS,aAAA,CAAc,EAAE,IAAA,EAAM,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,WAAA,GAAc,OAAO,QAAA,KAAa,UAAA;AACxC,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,MAAA;AAAA,MACL,IAAA;AAAA,MACA,QAAA,EAAU,EAAA;AAAA,MACV,YAAA,EAAa,cAAA;AAAA,MACb,aAAA,EAAY,MAAA;AAAA,MACZ,KAAA,EAAK,IAAA;AAAA,MACL,kBAAA,EAAiB,EAAA;AAAA,MAGjB,gBAAA,EAAe,EAAA;AAAA,MACf,eAAA,EAAc,MAAA;AAAA,MACd,gBAAA,EAAe,OAAA;AAAA,MACf,eAAA,EAAc,EAAA;AAAA,MACd,KAAA,EAAO;AAAA,QACL,QAAA,EAAU,UAAA;AAAA,QACV,IAAA,EAAM,KAAA;AAAA,QACN,KAAA,EAAO,CAAA;AAAA,QACP,MAAA,EAAQ,CAAA;AAAA,QACR,QAAA,EAAU,QAAA;AAAA,QACV,OAAA,EAAS,CAAA;AAAA,QACT,UAAA,EAAY,QAAA;AAAA,QACZ,aAAA,EAAe;AAAA,OACjB;AAAA,MACC,GAAI,WAAA,GACD;AAAA,QACE,OAAO,KAAA,IAAS,EAAA;AAAA,QAChB,QAAA,EAAU,CAAC,CAAA,KAA2C;AACpD,UAAA,QAAA,CAAU,CAAA,CAAE,OAAO,KAAK,CAAA;AACxB,UAAA,IAAI,CAAA,CAAE,OAAO,KAAA,EAAO;AAElB,YAAA,OAAA,CAAQ,KAAK,4BAA4B,CAAA;AAAA,UAC3C;AAAA,QACF;AAAA,OACF,GACA,EAAE,YAAA,EAAc,EAAA;AAAG;AAAA,GACzB;AAEJ;ACjDA,SAAS,eAAe,MAAA,EAAuD;AAC7E,EAAA,OAAO,CAAC,CAAC,MAAA,EAAQ,YAAA,IAAgB,CAAC,MAAA,CAAO,aAAA;AAC3C;AAGO,SAAS,gBACd,MAAA,EACsC;AACtC,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,SAAU,EAAC;AACrC,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,YAAA,EAAa;AAChC,EAAA,OAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,+BAAA,CAAA,EAAmC,QAAQ,MAAA,EAAO;AAC9E;AAaO,SAAS,oBAAA,CAAqB,EAAE,MAAA,EAAQ,QAAA,EAAS,EAA8B;AACpF,EAAA,IAAI,CAAC,cAAA,CAAe,MAAM,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,aAAY,KAAA,EAAO,MAAA,CAAQ,YAAA,EAAc,QAAA,EAAQ,IAAA,EAAC,CAAA;AAAA,IAC3E,QAAA,mBAAWA,GAAAA,CAAC,OAAA,EAAA,EAAM,IAAA,EAAK,QAAA,EAAS,IAAA,EAAK,YAAA,EAAa,KAAA,EAAO,QAAA,EAAU,QAAA,EAAQ,IAAA,EAAC,CAAA,GAAK;AAAA,GAAA,EACpF,CAAA;AAEJ","file":"chunk-5W56B52Z.mjs","sourcesContent":["/**\n * Single source of truth for the honeypot input — rendered by BOTH form\n * experiences (classic and stage) inside their <form>. The customRender path\n * deliberately gets none (documented limitation: custom renders lose the\n * honeypot, which is why alternate experiences must be render branches).\n *\n * Invariants (do not weaken any of these):\n * - `inert` blocks focus/interaction at the browser level, surviving hostile\n * site CSS that could defeat the inline styles.\n * - data-sk-honeypot gives site CSS a stable opt-OUT hook.\n * - Controlled input: bots filling via JS still fire React onChange, so the\n * value reaches submitForm's data payload.\n * - Name comes from config (`honeypot_field || DEFAULT_HONEYPOT_FIELD` from\n * the shared contract) — resolved by the caller, never forked here.\n * - The trap must be invisible to AUTOFILL as well as to people. A browser or\n * password manager filling a hidden input flags a real visitor as a bot, and\n * because the value is stripped server-side the mistake is undiagnosable\n * after the fact. `autocomplete=\"off\"` does not achieve this — it is the one\n * value Chrome deliberately ignores for contact/address autofill — so the\n * trap declares `new-password` (never offered saved contact data) plus the\n * documented per-manager opt-outs.\n */\n\nimport React from 'react'\n\nexport interface HoneypotFieldProps {\n name: string\n value?: string\n /**\n * Omit for STATIC mode — an uncontrolled trap a Server Component can render.\n * The trap's whole job is server-side (the value is read off the submission\n * and stripped), so it needs no client state to work; the controlled form is\n * only so the hydrated JSON path can read it back out of React state.\n */\n onChange?: (value: string) => void\n}\n\nexport function HoneypotField({ name, value, onChange }: HoneypotFieldProps) {\n const interactive = typeof onChange === 'function'\n return (\n <input\n type=\"text\"\n name={name}\n tabIndex={-1}\n autoComplete=\"new-password\"\n aria-hidden=\"true\"\n inert\n data-sk-honeypot=\"\"\n // Password-manager opt-outs: 1Password, LastPass, Dashlane, Bitwarden.\n // Each ignores its own attribute; none respects autocomplete alone.\n data-1p-ignore=\"\"\n data-lpignore=\"true\"\n data-form-type=\"other\"\n data-bwignore=\"\"\n style={{\n position: 'absolute',\n left: -9999,\n width: 1,\n height: 1,\n overflow: 'hidden',\n opacity: 0,\n visibility: 'hidden',\n pointerEvents: 'none',\n }}\n {...(interactive\n ? {\n value: value ?? '',\n onChange: (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange!(e.target.value)\n if (e.target.value) {\n // Bot detected\n console.warn('[Forms] Honeypot triggered')\n }\n },\n }\n : { defaultValue: '' })}\n />\n )\n}\n","'use client'\n\n/**\n * No-JS native submission fallback — the floor under every managed form.\n *\n * The classic form is the SSR/no-JS surface (experiences are post-hydration\n * chunks), so it alone carries a real `action`/`method` pointing at\n * sonor-api's POST /api/public/forms/submit-native. With JS running, the\n * form's onSubmit preventDefault()s and the JSON path wins; without JS the\n * browser performs an ordinary form-encoded POST and the lead still lands.\n *\n * Auth rides in the hidden `_sk_token` field: a signed, single-purpose\n * credential minted by the api-key-authenticated forms/config endpoint\n * (`native_token` in the response). No token in the config (older API, or no\n * signing secret) means no fallback — the form keeps its historical behavior\n * rather than pointing at an endpoint that will reject it.\n *\n * Multi-step forms are excluded: step navigation is JS, and a native POST of\n * step-1 fields alone fails whole-form validation server-side. Single-step\n * forms are the overwhelming lead-capture case.\n *\n * Single source of truth for the gating — the form attrs and the hidden\n * fields must always agree, so both read the same predicate.\n */\n\nimport React from 'react'\nimport type { ManagedFormConfig } from './types'\nimport { getApiConfig } from './submitForm'\n\nfunction nativeEligible(config: ManagedFormConfig | null | undefined): boolean {\n return !!config?.native_token && !config.is_multi_step\n}\n\n/** `action`/`method` for the classic <form> — empty when ineligible. */\nexport function nativeFormProps(\n config: ManagedFormConfig | null | undefined,\n): { action?: string; method?: 'post' } {\n if (!nativeEligible(config)) return {}\n const { apiUrl } = getApiConfig()\n return { action: `${apiUrl}/api/public/forms/submit-native`, method: 'post' }\n}\n\nexport interface NativeFallbackFieldsProps {\n config: ManagedFormConfig | null | undefined\n /**\n * Absolute URL the native 303 should land on (usually the page hosting the\n * form). Optional — without it the server falls back to the Referer origin,\n * which loses the path but still returns the visitor to the right site.\n */\n returnTo?: string\n}\n\n/** Hidden control fields the native endpoint reads (`_sk_*` namespace). */\nexport function NativeFallbackFields({ config, returnTo }: NativeFallbackFieldsProps) {\n if (!nativeEligible(config)) return null\n return (\n <>\n <input type=\"hidden\" name=\"_sk_token\" value={config!.native_token} readOnly />\n {returnTo ? <input type=\"hidden\" name=\"_sk_return\" value={returnTo} readOnly /> : null}\n </>\n )\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useSignalExperiment, useSignalEvent } from './chunk-
|
|
2
|
+
import { useSignalExperiment, useSignalEvent } from './chunk-NIJVVW4G.mjs';
|
|
3
3
|
import React, { useEffect } from 'react';
|
|
4
4
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -71,5 +71,5 @@ function ExperimentConversion({
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
export { ExperimentConversion, SignalExperiment, useExperimentVariant };
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
75
|
-
//# sourceMappingURL=chunk-
|
|
74
|
+
//# sourceMappingURL=chunk-6YKNDQYJ.mjs.map
|
|
75
|
+
//# sourceMappingURL=chunk-6YKNDQYJ.mjs.map
|