@sonordev/site-kit 5.4.0 → 5.6.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/AGENTS.md +16 -6
- package/README.md +9 -7
- package/agent-manifest.json +7 -7
- package/dist/AnalyticsProvider-6PXC7UDP.js +32 -0
- package/dist/{AnalyticsProvider-Y2P2BPOI.js.map → AnalyticsProvider-6PXC7UDP.js.map} +1 -1
- package/dist/AnalyticsProvider-FVQIYSLY.mjs +11 -0
- package/dist/{AnalyticsProvider-2XIOMRCN.mjs.map → AnalyticsProvider-FVQIYSLY.mjs.map} +1 -1
- package/dist/{BlogViewTracker-6EGEDPP3.js → BlogViewTracker-S4HSRCW7.js} +6 -6
- package/dist/{BlogViewTracker-6EGEDPP3.js.map → BlogViewTracker-S4HSRCW7.js.map} +1 -1
- package/dist/{BlogViewTracker-R4YQ76WP.mjs → BlogViewTracker-ZUGLBOVI.mjs} +5 -5
- package/dist/{BlogViewTracker-R4YQ76WP.mjs.map → BlogViewTracker-ZUGLBOVI.mjs.map} +1 -1
- package/dist/ChatWidget-2TQWCXWP.js +22 -0
- package/dist/{ChatWidget-2OFWPCWF.js.map → ChatWidget-2TQWCXWP.js.map} +1 -1
- package/dist/ChatWidget-DG52ZIE6.mjs +13 -0
- package/dist/{ChatWidget-4AOGHYXQ.mjs.map → ChatWidget-DG52ZIE6.mjs.map} +1 -1
- package/dist/EngageWidget-2VUJADIU.mjs +12 -0
- package/dist/{EngageWidget-SFO2XRNG.mjs.map → EngageWidget-2VUJADIU.mjs.map} +1 -1
- package/dist/EngageWidget-Z7RC2INM.js +21 -0
- package/dist/{EngageWidget-T4KAAD3G.js.map → EngageWidget-Z7RC2INM.js.map} +1 -1
- package/dist/{FileField-7DF2SLPF.mjs → FileField-FSQ7W3A5.mjs} +5 -5
- package/dist/{FileField-7DF2SLPF.mjs.map → FileField-FSQ7W3A5.mjs.map} +1 -1
- package/dist/{FileField-CE2XNBBG.js → FileField-UOQHL25J.js} +6 -6
- package/dist/{FileField-CE2XNBBG.js.map → FileField-UOQHL25J.js.map} +1 -1
- package/dist/{FormSpotlight-IRLKSZGV.mjs → FormSpotlight-RHL5FWM2.mjs} +3 -3
- package/dist/{FormSpotlight-IRLKSZGV.mjs.map → FormSpotlight-RHL5FWM2.mjs.map} +1 -1
- package/dist/{FormSpotlight-ZD3WR5BC.js → FormSpotlight-TED32NHP.js} +15 -15
- package/dist/{FormSpotlight-ZD3WR5BC.js.map → FormSpotlight-TED32NHP.js.map} +1 -1
- package/dist/{FormStage-2OSRNQJL.mjs → FormStage-DINIRFOX.mjs} +3 -3
- package/dist/{FormStage-2OSRNQJL.mjs.map → FormStage-DINIRFOX.mjs.map} +1 -1
- package/dist/{FormStage-OSPXOUQE.js → FormStage-PFEBKHGY.js} +13 -13
- package/dist/{FormStage-OSPXOUQE.js.map → FormStage-PFEBKHGY.js.map} +1 -1
- package/dist/ManagedForm-43WLCUAK.js +23 -0
- package/dist/{ManagedForm-JCHGBBQW.js.map → ManagedForm-43WLCUAK.js.map} +1 -1
- package/dist/ManagedForm-545YAUFC.mjs +14 -0
- package/dist/{ManagedForm-5G37EDJT.mjs.map → ManagedForm-545YAUFC.mjs.map} +1 -1
- package/dist/{ManagedNewsletterForm-4LVJZROZ.js → ManagedNewsletterForm-I3QN57HB.js} +8 -8
- package/dist/{ManagedNewsletterForm-4LVJZROZ.js.map → ManagedNewsletterForm-I3QN57HB.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-QJSVH23S.mjs → ManagedNewsletterForm-ZPY5RRKX.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-QJSVH23S.mjs.map → ManagedNewsletterForm-ZPY5RRKX.mjs.map} +1 -1
- package/dist/{SignalCore-L6Z3YTCF.mjs → SignalCore-EEH5IM4U.mjs} +5 -5
- package/dist/{SignalCore-L6Z3YTCF.mjs.map → SignalCore-EEH5IM4U.mjs.map} +1 -1
- package/dist/{SignalCore-NQ4YEOI7.js → SignalCore-M4AXIMV4.js} +11 -11
- package/dist/{SignalCore-NQ4YEOI7.js.map → SignalCore-M4AXIMV4.js.map} +1 -1
- package/dist/SitemapSync-46G7LVZS.mjs +9 -0
- package/dist/{SitemapSync-MYSTLJOM.mjs.map → SitemapSync-46G7LVZS.mjs.map} +1 -1
- package/dist/SitemapSync-XK4JKCS7.js +18 -0
- package/dist/{SitemapSync-3LUZWBTB.js.map → SitemapSync-XK4JKCS7.js.map} +1 -1
- package/dist/SitemapSync.d.ts +3 -2
- package/dist/SitemapSync.d.ts.map +1 -1
- package/dist/analytics/AnalyticsProvider.d.ts +3 -1
- package/dist/analytics/AnalyticsProvider.d.ts.map +1 -1
- package/dist/analytics/WebVitals.d.ts +3 -1
- package/dist/analytics/WebVitals.d.ts.map +1 -1
- package/dist/analytics/dispatch.d.ts +4 -4
- package/dist/analytics/index.js +19 -19
- package/dist/analytics/index.mjs +7 -7
- package/dist/analytics/send-gate.d.ts +8 -37
- package/dist/analytics/send-gate.d.ts.map +1 -1
- package/dist/{api-NTHZ6PAW.mjs → api-D745LGGU.mjs} +3 -3
- package/dist/api-D745LGGU.mjs.map +1 -0
- package/dist/{api-N5OLQXYN.js → api-XR5APCH3.js} +3 -3
- package/dist/api-XR5APCH3.js.map +1 -0
- 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-HMFFAUCD.js → chunk-3DWIYCQX.js} +2 -2
- package/dist/chunk-3DWIYCQX.js.map +1 -0
- package/dist/{chunk-3EPMDPWI.js → chunk-3SDMJMN2.js} +5 -5
- package/dist/{chunk-3EPMDPWI.js.map → chunk-3SDMJMN2.js.map} +1 -1
- package/dist/{chunk-LIYSLNEK.mjs → chunk-473WDGQZ.mjs} +3 -3
- package/dist/{chunk-LIYSLNEK.mjs.map → chunk-473WDGQZ.mjs.map} +1 -1
- package/dist/chunk-4U5NCKQY.mjs +39 -0
- package/dist/chunk-4U5NCKQY.mjs.map +1 -0
- package/dist/{chunk-ITFZZ6YT.js → chunk-53KMRZT7.js} +3 -3
- package/dist/{chunk-ITFZZ6YT.js.map → chunk-53KMRZT7.js.map} +1 -1
- package/dist/{chunk-N6AVWMIB.mjs → chunk-5KIEZHVK.mjs} +19 -18
- package/dist/chunk-5KIEZHVK.mjs.map +1 -0
- package/dist/{chunk-ZLPXFV5Y.js → chunk-5KIO6FXE.js} +5 -5
- package/dist/{chunk-ZLPXFV5Y.js.map → chunk-5KIO6FXE.js.map} +1 -1
- package/dist/chunk-5RNAUYWE.js +50 -0
- package/dist/chunk-5RNAUYWE.js.map +1 -0
- package/dist/{chunk-ACTLQ2RH.mjs → chunk-5UFDHGFE.mjs} +4 -4
- package/dist/chunk-5UFDHGFE.mjs.map +1 -0
- package/dist/{chunk-RO55G3OA.mjs → chunk-64BOVMXG.mjs} +3 -3
- package/dist/{chunk-RO55G3OA.mjs.map → chunk-64BOVMXG.mjs.map} +1 -1
- package/dist/{chunk-G5I3XEQS.mjs → chunk-6OP5XSMM.mjs} +3 -3
- package/dist/{chunk-G5I3XEQS.mjs.map → chunk-6OP5XSMM.mjs.map} +1 -1
- package/dist/{chunk-7Y2UPFSY.mjs → chunk-7AUDKXY5.mjs} +3 -3
- package/dist/{chunk-7Y2UPFSY.mjs.map → chunk-7AUDKXY5.mjs.map} +1 -1
- package/dist/{chunk-A2VLEORI.mjs → chunk-7C7XO5HX.mjs} +3 -3
- package/dist/{chunk-A2VLEORI.mjs.map → chunk-7C7XO5HX.mjs.map} +1 -1
- package/dist/chunk-A6UYV475.mjs +45 -0
- package/dist/chunk-A6UYV475.mjs.map +1 -0
- package/dist/{chunk-SZHKNGNR.mjs → chunk-AEARU24Q.mjs} +40 -26
- package/dist/chunk-AEARU24Q.mjs.map +1 -0
- package/dist/{chunk-ZDFVYSKK.mjs → chunk-AHZR4VGY.mjs} +5 -5
- package/dist/{chunk-ZDFVYSKK.mjs.map → chunk-AHZR4VGY.mjs.map} +1 -1
- package/dist/{chunk-4WQB2ORG.js → chunk-AY7JBGYC.js} +15 -15
- package/dist/chunk-AY7JBGYC.js.map +1 -0
- package/dist/{chunk-5737U6DI.js → chunk-B64AZC6P.js} +15 -15
- package/dist/{chunk-5737U6DI.js.map → chunk-B64AZC6P.js.map} +1 -1
- package/dist/{chunk-ZY5AVC4P.js → chunk-B6O7D5U4.js} +55 -49
- package/dist/chunk-B6O7D5U4.js.map +1 -0
- package/dist/{chunk-LHYVFWHL.js → chunk-BWSMUSDB.js} +8 -8
- package/dist/{chunk-LHYVFWHL.js.map → chunk-BWSMUSDB.js.map} +1 -1
- package/dist/{chunk-WSUQ76LN.js → chunk-BZLIOT7Q.js} +18 -18
- package/dist/{chunk-WSUQ76LN.js.map → chunk-BZLIOT7Q.js.map} +1 -1
- package/dist/{chunk-HH5KGXTK.mjs → chunk-C2MSD2UM.mjs} +4 -4
- package/dist/{chunk-HH5KGXTK.mjs.map → chunk-C2MSD2UM.mjs.map} +1 -1
- package/dist/{chunk-DPDV5Z4G.js → chunk-CQRLKNHQ.js} +12 -12
- package/dist/{chunk-DPDV5Z4G.js.map → chunk-CQRLKNHQ.js.map} +1 -1
- package/dist/{chunk-SJXGIUHP.mjs → chunk-CQS5ZYI6.mjs} +22 -9
- package/dist/chunk-CQS5ZYI6.mjs.map +1 -0
- package/dist/{chunk-LUYUFILE.js → chunk-DHIWR7CG.js} +4 -4
- package/dist/{chunk-LUYUFILE.js.map → chunk-DHIWR7CG.js.map} +1 -1
- package/dist/chunk-DQUBETXH.mjs +6 -0
- package/dist/{chunk-7U7C6XRI.mjs.map → chunk-DQUBETXH.mjs.map} +1 -1
- package/dist/chunk-ESP5RMB7.js +42 -0
- package/dist/chunk-ESP5RMB7.js.map +1 -0
- package/dist/chunk-G6WF4G3E.js +43 -0
- package/dist/chunk-G6WF4G3E.js.map +1 -0
- package/dist/{chunk-XWF7QPIP.mjs → chunk-GJ6NOLGC.mjs} +3 -3
- package/dist/{chunk-XWF7QPIP.mjs.map → chunk-GJ6NOLGC.mjs.map} +1 -1
- package/dist/{chunk-MTANHZKJ.mjs → chunk-GPLCPMVD.mjs} +7 -7
- package/dist/{chunk-MTANHZKJ.mjs.map → chunk-GPLCPMVD.mjs.map} +1 -1
- package/dist/{chunk-QWLL3B6U.js → chunk-H3D3ZGOJ.js} +26 -23
- package/dist/chunk-H3D3ZGOJ.js.map +1 -0
- package/dist/{chunk-NUH245XK.mjs → chunk-H44XZUOV.mjs} +16 -13
- package/dist/chunk-H44XZUOV.mjs.map +1 -0
- package/dist/{chunk-MIFP6QEQ.mjs → chunk-HIHAXEPD.mjs} +4 -4
- package/dist/{chunk-MIFP6QEQ.mjs.map → chunk-HIHAXEPD.mjs.map} +1 -1
- package/dist/{chunk-UOLY4NXK.mjs → chunk-IYCLN3XS.mjs} +15 -34
- package/dist/chunk-IYCLN3XS.mjs.map +1 -0
- package/dist/{chunk-HBMF3M5F.js → chunk-JE5DWAE6.js} +4 -4
- package/dist/{chunk-HBMF3M5F.js.map → chunk-JE5DWAE6.js.map} +1 -1
- package/dist/{chunk-KQ3VAOAF.mjs → chunk-JNABXCLY.mjs} +4 -4
- package/dist/{chunk-KQ3VAOAF.mjs.map → chunk-JNABXCLY.mjs.map} +1 -1
- package/dist/{chunk-3TXX5KIN.js → chunk-JNRHTZL4.js} +2 -2
- package/dist/{chunk-3TXX5KIN.js.map → chunk-JNRHTZL4.js.map} +1 -1
- package/dist/{chunk-I4PDSDVE.mjs → chunk-K2V3ZW36.mjs} +3 -3
- package/dist/{chunk-I4PDSDVE.mjs.map → chunk-K2V3ZW36.mjs.map} +1 -1
- package/dist/{chunk-L2LJQIM3.js → chunk-KPKQKFT4.js} +11 -11
- package/dist/chunk-KPKQKFT4.js.map +1 -0
- package/dist/chunk-KSL3WA2I.js +8 -0
- package/dist/{chunk-UTOHMK52.js.map → chunk-KSL3WA2I.js.map} +1 -1
- package/dist/{chunk-VWDT7H6L.js → chunk-KY6M76JW.js} +3 -3
- package/dist/{chunk-VWDT7H6L.js.map → chunk-KY6M76JW.js.map} +1 -1
- package/dist/{chunk-EBMPXFOP.mjs → chunk-LCSYJXIO.mjs} +3 -3
- package/dist/{chunk-EBMPXFOP.mjs.map → chunk-LCSYJXIO.mjs.map} +1 -1
- package/dist/{chunk-AWFZIXCT.js → chunk-N2PGTPWN.js} +25 -12
- package/dist/chunk-N2PGTPWN.js.map +1 -0
- package/dist/chunk-NSWO43XW.mjs +39 -0
- package/dist/chunk-NSWO43XW.mjs.map +1 -0
- package/dist/{chunk-KMGGAL2X.js → chunk-NZSFOZJV.js} +40 -26
- package/dist/chunk-NZSFOZJV.js.map +1 -0
- package/dist/{chunk-JJ26JKBJ.mjs → chunk-OA7KKOAK.mjs} +25 -31
- package/dist/chunk-OA7KKOAK.mjs.map +1 -0
- package/dist/{chunk-GQ6CUOLA.js → chunk-OC7AO7XS.js} +15 -15
- package/dist/{chunk-GQ6CUOLA.js.map → chunk-OC7AO7XS.js.map} +1 -1
- package/dist/{chunk-HDDV63XJ.mjs → chunk-QNPVVWR7.mjs} +3 -3
- package/dist/{chunk-HDDV63XJ.mjs.map → chunk-QNPVVWR7.mjs.map} +1 -1
- package/dist/{chunk-URVGBWCP.js → chunk-R3KTBKSW.js} +4 -4
- package/dist/{chunk-URVGBWCP.js.map → chunk-R3KTBKSW.js.map} +1 -1
- package/dist/{chunk-6CUBSQMD.mjs → chunk-RIYAMYLV.mjs} +3 -3
- package/dist/{chunk-6CUBSQMD.mjs.map → chunk-RIYAMYLV.mjs.map} +1 -1
- package/dist/{chunk-B4BFQSSS.mjs → chunk-RU54J2PY.mjs} +4 -4
- package/dist/chunk-RU54J2PY.mjs.map +1 -0
- package/dist/{chunk-7IPSQ5JR.js → chunk-S4RC6VAQ.js} +21 -20
- package/dist/chunk-S4RC6VAQ.js.map +1 -0
- package/dist/{chunk-3DPXOZAU.mjs → chunk-SHLWA6JY.mjs} +2 -2
- package/dist/chunk-SHLWA6JY.mjs.map +1 -0
- package/dist/{chunk-OXZYP32B.js → chunk-SYGGZZMU.js} +21 -17
- package/dist/chunk-SYGGZZMU.js.map +1 -0
- package/dist/{chunk-LF4L3ZP5.js → chunk-T5VTQUNF.js} +8 -8
- package/dist/{chunk-LF4L3ZP5.js.map → chunk-T5VTQUNF.js.map} +1 -1
- package/dist/{chunk-UOTXSWKZ.mjs → chunk-TP7H6BSK.mjs} +2 -2
- package/dist/{chunk-UOTXSWKZ.mjs.map → chunk-TP7H6BSK.mjs.map} +1 -1
- package/dist/{chunk-N6X76QUF.mjs → chunk-USKIL6V6.mjs} +3 -3
- package/dist/{chunk-N6X76QUF.mjs.map → chunk-USKIL6V6.mjs.map} +1 -1
- package/dist/{chunk-2KIGFOPM.js → chunk-UU47DGHE.js} +25 -44
- package/dist/chunk-UU47DGHE.js.map +1 -0
- package/dist/{chunk-B36PTS7B.mjs → chunk-VHZ4LHQT.mjs} +48 -42
- package/dist/chunk-VHZ4LHQT.mjs.map +1 -0
- package/dist/{chunk-7PLH3H3W.js → chunk-X5TCH7VZ.js} +3 -3
- package/dist/{chunk-7PLH3H3W.js.map → chunk-X5TCH7VZ.js.map} +1 -1
- package/dist/{chunk-LBS4PRC7.js → chunk-XK5AIWQG.js} +3 -3
- package/dist/{chunk-LBS4PRC7.js.map → chunk-XK5AIWQG.js.map} +1 -1
- package/dist/{chunk-U53KN4SA.js → chunk-XR32C47O.js} +26 -32
- package/dist/chunk-XR32C47O.js.map +1 -0
- package/dist/{chunk-DQM5GR2P.mjs → chunk-YCI36ZUS.mjs} +18 -14
- package/dist/chunk-YCI36ZUS.mjs.map +1 -0
- package/dist/{chunk-VA36CJRV.js → chunk-YYN4YZYZ.js} +4 -4
- package/dist/{chunk-VA36CJRV.js.map → chunk-YYN4YZYZ.js.map} +1 -1
- package/dist/cli/agent/checks.d.ts.map +1 -1
- package/dist/cli/agent/ssr-bailout.d.ts +27 -0
- package/dist/cli/agent/ssr-bailout.d.ts.map +1 -0
- package/dist/cli/agent/ssr-bailout.test.d.ts +2 -0
- package/dist/cli/agent/ssr-bailout.test.d.ts.map +1 -0
- package/dist/cli/api/{uptrade.d.ts → sonor.d.ts} +3 -2
- package/dist/cli/api/sonor.d.ts.map +1 -0
- package/dist/cli/codemod/transforms.d.ts.map +1 -1
- package/dist/cli/commands/config-regression.test.d.ts +2 -0
- package/dist/cli/commands/config-regression.test.d.ts.map +1 -0
- package/dist/cli/commands/faqs.d.ts.map +1 -1
- package/dist/cli/commands/images.d.ts.map +1 -1
- package/dist/cli/commands/locations.d.ts.map +1 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/config.d.ts +31 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.test.d.ts +2 -0
- package/dist/cli/config.test.d.ts.map +1 -0
- package/dist/cli/index.js +494 -518
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +487 -511
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/migrator/index.d.ts +1 -0
- package/dist/cli/migrator/index.d.ts.map +1 -1
- package/dist/cli/state.d.ts +7 -0
- package/dist/cli/state.d.ts.map +1 -0
- package/dist/cli/state.test.d.ts +2 -0
- package/dist/cli/state.test.d.ts.map +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +20 -7
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +5 -4
- package/dist/client/index.mjs.map +1 -1
- package/dist/cms/index.js.map +1 -1
- package/dist/cms/index.mjs.map +1 -1
- package/dist/cms/sanity-image.d.ts +1 -1
- package/dist/commerce/index.js +59 -59
- package/dist/commerce/index.mjs +8 -8
- package/dist/engage/ChatWidget.d.ts.map +1 -1
- package/dist/engage/EngageWidget.d.ts +4 -4
- package/dist/engage/EngageWidget.d.ts.map +1 -1
- package/dist/engage/chat-launcher.test.d.ts +2 -0
- package/dist/engage/chat-launcher.test.d.ts.map +1 -0
- package/dist/engage/index.js +13 -10
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +10 -7
- package/dist/engage/index.mjs.map +1 -1
- package/dist/engage/launcher-placement.d.ts +56 -0
- package/dist/engage/launcher-placement.d.ts.map +1 -0
- package/dist/engage/launcher-placement.test.d.ts +2 -0
- package/dist/engage/launcher-placement.test.d.ts.map +1 -0
- package/dist/engage/types.d.ts +41 -7
- package/dist/engage/types.d.ts.map +1 -1
- package/dist/fleet/FleetHeartbeat.d.ts +3 -2
- package/dist/fleet/FleetHeartbeat.d.ts.map +1 -1
- package/dist/fleet/heartbeat.d.ts +3 -2
- package/dist/fleet/heartbeat.d.ts.map +1 -1
- package/dist/fleet/heartbeat.test.d.ts +2 -0
- package/dist/fleet/heartbeat.test.d.ts.map +1 -0
- package/dist/fleet/index.js +9 -8
- package/dist/fleet/index.mjs +5 -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/ManagedImage.d.ts.map +1 -1
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +66 -66
- package/dist/index.mjs +12 -12
- package/dist/layout/SiteKitClientProviders.d.ts.map +1 -1
- package/dist/layout/client.d.ts.map +1 -1
- package/dist/layout/client.js +9 -8
- package/dist/layout/client.mjs +8 -7
- package/dist/layout/index.js +11 -10
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +9 -8
- package/dist/layout/index.mjs.map +1 -1
- package/dist/layout/types.d.ts +9 -3
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/llms/generateLLMsTxt.d.ts.map +1 -1
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.mjs +2 -2
- package/dist/llms/types.d.ts +7 -1
- package/dist/llms/types.d.ts.map +1 -1
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/mcp/WebMcpTools.d.ts +5 -2
- package/dist/mcp/WebMcpTools.d.ts.map +1 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/client.mjs.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/LocationPageContent.d.ts +6 -5
- package/dist/seo/LocationPageContent.d.ts.map +1 -1
- package/dist/seo/api.d.ts +4 -5
- package/dist/seo/api.d.ts.map +1 -1
- package/dist/seo/client.js +6 -6
- package/dist/seo/client.mjs +5 -5
- package/dist/seo/index.js +43 -43
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +9 -9
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/routing.d.ts +9 -23
- package/dist/seo/routing.d.ts.map +1 -1
- package/dist/seo/server-api.d.ts +11 -5
- package/dist/seo/server-api.d.ts.map +1 -1
- package/dist/seo/server.js +18 -18
- package/dist/seo/server.mjs +2 -2
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/{server-api-HW4PL2L2.mjs → server-api-RG3ZL3DV.mjs} +3 -3
- package/dist/{server-api-HW4PL2L2.mjs.map → server-api-RG3ZL3DV.mjs.map} +1 -1
- package/dist/{server-api-DB2SIUP4.js → server-api-RYJQAUGO.js} +21 -21
- package/dist/{server-api-DB2SIUP4.js.map → server-api-RYJQAUGO.js.map} +1 -1
- package/dist/shared/reporting-gate.d.ts +43 -0
- package/dist/shared/reporting-gate.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/shared/visual-viewport-gap.d.ts +52 -0
- package/dist/shared/visual-viewport-gap.d.ts.map +1 -0
- package/dist/shared/visual-viewport-gap.test.d.ts +2 -0
- package/dist/shared/visual-viewport-gap.test.d.ts.map +1 -0
- 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/AddToCalendar.d.ts +19 -0
- package/dist/sync/AddToCalendar.d.ts.map +1 -0
- package/dist/sync/BookingWidget.d.ts.map +1 -1
- package/dist/sync/add-to-calendar.test.d.ts +2 -0
- package/dist/sync/add-to-calendar.test.d.ts.map +1 -0
- package/dist/sync/api-errors.test.d.ts +2 -0
- package/dist/sync/api-errors.test.d.ts.map +1 -0
- package/dist/sync/api.d.ts.map +1 -1
- package/dist/sync/index.js +17 -17
- package/dist/sync/index.mjs +4 -4
- package/dist/sync/types.d.ts +14 -0
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/skills/site-kit/SKILL.md +8 -3
- package/dist/AnalyticsProvider-2XIOMRCN.mjs +0 -11
- package/dist/AnalyticsProvider-Y2P2BPOI.js +0 -32
- package/dist/ChatWidget-2OFWPCWF.js +0 -20
- package/dist/ChatWidget-4AOGHYXQ.mjs +0 -11
- package/dist/EngageWidget-SFO2XRNG.mjs +0 -9
- package/dist/EngageWidget-T4KAAD3G.js +0 -18
- package/dist/ManagedForm-5G37EDJT.mjs +0 -14
- package/dist/ManagedForm-JCHGBBQW.js +0 -23
- package/dist/SitemapSync-3LUZWBTB.js +0 -18
- package/dist/SitemapSync-MYSTLJOM.mjs +0 -9
- package/dist/api-N5OLQXYN.js.map +0 -1
- package/dist/api-NTHZ6PAW.mjs.map +0 -1
- package/dist/chunk-2KIGFOPM.js.map +0 -1
- package/dist/chunk-3DPXOZAU.mjs.map +0 -1
- package/dist/chunk-4WQB2ORG.js.map +0 -1
- package/dist/chunk-7IPSQ5JR.js.map +0 -1
- package/dist/chunk-7U7C6XRI.mjs +0 -6
- package/dist/chunk-ACTLQ2RH.mjs.map +0 -1
- package/dist/chunk-AWFZIXCT.js.map +0 -1
- package/dist/chunk-B36PTS7B.mjs.map +0 -1
- package/dist/chunk-B4BFQSSS.mjs.map +0 -1
- package/dist/chunk-DQM5GR2P.mjs.map +0 -1
- package/dist/chunk-HMFFAUCD.js.map +0 -1
- package/dist/chunk-JJ26JKBJ.mjs.map +0 -1
- package/dist/chunk-KMGGAL2X.js.map +0 -1
- package/dist/chunk-L2LJQIM3.js.map +0 -1
- package/dist/chunk-N6AVWMIB.mjs.map +0 -1
- package/dist/chunk-NUH245XK.mjs.map +0 -1
- package/dist/chunk-NVSWTDWU.mjs +0 -25
- package/dist/chunk-NVSWTDWU.mjs.map +0 -1
- package/dist/chunk-OL2QBWAU.js +0 -29
- package/dist/chunk-OL2QBWAU.js.map +0 -1
- package/dist/chunk-OXZYP32B.js.map +0 -1
- package/dist/chunk-QWLL3B6U.js.map +0 -1
- package/dist/chunk-SJXGIUHP.mjs.map +0 -1
- package/dist/chunk-SZHKNGNR.mjs.map +0 -1
- package/dist/chunk-U53KN4SA.js.map +0 -1
- package/dist/chunk-UOLY4NXK.mjs.map +0 -1
- package/dist/chunk-UTOHMK52.js +0 -8
- package/dist/chunk-ZY5AVC4P.js.map +0 -1
- package/dist/cli/api/uptrade.d.ts.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -4,11 +4,11 @@ import { parse } from '../chunk-5YA6SI4Z.mjs';
|
|
|
4
4
|
import { buildOgHtml, TITLE_MAX_PX, OG_REPORT_ATTR } from '../chunk-UJ6CHZAI.mjs';
|
|
5
5
|
import { require_main } from '../chunk-NNZDWY3L.mjs';
|
|
6
6
|
import { findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-XIJ4F6IE.mjs';
|
|
7
|
-
import { SITE_KIT_VERSION } from '../chunk-
|
|
7
|
+
import { SITE_KIT_VERSION } from '../chunk-DQUBETXH.mjs';
|
|
8
8
|
import { __commonJS, __require, __toESM, __export, __privateAdd, __publicField, __privateGet, __privateMethod, __privateSet, __privateWrapper } from '../chunk-BEXTDHO4.mjs';
|
|
9
9
|
import { EventEmitter } from 'events';
|
|
10
10
|
import childProcess, { execFile as execFile$1, execSync, spawnSync, spawn } from 'child_process';
|
|
11
|
-
import
|
|
11
|
+
import path12, { win32, posix } from 'path';
|
|
12
12
|
import * as fs from 'fs';
|
|
13
13
|
import fs__default, { realpathSync, existsSync, readFileSync, readdirSync, statSync, readlinkSync, readdir as readdir$1, lstatSync, rmSync, mkdtempSync, writeFileSync } from 'fs';
|
|
14
14
|
import process2 from 'process';
|
|
@@ -6202,10 +6202,10 @@ var require_lib2 = __commonJS({
|
|
|
6202
6202
|
exports.analyse = analyse;
|
|
6203
6203
|
var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
|
|
6204
6204
|
let fd;
|
|
6205
|
-
const
|
|
6205
|
+
const fs29 = (0, node_1.default)();
|
|
6206
6206
|
const handler = (err, buffer) => {
|
|
6207
6207
|
if (fd) {
|
|
6208
|
-
|
|
6208
|
+
fs29.closeSync(fd);
|
|
6209
6209
|
}
|
|
6210
6210
|
if (err) {
|
|
6211
6211
|
reject(err);
|
|
@@ -6217,9 +6217,9 @@ var require_lib2 = __commonJS({
|
|
|
6217
6217
|
};
|
|
6218
6218
|
const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
|
|
6219
6219
|
if (sampleSize > 0) {
|
|
6220
|
-
fd =
|
|
6220
|
+
fd = fs29.openSync(filepath, "r");
|
|
6221
6221
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
6222
|
-
|
|
6222
|
+
fs29.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
|
|
6223
6223
|
if (err) {
|
|
6224
6224
|
handler(err, null);
|
|
6225
6225
|
} else {
|
|
@@ -6231,22 +6231,22 @@ var require_lib2 = __commonJS({
|
|
|
6231
6231
|
});
|
|
6232
6232
|
return;
|
|
6233
6233
|
}
|
|
6234
|
-
|
|
6234
|
+
fs29.readFile(filepath, handler);
|
|
6235
6235
|
});
|
|
6236
6236
|
exports.detectFile = detectFile;
|
|
6237
6237
|
var detectFileSync = (filepath, opts = {}) => {
|
|
6238
|
-
const
|
|
6238
|
+
const fs29 = (0, node_1.default)();
|
|
6239
6239
|
if (opts && opts.sampleSize) {
|
|
6240
|
-
const fd =
|
|
6240
|
+
const fd = fs29.openSync(filepath, "r");
|
|
6241
6241
|
let sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
6242
|
-
const bytesRead =
|
|
6242
|
+
const bytesRead = fs29.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
|
|
6243
6243
|
if (bytesRead < opts.sampleSize) {
|
|
6244
6244
|
sample = sample.subarray(0, bytesRead);
|
|
6245
6245
|
}
|
|
6246
|
-
|
|
6246
|
+
fs29.closeSync(fd);
|
|
6247
6247
|
return (0, exports.detect)(sample);
|
|
6248
6248
|
}
|
|
6249
|
-
return (0, exports.detect)(
|
|
6249
|
+
return (0, exports.detect)(fs29.readFileSync(filepath));
|
|
6250
6250
|
};
|
|
6251
6251
|
exports.detectFileSync = detectFileSync;
|
|
6252
6252
|
exports.default = {
|
|
@@ -10135,7 +10135,7 @@ var require_run_async = __commonJS({
|
|
|
10135
10135
|
});
|
|
10136
10136
|
|
|
10137
10137
|
// src/cli/index.ts
|
|
10138
|
-
var
|
|
10138
|
+
var import_dotenv2 = __toESM(require_main());
|
|
10139
10139
|
|
|
10140
10140
|
// node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
10141
10141
|
var CommanderError = class extends Error {
|
|
@@ -12264,9 +12264,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
12264
12264
|
args = args.slice();
|
|
12265
12265
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
12266
12266
|
function findFile(baseDir, baseName) {
|
|
12267
|
-
const localBin =
|
|
12267
|
+
const localBin = path12.resolve(baseDir, baseName);
|
|
12268
12268
|
if (fs__default.existsSync(localBin)) return localBin;
|
|
12269
|
-
if (sourceExt.includes(
|
|
12269
|
+
if (sourceExt.includes(path12.extname(baseName))) return void 0;
|
|
12270
12270
|
const foundExt = sourceExt.find(
|
|
12271
12271
|
(ext2) => fs__default.existsSync(`${localBin}${ext2}`)
|
|
12272
12272
|
);
|
|
@@ -12284,17 +12284,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
12284
12284
|
} catch {
|
|
12285
12285
|
resolvedScriptPath = this._scriptPath;
|
|
12286
12286
|
}
|
|
12287
|
-
executableDir =
|
|
12288
|
-
|
|
12287
|
+
executableDir = path12.resolve(
|
|
12288
|
+
path12.dirname(resolvedScriptPath),
|
|
12289
12289
|
executableDir
|
|
12290
12290
|
);
|
|
12291
12291
|
}
|
|
12292
12292
|
if (executableDir) {
|
|
12293
12293
|
let localFile = findFile(executableDir, executableFile);
|
|
12294
12294
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
12295
|
-
const legacyName =
|
|
12295
|
+
const legacyName = path12.basename(
|
|
12296
12296
|
this._scriptPath,
|
|
12297
|
-
|
|
12297
|
+
path12.extname(this._scriptPath)
|
|
12298
12298
|
);
|
|
12299
12299
|
if (legacyName !== this._name) {
|
|
12300
12300
|
localFile = findFile(
|
|
@@ -12305,7 +12305,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
12305
12305
|
}
|
|
12306
12306
|
executableFile = localFile || executableFile;
|
|
12307
12307
|
}
|
|
12308
|
-
const launchWithNode = sourceExt.includes(
|
|
12308
|
+
const launchWithNode = sourceExt.includes(path12.extname(executableFile));
|
|
12309
12309
|
let proc;
|
|
12310
12310
|
if (process2.platform !== "win32") {
|
|
12311
12311
|
if (launchWithNode) {
|
|
@@ -13222,7 +13222,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
13222
13222
|
* @return {Command}
|
|
13223
13223
|
*/
|
|
13224
13224
|
nameFromFilename(filename) {
|
|
13225
|
-
this._name =
|
|
13225
|
+
this._name = path12.basename(filename, path12.extname(filename));
|
|
13226
13226
|
return this;
|
|
13227
13227
|
}
|
|
13228
13228
|
/**
|
|
@@ -13236,9 +13236,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
13236
13236
|
* @param {string} [path]
|
|
13237
13237
|
* @return {(string|null|Command)}
|
|
13238
13238
|
*/
|
|
13239
|
-
executableDir(
|
|
13240
|
-
if (
|
|
13241
|
-
this._executableDir =
|
|
13239
|
+
executableDir(path29) {
|
|
13240
|
+
if (path29 === void 0) return this._executableDir;
|
|
13241
|
+
this._executableDir = path29;
|
|
13242
13242
|
return this;
|
|
13243
13243
|
}
|
|
13244
13244
|
/**
|
|
@@ -18747,7 +18747,7 @@ function createPrompt(view) {
|
|
|
18747
18747
|
if (nextView === void 0) {
|
|
18748
18748
|
let callerFilename = callSites[1]?.getFileName();
|
|
18749
18749
|
if (callerFilename && !callerFilename.startsWith("file://")) {
|
|
18750
|
-
callerFilename =
|
|
18750
|
+
callerFilename = path12.resolve(callerFilename);
|
|
18751
18751
|
}
|
|
18752
18752
|
throw new Error(`Prompt functions must return a string.
|
|
18753
18753
|
at ${callerFilename}`);
|
|
@@ -19136,13 +19136,13 @@ var ExternalEditor = class {
|
|
|
19136
19136
|
}
|
|
19137
19137
|
createTempFile() {
|
|
19138
19138
|
try {
|
|
19139
|
-
const baseDir =
|
|
19140
|
-
this.tempDir = mkdtempSync(
|
|
19139
|
+
const baseDir = path12.resolve(this.fileOptions.dir ?? os.tmpdir());
|
|
19140
|
+
this.tempDir = mkdtempSync(path12.join(baseDir, "inquirer-editor-"));
|
|
19141
19141
|
const id = randomUUID();
|
|
19142
19142
|
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
|
19143
19143
|
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
|
19144
19144
|
const filename = `${prefix}${id}${postfix}`;
|
|
19145
|
-
this.tempFile =
|
|
19145
|
+
this.tempFile = path12.join(this.tempDir, filename);
|
|
19146
19146
|
const opt = { encoding: "utf8", flag: "wx" };
|
|
19147
19147
|
if (Object.prototype.hasOwnProperty.call(this.fileOptions, "mode")) {
|
|
19148
19148
|
opt.mode = this.fileOptions.mode;
|
|
@@ -20345,9 +20345,9 @@ function observableToAsyncIterable(source) {
|
|
|
20345
20345
|
|
|
20346
20346
|
// node_modules/.pnpm/inquirer@14.0.2_@types+node@26.2.0/node_modules/inquirer/dist/ui/prompt.js
|
|
20347
20347
|
var _ = {
|
|
20348
|
-
set: (obj,
|
|
20348
|
+
set: (obj, path29 = "", value) => {
|
|
20349
20349
|
let pointer = obj;
|
|
20350
|
-
|
|
20350
|
+
path29.split(".").forEach((key, index, arr) => {
|
|
20351
20351
|
if (key === "__proto__" || key === "constructor")
|
|
20352
20352
|
return;
|
|
20353
20353
|
if (index === arr.length - 1) {
|
|
@@ -20358,8 +20358,8 @@ var _ = {
|
|
|
20358
20358
|
pointer = pointer[key];
|
|
20359
20359
|
});
|
|
20360
20360
|
},
|
|
20361
|
-
get: (obj,
|
|
20362
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
20361
|
+
get: (obj, path29 = "", defaultValue) => {
|
|
20362
|
+
const travel = (regexp) => String.prototype.split.call(path29, regexp).filter(Boolean).reduce(
|
|
20363
20363
|
// @ts-expect-error implicit any on res[key]
|
|
20364
20364
|
(res, key) => res == null ? res : res[key],
|
|
20365
20365
|
obj
|
|
@@ -20649,7 +20649,7 @@ async function scanCodebase(rootDir) {
|
|
|
20649
20649
|
for (const file of files) {
|
|
20650
20650
|
try {
|
|
20651
20651
|
const content = await fs3.readFile(file, "utf-8");
|
|
20652
|
-
const relPath =
|
|
20652
|
+
const relPath = path12.relative(rootDir, file);
|
|
20653
20653
|
const ast = parse(content, {
|
|
20654
20654
|
sourceType: "module",
|
|
20655
20655
|
plugins: ["jsx", "typescript"]
|
|
@@ -20698,7 +20698,7 @@ async function scanCodebase(rootDir) {
|
|
|
20698
20698
|
async function findSourceFiles(dir, files = []) {
|
|
20699
20699
|
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
20700
20700
|
for (const entry of entries) {
|
|
20701
|
-
const fullPath =
|
|
20701
|
+
const fullPath = path12.join(dir, entry.name);
|
|
20702
20702
|
if (entry.isDirectory()) {
|
|
20703
20703
|
if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
|
|
20704
20704
|
continue;
|
|
@@ -20716,18 +20716,18 @@ function scanForForms(ast, content, filePath) {
|
|
|
20716
20716
|
const forms = [];
|
|
20717
20717
|
content.split("\n");
|
|
20718
20718
|
traverse(ast, {
|
|
20719
|
-
JSXElement(
|
|
20720
|
-
const opening =
|
|
20719
|
+
JSXElement(path29) {
|
|
20720
|
+
const opening = path29.node.openingElement;
|
|
20721
20721
|
if (isJSXIdentifier(opening.name) && opening.name.name === "form") {
|
|
20722
|
-
const fields = extractFieldsFromForm(
|
|
20722
|
+
const fields = extractFieldsFromForm(path29);
|
|
20723
20723
|
const hasOnSubmit = opening.attributes.some(
|
|
20724
20724
|
(attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "onSubmit"
|
|
20725
20725
|
);
|
|
20726
20726
|
if (hasOnSubmit && fields.length > 0) {
|
|
20727
|
-
const startLine =
|
|
20728
|
-
const endLine =
|
|
20727
|
+
const startLine = path29.node.loc?.start.line || 0;
|
|
20728
|
+
const endLine = path29.node.loc?.end.line || 0;
|
|
20729
20729
|
let componentName = "UnknownForm";
|
|
20730
|
-
let current =
|
|
20730
|
+
let current = path29.parentPath;
|
|
20731
20731
|
while (current) {
|
|
20732
20732
|
if (isFunctionDeclaration(current.node) && current.node.id) {
|
|
20733
20733
|
componentName = current.node.id.name;
|
|
@@ -20760,7 +20760,7 @@ function scanForForms(ast, content, filePath) {
|
|
|
20760
20760
|
}
|
|
20761
20761
|
if (isJSXIdentifier(opening.name) && opening.name.name === "Form") {
|
|
20762
20762
|
if (content.includes("Formik") || content.includes("formik")) {
|
|
20763
|
-
const fields = extractFieldsFromFormik(
|
|
20763
|
+
const fields = extractFieldsFromFormik(path29);
|
|
20764
20764
|
if (fields.length > 0) {
|
|
20765
20765
|
forms.push({
|
|
20766
20766
|
filePath,
|
|
@@ -20771,8 +20771,8 @@ function scanForForms(ast, content, filePath) {
|
|
|
20771
20771
|
submitsTo: null,
|
|
20772
20772
|
complexity: "moderate",
|
|
20773
20773
|
suggestedAction: "assisted",
|
|
20774
|
-
startLine:
|
|
20775
|
-
endLine:
|
|
20774
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
20775
|
+
endLine: path29.node.loc?.end.line || 0
|
|
20776
20776
|
});
|
|
20777
20777
|
}
|
|
20778
20778
|
}
|
|
@@ -20790,8 +20790,8 @@ function extractFieldsFromForm(formPath) {
|
|
|
20790
20790
|
const radioGroups = /* @__PURE__ */ new Map();
|
|
20791
20791
|
const checkboxGroups = /* @__PURE__ */ new Map();
|
|
20792
20792
|
formPath.traverse({
|
|
20793
|
-
JSXElement(
|
|
20794
|
-
const opening =
|
|
20793
|
+
JSXElement(path29) {
|
|
20794
|
+
const opening = path29.node.openingElement;
|
|
20795
20795
|
const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
|
|
20796
20796
|
if (["input", "textarea", "select"].includes(tagName || "")) {
|
|
20797
20797
|
const attrs = opening.attributes;
|
|
@@ -20838,7 +20838,7 @@ function extractFieldsFromForm(formPath) {
|
|
|
20838
20838
|
}
|
|
20839
20839
|
if (tagName === "select") {
|
|
20840
20840
|
const selectOptions = [];
|
|
20841
|
-
|
|
20841
|
+
path29.traverse({
|
|
20842
20842
|
JSXElement(optionPath) {
|
|
20843
20843
|
const optOpening = optionPath.node.openingElement;
|
|
20844
20844
|
const optTagName = isJSXIdentifier(optOpening.name) ? optOpening.name.name : null;
|
|
@@ -20913,8 +20913,8 @@ function extractFieldsFromForm(formPath) {
|
|
|
20913
20913
|
function extractFieldsFromFormik(formPath, content) {
|
|
20914
20914
|
const fields = [];
|
|
20915
20915
|
formPath.traverse({
|
|
20916
|
-
JSXElement(
|
|
20917
|
-
const opening =
|
|
20916
|
+
JSXElement(path29) {
|
|
20917
|
+
const opening = path29.node.openingElement;
|
|
20918
20918
|
const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
|
|
20919
20919
|
if (tagName === "Field" || tagName === "FastField") {
|
|
20920
20920
|
const attrs = opening.attributes;
|
|
@@ -21033,11 +21033,11 @@ function scanForMetadata(ast, content, filePath) {
|
|
|
21033
21033
|
}
|
|
21034
21034
|
let hasHeadComponent = false;
|
|
21035
21035
|
traverse(ast, {
|
|
21036
|
-
JSXElement(
|
|
21037
|
-
const opening =
|
|
21036
|
+
JSXElement(path29) {
|
|
21037
|
+
const opening = path29.node.openingElement;
|
|
21038
21038
|
if (isJSXIdentifier(opening.name) && opening.name.name === "Head") {
|
|
21039
21039
|
hasHeadComponent = true;
|
|
21040
|
-
|
|
21040
|
+
path29.stop();
|
|
21041
21041
|
}
|
|
21042
21042
|
}
|
|
21043
21043
|
});
|
|
@@ -21072,8 +21072,8 @@ function scanForWidgets(ast, content, filePath) {
|
|
|
21072
21072
|
for (const { pattern, type } of widgetPatterns) {
|
|
21073
21073
|
if (pattern.test(content)) {
|
|
21074
21074
|
traverse(ast, {
|
|
21075
|
-
JSXElement(
|
|
21076
|
-
const opening =
|
|
21075
|
+
JSXElement(path29) {
|
|
21076
|
+
const opening = path29.node.openingElement;
|
|
21077
21077
|
if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
|
|
21078
21078
|
const srcAttr = opening.attributes.find(
|
|
21079
21079
|
(attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "src"
|
|
@@ -21088,8 +21088,8 @@ function scanForWidgets(ast, content, filePath) {
|
|
|
21088
21088
|
filePath,
|
|
21089
21089
|
widgetType: type,
|
|
21090
21090
|
scriptTag: src,
|
|
21091
|
-
startLine:
|
|
21092
|
-
endLine:
|
|
21091
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
21092
|
+
endLine: path29.node.loc?.end.line || 0
|
|
21093
21093
|
});
|
|
21094
21094
|
}
|
|
21095
21095
|
}
|
|
@@ -21163,7 +21163,7 @@ async function scanForSitemapFiles(rootDir) {
|
|
|
21163
21163
|
"next-sitemap.config.ts"
|
|
21164
21164
|
];
|
|
21165
21165
|
for (const configPath of configPaths) {
|
|
21166
|
-
const fullPath =
|
|
21166
|
+
const fullPath = path12.join(rootDir, configPath);
|
|
21167
21167
|
try {
|
|
21168
21168
|
await fs3.access(fullPath);
|
|
21169
21169
|
const content = await fs3.readFile(fullPath, "utf-8");
|
|
@@ -21181,7 +21181,7 @@ async function scanForSitemapFiles(rootDir) {
|
|
|
21181
21181
|
} catch {
|
|
21182
21182
|
}
|
|
21183
21183
|
}
|
|
21184
|
-
const staticSitemapPath =
|
|
21184
|
+
const staticSitemapPath = path12.join(rootDir, "public", "sitemap.xml");
|
|
21185
21185
|
try {
|
|
21186
21186
|
await fs3.access(staticSitemapPath);
|
|
21187
21187
|
const content = await fs3.readFile(staticSitemapPath, "utf-8");
|
|
@@ -21204,7 +21204,7 @@ async function scanForSitemapFiles(rootDir) {
|
|
|
21204
21204
|
"out/sitemap.xml"
|
|
21205
21205
|
];
|
|
21206
21206
|
for (const genPath of generatedPaths) {
|
|
21207
|
-
const fullPath =
|
|
21207
|
+
const fullPath = path12.join(rootDir, genPath);
|
|
21208
21208
|
try {
|
|
21209
21209
|
await fs3.access(fullPath);
|
|
21210
21210
|
} catch {
|
|
@@ -21228,8 +21228,8 @@ function scanForSchemas(ast, content, filePath) {
|
|
|
21228
21228
|
return schemas;
|
|
21229
21229
|
}
|
|
21230
21230
|
traverse(ast, {
|
|
21231
|
-
JSXElement(
|
|
21232
|
-
const opening =
|
|
21231
|
+
JSXElement(path29) {
|
|
21232
|
+
const opening = path29.node.openingElement;
|
|
21233
21233
|
if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
|
|
21234
21234
|
const typeAttr = opening.attributes.find(
|
|
21235
21235
|
(attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "type"
|
|
@@ -21256,8 +21256,8 @@ function scanForSchemas(ast, content, filePath) {
|
|
|
21256
21256
|
filePath,
|
|
21257
21257
|
type: detectedType,
|
|
21258
21258
|
schemaType,
|
|
21259
|
-
startLine:
|
|
21260
|
-
endLine:
|
|
21259
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
21260
|
+
endLine: path29.node.loc?.end.line || 0
|
|
21261
21261
|
});
|
|
21262
21262
|
}
|
|
21263
21263
|
}
|
|
@@ -21290,8 +21290,8 @@ function scanForFAQs(ast, content, filePath) {
|
|
|
21290
21290
|
/questions?\s*(?:and|&)?\s*answers?/i
|
|
21291
21291
|
];
|
|
21292
21292
|
traverse(ast, {
|
|
21293
|
-
JSXElement(
|
|
21294
|
-
const opening =
|
|
21293
|
+
JSXElement(path29) {
|
|
21294
|
+
const opening = path29.node.openingElement;
|
|
21295
21295
|
let tagName = "";
|
|
21296
21296
|
if (isJSXIdentifier(opening.name)) {
|
|
21297
21297
|
tagName = opening.name.name;
|
|
@@ -21304,8 +21304,8 @@ function scanForFAQs(ast, content, filePath) {
|
|
|
21304
21304
|
faqs.push({
|
|
21305
21305
|
filePath,
|
|
21306
21306
|
type: "details-summary",
|
|
21307
|
-
startLine:
|
|
21308
|
-
endLine:
|
|
21307
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
21308
|
+
endLine: path29.node.loc?.end.line || 0,
|
|
21309
21309
|
hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
|
|
21310
21310
|
});
|
|
21311
21311
|
return;
|
|
@@ -21313,7 +21313,7 @@ function scanForFAQs(ast, content, filePath) {
|
|
|
21313
21313
|
for (const pattern of faqPatterns) {
|
|
21314
21314
|
if (pattern.test(tagName)) {
|
|
21315
21315
|
let itemCount = 0;
|
|
21316
|
-
|
|
21316
|
+
path29.traverse({
|
|
21317
21317
|
JSXElement(itemPath) {
|
|
21318
21318
|
const itemOpening = itemPath.node.openingElement;
|
|
21319
21319
|
if (isJSXIdentifier(itemOpening.name)) {
|
|
@@ -21329,8 +21329,8 @@ function scanForFAQs(ast, content, filePath) {
|
|
|
21329
21329
|
type: "accordion",
|
|
21330
21330
|
componentName: tagName,
|
|
21331
21331
|
itemCount: itemCount || void 0,
|
|
21332
|
-
startLine:
|
|
21333
|
-
endLine:
|
|
21332
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
21333
|
+
endLine: path29.node.loc?.end.line || 0,
|
|
21334
21334
|
hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
|
|
21335
21335
|
});
|
|
21336
21336
|
return;
|
|
@@ -21453,8 +21453,8 @@ function scanForImages(ast, content, filePath) {
|
|
|
21453
21453
|
return images;
|
|
21454
21454
|
}
|
|
21455
21455
|
traverse(ast, {
|
|
21456
|
-
JSXElement(
|
|
21457
|
-
const opening =
|
|
21456
|
+
JSXElement(path29) {
|
|
21457
|
+
const opening = path29.node.openingElement;
|
|
21458
21458
|
if (!isJSXIdentifier(opening.name)) return;
|
|
21459
21459
|
const tagName = opening.name.name;
|
|
21460
21460
|
if (tagName === "img" || tagName === "Image") {
|
|
@@ -21482,8 +21482,8 @@ function scanForImages(ast, content, filePath) {
|
|
|
21482
21482
|
src: src || void 0,
|
|
21483
21483
|
alt: alt || void 0,
|
|
21484
21484
|
isLocal,
|
|
21485
|
-
startLine:
|
|
21486
|
-
endLine:
|
|
21485
|
+
startLine: path29.node.loc?.start.line || 0,
|
|
21486
|
+
endLine: path29.node.loc?.end.line || 0
|
|
21487
21487
|
});
|
|
21488
21488
|
}
|
|
21489
21489
|
}
|
|
@@ -21548,15 +21548,11 @@ function addToExistingImport(content, namedExport, modulePath) {
|
|
|
21548
21548
|
}
|
|
21549
21549
|
return content;
|
|
21550
21550
|
}
|
|
21551
|
-
function insertManagedSchemaIntoJSX(content, pagePath
|
|
21551
|
+
function insertManagedSchemaIntoJSX(content, pagePath) {
|
|
21552
21552
|
if (content.includes("<ManagedSchema")) {
|
|
21553
21553
|
return content;
|
|
21554
21554
|
}
|
|
21555
|
-
const
|
|
21556
|
-
const schemaComponent = `<ManagedSchema
|
|
21557
|
-
projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
|
|
21558
|
-
path="${pagePath}"
|
|
21559
|
-
/>`;
|
|
21555
|
+
const schemaComponent = `<ManagedSchema path="${pagePath}" />`;
|
|
21560
21556
|
const returnPatterns = [
|
|
21561
21557
|
// return (<> ... - fragment
|
|
21562
21558
|
/return\s*\(\s*<>/,
|
|
@@ -21692,7 +21688,7 @@ async function migrateFiles(scanResults, options) {
|
|
|
21692
21688
|
}
|
|
21693
21689
|
async function migrateForm(form, options) {
|
|
21694
21690
|
const changes = [];
|
|
21695
|
-
const fullPath =
|
|
21691
|
+
const fullPath = path12.resolve(process.cwd(), form.filePath);
|
|
21696
21692
|
const formSlug = generateSlug(form.componentName);
|
|
21697
21693
|
let formId;
|
|
21698
21694
|
if (!options.dryRun) {
|
|
@@ -21831,7 +21827,7 @@ export default ${componentName}
|
|
|
21831
21827
|
`;
|
|
21832
21828
|
}
|
|
21833
21829
|
async function createFormInUptrade(form, slug, options) {
|
|
21834
|
-
const response = await fetch("https://api.sonor.io/forms
|
|
21830
|
+
const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/forms`, {
|
|
21835
21831
|
method: "POST",
|
|
21836
21832
|
headers: {
|
|
21837
21833
|
"Content-Type": "application/json",
|
|
@@ -21866,10 +21862,10 @@ async function migrateWidget(filePath, widget, options) {
|
|
|
21866
21862
|
const changes = [];
|
|
21867
21863
|
if (options.dryRun) {
|
|
21868
21864
|
changes.push(`[DRY RUN] Would remove ${widget.widgetType} script`);
|
|
21869
|
-
changes.push("[DRY RUN]
|
|
21865
|
+
changes.push("[DRY RUN] Sonor Engage chat would come from SiteKitLayout (engage is on by default)");
|
|
21870
21866
|
return { filePath, success: true, changes };
|
|
21871
21867
|
}
|
|
21872
|
-
const fullPath =
|
|
21868
|
+
const fullPath = path12.resolve(process.cwd(), filePath);
|
|
21873
21869
|
let content = await fs3.readFile(fullPath, "utf-8");
|
|
21874
21870
|
switch (widget.widgetType) {
|
|
21875
21871
|
case "intercom":
|
|
@@ -21885,7 +21881,7 @@ async function migrateWidget(filePath, widget, options) {
|
|
|
21885
21881
|
}
|
|
21886
21882
|
await fs3.writeFile(fullPath, content, "utf-8");
|
|
21887
21883
|
changes.push(`Removed ${widget.widgetType} script`);
|
|
21888
|
-
changes.push("
|
|
21884
|
+
changes.push("SiteKitLayout adds the Sonor Engage chat widget (engage is on by default)");
|
|
21889
21885
|
return { filePath, success: true, changes };
|
|
21890
21886
|
}
|
|
21891
21887
|
function matchBalancedBraces(content, startIndex) {
|
|
@@ -21906,15 +21902,15 @@ function matchBalancedBraces(content, startIndex) {
|
|
|
21906
21902
|
}
|
|
21907
21903
|
async function migrateMetadata(filePath, metadata, options) {
|
|
21908
21904
|
const changes = [];
|
|
21909
|
-
const fullPath =
|
|
21905
|
+
const fullPath = path12.resolve(process.cwd(), filePath);
|
|
21910
21906
|
let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\/layout\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
|
|
21911
21907
|
if (pagePath === "") pagePath = "/";
|
|
21912
21908
|
let content = await fs3.readFile(fullPath, "utf-8");
|
|
21913
21909
|
const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
|
|
21914
21910
|
const ext2 = isTypeScript ? ".tsx" : ".jsx";
|
|
21915
21911
|
if (isClientComponent(content)) {
|
|
21916
|
-
const dir =
|
|
21917
|
-
const layoutPath =
|
|
21912
|
+
const dir = path12.dirname(fullPath);
|
|
21913
|
+
const layoutPath = path12.join(dir, `layout${ext2}`);
|
|
21918
21914
|
try {
|
|
21919
21915
|
await fs3.access(layoutPath);
|
|
21920
21916
|
const layoutContent = await fs3.readFile(layoutPath, "utf-8");
|
|
@@ -21937,13 +21933,12 @@ async function migrateMetadata(filePath, metadata, options) {
|
|
|
21937
21933
|
} catch (error2) {
|
|
21938
21934
|
changes.push(`Page metadata may already exist: ${pagePath}`);
|
|
21939
21935
|
}
|
|
21940
|
-
const dirName =
|
|
21936
|
+
const dirName = path12.basename(dir).replace(/^\[\.\.\.([^\]]+)\]$/, "$1").replace(/^\[([^\]]+)\]$/, "$1");
|
|
21941
21937
|
const layoutName = dirName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("") + "Layout";
|
|
21942
21938
|
const layoutCode = `import { getManagedMetadata, ManagedSchema } from '@sonordev/site-kit/seo'
|
|
21943
21939
|
|
|
21944
21940
|
export async function generateMetadata() {
|
|
21945
21941
|
return getManagedMetadata({
|
|
21946
|
-
projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
|
|
21947
21942
|
path: '${pagePath}',
|
|
21948
21943
|
fallback: {
|
|
21949
21944
|
title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
|
|
@@ -21955,10 +21950,7 @@ export async function generateMetadata() {
|
|
|
21955
21950
|
export default function ${layoutName}({ children }${isTypeScript ? ": { children: React.ReactNode }" : ""}) {
|
|
21956
21951
|
return (
|
|
21957
21952
|
<>
|
|
21958
|
-
<ManagedSchema
|
|
21959
|
-
projectId={process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""}}
|
|
21960
|
-
path="${pagePath}"
|
|
21961
|
-
/>
|
|
21953
|
+
<ManagedSchema path="${pagePath}" />
|
|
21962
21954
|
{children}
|
|
21963
21955
|
</>
|
|
21964
21956
|
)
|
|
@@ -21988,7 +21980,6 @@ export default function ${layoutName}({ children }${isTypeScript ? ": { children
|
|
|
21988
21980
|
const generateMetadataCode = `
|
|
21989
21981
|
export async function generateMetadata() {
|
|
21990
21982
|
return getManagedMetadata({
|
|
21991
|
-
projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
|
|
21992
21983
|
path: '${pagePath}',
|
|
21993
21984
|
fallback: {
|
|
21994
21985
|
title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
|
|
@@ -22010,7 +22001,7 @@ export async function generateMetadata() {
|
|
|
22010
22001
|
content = generateMetadataCode + content;
|
|
22011
22002
|
}
|
|
22012
22003
|
}
|
|
22013
|
-
content = insertManagedSchemaIntoJSX(content, pagePath
|
|
22004
|
+
content = insertManagedSchemaIntoJSX(content, pagePath);
|
|
22014
22005
|
changes.push("Added ManagedSchema component");
|
|
22015
22006
|
await fs3.writeFile(fullPath, content, "utf-8");
|
|
22016
22007
|
changes.push("Added generateMetadata function");
|
|
@@ -22030,7 +22021,6 @@ export async function generateMetadata() {
|
|
|
22030
22021
|
}
|
|
22031
22022
|
const generateMetadataCode = `export async function generateMetadata() {
|
|
22032
22023
|
return getManagedMetadata({
|
|
22033
|
-
projectId: process.env.SONOR_PROJECT_ID${isTypeScript ? "!" : ""},
|
|
22034
22024
|
path: '${pagePath}',
|
|
22035
22025
|
fallback: {
|
|
22036
22026
|
title: '${(metadata.title || "Page Title").replace(/'/g, "\\'")}',
|
|
@@ -22040,7 +22030,7 @@ export async function generateMetadata() {
|
|
|
22040
22030
|
}`;
|
|
22041
22031
|
content = content.replace(fullMatch, generateMetadataCode);
|
|
22042
22032
|
changes.push("Replaced static metadata with getManagedMetadata");
|
|
22043
|
-
content = insertManagedSchemaIntoJSX(content, pagePath
|
|
22033
|
+
content = insertManagedSchemaIntoJSX(content, pagePath);
|
|
22044
22034
|
changes.push("Added ManagedSchema component");
|
|
22045
22035
|
}
|
|
22046
22036
|
}
|
|
@@ -22052,7 +22042,7 @@ export async function generateMetadata() {
|
|
|
22052
22042
|
return { filePath, success: true, changes };
|
|
22053
22043
|
}
|
|
22054
22044
|
async function createPageMetadata(pagePath, metadata, options) {
|
|
22055
|
-
const response = await fetch("https://api.sonor.io/seo/pages
|
|
22045
|
+
const response = await fetch(`${options.apiUrl || "https://api.sonor.io"}/seo/pages`, {
|
|
22056
22046
|
method: "POST",
|
|
22057
22047
|
headers: {
|
|
22058
22048
|
"Content-Type": "application/json",
|
|
@@ -22137,7 +22127,7 @@ async function createSchemaRecord(pagePath, schemaType, schemaJson, options) {
|
|
|
22137
22127
|
}
|
|
22138
22128
|
async function migrateSchema(filePath, schema, options) {
|
|
22139
22129
|
const changes = [];
|
|
22140
|
-
const fullPath =
|
|
22130
|
+
const fullPath = path12.resolve(process.cwd(), filePath);
|
|
22141
22131
|
let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
|
|
22142
22132
|
if (pagePath === "") pagePath = "/";
|
|
22143
22133
|
let content = await fs3.readFile(fullPath, "utf-8");
|
|
@@ -22164,8 +22154,6 @@ async function migrateSchema(filePath, schema, options) {
|
|
|
22164
22154
|
}
|
|
22165
22155
|
}
|
|
22166
22156
|
const alreadyHasManagedSchema = content.includes("<ManagedSchema");
|
|
22167
|
-
const isTypeScript = filePath.endsWith(".tsx") || filePath.endsWith(".ts");
|
|
22168
|
-
const projectIdSuffix = isTypeScript ? "!" : "";
|
|
22169
22157
|
const jsonLdPattern = /<script\s+type=["']application\/ld\+json["'][^>]*>[\s\S]*?<\/script>/gi;
|
|
22170
22158
|
const scriptPattern = /<Script\s+[^>]*type=["']application\/ld\+json["'][^>]*>[\s\S]*?<\/Script>/gi;
|
|
22171
22159
|
const hasJsonLd = jsonLdPattern.test(content) || scriptPattern.test(content);
|
|
@@ -22185,14 +22173,8 @@ async function migrateSchema(filePath, schema, options) {
|
|
|
22185
22173
|
}
|
|
22186
22174
|
changes.push("Added ManagedSchema import");
|
|
22187
22175
|
}
|
|
22188
|
-
content = content.replace(jsonLdPattern, `<ManagedSchema
|
|
22189
|
-
|
|
22190
|
-
path="${pagePath}"
|
|
22191
|
-
/>`);
|
|
22192
|
-
content = content.replace(scriptPattern, `<ManagedSchema
|
|
22193
|
-
projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
|
|
22194
|
-
path="${pagePath}"
|
|
22195
|
-
/>`);
|
|
22176
|
+
content = content.replace(jsonLdPattern, `<ManagedSchema path="${pagePath}" />`);
|
|
22177
|
+
content = content.replace(scriptPattern, `<ManagedSchema path="${pagePath}" />`);
|
|
22196
22178
|
changes.push("Replaced JSON-LD script with ManagedSchema component");
|
|
22197
22179
|
}
|
|
22198
22180
|
}
|
|
@@ -22256,7 +22238,7 @@ async function createFAQRecord(pagePath, items, options) {
|
|
|
22256
22238
|
}
|
|
22257
22239
|
async function migrateFAQ(filePath, faq, options) {
|
|
22258
22240
|
const changes = [];
|
|
22259
|
-
const fullPath =
|
|
22241
|
+
const fullPath = path12.resolve(process.cwd(), filePath);
|
|
22260
22242
|
let pagePath = filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
|
|
22261
22243
|
if (pagePath === "") pagePath = "/";
|
|
22262
22244
|
let content = await fs3.readFile(fullPath, "utf-8");
|
|
@@ -22296,12 +22278,7 @@ async function migrateFAQ(filePath, faq, options) {
|
|
|
22296
22278
|
}
|
|
22297
22279
|
changes.push("Added ManagedFAQ import");
|
|
22298
22280
|
}
|
|
22299
|
-
const
|
|
22300
|
-
const projectIdSuffix = isTypeScript ? "!" : "";
|
|
22301
|
-
const managedFAQComponent = `<ManagedFAQ
|
|
22302
|
-
projectId={process.env.SONOR_PROJECT_ID${projectIdSuffix}}
|
|
22303
|
-
path="${pagePath}"
|
|
22304
|
-
/>`;
|
|
22281
|
+
const managedFAQComponent = `<ManagedFAQ path="${pagePath}" />`;
|
|
22305
22282
|
if (faq.componentName) {
|
|
22306
22283
|
const componentPattern = new RegExp(`(<${faq.componentName}[^>]*>)`, "i");
|
|
22307
22284
|
if (componentPattern.test(content)) {
|
|
@@ -22329,7 +22306,7 @@ async function migrateFAQ(filePath, faq, options) {
|
|
|
22329
22306
|
}
|
|
22330
22307
|
async function migrateSitemap(filePath, sitemap, options) {
|
|
22331
22308
|
const changes = [];
|
|
22332
|
-
const fullPath =
|
|
22309
|
+
const fullPath = path12.resolve(process.cwd(), filePath);
|
|
22333
22310
|
if (options.dryRun) {
|
|
22334
22311
|
changes.push(`[DRY RUN] Would migrate ${sitemap.type} to Site-Kit sitemap`);
|
|
22335
22312
|
if (sitemap.type === "next-sitemap-config") {
|
|
@@ -22354,7 +22331,7 @@ async function migrateSitemap(filePath, sitemap, options) {
|
|
|
22354
22331
|
}
|
|
22355
22332
|
if (sitemap.type === "custom-sitemap" && filePath.includes("sitemap")) {
|
|
22356
22333
|
changes.push("Custom sitemap detected - consider using Site-Kit's createSitemap helper");
|
|
22357
|
-
changes.push("Import: import { createSitemap } from '@sonordev/site-kit/
|
|
22334
|
+
changes.push("Import: import { createSitemap } from '@sonordev/site-kit/sitemap'");
|
|
22358
22335
|
}
|
|
22359
22336
|
return { filePath, success: true, changes };
|
|
22360
22337
|
}
|
|
@@ -22362,17 +22339,17 @@ async function migrateAnalytics(filePath, analytics, options) {
|
|
|
22362
22339
|
const changes = [];
|
|
22363
22340
|
if (options.dryRun) {
|
|
22364
22341
|
changes.push(`[DRY RUN] Detected ${analytics.type}${analytics.trackingId ? ` (${analytics.trackingId})` : ""}`);
|
|
22365
|
-
changes.push("[DRY RUN] Would recommend
|
|
22342
|
+
changes.push("[DRY RUN] Would recommend Sonor analytics from SiteKitLayout (on by default)");
|
|
22366
22343
|
return { filePath, success: true, changes };
|
|
22367
22344
|
}
|
|
22368
22345
|
changes.push(`Detected ${analytics.type}${analytics.trackingId ? ` (${analytics.trackingId})` : ""}`);
|
|
22369
|
-
changes.push("
|
|
22346
|
+
changes.push("SiteKitLayout already tracks Sonor analytics (on by default)");
|
|
22370
22347
|
changes.push("Configure analytics in project settings to consolidate tracking");
|
|
22371
22348
|
return { filePath, success: true, changes };
|
|
22372
22349
|
}
|
|
22373
22350
|
async function migrateFile(filePath, options) {
|
|
22374
|
-
const fullPath =
|
|
22375
|
-
const relPath =
|
|
22351
|
+
const fullPath = path12.resolve(filePath);
|
|
22352
|
+
const relPath = path12.relative(process.cwd(), fullPath);
|
|
22376
22353
|
const content = await fs3.readFile(fullPath, "utf-8");
|
|
22377
22354
|
const hasFormTag = content.includes("<form") || content.includes("onSubmit");
|
|
22378
22355
|
const hasWidget = /intercom|crisp|drift|hubspot|zendesk/i.test(content);
|
|
@@ -22389,26 +22366,26 @@ async function migrateFile(filePath, options) {
|
|
|
22389
22366
|
return migrateWidget(relPath, {
|
|
22390
22367
|
widgetType}, options);
|
|
22391
22368
|
}
|
|
22392
|
-
const { parse:
|
|
22393
|
-
const ast =
|
|
22369
|
+
const { parse: parse3 } = await import('../lib-R7IQ4ZHE.mjs');
|
|
22370
|
+
const ast = parse3(content, {
|
|
22394
22371
|
sourceType: "module",
|
|
22395
22372
|
plugins: ["jsx", "typescript"]
|
|
22396
22373
|
});
|
|
22397
22374
|
let componentName = "Form";
|
|
22398
22375
|
const traverse2 = (await import('../lib-RSDMEKDQ.mjs')).default;
|
|
22399
22376
|
traverse2(ast, {
|
|
22400
|
-
ExportNamedDeclaration(
|
|
22401
|
-
const decl =
|
|
22377
|
+
ExportNamedDeclaration(path29) {
|
|
22378
|
+
const decl = path29.node.declaration;
|
|
22402
22379
|
if (decl && decl.type === "FunctionDeclaration" && decl.id) {
|
|
22403
22380
|
componentName = decl.id.name;
|
|
22404
|
-
|
|
22381
|
+
path29.stop();
|
|
22405
22382
|
}
|
|
22406
22383
|
},
|
|
22407
|
-
ExportDefaultDeclaration(
|
|
22408
|
-
const decl =
|
|
22384
|
+
ExportDefaultDeclaration(path29) {
|
|
22385
|
+
const decl = path29.node.declaration;
|
|
22409
22386
|
if (decl && decl.type === "FunctionDeclaration" && decl.id) {
|
|
22410
22387
|
componentName = decl.id.name;
|
|
22411
|
-
|
|
22388
|
+
path29.stop();
|
|
22412
22389
|
}
|
|
22413
22390
|
}
|
|
22414
22391
|
});
|
|
@@ -22465,7 +22442,7 @@ function detectFormType(form) {
|
|
|
22465
22442
|
return "contact";
|
|
22466
22443
|
}
|
|
22467
22444
|
async function generateEnvFile(options) {
|
|
22468
|
-
const envPath =
|
|
22445
|
+
const envPath = path12.join(process.cwd(), ".env.local");
|
|
22469
22446
|
let existingContent = "";
|
|
22470
22447
|
try {
|
|
22471
22448
|
existingContent = await fs3.readFile(envPath, "utf-8");
|
|
@@ -22565,7 +22542,7 @@ async function findLayoutFile() {
|
|
|
22565
22542
|
"app/layout.jsx"
|
|
22566
22543
|
];
|
|
22567
22544
|
for (const relativePath of possiblePaths) {
|
|
22568
|
-
const fullPath =
|
|
22545
|
+
const fullPath = path12.join(process.cwd(), relativePath);
|
|
22569
22546
|
try {
|
|
22570
22547
|
await fs3.access(fullPath);
|
|
22571
22548
|
return fullPath;
|
|
@@ -22735,15 +22712,15 @@ var wslDefaultBrowser = async () => {
|
|
|
22735
22712
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
22736
22713
|
return stdout.trim();
|
|
22737
22714
|
};
|
|
22738
|
-
var convertWslPathToWindows = async (
|
|
22739
|
-
if (/^[a-z]+:\/\//i.test(
|
|
22740
|
-
return
|
|
22715
|
+
var convertWslPathToWindows = async (path29) => {
|
|
22716
|
+
if (/^[a-z]+:\/\//i.test(path29)) {
|
|
22717
|
+
return path29;
|
|
22741
22718
|
}
|
|
22742
22719
|
try {
|
|
22743
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
22720
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path29], { encoding: "utf8" });
|
|
22744
22721
|
return stdout.trim();
|
|
22745
22722
|
} catch {
|
|
22746
|
-
return
|
|
22723
|
+
return path29;
|
|
22747
22724
|
}
|
|
22748
22725
|
};
|
|
22749
22726
|
|
|
@@ -22863,8 +22840,8 @@ var is_in_ssh_default = isInSsh;
|
|
|
22863
22840
|
|
|
22864
22841
|
// node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
|
|
22865
22842
|
var fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
|
|
22866
|
-
var __dirname2 = import.meta.url ?
|
|
22867
|
-
var localXdgOpenPath =
|
|
22843
|
+
var __dirname2 = import.meta.url ? path12.dirname(fileURLToPath(import.meta.url)) : "";
|
|
22844
|
+
var localXdgOpenPath = path12.join(__dirname2, "xdg-open");
|
|
22868
22845
|
var { platform, arch } = process2;
|
|
22869
22846
|
var tryEachApp = async (apps2, opener) => {
|
|
22870
22847
|
if (apps2.length === 0) {
|
|
@@ -23142,8 +23119,37 @@ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
|
23142
23119
|
darwin: "Safari"
|
|
23143
23120
|
}));
|
|
23144
23121
|
var open_default = open;
|
|
23122
|
+
var SONOR_STATE_DIR = ".sonor";
|
|
23123
|
+
var IMAGE_MANIFEST = ".sonor-images.json";
|
|
23124
|
+
var LEGACY_IMAGE_MANIFEST = ".uptrade-images.json";
|
|
23125
|
+
var LEGACY_STATE_DIR = ".uptrade";
|
|
23126
|
+
function resolveStateReadPath(relativePath, root = process.cwd()) {
|
|
23127
|
+
return preferCurrent(path12.join(root, SONOR_STATE_DIR, relativePath), path12.join(root, LEGACY_STATE_DIR, relativePath));
|
|
23128
|
+
}
|
|
23129
|
+
function resolveImageManifestReadPath(root) {
|
|
23130
|
+
return preferCurrent(path12.join(root, IMAGE_MANIFEST), path12.join(root, LEGACY_IMAGE_MANIFEST));
|
|
23131
|
+
}
|
|
23132
|
+
function preferCurrent(current, legacy) {
|
|
23133
|
+
return existsSync(current) || !existsSync(legacy) ? current : legacy;
|
|
23134
|
+
}
|
|
23135
|
+
async function listLocalTemplates(root = process.cwd()) {
|
|
23136
|
+
const names = /* @__PURE__ */ new Set();
|
|
23137
|
+
for (const dir of [SONOR_STATE_DIR, LEGACY_STATE_DIR]) {
|
|
23138
|
+
try {
|
|
23139
|
+
const files = await fs3.readdir(path12.join(root, dir, "templates"));
|
|
23140
|
+
for (const file of files) if (file.endsWith(".json")) names.add(file);
|
|
23141
|
+
} catch (error2) {
|
|
23142
|
+
if (error2.code !== "ENOENT") throw error2;
|
|
23143
|
+
}
|
|
23144
|
+
}
|
|
23145
|
+
return [...names].sort();
|
|
23146
|
+
}
|
|
23147
|
+
|
|
23148
|
+
// src/cli/api/sonor.ts
|
|
23145
23149
|
var PORTAL_URL = "https://app.sonor.io";
|
|
23146
|
-
|
|
23150
|
+
function getSonorApiUrl() {
|
|
23151
|
+
return (process.env.SONOR_API_URL || "https://api.sonor.io").replace(/\/+$/, "");
|
|
23152
|
+
}
|
|
23147
23153
|
async function authenticateWithSonor() {
|
|
23148
23154
|
return new Promise((resolve, reject) => {
|
|
23149
23155
|
const server = http.createServer(async (req, res) => {
|
|
@@ -23170,7 +23176,7 @@ async function authenticateWithSonor() {
|
|
|
23170
23176
|
server.close();
|
|
23171
23177
|
return;
|
|
23172
23178
|
}
|
|
23173
|
-
const tokenResponse = await fetch(`${
|
|
23179
|
+
const tokenResponse = await fetch(`${getSonorApiUrl()}/auth/cli-token`, {
|
|
23174
23180
|
method: "POST",
|
|
23175
23181
|
headers: { "Content-Type": "application/json" },
|
|
23176
23182
|
body: JSON.stringify({ code, redirect_uri: `http://localhost:${port}/callback` })
|
|
@@ -23216,32 +23222,41 @@ async function authenticateWithSonor() {
|
|
|
23216
23222
|
}, 5 * 60 * 1e3);
|
|
23217
23223
|
});
|
|
23218
23224
|
}
|
|
23219
|
-
async function authenticateWithApiKey(apiKey) {
|
|
23220
|
-
|
|
23221
|
-
|
|
23222
|
-
|
|
23223
|
-
|
|
23224
|
-
|
|
23225
|
-
|
|
23226
|
-
|
|
23227
|
-
|
|
23228
|
-
userId: "api-key-user",
|
|
23229
|
-
email: data.project?.name ? `Project: ${data.project.name}` : `API Key verified`,
|
|
23230
|
-
projectId: data.project?.id,
|
|
23231
|
-
projectName: data.project?.name,
|
|
23232
|
-
orgId: data.organization?.id,
|
|
23233
|
-
orgName: data.organization?.name,
|
|
23234
|
-
isApiKey: true
|
|
23235
|
-
};
|
|
23236
|
-
}
|
|
23225
|
+
async function authenticateWithApiKey(apiKey, apiUrl = getSonorApiUrl()) {
|
|
23226
|
+
let response;
|
|
23227
|
+
try {
|
|
23228
|
+
response = await fetch(`${apiUrl}/api/public/seo/verify-api-key`, {
|
|
23229
|
+
headers: { "X-API-Key": apiKey },
|
|
23230
|
+
signal: AbortSignal.timeout(15e3)
|
|
23231
|
+
});
|
|
23232
|
+
} catch {
|
|
23233
|
+
throw new NetworkError("PROJECT_LOOKUP_FAILED", "Could not reach the Sonor API to resolve the project. Check SONOR_API_URL and your connection.");
|
|
23237
23234
|
}
|
|
23238
|
-
if (response.
|
|
23239
|
-
throw new
|
|
23235
|
+
if (!response.ok) {
|
|
23236
|
+
throw new NetworkError("PROJECT_LOOKUP_FAILED", `Sonor API verification failed (HTTP ${response.status}). Check SONOR_API_KEY and SONOR_API_URL.`);
|
|
23237
|
+
}
|
|
23238
|
+
let data;
|
|
23239
|
+
try {
|
|
23240
|
+
data = await response.json();
|
|
23241
|
+
} catch {
|
|
23242
|
+
throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API returned an invalid project response.");
|
|
23243
|
+
}
|
|
23244
|
+
if (data?.valid !== true || typeof data.project?.id !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(data.project.id)) {
|
|
23245
|
+
throw new NetworkError("INVALID_PROJECT_RESPONSE", "Sonor API did not return a valid full project UUID. Check SONOR_API_KEY.");
|
|
23240
23246
|
}
|
|
23241
|
-
|
|
23247
|
+
return {
|
|
23248
|
+
accessToken: apiKey,
|
|
23249
|
+
userId: "api-key-user",
|
|
23250
|
+
email: data.project.name ? `Project: ${data.project.name}` : "API Key verified",
|
|
23251
|
+
projectId: data.project.id,
|
|
23252
|
+
projectName: data.project.name,
|
|
23253
|
+
orgId: data.organization?.id,
|
|
23254
|
+
orgName: data.organization?.name,
|
|
23255
|
+
isApiKey: true
|
|
23256
|
+
};
|
|
23242
23257
|
}
|
|
23243
23258
|
async function fetchOrganizations(accessToken) {
|
|
23244
|
-
const response = await fetch(`${
|
|
23259
|
+
const response = await fetch(`${getSonorApiUrl()}/organizations`, {
|
|
23245
23260
|
headers: { "Authorization": `Bearer ${accessToken}` }
|
|
23246
23261
|
});
|
|
23247
23262
|
if (!response.ok) {
|
|
@@ -23250,7 +23265,7 @@ async function fetchOrganizations(accessToken) {
|
|
|
23250
23265
|
return response.json();
|
|
23251
23266
|
}
|
|
23252
23267
|
async function fetchProjects(accessToken, orgId) {
|
|
23253
|
-
const response = await fetch(`${
|
|
23268
|
+
const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
|
|
23254
23269
|
headers: { "Authorization": `Bearer ${accessToken}` }
|
|
23255
23270
|
});
|
|
23256
23271
|
if (!response.ok) {
|
|
@@ -23259,7 +23274,7 @@ async function fetchProjects(accessToken, orgId) {
|
|
|
23259
23274
|
return response.json();
|
|
23260
23275
|
}
|
|
23261
23276
|
async function createProject(accessToken, orgId, data) {
|
|
23262
|
-
const response = await fetch(`${
|
|
23277
|
+
const response = await fetch(`${getSonorApiUrl()}/organizations/${orgId}/projects`, {
|
|
23263
23278
|
method: "POST",
|
|
23264
23279
|
headers: {
|
|
23265
23280
|
"Authorization": `Bearer ${accessToken}`,
|
|
@@ -23273,7 +23288,7 @@ async function createProject(accessToken, orgId, data) {
|
|
|
23273
23288
|
return response.json();
|
|
23274
23289
|
}
|
|
23275
23290
|
async function generateApiKey(accessToken, projectId) {
|
|
23276
|
-
const response = await fetch(`${
|
|
23291
|
+
const response = await fetch(`${getSonorApiUrl()}/projects/${projectId}/api-keys`, {
|
|
23277
23292
|
method: "POST",
|
|
23278
23293
|
headers: {
|
|
23279
23294
|
"Authorization": `Bearer ${accessToken}`,
|
|
@@ -23477,7 +23492,7 @@ function progress(ctx, line) {
|
|
|
23477
23492
|
// src/cli/commands/init.ts
|
|
23478
23493
|
async function checkNextJsProject(cwd) {
|
|
23479
23494
|
try {
|
|
23480
|
-
const pkg = JSON.parse(await fs3.readFile(
|
|
23495
|
+
const pkg = JSON.parse(await fs3.readFile(path12.join(cwd, "package.json"), "utf-8"));
|
|
23481
23496
|
return !!(pkg.dependencies?.next || pkg.devDependencies?.next);
|
|
23482
23497
|
} catch {
|
|
23483
23498
|
return false;
|
|
@@ -23557,7 +23572,7 @@ async function run(ctx, options) {
|
|
|
23557
23572
|
]);
|
|
23558
23573
|
if (chosen === "new") {
|
|
23559
23574
|
const answers = await dist_default14.prompt([
|
|
23560
|
-
{ type: "input", name: "name", message: "Project name:", default:
|
|
23575
|
+
{ type: "input", name: "name", message: "Project name:", default: path12.basename(ctx.cwd) },
|
|
23561
23576
|
{ type: "input", name: "domain", message: "Project domain (optional):" }
|
|
23562
23577
|
]);
|
|
23563
23578
|
const project = await createProject(auth.accessToken, orgId, { name: answers.name, domain: answers.domain || "" });
|
|
@@ -23612,7 +23627,7 @@ async function run(ctx, options) {
|
|
|
23612
23627
|
};
|
|
23613
23628
|
}
|
|
23614
23629
|
async function ensureSitemapPostbuild(ctx) {
|
|
23615
|
-
const pkgPath =
|
|
23630
|
+
const pkgPath = path12.join(ctx.cwd, "package.json");
|
|
23616
23631
|
try {
|
|
23617
23632
|
const pkg = JSON.parse(await fs3.readFile(pkgPath, "utf-8"));
|
|
23618
23633
|
if (!pkg.scripts) pkg.scripts = {};
|
|
@@ -23654,7 +23669,7 @@ async function scanCommand(options) {
|
|
|
23654
23669
|
console.log("");
|
|
23655
23670
|
console.log(source_default.bold(" Scanning codebase..."));
|
|
23656
23671
|
console.log("");
|
|
23657
|
-
const targetDir =
|
|
23672
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
23658
23673
|
const spinner = ora("Looking for forms, metadata, widgets, schemas, FAQs, analytics, and images...").start();
|
|
23659
23674
|
let scanResults;
|
|
23660
23675
|
try {
|
|
@@ -23832,6 +23847,48 @@ async function scanCommand(options) {
|
|
|
23832
23847
|
process.exit(1);
|
|
23833
23848
|
}
|
|
23834
23849
|
}
|
|
23850
|
+
|
|
23851
|
+
// src/cli/config.ts
|
|
23852
|
+
var import_dotenv = __toESM(require_main());
|
|
23853
|
+
async function loadConfig({ resolveProject = false, cwd = process.cwd() } = {}) {
|
|
23854
|
+
const envFile = await readOptionalFile(path12.join(cwd, ".env.local"));
|
|
23855
|
+
const env3 = { ...(0, import_dotenv.parse)(envFile || ""), ...process.env };
|
|
23856
|
+
const configPath = resolveStateReadPath("config.json", cwd);
|
|
23857
|
+
const saved = await readOptionalFile(configPath);
|
|
23858
|
+
let stored = {};
|
|
23859
|
+
if (saved !== void 0) {
|
|
23860
|
+
try {
|
|
23861
|
+
stored = JSON.parse(saved);
|
|
23862
|
+
if (!stored || typeof stored !== "object" || Array.isArray(stored)) throw new Error();
|
|
23863
|
+
} catch {
|
|
23864
|
+
throw new ConfigError("INVALID_CONFIG", `Invalid JSON config: ${configPath}. Fix or remove it, then set SONOR_API_KEY in .env.local.`);
|
|
23865
|
+
}
|
|
23866
|
+
}
|
|
23867
|
+
const apiKey = String(env3.SONOR_API_KEY || stored.apiKey || stored.api_key || "").trim();
|
|
23868
|
+
if (!apiKey) {
|
|
23869
|
+
throw new ConfigError("MISSING_API_KEY", "Set SONOR_API_KEY in .env.local or run `sonor-setup init` first.");
|
|
23870
|
+
}
|
|
23871
|
+
if (!/^sonor_[0-9a-f]{8}_.+$/i.test(apiKey)) {
|
|
23872
|
+
throw new ConfigError("INVALID_API_KEY", "SONOR_API_KEY must be a sonor_ key from app.sonor.io.");
|
|
23873
|
+
}
|
|
23874
|
+
const config2 = {
|
|
23875
|
+
apiKey,
|
|
23876
|
+
apiUrl: (env3.SONOR_API_URL || getSonorApiUrl()).replace(/\/+$/, ""),
|
|
23877
|
+
siteUrl: env3.NEXT_PUBLIC_SITE_URL || env3.SITE_URL || stored.siteUrl || stored.site_url,
|
|
23878
|
+
businessInfo: stored.businessInfo || stored.business_info
|
|
23879
|
+
};
|
|
23880
|
+
if (!resolveProject) return config2;
|
|
23881
|
+
const auth = await authenticateWithApiKey(apiKey, config2.apiUrl);
|
|
23882
|
+
return { ...config2, projectId: auth.projectId };
|
|
23883
|
+
}
|
|
23884
|
+
async function readOptionalFile(file) {
|
|
23885
|
+
try {
|
|
23886
|
+
return await fs3.readFile(file, "utf-8");
|
|
23887
|
+
} catch (error2) {
|
|
23888
|
+
if (error2.code === "ENOENT") return void 0;
|
|
23889
|
+
throw new ConfigError("CONFIG_READ_FAILED", `Could not read ${file}. Check file permissions.`);
|
|
23890
|
+
}
|
|
23891
|
+
}
|
|
23835
23892
|
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".avif"];
|
|
23836
23893
|
var MIME_TYPES = {
|
|
23837
23894
|
".jpg": "image/jpeg",
|
|
@@ -23854,7 +23911,7 @@ function filePathToPagePath(filePath) {
|
|
|
23854
23911
|
}
|
|
23855
23912
|
if (p.startsWith("pages/") || p.startsWith("src/pages/")) {
|
|
23856
23913
|
p = p.replace(/^pages\//, "").replace(/^src\/pages\//, "");
|
|
23857
|
-
const base =
|
|
23914
|
+
const base = path12.basename(p, path12.extname(p));
|
|
23858
23915
|
return base === "index" ? "/" : "/" + base;
|
|
23859
23916
|
}
|
|
23860
23917
|
p = p.replace(/\.[^.]+$/, "").replace(/^\.\//, "").replace(/\\/g, "/");
|
|
@@ -23897,8 +23954,8 @@ async function imagesCommand(subcommand, options) {
|
|
|
23897
23954
|
}
|
|
23898
23955
|
}
|
|
23899
23956
|
async function scanImages(options) {
|
|
23900
|
-
const targetDir =
|
|
23901
|
-
const publicDir =
|
|
23957
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
23958
|
+
const publicDir = path12.join(targetDir, "public");
|
|
23902
23959
|
try {
|
|
23903
23960
|
await fs3.access(publicDir);
|
|
23904
23961
|
} catch {
|
|
@@ -23968,7 +24025,7 @@ async function uploadImages(options) {
|
|
|
23968
24025
|
console.log("");
|
|
23969
24026
|
process.exit(1);
|
|
23970
24027
|
}
|
|
23971
|
-
const targetDir =
|
|
24028
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
23972
24029
|
const spinner = ora("Scanning for images...").start();
|
|
23973
24030
|
const results = await scanPublicImages(targetDir);
|
|
23974
24031
|
spinner.stop();
|
|
@@ -24021,7 +24078,7 @@ async function uploadImages(options) {
|
|
|
24021
24078
|
const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
|
|
24022
24079
|
try {
|
|
24023
24080
|
const result = await uploadImageToPortal(
|
|
24024
|
-
|
|
24081
|
+
path12.join(targetDir, img.filePath),
|
|
24025
24082
|
img,
|
|
24026
24083
|
{ apiUrl, apiKey, category: options.category }
|
|
24027
24084
|
);
|
|
@@ -24040,7 +24097,7 @@ async function uploadImages(options) {
|
|
|
24040
24097
|
}
|
|
24041
24098
|
console.log("");
|
|
24042
24099
|
if (uploaded.length > 0) {
|
|
24043
|
-
const manifestPath =
|
|
24100
|
+
const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
|
|
24044
24101
|
await fs3.writeFile(manifestPath, JSON.stringify({
|
|
24045
24102
|
uploaded,
|
|
24046
24103
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -24053,8 +24110,8 @@ async function uploadImages(options) {
|
|
|
24053
24110
|
console.log("");
|
|
24054
24111
|
}
|
|
24055
24112
|
async function migrateImages(options) {
|
|
24056
|
-
const targetDir =
|
|
24057
|
-
const manifestPath =
|
|
24113
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
24114
|
+
const manifestPath = resolveImageManifestReadPath(targetDir);
|
|
24058
24115
|
const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
24059
24116
|
const apiKey = process.env.SONOR_API_KEY || "";
|
|
24060
24117
|
if (!apiKey) {
|
|
@@ -24157,9 +24214,9 @@ async function migrateImages(options) {
|
|
|
24157
24214
|
let successCount = 0;
|
|
24158
24215
|
let failCount = 0;
|
|
24159
24216
|
for (const [filePath, fileMigrations] of byFile) {
|
|
24160
|
-
const fileSpinner = ora(`Migrating ${
|
|
24217
|
+
const fileSpinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
|
|
24161
24218
|
try {
|
|
24162
|
-
await migrateFileImages(
|
|
24219
|
+
await migrateFileImages(path12.join(targetDir, filePath), fileMigrations);
|
|
24163
24220
|
successCount += fileMigrations.length;
|
|
24164
24221
|
fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
|
|
24165
24222
|
} catch (error2) {
|
|
@@ -24181,7 +24238,7 @@ async function migrateImages(options) {
|
|
|
24181
24238
|
console.log("");
|
|
24182
24239
|
}
|
|
24183
24240
|
async function uploadAndMigrate(options) {
|
|
24184
|
-
const targetDir =
|
|
24241
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
24185
24242
|
const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
24186
24243
|
const apiKey = process.env.SONOR_API_KEY || "";
|
|
24187
24244
|
if (!apiKey) {
|
|
@@ -24248,7 +24305,7 @@ async function uploadAndMigrate(options) {
|
|
|
24248
24305
|
const uploadSpinner = ora(`Uploading ${img.filename}...`).start();
|
|
24249
24306
|
try {
|
|
24250
24307
|
const result = await uploadImageToPortal(
|
|
24251
|
-
|
|
24308
|
+
path12.join(targetDir, img.filePath),
|
|
24252
24309
|
img,
|
|
24253
24310
|
{ apiUrl, apiKey, category: options.category }
|
|
24254
24311
|
);
|
|
@@ -24320,9 +24377,9 @@ async function uploadAndMigrate(options) {
|
|
|
24320
24377
|
let successCount = 0;
|
|
24321
24378
|
let failCount = 0;
|
|
24322
24379
|
for (const [filePath, fileMigrations] of byFile) {
|
|
24323
|
-
const fileSpinner = ora(`Migrating ${
|
|
24380
|
+
const fileSpinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
|
|
24324
24381
|
try {
|
|
24325
|
-
await migrateFileImages(
|
|
24382
|
+
await migrateFileImages(path12.join(targetDir, filePath), fileMigrations);
|
|
24326
24383
|
successCount += fileMigrations.length;
|
|
24327
24384
|
fileSpinner.succeed(`Migrated: ${filePath} (${fileMigrations.length} images)`);
|
|
24328
24385
|
} catch (error2) {
|
|
@@ -24330,7 +24387,7 @@ async function uploadAndMigrate(options) {
|
|
|
24330
24387
|
fileSpinner.fail(`Failed: ${filePath} - ${error2.message}`);
|
|
24331
24388
|
}
|
|
24332
24389
|
}
|
|
24333
|
-
const manifestPath =
|
|
24390
|
+
const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
|
|
24334
24391
|
await fs3.writeFile(manifestPath, JSON.stringify({
|
|
24335
24392
|
uploaded,
|
|
24336
24393
|
criticalKeptLocal: criticalImages.map((i) => i.filename),
|
|
@@ -24357,8 +24414,8 @@ async function uploadAndMigrate(options) {
|
|
|
24357
24414
|
console.log("");
|
|
24358
24415
|
}
|
|
24359
24416
|
async function replaceWithCdnUrls(options) {
|
|
24360
|
-
const targetDir =
|
|
24361
|
-
const manifestPath =
|
|
24417
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
24418
|
+
const manifestPath = resolveImageManifestReadPath(targetDir);
|
|
24362
24419
|
let manifest;
|
|
24363
24420
|
try {
|
|
24364
24421
|
const content = await fs3.readFile(manifestPath, "utf-8");
|
|
@@ -24406,7 +24463,7 @@ async function replaceWithCdnUrls(options) {
|
|
|
24406
24463
|
if (!seenFileLines.has(key)) {
|
|
24407
24464
|
seenFileLines.add(key);
|
|
24408
24465
|
replacements2.push({
|
|
24409
|
-
file:
|
|
24466
|
+
file: path12.relative(targetDir, file),
|
|
24410
24467
|
localPath: pattern,
|
|
24411
24468
|
cdnUrl: img.publicUrl,
|
|
24412
24469
|
line: i + 1
|
|
@@ -24454,9 +24511,9 @@ async function replaceWithCdnUrls(options) {
|
|
|
24454
24511
|
let successCount = 0;
|
|
24455
24512
|
let failCount = 0;
|
|
24456
24513
|
for (const [filePath, fileReplacements] of byFile) {
|
|
24457
|
-
const fileSpinner = ora(`Updating ${
|
|
24514
|
+
const fileSpinner = ora(`Updating ${path12.basename(filePath)}...`).start();
|
|
24458
24515
|
try {
|
|
24459
|
-
const fullPath =
|
|
24516
|
+
const fullPath = path12.join(targetDir, filePath);
|
|
24460
24517
|
let content = await fs3.readFile(fullPath, "utf-8");
|
|
24461
24518
|
for (const r of fileReplacements) {
|
|
24462
24519
|
const escaped = r.localPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -24484,8 +24541,8 @@ async function replaceWithCdnUrls(options) {
|
|
|
24484
24541
|
console.log("");
|
|
24485
24542
|
}
|
|
24486
24543
|
async function refreshManifest(options) {
|
|
24487
|
-
const targetDir =
|
|
24488
|
-
const manifestPath =
|
|
24544
|
+
const targetDir = path12.resolve(options.dir || ".");
|
|
24545
|
+
const manifestPath = path12.join(targetDir, IMAGE_MANIFEST);
|
|
24489
24546
|
const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
24490
24547
|
const apiKey = process.env.SONOR_API_KEY || "";
|
|
24491
24548
|
if (!apiKey) {
|
|
@@ -24494,7 +24551,7 @@ async function refreshManifest(options) {
|
|
|
24494
24551
|
}
|
|
24495
24552
|
let manifest;
|
|
24496
24553
|
try {
|
|
24497
|
-
const content = await fs3.readFile(
|
|
24554
|
+
const content = await fs3.readFile(resolveImageManifestReadPath(targetDir), "utf-8");
|
|
24498
24555
|
manifest = JSON.parse(content);
|
|
24499
24556
|
} catch {
|
|
24500
24557
|
console.log(source_default.yellow(" \u26A0 No upload manifest found"));
|
|
@@ -24547,12 +24604,12 @@ async function refreshManifest(options) {
|
|
|
24547
24604
|
}
|
|
24548
24605
|
async function findDataFiles(rootDir) {
|
|
24549
24606
|
const files = [];
|
|
24550
|
-
const excludeFiles = [
|
|
24607
|
+
const excludeFiles = [IMAGE_MANIFEST, LEGACY_IMAGE_MANIFEST];
|
|
24551
24608
|
async function scan(dir) {
|
|
24552
24609
|
try {
|
|
24553
24610
|
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
24554
24611
|
for (const entry of entries) {
|
|
24555
|
-
const fullPath =
|
|
24612
|
+
const fullPath = path12.join(dir, entry.name);
|
|
24556
24613
|
if (entry.isDirectory()) {
|
|
24557
24614
|
if (["node_modules", ".next", ".git", "dist", "build"].includes(entry.name)) {
|
|
24558
24615
|
continue;
|
|
@@ -24562,7 +24619,7 @@ async function findDataFiles(rootDir) {
|
|
|
24562
24619
|
if (excludeFiles.includes(entry.name)) {
|
|
24563
24620
|
continue;
|
|
24564
24621
|
}
|
|
24565
|
-
const ext2 =
|
|
24622
|
+
const ext2 = path12.extname(entry.name).toLowerCase();
|
|
24566
24623
|
if ([".js", ".ts", ".json", ".jsx", ".tsx", ".mjs", ".cjs"].includes(ext2)) {
|
|
24567
24624
|
files.push(fullPath);
|
|
24568
24625
|
}
|
|
@@ -24575,16 +24632,16 @@ async function findDataFiles(rootDir) {
|
|
|
24575
24632
|
return files;
|
|
24576
24633
|
}
|
|
24577
24634
|
async function scanPublicImages(rootDir) {
|
|
24578
|
-
const publicDir =
|
|
24635
|
+
const publicDir = path12.join(rootDir, "public");
|
|
24579
24636
|
const images = [];
|
|
24580
24637
|
let totalSize = 0;
|
|
24581
24638
|
let usageCount = 0;
|
|
24582
24639
|
const imageFiles = await findImagesRecursive(publicDir);
|
|
24583
24640
|
const sourceFiles = await findSourceFiles2(rootDir);
|
|
24584
24641
|
for (const imagePath of imageFiles) {
|
|
24585
|
-
const relPath =
|
|
24586
|
-
const filename =
|
|
24587
|
-
const ext2 =
|
|
24642
|
+
const relPath = path12.relative(rootDir, imagePath);
|
|
24643
|
+
const filename = path12.basename(imagePath);
|
|
24644
|
+
const ext2 = path12.extname(filename).toLowerCase();
|
|
24588
24645
|
const stat = await fs3.stat(imagePath);
|
|
24589
24646
|
const category = getCategoryFromPath(relPath);
|
|
24590
24647
|
const suggestedSlotId = generateSlotId(relPath);
|
|
@@ -24610,11 +24667,11 @@ async function findImagesRecursive(dir, files = []) {
|
|
|
24610
24667
|
try {
|
|
24611
24668
|
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
24612
24669
|
for (const entry of entries) {
|
|
24613
|
-
const fullPath =
|
|
24670
|
+
const fullPath = path12.join(dir, entry.name);
|
|
24614
24671
|
if (entry.isDirectory()) {
|
|
24615
24672
|
await findImagesRecursive(fullPath, files);
|
|
24616
24673
|
} else if (entry.isFile()) {
|
|
24617
|
-
const ext2 =
|
|
24674
|
+
const ext2 = path12.extname(entry.name).toLowerCase();
|
|
24618
24675
|
if (IMAGE_EXTENSIONS.includes(ext2)) {
|
|
24619
24676
|
files.push(fullPath);
|
|
24620
24677
|
}
|
|
@@ -24627,7 +24684,7 @@ async function findImagesRecursive(dir, files = []) {
|
|
|
24627
24684
|
async function findSourceFiles2(dir, files = []) {
|
|
24628
24685
|
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
24629
24686
|
for (const entry of entries) {
|
|
24630
|
-
const fullPath =
|
|
24687
|
+
const fullPath = path12.join(dir, entry.name);
|
|
24631
24688
|
if (entry.isDirectory()) {
|
|
24632
24689
|
if (["node_modules", ".next", ".git", "dist", "build", "public"].includes(entry.name)) {
|
|
24633
24690
|
continue;
|
|
@@ -24643,8 +24700,8 @@ async function findSourceFiles2(dir, files = []) {
|
|
|
24643
24700
|
}
|
|
24644
24701
|
async function findImageUsages(imagePath, sourceFiles, rootDir) {
|
|
24645
24702
|
const usages = [];
|
|
24646
|
-
const filename =
|
|
24647
|
-
const relPath =
|
|
24703
|
+
const filename = path12.basename(imagePath);
|
|
24704
|
+
const relPath = path12.relative(path12.join(rootDir, "public"), imagePath);
|
|
24648
24705
|
const patterns = [
|
|
24649
24706
|
`/${relPath}`,
|
|
24650
24707
|
// /images/hero.jpg
|
|
@@ -24666,7 +24723,7 @@ async function findImageUsages(imagePath, sourceFiles, rootDir) {
|
|
|
24666
24723
|
const elementType = detectElementType(line);
|
|
24667
24724
|
const canAutoMigrate = ["img", "Image"].includes(elementType);
|
|
24668
24725
|
usages.push({
|
|
24669
|
-
filePath:
|
|
24726
|
+
filePath: path12.relative(rootDir, sourceFile),
|
|
24670
24727
|
line: i + 1,
|
|
24671
24728
|
elementType,
|
|
24672
24729
|
altText: extractAltText(line),
|
|
@@ -24738,7 +24795,7 @@ function detectCriticalImage(filename, relPath, usages, fileSize) {
|
|
|
24738
24795
|
(u) => u.filePath.includes("layout.") || u.filePath.includes("/layout/")
|
|
24739
24796
|
);
|
|
24740
24797
|
const usedInCriticalComponent = usages.some((u) => {
|
|
24741
|
-
const fileName =
|
|
24798
|
+
const fileName = path12.basename(u.filePath).toLowerCase();
|
|
24742
24799
|
return fileName.includes("header") || fileName.includes("navbar") || fileName.includes("nav.") || fileName.includes("hero") || fileName.includes("footer");
|
|
24743
24800
|
});
|
|
24744
24801
|
const isSiteLogo = SITE_LOGO_PATTERNS.some((p) => p.test(filename));
|
|
@@ -24874,7 +24931,7 @@ async function uploadAndMigrateImages(scanResults, options) {
|
|
|
24874
24931
|
for (const img of scanResults.images) {
|
|
24875
24932
|
try {
|
|
24876
24933
|
const uploadResult = await uploadImageToPortal(
|
|
24877
|
-
|
|
24934
|
+
path12.join(rootDir, img.filePath),
|
|
24878
24935
|
img,
|
|
24879
24936
|
{
|
|
24880
24937
|
apiUrl: options.apiUrl,
|
|
@@ -24902,7 +24959,7 @@ async function uploadAndMigrateImages(scanResults, options) {
|
|
|
24902
24959
|
}
|
|
24903
24960
|
for (const [filePath, migrations] of byFile) {
|
|
24904
24961
|
try {
|
|
24905
|
-
await migrateFileImages(
|
|
24962
|
+
await migrateFileImages(path12.join(rootDir, filePath), migrations);
|
|
24906
24963
|
result.migrated += migrations.length;
|
|
24907
24964
|
} catch (error2) {
|
|
24908
24965
|
result.errors.push(`Migration failed for ${filePath}: ${error2.message}`);
|
|
@@ -24916,31 +24973,25 @@ async function migrateCommand(options) {
|
|
|
24916
24973
|
console.log("");
|
|
24917
24974
|
console.log(source_default.bold(" Site-Kit Migration"));
|
|
24918
24975
|
console.log("");
|
|
24919
|
-
const apiKey =
|
|
24920
|
-
const projectId = process.env.SONOR_PROJECT_ID;
|
|
24921
|
-
if (!apiKey || !projectId) {
|
|
24922
|
-
console.log(source_default.red(" \u2717 Missing environment variables"));
|
|
24923
|
-
console.log(source_default.gray(" Run `sonor-setup init` first to configure your project."));
|
|
24924
|
-
console.log("");
|
|
24925
|
-
process.exit(1);
|
|
24926
|
-
}
|
|
24976
|
+
const { apiKey, projectId, apiUrl } = await loadConfig({ resolveProject: true });
|
|
24927
24977
|
if (options.dryRun) {
|
|
24928
24978
|
console.log(source_default.yellow(" Running in dry-run mode - no files will be modified"));
|
|
24929
24979
|
console.log("");
|
|
24930
24980
|
}
|
|
24931
24981
|
if (options.file) {
|
|
24932
|
-
const filePath =
|
|
24982
|
+
const filePath = path12.resolve(options.file);
|
|
24933
24983
|
try {
|
|
24934
24984
|
await fs3.access(filePath);
|
|
24935
24985
|
} catch {
|
|
24936
24986
|
console.log(source_default.red(` \u2717 File not found: ${filePath}`));
|
|
24937
24987
|
process.exit(1);
|
|
24938
24988
|
}
|
|
24939
|
-
const spinner = ora(`Migrating ${
|
|
24989
|
+
const spinner = ora(`Migrating ${path12.basename(filePath)}...`).start();
|
|
24940
24990
|
try {
|
|
24941
24991
|
const result = await migrateFile(filePath, {
|
|
24942
24992
|
projectId,
|
|
24943
24993
|
apiKey,
|
|
24994
|
+
apiUrl,
|
|
24944
24995
|
dryRun: options.dryRun
|
|
24945
24996
|
});
|
|
24946
24997
|
if (result.success) {
|
|
@@ -25003,6 +25054,7 @@ async function migrateCommand(options) {
|
|
|
25003
25054
|
const results = await migrateFiles(scanResults, {
|
|
25004
25055
|
projectId,
|
|
25005
25056
|
apiKey,
|
|
25057
|
+
apiUrl,
|
|
25006
25058
|
dryRun: options.dryRun
|
|
25007
25059
|
});
|
|
25008
25060
|
const successful = results.filter((r) => r.success);
|
|
@@ -25032,10 +25084,9 @@ async function migrateCommand(options) {
|
|
|
25032
25084
|
process.exit(1);
|
|
25033
25085
|
}
|
|
25034
25086
|
console.log("");
|
|
25035
|
-
await handleImageMigration(options, apiKey);
|
|
25087
|
+
await handleImageMigration(options, apiKey, apiUrl);
|
|
25036
25088
|
}
|
|
25037
|
-
async function handleImageMigration(options, apiKey,
|
|
25038
|
-
const apiUrl = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
25089
|
+
async function handleImageMigration(options, apiKey, apiUrl) {
|
|
25039
25090
|
const imageScanSpinner = ora("Scanning for images...").start();
|
|
25040
25091
|
let imageResults;
|
|
25041
25092
|
try {
|
|
@@ -25099,17 +25150,11 @@ function formatBytes2(bytes) {
|
|
|
25099
25150
|
return `${parseFloat((bytes / Math.pow(k2, i)).toFixed(1))} ${sizes[i]}`;
|
|
25100
25151
|
}
|
|
25101
25152
|
var SKIP_PROPS = ["href", "src", "className", "style", "onClick", "ref", "key", "id", "target", "rel", "type", "name", "variant", "size", "icon"];
|
|
25102
|
-
var
|
|
25103
|
-
var TEMPLATES_DIR = ".uptrade/templates";
|
|
25153
|
+
var TEMPLATES_DIR = path12.join(SONOR_STATE_DIR, "templates");
|
|
25104
25154
|
async function locationsCommand(subcommand, arg, options) {
|
|
25105
25155
|
console.log("");
|
|
25106
25156
|
console.log(source_default.bold(" \u{1F4CD} Site-Kit Location Page Manager"));
|
|
25107
25157
|
console.log("");
|
|
25108
|
-
const config2 = await loadConfig();
|
|
25109
|
-
if (!config2?.projectId) {
|
|
25110
|
-
console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
|
|
25111
|
-
return;
|
|
25112
|
-
}
|
|
25113
25158
|
switch (subcommand) {
|
|
25114
25159
|
case "template":
|
|
25115
25160
|
if (!arg) {
|
|
@@ -25117,6 +25162,7 @@ async function locationsCommand(subcommand, arg, options) {
|
|
|
25117
25162
|
console.log(source_default.gray(" Example: locations template ./app/services/plumbing/page.tsx"));
|
|
25118
25163
|
return;
|
|
25119
25164
|
}
|
|
25165
|
+
await loadConfig();
|
|
25120
25166
|
await templateCommand(arg, options);
|
|
25121
25167
|
break;
|
|
25122
25168
|
case "upload":
|
|
@@ -25124,17 +25170,17 @@ async function locationsCommand(subcommand, arg, options) {
|
|
|
25124
25170
|
console.log(source_default.red(" \u2717 Usage: locations upload --template <name>"));
|
|
25125
25171
|
return;
|
|
25126
25172
|
}
|
|
25127
|
-
await uploadCommand(options.template,
|
|
25173
|
+
await uploadCommand(options.template, await loadConfig({ resolveProject: true }));
|
|
25128
25174
|
break;
|
|
25129
25175
|
case "generate":
|
|
25130
25176
|
if (!options.template) {
|
|
25131
25177
|
console.log(source_default.red(' \u2717 Usage: locations generate --template <name> --locations "City, ST" ...'));
|
|
25132
25178
|
return;
|
|
25133
25179
|
}
|
|
25134
|
-
await generateCommand(options,
|
|
25180
|
+
await generateCommand(options, await loadConfig({ resolveProject: true }));
|
|
25135
25181
|
break;
|
|
25136
25182
|
case "list":
|
|
25137
|
-
await listCommand(
|
|
25183
|
+
await listCommand(await loadConfig({ resolveProject: true }));
|
|
25138
25184
|
break;
|
|
25139
25185
|
default:
|
|
25140
25186
|
console.log(source_default.yellow(" Available subcommands:"));
|
|
@@ -25146,10 +25192,10 @@ async function locationsCommand(subcommand, arg, options) {
|
|
|
25146
25192
|
console.log("");
|
|
25147
25193
|
}
|
|
25148
25194
|
}
|
|
25149
|
-
async function templateCommand(sourcePath, options
|
|
25195
|
+
async function templateCommand(sourcePath, options) {
|
|
25150
25196
|
const spinner = ora("Analyzing source page...").start();
|
|
25151
25197
|
try {
|
|
25152
|
-
const resolvedPath =
|
|
25198
|
+
const resolvedPath = path12.resolve(sourcePath);
|
|
25153
25199
|
if (!existsSync(resolvedPath)) {
|
|
25154
25200
|
spinner.fail(`File not found: ${sourcePath}`);
|
|
25155
25201
|
return;
|
|
@@ -25162,8 +25208,8 @@ async function templateCommand(sourcePath, options, config2) {
|
|
|
25162
25208
|
const slots = [];
|
|
25163
25209
|
const componentNames = [];
|
|
25164
25210
|
traverse(ast, {
|
|
25165
|
-
JSXElement(
|
|
25166
|
-
const openingElement =
|
|
25211
|
+
JSXElement(path29) {
|
|
25212
|
+
const openingElement = path29.node.openingElement;
|
|
25167
25213
|
if (isJSXIdentifier(openingElement.name)) {
|
|
25168
25214
|
const componentName = openingElement.name.name;
|
|
25169
25215
|
if (componentName[0] === componentName[0].toUpperCase()) {
|
|
@@ -25203,8 +25249,9 @@ async function templateCommand(sourcePath, options, config2) {
|
|
|
25203
25249
|
},
|
|
25204
25250
|
managed_components: ["schema", "faqs", "metadata"]
|
|
25205
25251
|
};
|
|
25206
|
-
|
|
25207
|
-
|
|
25252
|
+
const templatesDir = path12.join(process.cwd(), TEMPLATES_DIR);
|
|
25253
|
+
await fs3.mkdir(templatesDir, { recursive: true });
|
|
25254
|
+
const templatePath = path12.join(templatesDir, `${templateName}.json`);
|
|
25208
25255
|
await fs3.writeFile(templatePath, JSON.stringify(template, null, 2));
|
|
25209
25256
|
console.log("");
|
|
25210
25257
|
console.log(source_default.green(" \u2713 Template created:"), source_default.cyan(templatePath));
|
|
@@ -25283,7 +25330,7 @@ function inferGenerationHint(propName) {
|
|
|
25283
25330
|
return void 0;
|
|
25284
25331
|
}
|
|
25285
25332
|
function inferTemplateName(sourcePath) {
|
|
25286
|
-
const parts = sourcePath.split(
|
|
25333
|
+
const parts = sourcePath.split(path12.sep);
|
|
25287
25334
|
const pageIndex = parts.findIndex((p) => p === "page.tsx" || p === "page.jsx");
|
|
25288
25335
|
if (pageIndex > 0) {
|
|
25289
25336
|
return parts[pageIndex - 1];
|
|
@@ -25292,14 +25339,14 @@ function inferTemplateName(sourcePath) {
|
|
|
25292
25339
|
return filtered[filtered.length - 1] || "template";
|
|
25293
25340
|
}
|
|
25294
25341
|
function inferSourcePagePath(sourcePath) {
|
|
25295
|
-
const parts = sourcePath.split(
|
|
25342
|
+
const parts = sourcePath.split(path12.sep);
|
|
25296
25343
|
const appIndex = parts.findIndex((p) => p === "app" || p === "pages");
|
|
25297
25344
|
if (appIndex >= 0) {
|
|
25298
25345
|
const pathParts = parts.slice(appIndex + 1);
|
|
25299
25346
|
const filtered = pathParts.filter((p) => !["page.tsx", "page.jsx", "index.tsx", "index.jsx"].includes(p));
|
|
25300
25347
|
return "/" + filtered.join("/");
|
|
25301
25348
|
}
|
|
25302
|
-
return "/" +
|
|
25349
|
+
return "/" + path12.basename(sourcePath, path12.extname(sourcePath));
|
|
25303
25350
|
}
|
|
25304
25351
|
function toSnakeCase(str) {
|
|
25305
25352
|
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
@@ -25311,22 +25358,22 @@ function truncate(str, maxLength) {
|
|
|
25311
25358
|
async function uploadCommand(templateName, config2) {
|
|
25312
25359
|
const spinner = ora("Uploading template to Portal...").start();
|
|
25313
25360
|
try {
|
|
25314
|
-
const templatePath =
|
|
25361
|
+
const templatePath = resolveStateReadPath(path12.join("templates", `${templateName}.json`));
|
|
25315
25362
|
if (!existsSync(templatePath)) {
|
|
25316
25363
|
spinner.fail(`Template not found: ${templatePath}`);
|
|
25317
25364
|
console.log(source_default.gray(` Run: npx sonor-setup locations template <page> --name ${templateName}`));
|
|
25318
25365
|
return;
|
|
25319
25366
|
}
|
|
25320
25367
|
const template = JSON.parse(readFileSync(templatePath, "utf-8"));
|
|
25321
|
-
const response = await fetch(`${
|
|
25368
|
+
const response = await fetch(`${config2.apiUrl}/seo/location-templates`, {
|
|
25322
25369
|
method: "POST",
|
|
25323
25370
|
headers: {
|
|
25324
25371
|
"Content-Type": "application/json",
|
|
25325
25372
|
"Authorization": `Bearer ${config2.apiKey}`
|
|
25326
25373
|
},
|
|
25327
25374
|
body: JSON.stringify({
|
|
25328
|
-
|
|
25329
|
-
|
|
25375
|
+
...template,
|
|
25376
|
+
project_id: config2.projectId
|
|
25330
25377
|
})
|
|
25331
25378
|
});
|
|
25332
25379
|
if (!response.ok) {
|
|
@@ -25334,11 +25381,11 @@ async function uploadCommand(templateName, config2) {
|
|
|
25334
25381
|
if (response.status === 409) {
|
|
25335
25382
|
spinner.text = "Template exists, updating...";
|
|
25336
25383
|
const existing = await fetch(
|
|
25337
|
-
`${
|
|
25384
|
+
`${config2.apiUrl}/seo/location-templates/by-name/${templateName}?project_id=${config2.projectId}`,
|
|
25338
25385
|
{ headers: { "Authorization": `Bearer ${config2.apiKey}` } }
|
|
25339
25386
|
);
|
|
25340
25387
|
const existingData = await existing.json();
|
|
25341
|
-
const updateResponse = await fetch(`${
|
|
25388
|
+
const updateResponse = await fetch(`${config2.apiUrl}/seo/location-templates/${existingData.id}`, {
|
|
25342
25389
|
method: "PUT",
|
|
25343
25390
|
headers: {
|
|
25344
25391
|
"Content-Type": "application/json",
|
|
@@ -25387,7 +25434,7 @@ async function generateCommand(options, config2) {
|
|
|
25387
25434
|
}
|
|
25388
25435
|
const spinner = ora(`Generating ${type || "service-location"} pages...`).start();
|
|
25389
25436
|
try {
|
|
25390
|
-
const response = await fetch(`${
|
|
25437
|
+
const response = await fetch(`${config2.apiUrl}/seo/location-pages/generate`, {
|
|
25391
25438
|
method: "POST",
|
|
25392
25439
|
headers: {
|
|
25393
25440
|
"Content-Type": "application/json",
|
|
@@ -25427,7 +25474,7 @@ async function listCommand(config2) {
|
|
|
25427
25474
|
const spinner = ora("Fetching templates...").start();
|
|
25428
25475
|
try {
|
|
25429
25476
|
const response = await fetch(
|
|
25430
|
-
`${
|
|
25477
|
+
`${config2.apiUrl}/seo/location-templates?project_id=${config2.projectId}`,
|
|
25431
25478
|
{ headers: { "Authorization": `Bearer ${config2.apiKey}` } }
|
|
25432
25479
|
);
|
|
25433
25480
|
if (!response.ok) {
|
|
@@ -25452,69 +25499,21 @@ async function listCommand(config2) {
|
|
|
25452
25499
|
});
|
|
25453
25500
|
}
|
|
25454
25501
|
console.log("");
|
|
25455
|
-
|
|
25456
|
-
|
|
25457
|
-
|
|
25458
|
-
|
|
25459
|
-
console.log(source_default.gray(
|
|
25460
|
-
|
|
25461
|
-
|
|
25462
|
-
});
|
|
25463
|
-
console.log("");
|
|
25464
|
-
}
|
|
25502
|
+
const localTemplates = await listLocalTemplates();
|
|
25503
|
+
if (localTemplates.length > 0) {
|
|
25504
|
+
console.log(source_default.gray(" Local (not uploaded):"));
|
|
25505
|
+
localTemplates.forEach((f) => {
|
|
25506
|
+
console.log(source_default.gray(` \u2022 ${f.replace(".json", "")}`));
|
|
25507
|
+
});
|
|
25508
|
+
console.log("");
|
|
25465
25509
|
}
|
|
25466
25510
|
} catch (error2) {
|
|
25467
25511
|
spinner.fail(`Failed to fetch templates: ${error2.message}`);
|
|
25468
25512
|
}
|
|
25469
25513
|
}
|
|
25470
|
-
async function loadConfig() {
|
|
25471
|
-
const configPath = path10.join(".uptrade", "config.json");
|
|
25472
|
-
if (existsSync(configPath)) {
|
|
25473
|
-
try {
|
|
25474
|
-
const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
25475
|
-
return {
|
|
25476
|
-
projectId: config2.projectId || config2.project_id,
|
|
25477
|
-
apiKey: config2.apiKey || config2.api_key
|
|
25478
|
-
};
|
|
25479
|
-
} catch {
|
|
25480
|
-
return null;
|
|
25481
|
-
}
|
|
25482
|
-
}
|
|
25483
|
-
const projectId = process.env.SONOR_PROJECT_ID;
|
|
25484
|
-
const apiKey = process.env.SONOR_API_KEY;
|
|
25485
|
-
if (projectId && apiKey) {
|
|
25486
|
-
return { projectId, apiKey };
|
|
25487
|
-
}
|
|
25488
|
-
return null;
|
|
25489
|
-
}
|
|
25490
|
-
var API_URL3 = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
25491
|
-
async function loadConfig2() {
|
|
25492
|
-
const configPath = path10.join(".uptrade", "config.json");
|
|
25493
|
-
if (existsSync(configPath)) {
|
|
25494
|
-
try {
|
|
25495
|
-
const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
25496
|
-
return {
|
|
25497
|
-
projectId: config2.projectId || config2.project_id,
|
|
25498
|
-
apiKey: config2.apiKey || config2.api_key
|
|
25499
|
-
};
|
|
25500
|
-
} catch {
|
|
25501
|
-
return null;
|
|
25502
|
-
}
|
|
25503
|
-
}
|
|
25504
|
-
const projectId = process.env.SONOR_PROJECT_ID;
|
|
25505
|
-
const apiKey = process.env.SONOR_API_KEY;
|
|
25506
|
-
if (projectId && apiKey) return { projectId, apiKey };
|
|
25507
|
-
return null;
|
|
25508
|
-
}
|
|
25509
25514
|
async function faqsCommand(subcommand, options) {
|
|
25510
25515
|
console.log("");
|
|
25511
|
-
const config2 = await
|
|
25512
|
-
if (!config2?.projectId || !config2?.apiKey) {
|
|
25513
|
-
console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
|
|
25514
|
-
console.log(source_default.gray(" Set SONOR_API_KEY, or use .uptrade/config.json"));
|
|
25515
|
-
console.log("");
|
|
25516
|
-
return;
|
|
25517
|
-
}
|
|
25516
|
+
const config2 = await loadConfig({ resolveProject: true });
|
|
25518
25517
|
switch (subcommand) {
|
|
25519
25518
|
case "extract":
|
|
25520
25519
|
await extractCommand(options, config2);
|
|
@@ -25564,7 +25563,7 @@ async function extractCommand(options, config2) {
|
|
|
25564
25563
|
const faqContexts = [];
|
|
25565
25564
|
for (const faq of faqSections) {
|
|
25566
25565
|
try {
|
|
25567
|
-
const fullPath =
|
|
25566
|
+
const fullPath = path12.resolve(process.cwd(), faq.filePath);
|
|
25568
25567
|
const content = await fs3.readFile(fullPath, "utf-8");
|
|
25569
25568
|
let pagePath = faq.filePath.replace(/^app\//, "/").replace(/^src\/app\//, "/").replace(/\/page\.(tsx?|jsx?)$/, "").replace(/\[([^\]]+)\]/g, ":$1");
|
|
25570
25569
|
if (pagePath === "" || pagePath === "/page") pagePath = "/";
|
|
@@ -25579,7 +25578,7 @@ async function extractCommand(options, config2) {
|
|
|
25579
25578
|
if (importPath.startsWith("@/")) {
|
|
25580
25579
|
resolvedPath = importPath.replace("@/", "./");
|
|
25581
25580
|
} else if (importPath.startsWith(".")) {
|
|
25582
|
-
resolvedPath =
|
|
25581
|
+
resolvedPath = path12.resolve(path12.dirname(fullPath), importPath);
|
|
25583
25582
|
}
|
|
25584
25583
|
const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
|
|
25585
25584
|
for (const ext2 of extensions) {
|
|
@@ -25624,7 +25623,7 @@ async function extractCommand(options, config2) {
|
|
|
25624
25623
|
}
|
|
25625
25624
|
const extractSpinner = ora("Extracting FAQs via AI...").start();
|
|
25626
25625
|
try {
|
|
25627
|
-
const response = await fetch(`${
|
|
25626
|
+
const response = await fetch(`${config2.apiUrl}/seo/managed/faqs/extract`, {
|
|
25628
25627
|
method: "POST",
|
|
25629
25628
|
headers: {
|
|
25630
25629
|
"Content-Type": "application/json",
|
|
@@ -25659,7 +25658,7 @@ async function extractCommand(options, config2) {
|
|
|
25659
25658
|
let failed = 0;
|
|
25660
25659
|
for (const faq of extractedFaqs) {
|
|
25661
25660
|
try {
|
|
25662
|
-
const res = await fetch(`${
|
|
25661
|
+
const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
|
|
25663
25662
|
method: "POST",
|
|
25664
25663
|
headers: {
|
|
25665
25664
|
"Content-Type": "application/json",
|
|
@@ -25684,7 +25683,7 @@ async function extractCommand(options, config2) {
|
|
|
25684
25683
|
uploaded++;
|
|
25685
25684
|
console.log(source_default.green(` \u2713 ${faq.path}`) + source_default.gray(` (${faq.items.length} items)`));
|
|
25686
25685
|
} else if (res.status === 409 || res.status === 400) {
|
|
25687
|
-
const updateRes = await fetch(`${
|
|
25686
|
+
const updateRes = await fetch(`${config2.apiUrl}/seo/managed/faqs/by-path`, {
|
|
25688
25687
|
method: "PUT",
|
|
25689
25688
|
headers: {
|
|
25690
25689
|
"Content-Type": "application/json",
|
|
@@ -25754,7 +25753,7 @@ async function syncCommand(options, config2) {
|
|
|
25754
25753
|
if (codePaths.length === 0) {
|
|
25755
25754
|
spinner.warn("No ManagedFAQ components found");
|
|
25756
25755
|
console.log("");
|
|
25757
|
-
console.log(source_default.gray(' Add <ManagedFAQ
|
|
25756
|
+
console.log(source_default.gray(' Add <ManagedFAQ path="/your-page" /> to your pages, then run:'));
|
|
25758
25757
|
console.log(source_default.gray(" npx sonor-setup migrate (to add the component)"));
|
|
25759
25758
|
console.log(source_default.gray(" npx sonor-setup faqs sync (to register paths in Portal)"));
|
|
25760
25759
|
console.log("");
|
|
@@ -25771,7 +25770,7 @@ async function syncCommand(options, config2) {
|
|
|
25771
25770
|
const listSpinner = ora("Fetching existing FAQ sections from Portal...").start();
|
|
25772
25771
|
let existing = [];
|
|
25773
25772
|
try {
|
|
25774
|
-
const res = await fetch(`${
|
|
25773
|
+
const res = await fetch(`${config2.apiUrl}/seo/managed/faqs/project/${config2.projectId}`, {
|
|
25775
25774
|
headers: { Authorization: `Bearer ${config2.apiKey}` }
|
|
25776
25775
|
});
|
|
25777
25776
|
if (!res.ok) {
|
|
@@ -25800,7 +25799,7 @@ async function syncCommand(options, config2) {
|
|
|
25800
25799
|
let failed = 0;
|
|
25801
25800
|
for (const p of toCreate) {
|
|
25802
25801
|
try {
|
|
25803
|
-
const res = await fetch(`${
|
|
25802
|
+
const res = await fetch(`${config2.apiUrl}/seo/managed/faqs`, {
|
|
25804
25803
|
method: "POST",
|
|
25805
25804
|
headers: {
|
|
25806
25805
|
"Content-Type": "application/json",
|
|
@@ -25837,44 +25836,12 @@ async function syncCommand(options, config2) {
|
|
|
25837
25836
|
console.log(source_default.gray(" Add questions and answers there; they will appear on your site."));
|
|
25838
25837
|
console.log("");
|
|
25839
25838
|
}
|
|
25840
|
-
function getApiUrl() {
|
|
25841
|
-
return process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
25842
|
-
}
|
|
25843
|
-
async function loadConfig3() {
|
|
25844
|
-
const configPath = path10.join(".uptrade", "config.json");
|
|
25845
|
-
if (existsSync(configPath)) {
|
|
25846
|
-
try {
|
|
25847
|
-
const config2 = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
25848
|
-
return {
|
|
25849
|
-
projectId: config2.projectId || config2.project_id,
|
|
25850
|
-
apiKey: config2.apiKey || config2.api_key,
|
|
25851
|
-
siteUrl: config2.siteUrl || config2.site_url,
|
|
25852
|
-
businessInfo: config2.businessInfo || config2.business_info
|
|
25853
|
-
};
|
|
25854
|
-
} catch {
|
|
25855
|
-
return null;
|
|
25856
|
-
}
|
|
25857
|
-
}
|
|
25858
|
-
const projectId = process.env.SONOR_PROJECT_ID;
|
|
25859
|
-
const apiKey = process.env.SONOR_API_KEY;
|
|
25860
|
-
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || process.env.SITE_URL;
|
|
25861
|
-
if (projectId && apiKey) {
|
|
25862
|
-
return { projectId, apiKey, siteUrl };
|
|
25863
|
-
}
|
|
25864
|
-
return null;
|
|
25865
|
-
}
|
|
25866
25839
|
async function setupCommand(options) {
|
|
25867
25840
|
console.log("");
|
|
25868
25841
|
console.log(source_default.bold.blue(" \u{1F680} Signal-Enhanced SEO Setup"));
|
|
25869
25842
|
console.log(source_default.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
25870
25843
|
console.log("");
|
|
25871
|
-
const config2 = await
|
|
25872
|
-
if (!config2?.projectId || !config2?.apiKey) {
|
|
25873
|
-
console.log(source_default.red(" \u2717 Not configured. Run `npx sonor-setup init` first."));
|
|
25874
|
-
console.log(source_default.gray(" Set SONOR_API_KEY"));
|
|
25875
|
-
console.log("");
|
|
25876
|
-
return;
|
|
25877
|
-
}
|
|
25844
|
+
const config2 = await loadConfig();
|
|
25878
25845
|
const capabilities = [];
|
|
25879
25846
|
if (options.faqsOnly) {
|
|
25880
25847
|
capabilities.push("extract_faqs");
|
|
@@ -25972,14 +25939,13 @@ async function setupCommand(options) {
|
|
|
25972
25939
|
const batch = batches[batchIndex];
|
|
25973
25940
|
const batchSpinner = ora(`Batch ${batchIndex + 1}/${batches.length}: Analyzing ${batch.length} pages...`).start();
|
|
25974
25941
|
try {
|
|
25975
|
-
const response = await fetch(`${
|
|
25942
|
+
const response = await fetch(`${config2.apiUrl}/api/public/seo/site-setup`, {
|
|
25976
25943
|
method: "POST",
|
|
25977
25944
|
headers: {
|
|
25978
25945
|
"Content-Type": "application/json",
|
|
25979
25946
|
"x-api-key": config2.apiKey
|
|
25980
25947
|
},
|
|
25981
25948
|
body: JSON.stringify({
|
|
25982
|
-
project_id: config2.projectId,
|
|
25983
25949
|
site_url: config2.siteUrl || "https://example.com",
|
|
25984
25950
|
// Only send business_info on first batch (for org schema)
|
|
25985
25951
|
business_info: batchIndex === 0 ? config2.businessInfo : void 0,
|
|
@@ -26071,10 +26037,10 @@ async function setupCommand(options) {
|
|
|
26071
26037
|
}
|
|
26072
26038
|
async function scanForPageFiles(rootDir) {
|
|
26073
26039
|
const pages = [];
|
|
26074
|
-
const appDir =
|
|
26075
|
-
const srcAppDir =
|
|
26076
|
-
const pagesDir =
|
|
26077
|
-
const srcPagesDir =
|
|
26040
|
+
const appDir = path12.join(rootDir, "app");
|
|
26041
|
+
const srcAppDir = path12.join(rootDir, "src", "app");
|
|
26042
|
+
const pagesDir = path12.join(rootDir, "pages");
|
|
26043
|
+
const srcPagesDir = path12.join(rootDir, "src", "pages");
|
|
26078
26044
|
const dirs = [appDir, srcAppDir, pagesDir, srcPagesDir];
|
|
26079
26045
|
for (const dir of dirs) {
|
|
26080
26046
|
if (existsSync(dir)) {
|
|
@@ -26086,7 +26052,7 @@ async function scanForPageFiles(rootDir) {
|
|
|
26086
26052
|
async function scanDirectory(dir, baseDir, pages) {
|
|
26087
26053
|
const entries = await fs3.readdir(dir, { withFileTypes: true });
|
|
26088
26054
|
for (const entry of entries) {
|
|
26089
|
-
const fullPath =
|
|
26055
|
+
const fullPath = path12.join(dir, entry.name);
|
|
26090
26056
|
if (entry.isDirectory()) {
|
|
26091
26057
|
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "api") {
|
|
26092
26058
|
continue;
|
|
@@ -26097,8 +26063,8 @@ async function scanDirectory(dir, baseDir, pages) {
|
|
|
26097
26063
|
const isLegacyPage = baseDir.includes("/pages") && entry.name.match(/\.(tsx?|jsx?)$/) && !entry.name.startsWith("_");
|
|
26098
26064
|
if (isPage || isLegacyPage) {
|
|
26099
26065
|
const content = await fs3.readFile(fullPath, "utf-8");
|
|
26100
|
-
const relativePath =
|
|
26101
|
-
let pagePath = "/" +
|
|
26066
|
+
const relativePath = path12.relative(baseDir, fullPath);
|
|
26067
|
+
let pagePath = "/" + path12.dirname(relativePath).replace(/\\/g, "/").replace(/\/page$/, "");
|
|
26102
26068
|
pagePath = pagePath.replace(/\[([^\]]+)\]/g, ":$1").replace(/^\/\.$/, "/");
|
|
26103
26069
|
if (pagePath === "/.") pagePath = "/";
|
|
26104
26070
|
pages.push({
|
|
@@ -26118,10 +26084,10 @@ async function gatherImportedFiles(page, rootDir) {
|
|
|
26118
26084
|
if (importPath.toLowerCase().includes("faq") || importPath.includes("@/data") || importPath.includes("./data") || importPath.includes("../data") || importPath.includes("/constants") || importPath.includes("/content") || importPath.includes("practice-areas") || importPath.includes("subpages") || importPath.includes("pages-data")) {
|
|
26119
26085
|
let resolvedPath = importPath;
|
|
26120
26086
|
if (importPath.startsWith("@/")) {
|
|
26121
|
-
resolvedPath =
|
|
26087
|
+
resolvedPath = path12.join(rootDir, importPath.replace("@/", ""));
|
|
26122
26088
|
} else if (importPath.startsWith(".")) {
|
|
26123
|
-
const pageDir =
|
|
26124
|
-
resolvedPath =
|
|
26089
|
+
const pageDir = path12.dirname(path12.join(rootDir, "app", page.filePath));
|
|
26090
|
+
resolvedPath = path12.resolve(pageDir, importPath);
|
|
26125
26091
|
}
|
|
26126
26092
|
const extensions = ["", ".js", ".ts", ".jsx", ".tsx", ".json"];
|
|
26127
26093
|
for (const ext2 of extensions) {
|
|
@@ -26177,20 +26143,20 @@ async function expandDynamicRoutes(pages, rootDir) {
|
|
|
26177
26143
|
async function findDynamicRouteData(page, parentPath, rootDir) {
|
|
26178
26144
|
const results = [];
|
|
26179
26145
|
const dataFilePaths = [
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26184
|
-
|
|
26185
|
-
|
|
26186
|
-
|
|
26187
|
-
|
|
26188
|
-
|
|
26189
|
-
|
|
26190
|
-
|
|
26191
|
-
|
|
26192
|
-
|
|
26193
|
-
|
|
26146
|
+
path12.join(rootDir, "data", "practice-areas.js"),
|
|
26147
|
+
path12.join(rootDir, "data", "practice-areas.ts"),
|
|
26148
|
+
path12.join(rootDir, "data", "personal-injury-pages.js"),
|
|
26149
|
+
path12.join(rootDir, "data", "personal-injury-pages.ts"),
|
|
26150
|
+
path12.join(rootDir, "data", "pages.js"),
|
|
26151
|
+
path12.join(rootDir, "data", "pages.ts"),
|
|
26152
|
+
path12.join(rootDir, "data", "content.js"),
|
|
26153
|
+
path12.join(rootDir, "data", "content.ts"),
|
|
26154
|
+
path12.join(rootDir, "data", "services.js"),
|
|
26155
|
+
path12.join(rootDir, "data", "services.ts"),
|
|
26156
|
+
path12.join(rootDir, "data", "subpages.js"),
|
|
26157
|
+
path12.join(rootDir, "data", "subpages.ts"),
|
|
26158
|
+
path12.join(rootDir, "src", "data", "practice-areas.js"),
|
|
26159
|
+
path12.join(rootDir, "src", "data", "practice-areas.ts")
|
|
26194
26160
|
];
|
|
26195
26161
|
const routeSegment = parentPath.replace(/^\//, "").split("/")[0];
|
|
26196
26162
|
const routeSegmentNormalized = routeSegment.replace(/-/g, "");
|
|
@@ -26282,7 +26248,7 @@ async function uploadFaqs(pages, config2) {
|
|
|
26282
26248
|
for (const page of pages) {
|
|
26283
26249
|
if (!page.faqs?.items?.length) continue;
|
|
26284
26250
|
try {
|
|
26285
|
-
const res = await fetch(`${
|
|
26251
|
+
const res = await fetch(`${config2.apiUrl}/api/public/seo/register-faq`, {
|
|
26286
26252
|
method: "POST",
|
|
26287
26253
|
headers: {
|
|
26288
26254
|
"Content-Type": "application/json",
|
|
@@ -26317,7 +26283,7 @@ async function uploadFaqs(pages, config2) {
|
|
|
26317
26283
|
async function uploadSchemas(pages, globalSchema, config2) {
|
|
26318
26284
|
if (globalSchema) {
|
|
26319
26285
|
try {
|
|
26320
|
-
const res = await fetch(`${
|
|
26286
|
+
const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
|
|
26321
26287
|
method: "POST",
|
|
26322
26288
|
headers: {
|
|
26323
26289
|
"Content-Type": "application/json",
|
|
@@ -26343,7 +26309,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
|
|
|
26343
26309
|
if (!page.schemas?.length) continue;
|
|
26344
26310
|
for (const schema of page.schemas) {
|
|
26345
26311
|
try {
|
|
26346
|
-
const res = await fetch(`${
|
|
26312
|
+
const res = await fetch(`${config2.apiUrl}/api/public/seo/register-schema`, {
|
|
26347
26313
|
method: "POST",
|
|
26348
26314
|
headers: {
|
|
26349
26315
|
"Content-Type": "application/json",
|
|
@@ -26367,7 +26333,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
|
|
|
26367
26333
|
}
|
|
26368
26334
|
}
|
|
26369
26335
|
}
|
|
26370
|
-
var APP_DIRS = ["app",
|
|
26336
|
+
var APP_DIRS = ["app", path12.join("src", "app")];
|
|
26371
26337
|
var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
|
|
26372
26338
|
function safeExists(p) {
|
|
26373
26339
|
try {
|
|
@@ -26387,19 +26353,19 @@ function findPageCards(cwd) {
|
|
|
26387
26353
|
}
|
|
26388
26354
|
for (const entry of entries) {
|
|
26389
26355
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
26390
|
-
const full =
|
|
26356
|
+
const full = path12.join(dir, entry.name);
|
|
26391
26357
|
if (entry.isDirectory()) walk(full);
|
|
26392
26358
|
else if (CARD_FILE.test(entry.name)) found.push(full);
|
|
26393
26359
|
}
|
|
26394
26360
|
};
|
|
26395
|
-
for (const rel of APP_DIRS) walk(
|
|
26361
|
+
for (const rel of APP_DIRS) walk(path12.join(cwd, rel));
|
|
26396
26362
|
return found;
|
|
26397
26363
|
}
|
|
26398
26364
|
function readOgWiring(cwd) {
|
|
26399
26365
|
const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
|
|
26400
|
-
(rel) => safeExists(
|
|
26366
|
+
(rel) => safeExists(path12.join(cwd, rel))
|
|
26401
26367
|
);
|
|
26402
|
-
const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) =>
|
|
26368
|
+
const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path12.join(cwd, rel)).find(safeExists);
|
|
26403
26369
|
let layout = "";
|
|
26404
26370
|
if (layoutPath) {
|
|
26405
26371
|
try {
|
|
@@ -26458,8 +26424,15 @@ function checkOgWiring(cwd) {
|
|
|
26458
26424
|
return judgeOgWiring(readOgWiring(cwd));
|
|
26459
26425
|
}
|
|
26460
26426
|
|
|
26427
|
+
// src/cli/agent/ssr-bailout.ts
|
|
26428
|
+
var DEFERRED_SIBLING_SINCE = "3.0.2";
|
|
26429
|
+
var LAYOUT_ALREADY_DEFERS = `plain <SiteKitLayout>{children}</SiteKitLayout> already mounts analytics as a deferred, childless sibling on site-kit >=${DEFERRED_SIBLING_SINCE}`;
|
|
26430
|
+
var LEGACY_STOPGAP = `Only on site-kit <${DEFERRED_SIBLING_SINCE}: upgrade, or as a stopgap run SiteKitLayout with analytics={false} plus a deferred, childless analytics sibling.`;
|
|
26431
|
+
var SSR_BAILOUT_FIX = `Keep the layout: ${LAYOUT_ALREADY_DEFERS}, so it is not the cause. Find what else wraps {children}, usually a next/dynamic({ ssr: false }) component such as a site's own lazy Providers. Import it statically (a client component still server-renders; only ssr: false skips that) or mount it as a childless sibling. ${LEGACY_STOPGAP}`;
|
|
26432
|
+
var ANALYTICS_WRAPPER_FIX = `Remove the <AnalyticsProvider> wrapper: ${LAYOUT_ALREADY_DEFERS} (configure it with analytics={{ ... }}). Track custom events with trackEvent / trackConversion from @sonordev/site-kit/analytics, which need no provider, instead of useAnalytics(). ` + LEGACY_STOPGAP;
|
|
26433
|
+
|
|
26461
26434
|
// src/cli/agent/checks.ts
|
|
26462
|
-
var
|
|
26435
|
+
var API_URL = process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
26463
26436
|
async function readFileOrNull(p) {
|
|
26464
26437
|
try {
|
|
26465
26438
|
return await fs3.readFile(p, "utf-8");
|
|
@@ -26469,7 +26442,7 @@ async function readFileOrNull(p) {
|
|
|
26469
26442
|
}
|
|
26470
26443
|
async function findFirst(cwd, candidates) {
|
|
26471
26444
|
for (const rel of candidates) {
|
|
26472
|
-
const full =
|
|
26445
|
+
const full = path12.join(cwd, rel);
|
|
26473
26446
|
if (await readFileOrNull(full)) return full;
|
|
26474
26447
|
}
|
|
26475
26448
|
return null;
|
|
@@ -26521,7 +26494,7 @@ function checkApiKeyEnv() {
|
|
|
26521
26494
|
};
|
|
26522
26495
|
}
|
|
26523
26496
|
async function checkPackageInstalled(cwd) {
|
|
26524
|
-
const raw = await readFileOrNull(
|
|
26497
|
+
const raw = await readFileOrNull(path12.join(cwd, "package.json"));
|
|
26525
26498
|
if (!raw) {
|
|
26526
26499
|
return {
|
|
26527
26500
|
id: "package.installed",
|
|
@@ -26585,7 +26558,7 @@ async function checkSiteKitLayout(cwd) {
|
|
|
26585
26558
|
};
|
|
26586
26559
|
}
|
|
26587
26560
|
const content = await readFileOrNull(layoutPath) || "";
|
|
26588
|
-
const rel =
|
|
26561
|
+
const rel = path12.relative(cwd, layoutPath);
|
|
26589
26562
|
if (content.includes("SiteKitLayout")) {
|
|
26590
26563
|
return {
|
|
26591
26564
|
id: "layout.sitekit",
|
|
@@ -26641,7 +26614,7 @@ async function checkSitemap(cwd) {
|
|
|
26641
26614
|
};
|
|
26642
26615
|
}
|
|
26643
26616
|
async function checkPostbuildSitemap(cwd) {
|
|
26644
|
-
const raw = await readFileOrNull(
|
|
26617
|
+
const raw = await readFileOrNull(path12.join(cwd, "package.json"));
|
|
26645
26618
|
let pkg = {};
|
|
26646
26619
|
try {
|
|
26647
26620
|
pkg = raw ? JSON.parse(raw) : {};
|
|
@@ -26678,18 +26651,18 @@ async function checkPostbuildSitemap(cwd) {
|
|
|
26678
26651
|
async function checkApiReachable(timeoutMs = 5e3) {
|
|
26679
26652
|
const key = process.env.SONOR_API_KEY;
|
|
26680
26653
|
try {
|
|
26681
|
-
const res = await fetch(`${
|
|
26654
|
+
const res = await fetch(`${API_URL}/health`, {
|
|
26682
26655
|
headers: key ? { "x-api-key": key } : {},
|
|
26683
26656
|
signal: AbortSignal.timeout(timeoutMs)
|
|
26684
26657
|
});
|
|
26685
26658
|
if (res.ok) {
|
|
26686
|
-
return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${
|
|
26659
|
+
return { id: "api.reachable", title: "Sonor API", level: "ok", message: `Reachable (${API_URL})` };
|
|
26687
26660
|
}
|
|
26688
26661
|
return {
|
|
26689
26662
|
id: "api.reachable",
|
|
26690
26663
|
title: "Sonor API",
|
|
26691
26664
|
level: "warn",
|
|
26692
|
-
message: `HTTP ${res.status} from ${
|
|
26665
|
+
message: `HTTP ${res.status} from ${API_URL}`
|
|
26693
26666
|
};
|
|
26694
26667
|
} catch (err) {
|
|
26695
26668
|
return {
|
|
@@ -26714,7 +26687,7 @@ async function checkKeyValid(timeoutMs = 8e3) {
|
|
|
26714
26687
|
};
|
|
26715
26688
|
}
|
|
26716
26689
|
try {
|
|
26717
|
-
const res = await fetch(`${
|
|
26690
|
+
const res = await fetch(`${API_URL}/api/public/seo/verify-api-key`, {
|
|
26718
26691
|
headers: { "x-api-key": key },
|
|
26719
26692
|
signal: AbortSignal.timeout(timeoutMs)
|
|
26720
26693
|
});
|
|
@@ -26817,7 +26790,7 @@ async function checkClientAuth(timeoutMs = 8e3) {
|
|
|
26817
26790
|
}
|
|
26818
26791
|
const qs2 = host ? `?host=${encodeURIComponent(host)}` : "";
|
|
26819
26792
|
try {
|
|
26820
|
-
const res = await fetch(`${
|
|
26793
|
+
const res = await fetch(`${API_URL}/api/public/site-token/status${qs2}`, {
|
|
26821
26794
|
headers: { "x-api-key": key },
|
|
26822
26795
|
signal: AbortSignal.timeout(timeoutMs)
|
|
26823
26796
|
});
|
|
@@ -26940,7 +26913,7 @@ async function checkSsrRenderFromUrl(url, timeoutMs = 12e3) {
|
|
|
26940
26913
|
level: "error",
|
|
26941
26914
|
message: "Page bailed to client rendering",
|
|
26942
26915
|
detail: `Only ${contentTags} content tags in the server HTML \u2014 the route ships an empty shell + RSC flight data.`,
|
|
26943
|
-
fix:
|
|
26916
|
+
fix: SSR_BAILOUT_FIX,
|
|
26944
26917
|
docs: "manifest#failureModes"
|
|
26945
26918
|
};
|
|
26946
26919
|
}
|
|
@@ -26962,7 +26935,7 @@ async function checkSsrRenderFromUrl(url, timeoutMs = 12e3) {
|
|
|
26962
26935
|
}
|
|
26963
26936
|
}
|
|
26964
26937
|
async function checkSsrRenderFromBuild(cwd) {
|
|
26965
|
-
const appDir =
|
|
26938
|
+
const appDir = path12.join(cwd, ".next", "server", "app");
|
|
26966
26939
|
let entries;
|
|
26967
26940
|
try {
|
|
26968
26941
|
entries = await fs3.readdir(appDir);
|
|
@@ -26985,7 +26958,7 @@ async function checkSsrRenderFromBuild(cwd) {
|
|
|
26985
26958
|
detail: "The root route may be fully dynamic. Pass --url to verify a running instance."
|
|
26986
26959
|
};
|
|
26987
26960
|
}
|
|
26988
|
-
const html = await readFileOrNull(
|
|
26961
|
+
const html = await readFileOrNull(path12.join(appDir, htmlName)) || "";
|
|
26989
26962
|
const { rendered, contentTags } = looksServerRendered(html);
|
|
26990
26963
|
if (rendered) {
|
|
26991
26964
|
return {
|
|
@@ -27000,7 +26973,7 @@ async function checkSsrRenderFromBuild(cwd) {
|
|
|
27000
26973
|
title: "Server-side rendering",
|
|
27001
26974
|
level: "error",
|
|
27002
26975
|
message: `Prerendered HTML has only ${contentTags} content tags \u2014 likely CSR bailout`,
|
|
27003
|
-
fix:
|
|
26976
|
+
fix: SSR_BAILOUT_FIX,
|
|
27004
26977
|
docs: "manifest#failureModes"
|
|
27005
26978
|
};
|
|
27006
26979
|
}
|
|
@@ -27008,7 +26981,7 @@ async function checkNetlifyMiddleware(cwd) {
|
|
|
27008
26981
|
const runtimeRe = /runtime\s*[:=]\s*['"](nodejs|edge)['"]/;
|
|
27009
26982
|
const proxyFiles = ["proxy.ts", "proxy.js", "src/proxy.ts", "src/proxy.js"];
|
|
27010
26983
|
for (const rel of proxyFiles) {
|
|
27011
|
-
const content = await readFileOrNull(
|
|
26984
|
+
const content = await readFileOrNull(path12.join(cwd, rel));
|
|
27012
26985
|
if (content === null) continue;
|
|
27013
26986
|
if (runtimeRe.test(content)) {
|
|
27014
26987
|
return {
|
|
@@ -27025,7 +26998,7 @@ async function checkNetlifyMiddleware(cwd) {
|
|
|
27025
26998
|
}
|
|
27026
26999
|
const middlewareFiles = ["middleware.ts", "middleware.js", "src/middleware.ts", "src/middleware.js"];
|
|
27027
27000
|
for (const rel of middlewareFiles) {
|
|
27028
|
-
const content = await readFileOrNull(
|
|
27001
|
+
const content = await readFileOrNull(path12.join(cwd, rel));
|
|
27029
27002
|
if (content === null) continue;
|
|
27030
27003
|
if (/runtime\s*[:=]\s*['"]nodejs['"]/.test(content)) {
|
|
27031
27004
|
return {
|
|
@@ -27052,7 +27025,7 @@ async function checkNetlifyMiddleware(cwd) {
|
|
|
27052
27025
|
}
|
|
27053
27026
|
async function checkImageDimsDrift(cwd) {
|
|
27054
27027
|
const scanRoots = ["app", "src/app", "components", "src/components"];
|
|
27055
|
-
const publicDir =
|
|
27028
|
+
const publicDir = path12.join(cwd, "public");
|
|
27056
27029
|
const files = [];
|
|
27057
27030
|
async function walk(dir, depth) {
|
|
27058
27031
|
if (depth > 4) return;
|
|
@@ -27064,19 +27037,19 @@ async function checkImageDimsDrift(cwd) {
|
|
|
27064
27037
|
}
|
|
27065
27038
|
for (const e of entries) {
|
|
27066
27039
|
if (e.name === "node_modules" || e.name.startsWith(".")) continue;
|
|
27067
|
-
const full =
|
|
27040
|
+
const full = path12.join(dir, e.name);
|
|
27068
27041
|
if (e.isDirectory()) await walk(full, depth + 1);
|
|
27069
27042
|
else if (/\.(tsx|jsx)$/.test(e.name)) files.push(full);
|
|
27070
27043
|
}
|
|
27071
27044
|
}
|
|
27072
|
-
for (const root of scanRoots) await walk(
|
|
27045
|
+
for (const root of scanRoots) await walk(path12.join(cwd, root), 0);
|
|
27073
27046
|
if (files.length === 0) {
|
|
27074
27047
|
return { id: "images.dims-drift", title: "Image dims vs SVG", level: "skip", message: "No component files found" };
|
|
27075
27048
|
}
|
|
27076
27049
|
const viewBoxCache = /* @__PURE__ */ new Map();
|
|
27077
27050
|
async function svgAspect(publicPath) {
|
|
27078
27051
|
if (viewBoxCache.has(publicPath)) return viewBoxCache.get(publicPath);
|
|
27079
|
-
const svg = await readFileOrNull(
|
|
27052
|
+
const svg = await readFileOrNull(path12.join(publicDir, publicPath.replace(/^\//, "")));
|
|
27080
27053
|
let aspect = null;
|
|
27081
27054
|
if (svg) {
|
|
27082
27055
|
const vb = svg.match(/viewBox="([\d.\s-]+)"/);
|
|
@@ -27103,7 +27076,7 @@ async function checkImageDimsDrift(cwd) {
|
|
|
27103
27076
|
const drift = Math.abs(declared - actual) / actual;
|
|
27104
27077
|
if (drift > 0.02) {
|
|
27105
27078
|
drifts.push(
|
|
27106
|
-
`${
|
|
27079
|
+
`${path12.relative(cwd, file)}: ${src} is ${actual.toFixed(2)}:1 but width/height declare ${declared.toFixed(2)}:1 (${Math.round(drift * 100)}% off)`
|
|
27107
27080
|
);
|
|
27108
27081
|
}
|
|
27109
27082
|
}
|
|
@@ -27219,8 +27192,8 @@ async function statusCommand(options) {
|
|
|
27219
27192
|
|
|
27220
27193
|
// src/og/pages.ts
|
|
27221
27194
|
var DYNAMIC = "*";
|
|
27222
|
-
function pathSegments(
|
|
27223
|
-
return
|
|
27195
|
+
function pathSegments(path29) {
|
|
27196
|
+
return path29.split("/").filter(Boolean);
|
|
27224
27197
|
}
|
|
27225
27198
|
function stripBrandSuffix(title, brand) {
|
|
27226
27199
|
const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
|
|
@@ -27228,13 +27201,13 @@ function stripBrandSuffix(title, brand) {
|
|
|
27228
27201
|
if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
|
|
27229
27202
|
return cleaned;
|
|
27230
27203
|
}
|
|
27231
|
-
function titleFromPath(
|
|
27232
|
-
const last = pathSegments(
|
|
27204
|
+
function titleFromPath(path29) {
|
|
27205
|
+
const last = pathSegments(path29).filter((s) => s !== DYNAMIC).pop();
|
|
27233
27206
|
if (!last) return "Home";
|
|
27234
27207
|
return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
|
|
27235
27208
|
}
|
|
27236
|
-
function kickerFromPath(
|
|
27237
|
-
const parts = pathSegments(
|
|
27209
|
+
function kickerFromPath(path29, fallback) {
|
|
27210
|
+
const parts = pathSegments(path29);
|
|
27238
27211
|
const section = parts.includes(DYNAMIC) ? parts.filter((s) => s !== DYNAMIC) : parts.slice(0, -1);
|
|
27239
27212
|
if (!section.length) return fallback;
|
|
27240
27213
|
return section.join(" / ").replace(/[-_]+/g, " ");
|
|
@@ -27258,8 +27231,8 @@ function kickerIsRedundant(kicker, title) {
|
|
|
27258
27231
|
const titleWords = new Set(t.split(" "));
|
|
27259
27232
|
return k2.split(" ").every((w) => titleWords.has(w));
|
|
27260
27233
|
}
|
|
27261
|
-
function slugForPath(
|
|
27262
|
-
const segments = pathSegments(
|
|
27234
|
+
function slugForPath(path29) {
|
|
27235
|
+
const segments = pathSegments(path29);
|
|
27263
27236
|
if (!segments.length) return "home";
|
|
27264
27237
|
return segments.map((s) => s === DYNAMIC ? "any" : s).join("-").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
27265
27238
|
}
|
|
@@ -27313,10 +27286,10 @@ function findChrome() {
|
|
|
27313
27286
|
}
|
|
27314
27287
|
return null;
|
|
27315
27288
|
}
|
|
27316
|
-
async function
|
|
27289
|
+
async function loadConfig2(cwd) {
|
|
27317
27290
|
const candidates = ["og.config.ts", "og.config.mts", "og.config.mjs", "og.config.js"];
|
|
27318
27291
|
for (const rel of candidates) {
|
|
27319
|
-
const full =
|
|
27292
|
+
const full = path12.join(cwd, rel);
|
|
27320
27293
|
if (!existsSync(full)) continue;
|
|
27321
27294
|
try {
|
|
27322
27295
|
const mod = await import(
|
|
@@ -27341,7 +27314,7 @@ async function loadConfig4(cwd) {
|
|
|
27341
27314
|
return null;
|
|
27342
27315
|
}
|
|
27343
27316
|
async function seedConfig(cwd) {
|
|
27344
|
-
let name =
|
|
27317
|
+
let name = path12.basename(cwd).replace(/-nextjs$/, "").replace(/-/g, " ");
|
|
27345
27318
|
let accent = "#111111";
|
|
27346
27319
|
let logo;
|
|
27347
27320
|
try {
|
|
@@ -27354,7 +27327,7 @@ async function seedConfig(cwd) {
|
|
|
27354
27327
|
} catch {
|
|
27355
27328
|
}
|
|
27356
27329
|
for (const candidate of ["/logo-mark.svg", "/logo.svg", "/logohorizontal.svg"]) {
|
|
27357
|
-
if (existsSync(
|
|
27330
|
+
if (existsSync(path12.join(cwd, "public", candidate))) {
|
|
27358
27331
|
logo = candidate;
|
|
27359
27332
|
break;
|
|
27360
27333
|
}
|
|
@@ -27368,14 +27341,14 @@ async function seedConfig(cwd) {
|
|
|
27368
27341
|
}
|
|
27369
27342
|
function inlinePublicPaths(html, cwd) {
|
|
27370
27343
|
return html.replace(/src="(\/[^"]+)"/g, (_3, p) => {
|
|
27371
|
-
const full =
|
|
27344
|
+
const full = path12.join(cwd, "public", p);
|
|
27372
27345
|
return existsSync(full) ? `src="file://${full}"` : `src="${p}"`;
|
|
27373
27346
|
});
|
|
27374
27347
|
}
|
|
27375
27348
|
async function renderCard(config2, outPath, cwd, chrome, tmpSuffix) {
|
|
27376
|
-
const tmpHtml =
|
|
27349
|
+
const tmpHtml = path12.join(cwd, `.sonor-og-${tmpSuffix}.html`);
|
|
27377
27350
|
try {
|
|
27378
|
-
await fs3.mkdir(
|
|
27351
|
+
await fs3.mkdir(path12.dirname(outPath), { recursive: true });
|
|
27379
27352
|
await fs3.writeFile(tmpHtml, inlinePublicPaths(buildOgHtml(config2), cwd));
|
|
27380
27353
|
const { stdout } = await execFileAsync5(
|
|
27381
27354
|
chrome,
|
|
@@ -27410,7 +27383,7 @@ function parseReport(dom) {
|
|
|
27410
27383
|
}
|
|
27411
27384
|
async function compressCard(pngPath, cwd) {
|
|
27412
27385
|
try {
|
|
27413
|
-
const require_ = (await import('module')).createRequire(
|
|
27386
|
+
const require_ = (await import('module')).createRequire(path12.join(cwd, "package.json"));
|
|
27414
27387
|
const sharp = require_("sharp");
|
|
27415
27388
|
const jpgPath = pngPath.replace(/\.png$/, ".jpg");
|
|
27416
27389
|
await sharp(pngPath).jpeg({ quality: 84, mozjpeg: true }).toFile(jpgPath);
|
|
@@ -27427,13 +27400,13 @@ function discoverDynamicSegments(appDir) {
|
|
|
27427
27400
|
if (!entry.isDirectory()) continue;
|
|
27428
27401
|
if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
|
|
27429
27402
|
if (entry.name === "api" || entry.name === "node_modules") continue;
|
|
27430
|
-
const full =
|
|
27403
|
+
const full = path12.join(dir, entry.name);
|
|
27431
27404
|
const isGroup = entry.name.startsWith("(") && entry.name.endsWith(")");
|
|
27432
27405
|
const isDynamic = entry.name.startsWith("[") && entry.name.endsWith("]");
|
|
27433
27406
|
const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
|
|
27434
27407
|
const nextPattern = isGroup ? pattern : [...pattern, isDynamic ? DYNAMIC : entry.name];
|
|
27435
27408
|
if (isDynamic) {
|
|
27436
|
-
const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(
|
|
27409
|
+
const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(path12.join(full, `page.${ext2}`)));
|
|
27437
27410
|
if (hasPage) {
|
|
27438
27411
|
found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: `/${urlSegments.join("/")}` });
|
|
27439
27412
|
}
|
|
@@ -27461,7 +27434,7 @@ async function resolveRouteCopy(paths) {
|
|
|
27461
27434
|
try {
|
|
27462
27435
|
if (process.env.SONOR_API_KEY) {
|
|
27463
27436
|
;
|
|
27464
|
-
({ getSEOPageData } = await import('../api-
|
|
27437
|
+
({ getSEOPageData } = await import('../api-D745LGGU.mjs'));
|
|
27465
27438
|
}
|
|
27466
27439
|
} catch {
|
|
27467
27440
|
getSEOPageData = null;
|
|
@@ -27509,7 +27482,7 @@ async function runOg(options) {
|
|
|
27509
27482
|
errors: [{ code: "chrome_missing", message: "No Chrome or Chromium binary found", fix: "Install Chrome, or set SONOR_CHROME_PATH to its path." }]
|
|
27510
27483
|
};
|
|
27511
27484
|
}
|
|
27512
|
-
let config2 = await
|
|
27485
|
+
let config2 = await loadConfig2(cwd);
|
|
27513
27486
|
let seeded = false;
|
|
27514
27487
|
if (!config2) {
|
|
27515
27488
|
config2 = await seedConfig(cwd);
|
|
@@ -27517,7 +27490,7 @@ async function runOg(options) {
|
|
|
27517
27490
|
console.log(source_default.yellow(" ! No og.config.ts \u2014 generating a seed card from Sonor brand data."));
|
|
27518
27491
|
console.log(source_default.gray(" The site owns its theme: add og.config.ts (defineOgCard) with the real palette."));
|
|
27519
27492
|
}
|
|
27520
|
-
const outPath =
|
|
27493
|
+
const outPath = path12.resolve(cwd, options.out || "public/og.png");
|
|
27521
27494
|
let clean = true;
|
|
27522
27495
|
let cardKeyFix = null;
|
|
27523
27496
|
let pageCardsWritten = 0;
|
|
@@ -27527,8 +27500,8 @@ async function runOg(options) {
|
|
|
27527
27500
|
const report = await renderCard(config2, outPath, cwd, chrome, "site");
|
|
27528
27501
|
spinner.stop();
|
|
27529
27502
|
console.log(source_default.bold(` Site card${seeded ? source_default.gray(" (seed)") : ""}`));
|
|
27530
|
-
clean = reportCard(`${
|
|
27531
|
-
checks.push(cardCheck("site card",
|
|
27503
|
+
clean = reportCard(`${path12.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
|
|
27504
|
+
checks.push(cardCheck("site card", path12.relative(cwd, outPath), report));
|
|
27532
27505
|
} catch (err) {
|
|
27533
27506
|
const message = err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
27534
27507
|
spinner.fail(`Render failed: ${message}`);
|
|
@@ -27591,16 +27564,16 @@ async function runOg(options) {
|
|
|
27591
27564
|
const pageConfig = pageCardConfig(config2, route, brand);
|
|
27592
27565
|
const dir = route.dir ?? routeOutputDir(appDir, route.path);
|
|
27593
27566
|
for (const ext2 of ["png", "jpg", "jpeg"]) {
|
|
27594
|
-
await fs3.rm(
|
|
27567
|
+
await fs3.rm(path12.join(dir, `opengraph-image.${ext2}`), { force: true });
|
|
27595
27568
|
}
|
|
27596
|
-
const png =
|
|
27569
|
+
const png = path12.join(dir, "opengraph-image.png");
|
|
27597
27570
|
const report = await renderCard(pageConfig, png, cwd, chrome, `page-${i}`);
|
|
27598
27571
|
const file = await compressCard(png, cwd);
|
|
27599
27572
|
return { route, file, report };
|
|
27600
27573
|
});
|
|
27601
27574
|
for (const { route, file, report } of reports) {
|
|
27602
|
-
clean = reportCard(`${route.path} ${source_default.gray(
|
|
27603
|
-
checks.push(cardCheck(route.path,
|
|
27575
|
+
clean = reportCard(`${route.path} ${source_default.gray(path12.relative(cwd, file))}`, report) && clean;
|
|
27576
|
+
checks.push(cardCheck(route.path, path12.relative(cwd, file), report));
|
|
27604
27577
|
}
|
|
27605
27578
|
pageCardsWritten = reports.length;
|
|
27606
27579
|
const bytes = await totalBytes(reports.map((r) => r.file));
|
|
@@ -27611,13 +27584,13 @@ async function runOg(options) {
|
|
|
27611
27584
|
}
|
|
27612
27585
|
if (options.preview !== false) {
|
|
27613
27586
|
try {
|
|
27614
|
-
const require_ = (await import('module')).createRequire(
|
|
27587
|
+
const require_ = (await import('module')).createRequire(path12.join(cwd, "package.json"));
|
|
27615
27588
|
const sharp = require_("sharp");
|
|
27616
|
-
const previewPath =
|
|
27617
|
-
await fs3.mkdir(
|
|
27589
|
+
const previewPath = path12.join(cwd, ".sonor", "og-preview.png");
|
|
27590
|
+
await fs3.mkdir(path12.dirname(previewPath), { recursive: true });
|
|
27618
27591
|
await sharp(outPath).resize(300).toFile(previewPath);
|
|
27619
27592
|
console.log("");
|
|
27620
|
-
console.log(source_default.gray(` Thumbnail check: ${
|
|
27593
|
+
console.log(source_default.gray(` Thumbnail check: ${path12.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
|
|
27621
27594
|
} catch {
|
|
27622
27595
|
console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
|
|
27623
27596
|
}
|
|
@@ -27676,15 +27649,15 @@ function routeOutputDir(appDir, urlPath) {
|
|
|
27676
27649
|
const segments = urlPath.split("/").filter(Boolean);
|
|
27677
27650
|
let dir = appDir;
|
|
27678
27651
|
for (const segment of segments) {
|
|
27679
|
-
const direct =
|
|
27652
|
+
const direct = path12.join(dir, segment);
|
|
27680
27653
|
if (existsSync(direct)) {
|
|
27681
27654
|
dir = direct;
|
|
27682
27655
|
continue;
|
|
27683
27656
|
}
|
|
27684
27657
|
const group = existsSync(dir) ? readdirSync(dir, { withFileTypes: true }).find(
|
|
27685
|
-
(e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && existsSync(
|
|
27658
|
+
(e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && existsSync(path12.join(dir, e.name, segment))
|
|
27686
27659
|
) : void 0;
|
|
27687
|
-
dir = group ?
|
|
27660
|
+
dir = group ? path12.join(dir, group.name, segment) : direct;
|
|
27688
27661
|
}
|
|
27689
27662
|
return dir;
|
|
27690
27663
|
}
|
|
@@ -27699,7 +27672,7 @@ async function totalBytes(files) {
|
|
|
27699
27672
|
return total;
|
|
27700
27673
|
}
|
|
27701
27674
|
async function siteDomain(cwd) {
|
|
27702
|
-
const envFile =
|
|
27675
|
+
const envFile = path12.join(cwd, ".env.local");
|
|
27703
27676
|
if (existsSync(envFile)) {
|
|
27704
27677
|
const env3 = await fs3.readFile(envFile, "utf-8").catch(() => "");
|
|
27705
27678
|
const url = env3.match(/^NEXT_PUBLIC_SITE_URL=(.+)$/m)?.[1]?.trim();
|
|
@@ -27824,14 +27797,14 @@ var hs = new RegExp(pe, "g");
|
|
|
27824
27797
|
var as = /\\\\/g;
|
|
27825
27798
|
var ls = /\\{/g;
|
|
27826
27799
|
var cs = /\\}/g;
|
|
27827
|
-
var
|
|
27800
|
+
var fs22 = /\\,/g;
|
|
27828
27801
|
var us = /\\./g;
|
|
27829
27802
|
var ds = 1e5;
|
|
27830
27803
|
function Ht(n5) {
|
|
27831
27804
|
return isNaN(n5) ? n5.charCodeAt(0) : parseInt(n5, 10);
|
|
27832
27805
|
}
|
|
27833
27806
|
function ps(n5) {
|
|
27834
|
-
return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(
|
|
27807
|
+
return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs22, de).replace(us, pe);
|
|
27835
27808
|
}
|
|
27836
27809
|
function ms(n5) {
|
|
27837
27810
|
return n5.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
|
|
@@ -30863,10 +30836,10 @@ function unifiedDiff(before, after, filePath, context = 2) {
|
|
|
30863
30836
|
return lines.join("\n");
|
|
30864
30837
|
}
|
|
30865
30838
|
function ext(filePath) {
|
|
30866
|
-
return
|
|
30839
|
+
return path12.extname(filePath).toLowerCase();
|
|
30867
30840
|
}
|
|
30868
30841
|
function basename(filePath) {
|
|
30869
|
-
return
|
|
30842
|
+
return path12.basename(filePath).toLowerCase();
|
|
30870
30843
|
}
|
|
30871
30844
|
var CODE_EXT = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
|
|
30872
30845
|
var TEXT_EXT = /* @__PURE__ */ new Set([...CODE_EXT, ".css", ".scss", ".json", ".md", ".mdx"]);
|
|
@@ -30966,18 +30939,21 @@ var analyticsSibling = {
|
|
|
30966
30939
|
appliesTo(filePath) {
|
|
30967
30940
|
return LAYOUT_FILE.test(filePath.replace(/\\/g, "/"));
|
|
30968
30941
|
},
|
|
30969
|
-
// Deliberately detect-and-flag, never auto-rewrite:
|
|
30970
|
-
//
|
|
30971
|
-
//
|
|
30942
|
+
// Deliberately detect-and-flag, never auto-rewrite: removing a wrapper from
|
|
30943
|
+
// an arbitrary layout can silently drop analytics or break the tree. We
|
|
30944
|
+
// surface the exact fix instead of guessing.
|
|
30945
|
+
//
|
|
30946
|
+
// A plain <SiteKitLayout>{children}</SiteKitLayout> is NOT flagged: it is the
|
|
30947
|
+
// blessed layout, and since 3.0.2 it mounts analytics as a deferred, childless
|
|
30948
|
+
// sibling itself (see ssr-bailout.ts). Flagging it told every correct site to
|
|
30949
|
+
// hand-roll the sibling the package already ships.
|
|
30972
30950
|
run(source) {
|
|
30973
30951
|
const flags = [];
|
|
30974
|
-
const wrapsChildren = /\{\s*children\s*\}/.test(source);
|
|
30975
|
-
const sitekitLayoutOn = /<SiteKitLayout(?![^>]*analytics\s*=\s*\{?\s*false)/.test(source) && /<SiteKitLayout[\s\S]*\{\s*children\s*\}[\s\S]*<\/SiteKitLayout>/.test(source);
|
|
30976
30952
|
const rawAnalyticsWrapper = /<AnalyticsProvider[\s\S]*\{\s*children\s*\}[\s\S]*<\/AnalyticsProvider>/.test(source);
|
|
30977
|
-
if (
|
|
30953
|
+
if (rawAnalyticsWrapper) {
|
|
30978
30954
|
flags.push({
|
|
30979
|
-
reason:
|
|
30980
|
-
fix:
|
|
30955
|
+
reason: "AnalyticsProvider wraps {children}: analytics joins the hydration path, and if the provider is lazy-loaded with next/dynamic({ ssr: false }) the whole route de-opts to client rendering (SSR bailout)",
|
|
30956
|
+
fix: ANALYTICS_WRAPPER_FIX
|
|
30981
30957
|
});
|
|
30982
30958
|
}
|
|
30983
30959
|
return { output: source, changes: [], flags };
|
|
@@ -31017,7 +30993,7 @@ var IGNORE = [
|
|
|
31017
30993
|
];
|
|
31018
30994
|
async function listFiles(cwd, onlyPath) {
|
|
31019
30995
|
if (onlyPath) {
|
|
31020
|
-
const rel =
|
|
30996
|
+
const rel = path12.isAbsolute(onlyPath) ? path12.relative(cwd, onlyPath) : onlyPath;
|
|
31021
30997
|
return [rel];
|
|
31022
30998
|
}
|
|
31023
30999
|
const matches = await Ze(SCAN_PATTERNS, { cwd, ignore: IGNORE, dot: true, nodir: true });
|
|
@@ -31029,7 +31005,7 @@ async function runCodemod(options) {
|
|
|
31029
31005
|
const files = await listFiles(cwd, onlyPath);
|
|
31030
31006
|
const changes = [];
|
|
31031
31007
|
for (const rel of files) {
|
|
31032
|
-
const full =
|
|
31008
|
+
const full = path12.join(cwd, rel);
|
|
31033
31009
|
let source;
|
|
31034
31010
|
try {
|
|
31035
31011
|
source = await fs3.readFile(full, "utf-8");
|
|
@@ -31178,9 +31154,9 @@ function findManifestPath() {
|
|
|
31178
31154
|
const baseDir = typeof __dirname !== "undefined" ? __dirname : process.cwd();
|
|
31179
31155
|
let dir = baseDir;
|
|
31180
31156
|
for (let i = 0; i < 8; i++) {
|
|
31181
|
-
const candidate =
|
|
31157
|
+
const candidate = path12.join(dir, "agent-manifest.json");
|
|
31182
31158
|
if (fs__default.existsSync(candidate)) return candidate;
|
|
31183
|
-
const parent =
|
|
31159
|
+
const parent = path12.dirname(dir);
|
|
31184
31160
|
if (parent === dir) break;
|
|
31185
31161
|
dir = parent;
|
|
31186
31162
|
}
|
|
@@ -31322,8 +31298,8 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
|
|
|
31322
31298
|
}
|
|
31323
31299
|
function findAppDir() {
|
|
31324
31300
|
const candidates = [
|
|
31325
|
-
|
|
31326
|
-
|
|
31301
|
+
path12.join(process.cwd(), "app"),
|
|
31302
|
+
path12.join(process.cwd(), "src", "app")
|
|
31327
31303
|
];
|
|
31328
31304
|
for (const candidate of candidates) {
|
|
31329
31305
|
if (existsSync(candidate)) {
|
|
@@ -31333,7 +31309,7 @@ function findAppDir() {
|
|
|
31333
31309
|
return null;
|
|
31334
31310
|
}
|
|
31335
31311
|
function discoverPages(appDir, currentPath = "", pages = []) {
|
|
31336
|
-
const fullPath =
|
|
31312
|
+
const fullPath = path12.join(appDir, currentPath);
|
|
31337
31313
|
if (!existsSync(fullPath)) {
|
|
31338
31314
|
return pages;
|
|
31339
31315
|
}
|
|
@@ -31355,7 +31331,7 @@ function discoverPages(appDir, currentPath = "", pages = []) {
|
|
|
31355
31331
|
});
|
|
31356
31332
|
}
|
|
31357
31333
|
for (const entry of entries) {
|
|
31358
|
-
const entryPath =
|
|
31334
|
+
const entryPath = path12.join(fullPath, entry);
|
|
31359
31335
|
const stat = statSync(entryPath);
|
|
31360
31336
|
if (stat.isDirectory()) {
|
|
31361
31337
|
const folderName = entry.toLowerCase();
|
|
@@ -31368,21 +31344,21 @@ function discoverPages(appDir, currentPath = "", pages = []) {
|
|
|
31368
31344
|
if (entry.startsWith("_")) {
|
|
31369
31345
|
continue;
|
|
31370
31346
|
}
|
|
31371
|
-
discoverPages(appDir,
|
|
31347
|
+
discoverPages(appDir, path12.join(currentPath, entry), pages);
|
|
31372
31348
|
}
|
|
31373
31349
|
}
|
|
31374
31350
|
return pages;
|
|
31375
31351
|
}
|
|
31376
31352
|
function findNextBuildDir() {
|
|
31377
31353
|
const cwd = process.cwd();
|
|
31378
|
-
const candidate =
|
|
31354
|
+
const candidate = path12.join(cwd, ".next", "server", "app");
|
|
31379
31355
|
return existsSync(candidate) ? candidate : null;
|
|
31380
31356
|
}
|
|
31381
31357
|
function extractPageContent(buildDir, pagePath) {
|
|
31382
31358
|
const baseName = pagePath === "/" ? "index" : pagePath.replace(/^\//, "");
|
|
31383
31359
|
const htmlCandidates = [
|
|
31384
|
-
|
|
31385
|
-
|
|
31360
|
+
path12.join(buildDir, `${baseName}.html`),
|
|
31361
|
+
path12.join(buildDir, baseName, "index.html")
|
|
31386
31362
|
];
|
|
31387
31363
|
let html = null;
|
|
31388
31364
|
for (const candidate of htmlCandidates) {
|
|
@@ -31396,8 +31372,8 @@ function extractPageContent(buildDir, pagePath) {
|
|
|
31396
31372
|
}
|
|
31397
31373
|
}
|
|
31398
31374
|
const rscCandidates = [
|
|
31399
|
-
|
|
31400
|
-
|
|
31375
|
+
path12.join(buildDir, `${baseName}.rsc`),
|
|
31376
|
+
path12.join(buildDir, baseName, "index.rsc")
|
|
31401
31377
|
];
|
|
31402
31378
|
let rsc = null;
|
|
31403
31379
|
for (const candidate of rscCandidates) {
|
|
@@ -31508,7 +31484,7 @@ var BLOG_EXTENSIONS = [".mdx", ".md"];
|
|
|
31508
31484
|
function findBlogDir() {
|
|
31509
31485
|
const cwd = process.cwd();
|
|
31510
31486
|
for (const dir of BLOG_DIRS) {
|
|
31511
|
-
const full =
|
|
31487
|
+
const full = path12.join(cwd, dir);
|
|
31512
31488
|
if (existsSync(full)) return full;
|
|
31513
31489
|
}
|
|
31514
31490
|
return null;
|
|
@@ -31518,7 +31494,7 @@ async function discoverBlogPosts(dir) {
|
|
|
31518
31494
|
async function walk(currentDir) {
|
|
31519
31495
|
const entries = readdirSync(currentDir);
|
|
31520
31496
|
for (const entry of entries) {
|
|
31521
|
-
const fullPath =
|
|
31497
|
+
const fullPath = path12.join(currentDir, entry);
|
|
31522
31498
|
const stat = statSync(fullPath);
|
|
31523
31499
|
if (stat.isDirectory()) {
|
|
31524
31500
|
await walk(fullPath);
|
|
@@ -31535,7 +31511,7 @@ async function discoverBlogPosts(dir) {
|
|
|
31535
31511
|
date: frontmatter.date,
|
|
31536
31512
|
tags: frontmatter.tags,
|
|
31537
31513
|
author: frontmatter.author,
|
|
31538
|
-
filePath:
|
|
31514
|
+
filePath: path12.relative(process.cwd(), fullPath)
|
|
31539
31515
|
});
|
|
31540
31516
|
}
|
|
31541
31517
|
}
|
|
@@ -31568,7 +31544,7 @@ async function syncBlogToPortal(_apiUrl, _apiKey, _dryRun) {
|
|
|
31568
31544
|
}
|
|
31569
31545
|
const spinner = ora("Discovering blog posts...").start();
|
|
31570
31546
|
const posts = await discoverBlogPosts(blogDir);
|
|
31571
|
-
spinner.succeed(`Found ${posts.length} local markdown post(s) in ${
|
|
31547
|
+
spinner.succeed(`Found ${posts.length} local markdown post(s) in ${path12.relative(process.cwd(), blogDir)}`);
|
|
31572
31548
|
if (posts.length === 0) return;
|
|
31573
31549
|
for (const post of posts.slice(0, 10)) {
|
|
31574
31550
|
console.log(source_default.gray(` ${post.slug}: ${post.title || "(no title)"}`));
|
|
@@ -31585,11 +31561,11 @@ async function discoverSchemaUsage(appDir) {
|
|
|
31585
31561
|
async function walk(currentDir, currentPath = "") {
|
|
31586
31562
|
const entries = readdirSync(currentDir);
|
|
31587
31563
|
for (const entry of entries) {
|
|
31588
|
-
const fullPath =
|
|
31564
|
+
const fullPath = path12.join(currentDir, entry);
|
|
31589
31565
|
const stat = statSync(fullPath);
|
|
31590
31566
|
if (stat.isDirectory()) {
|
|
31591
31567
|
if (entry.startsWith(".") || entry === "node_modules") continue;
|
|
31592
|
-
await walk(fullPath,
|
|
31568
|
+
await walk(fullPath, path12.join(currentPath, entry));
|
|
31593
31569
|
continue;
|
|
31594
31570
|
}
|
|
31595
31571
|
if (!/\.(tsx?|jsx?)$/.test(entry)) continue;
|
|
@@ -31603,7 +31579,7 @@ async function discoverSchemaUsage(appDir) {
|
|
|
31603
31579
|
pagePath: pathMatch[1],
|
|
31604
31580
|
schemaTypes: ["managed"],
|
|
31605
31581
|
source: "ManagedSchema",
|
|
31606
|
-
filePath:
|
|
31582
|
+
filePath: path12.relative(process.cwd(), fullPath)
|
|
31607
31583
|
});
|
|
31608
31584
|
}
|
|
31609
31585
|
}
|
|
@@ -31621,7 +31597,7 @@ async function discoverSchemaUsage(appDir) {
|
|
|
31621
31597
|
pagePath,
|
|
31622
31598
|
schemaTypes: [...new Set(types)],
|
|
31623
31599
|
source: "json-ld",
|
|
31624
|
-
filePath:
|
|
31600
|
+
filePath: path12.relative(process.cwd(), fullPath)
|
|
31625
31601
|
});
|
|
31626
31602
|
}
|
|
31627
31603
|
}
|
|
@@ -31681,8 +31657,8 @@ async function apiRoutesCommand(options) {
|
|
|
31681
31657
|
console.log("");
|
|
31682
31658
|
process.exit(1);
|
|
31683
31659
|
}
|
|
31684
|
-
const routeDir =
|
|
31685
|
-
const routeFile =
|
|
31660
|
+
const routeDir = path12.join(appDir, "_uptrade", "api", "[...path]");
|
|
31661
|
+
const routeFile = path12.join(routeDir, "route.ts");
|
|
31686
31662
|
if (existsSync(routeFile) && !options.force) {
|
|
31687
31663
|
console.log(source_default.yellow(" \u26A0 API routes already exist"));
|
|
31688
31664
|
console.log(source_default.gray(` ${routeFile}`));
|
|
@@ -31719,8 +31695,8 @@ async function apiRoutesCommand(options) {
|
|
|
31719
31695
|
}
|
|
31720
31696
|
function findAppDir2() {
|
|
31721
31697
|
const candidates = [
|
|
31722
|
-
|
|
31723
|
-
|
|
31698
|
+
path12.join(process.cwd(), "app"),
|
|
31699
|
+
path12.join(process.cwd(), "src", "app")
|
|
31724
31700
|
];
|
|
31725
31701
|
for (const candidate of candidates) {
|
|
31726
31702
|
if (existsSync(candidate)) {
|
|
@@ -31833,12 +31809,12 @@ async function handleRequest(
|
|
|
31833
31809
|
`;
|
|
31834
31810
|
}
|
|
31835
31811
|
function detectPackageManager(cwd) {
|
|
31836
|
-
if (existsSync(
|
|
31837
|
-
if (existsSync(
|
|
31812
|
+
if (existsSync(path12.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
31813
|
+
if (existsSync(path12.join(cwd, "yarn.lock"))) return "yarn";
|
|
31838
31814
|
return "npm";
|
|
31839
31815
|
}
|
|
31840
31816
|
async function run6(ctx, options) {
|
|
31841
|
-
if (!existsSync(
|
|
31817
|
+
if (!existsSync(path12.join(ctx.cwd, "package.json"))) {
|
|
31842
31818
|
throw new UsageError(
|
|
31843
31819
|
"NO_PACKAGE_JSON",
|
|
31844
31820
|
"No package.json found",
|
|
@@ -31883,12 +31859,12 @@ async function installCommand(options) {
|
|
|
31883
31859
|
await runCommand(ctx, (c) => run6(c, options), renderHuman4);
|
|
31884
31860
|
}
|
|
31885
31861
|
function detectPackageManager2(cwd) {
|
|
31886
|
-
if (existsSync(
|
|
31887
|
-
if (existsSync(
|
|
31862
|
+
if (existsSync(path12.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
31863
|
+
if (existsSync(path12.join(cwd, "yarn.lock"))) return "yarn";
|
|
31888
31864
|
return "npm";
|
|
31889
31865
|
}
|
|
31890
31866
|
async function run7(ctx, options) {
|
|
31891
|
-
const pkgPath =
|
|
31867
|
+
const pkgPath = path12.join(ctx.cwd, "package.json");
|
|
31892
31868
|
if (!existsSync(pkgPath)) {
|
|
31893
31869
|
throw new UsageError("NO_PACKAGE_JSON", "No package.json found", "Run this from your project root.");
|
|
31894
31870
|
}
|
|
@@ -31950,7 +31926,7 @@ async function scaffoldCommand(options) {
|
|
|
31950
31926
|
}
|
|
31951
31927
|
const files = [
|
|
31952
31928
|
{
|
|
31953
|
-
path:
|
|
31929
|
+
path: path12.join(appDir, "sitemap.ts"),
|
|
31954
31930
|
label: "Sitemap",
|
|
31955
31931
|
content: `import { createSitemap } from '@sonordev/site-kit/sitemap'
|
|
31956
31932
|
|
|
@@ -31965,7 +31941,7 @@ export default createSitemap({
|
|
|
31965
31941
|
`
|
|
31966
31942
|
},
|
|
31967
31943
|
{
|
|
31968
|
-
path:
|
|
31944
|
+
path: path12.join(appDir, "robots.txt", "route.ts"),
|
|
31969
31945
|
label: "Robots.txt",
|
|
31970
31946
|
content: `import { createRobots } from '@sonordev/site-kit/robots'
|
|
31971
31947
|
|
|
@@ -31973,7 +31949,7 @@ export const GET = createRobots({})
|
|
|
31973
31949
|
`
|
|
31974
31950
|
},
|
|
31975
31951
|
{
|
|
31976
|
-
path:
|
|
31952
|
+
path: path12.join(appDir, "llms.txt", "route.ts"),
|
|
31977
31953
|
label: "llms.txt",
|
|
31978
31954
|
content: `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
|
|
31979
31955
|
|
|
@@ -31981,7 +31957,7 @@ export const GET = createLLMsTxtHandler({ preferStatic: true })
|
|
|
31981
31957
|
`
|
|
31982
31958
|
},
|
|
31983
31959
|
{
|
|
31984
|
-
path:
|
|
31960
|
+
path: path12.join(appDir, "llms-full.txt", "route.ts"),
|
|
31985
31961
|
label: "llms-full.txt",
|
|
31986
31962
|
content: `import { createLLMsFullTxtHandler } from '@sonordev/site-kit/llms'
|
|
31987
31963
|
|
|
@@ -31992,7 +31968,7 @@ export const GET = createLLMsFullTxtHandler({ preferStatic: true })
|
|
|
31992
31968
|
if (!options.minimal) {
|
|
31993
31969
|
files.push(
|
|
31994
31970
|
{
|
|
31995
|
-
path:
|
|
31971
|
+
path: path12.join(cwd, "proxy.ts"),
|
|
31996
31972
|
label: "Proxy (security headers; redirects resolve at the 404 boundary)",
|
|
31997
31973
|
content: `import { createProxy } from '@sonordev/site-kit/proxy'
|
|
31998
31974
|
|
|
@@ -32012,7 +31988,7 @@ export const config = {
|
|
|
32012
31988
|
`
|
|
32013
31989
|
},
|
|
32014
31990
|
{
|
|
32015
|
-
path:
|
|
31991
|
+
path: path12.join(appDir, "manifest.webmanifest", "route.ts"),
|
|
32016
31992
|
label: "PWA Manifest",
|
|
32017
31993
|
content: `import { createManifest } from '@sonordev/site-kit/manifest'
|
|
32018
31994
|
|
|
@@ -32020,7 +31996,7 @@ export const GET = createManifest()
|
|
|
32020
31996
|
`
|
|
32021
31997
|
},
|
|
32022
31998
|
{
|
|
32023
|
-
path:
|
|
31999
|
+
path: path12.join(appDir, "not-found.tsx"),
|
|
32024
32000
|
label: "404 Page (resolves managed redirects)",
|
|
32025
32001
|
content: `import { redirect, permanentRedirect } from 'next/navigation'
|
|
32026
32002
|
import { resolveManagedRedirect } from '@sonordev/site-kit/redirects/not-found'
|
|
@@ -32060,7 +32036,7 @@ export default async function NotFound() {
|
|
|
32060
32036
|
`
|
|
32061
32037
|
},
|
|
32062
32038
|
{
|
|
32063
|
-
path:
|
|
32039
|
+
path: path12.join(appDir, "error.tsx"),
|
|
32064
32040
|
label: "Error Boundary",
|
|
32065
32041
|
content: `'use client'
|
|
32066
32042
|
|
|
@@ -32100,7 +32076,7 @@ export default function Error({
|
|
|
32100
32076
|
`
|
|
32101
32077
|
},
|
|
32102
32078
|
{
|
|
32103
|
-
path:
|
|
32079
|
+
path: path12.join(cwd, "og.config.ts"),
|
|
32104
32080
|
label: "OG card config (run: sonor-setup og)",
|
|
32105
32081
|
content: `import { defineOgCard } from '@sonordev/site-kit/og'
|
|
32106
32082
|
|
|
@@ -32129,7 +32105,7 @@ export default defineOgCard({
|
|
|
32129
32105
|
// .env.local, not .env.example: one real env file per project. The
|
|
32130
32106
|
// deployer copies these values into the host's env settings. Skipped
|
|
32131
32107
|
// when the file already exists, so real keys are never touched.
|
|
32132
|
-
path:
|
|
32108
|
+
path: path12.join(cwd, ".env.local"),
|
|
32133
32109
|
label: ".env.local",
|
|
32134
32110
|
content: `# ===================================
|
|
32135
32111
|
# @sonordev/site-kit \u2014 Environment Variables
|
|
@@ -32151,7 +32127,7 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
|
|
|
32151
32127
|
if (options.dryRun) {
|
|
32152
32128
|
console.log(source_default.yellow(" [DRY RUN] Would create:"));
|
|
32153
32129
|
for (const f of files) {
|
|
32154
|
-
const rel =
|
|
32130
|
+
const rel = path12.relative(cwd, f.path);
|
|
32155
32131
|
const exists = existsSync(f.path);
|
|
32156
32132
|
console.log(
|
|
32157
32133
|
source_default.gray(` ${rel}`) + (exists ? source_default.yellow(" (exists, would skip)") : "")
|
|
@@ -32166,13 +32142,13 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
|
|
|
32166
32142
|
for (const f of files) {
|
|
32167
32143
|
try {
|
|
32168
32144
|
if (existsSync(f.path) && !options.force) {
|
|
32169
|
-
spinner.warn(`Skipped (exists): ${
|
|
32145
|
+
spinner.warn(`Skipped (exists): ${path12.relative(cwd, f.path)}`);
|
|
32170
32146
|
skipped++;
|
|
32171
32147
|
continue;
|
|
32172
32148
|
}
|
|
32173
|
-
await fs3.mkdir(
|
|
32149
|
+
await fs3.mkdir(path12.dirname(f.path), { recursive: true });
|
|
32174
32150
|
await fs3.writeFile(f.path, f.content, "utf-8");
|
|
32175
|
-
spinner.succeed(`${f.label}: ${
|
|
32151
|
+
spinner.succeed(`${f.label}: ${path12.relative(cwd, f.path)}`);
|
|
32176
32152
|
created++;
|
|
32177
32153
|
} catch (err) {
|
|
32178
32154
|
spinner.fail(`Failed: ${f.path}`);
|
|
@@ -32221,8 +32197,8 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
|
|
|
32221
32197
|
async function findAppDir3() {
|
|
32222
32198
|
const cwd = process.cwd();
|
|
32223
32199
|
const candidates = [
|
|
32224
|
-
|
|
32225
|
-
|
|
32200
|
+
path12.join(cwd, "app"),
|
|
32201
|
+
path12.join(cwd, "src", "app")
|
|
32226
32202
|
];
|
|
32227
32203
|
for (const dir of candidates) {
|
|
32228
32204
|
if (existsSync(dir)) return dir;
|
|
@@ -32246,17 +32222,17 @@ async function readIfExists(p) {
|
|
|
32246
32222
|
}
|
|
32247
32223
|
}
|
|
32248
32224
|
async function ensureLlmsRouteFiles(appDir, dryRun) {
|
|
32249
|
-
const llms =
|
|
32250
|
-
const llmsFull =
|
|
32225
|
+
const llms = path12.join(appDir, "llms.txt", "route.ts");
|
|
32226
|
+
const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
|
|
32251
32227
|
let n5 = 0;
|
|
32252
32228
|
if (dryRun) return 0;
|
|
32253
32229
|
if (!existsSync(llms)) {
|
|
32254
|
-
await fs3.mkdir(
|
|
32230
|
+
await fs3.mkdir(path12.dirname(llms), { recursive: true });
|
|
32255
32231
|
await fs3.writeFile(llms, LLMS_ROUTE, "utf-8");
|
|
32256
32232
|
n5++;
|
|
32257
32233
|
}
|
|
32258
32234
|
if (!existsSync(llmsFull)) {
|
|
32259
|
-
await fs3.mkdir(
|
|
32235
|
+
await fs3.mkdir(path12.dirname(llmsFull), { recursive: true });
|
|
32260
32236
|
await fs3.writeFile(llmsFull, LLMS_FULL_ROUTE, "utf-8");
|
|
32261
32237
|
n5++;
|
|
32262
32238
|
}
|
|
@@ -32290,9 +32266,9 @@ async function geoCommand(options) {
|
|
|
32290
32266
|
console.log(source_default.red(" \u2717 No app directory (app/ or src/app/)"));
|
|
32291
32267
|
process.exit(1);
|
|
32292
32268
|
}
|
|
32293
|
-
const llms =
|
|
32294
|
-
const llmsFull =
|
|
32295
|
-
const sitemap =
|
|
32269
|
+
const llms = path12.join(appDir, "llms.txt", "route.ts");
|
|
32270
|
+
const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
|
|
32271
|
+
const sitemap = path12.join(appDir, "sitemap.ts");
|
|
32296
32272
|
let allOk = true;
|
|
32297
32273
|
const row = (label, pass) => {
|
|
32298
32274
|
if (!pass) allOk = false;
|
|
@@ -32311,9 +32287,9 @@ async function geoCommand(options) {
|
|
|
32311
32287
|
row("sitemap.ts lists llms URLs", false);
|
|
32312
32288
|
}
|
|
32313
32289
|
const nextConfigs = [
|
|
32314
|
-
|
|
32315
|
-
|
|
32316
|
-
|
|
32290
|
+
path12.join(cwd, "next.config.ts"),
|
|
32291
|
+
path12.join(cwd, "next.config.mjs"),
|
|
32292
|
+
path12.join(cwd, "next.config.js")
|
|
32317
32293
|
];
|
|
32318
32294
|
let nextCfg = "";
|
|
32319
32295
|
for (const p of nextConfigs) {
|
|
@@ -32323,9 +32299,9 @@ async function geoCommand(options) {
|
|
|
32323
32299
|
}
|
|
32324
32300
|
}
|
|
32325
32301
|
const layoutCandidates = [
|
|
32326
|
-
|
|
32327
|
-
|
|
32328
|
-
|
|
32302
|
+
path12.join(appDir, "layout.tsx"),
|
|
32303
|
+
path12.join(appDir, "layout.jsx"),
|
|
32304
|
+
path12.join(appDir, "layout.js")
|
|
32329
32305
|
];
|
|
32330
32306
|
let layoutTxt = "";
|
|
32331
32307
|
for (const p of layoutCandidates) {
|
|
@@ -32385,8 +32361,8 @@ async function geoCommand(options) {
|
|
|
32385
32361
|
}
|
|
32386
32362
|
|
|
32387
32363
|
// src/cli/index.ts
|
|
32388
|
-
(0,
|
|
32389
|
-
(0,
|
|
32364
|
+
(0, import_dotenv2.config)({ path: ".env.local", quiet: true });
|
|
32365
|
+
(0, import_dotenv2.config)({ path: ".env", quiet: true });
|
|
32390
32366
|
var program2 = new Command();
|
|
32391
32367
|
program2.name("sonor-setup").description("Setup + verification toolchain for @sonordev/site-kit").version(SITE_KIT_VERSION);
|
|
32392
32368
|
withAgentFlags(
|