@sonordev/site-kit 5.6.0 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-manifest.json +11 -3
- package/dist/AnalyticsProvider-EWF7JN2X.mjs +11 -0
- package/dist/{AnalyticsProvider-FVQIYSLY.mjs.map → AnalyticsProvider-EWF7JN2X.mjs.map} +1 -1
- package/dist/AnalyticsProvider-GJFG7YXA.js +32 -0
- package/dist/{AnalyticsProvider-6PXC7UDP.js.map → AnalyticsProvider-GJFG7YXA.js.map} +1 -1
- package/dist/{BlogViewTracker-S4HSRCW7.js → BlogViewTracker-2D3IJPJK.js} +6 -6
- package/dist/{BlogViewTracker-S4HSRCW7.js.map → BlogViewTracker-2D3IJPJK.js.map} +1 -1
- package/dist/{BlogViewTracker-ZUGLBOVI.mjs → BlogViewTracker-CKYG6MYU.mjs} +5 -5
- package/dist/{BlogViewTracker-ZUGLBOVI.mjs.map → BlogViewTracker-CKYG6MYU.mjs.map} +1 -1
- package/dist/ChatWidget-AWP6GBVW.js +22 -0
- package/dist/{ChatWidget-2TQWCXWP.js.map → ChatWidget-AWP6GBVW.js.map} +1 -1
- package/dist/ChatWidget-Z5QXDZP3.mjs +13 -0
- package/dist/{ChatWidget-DG52ZIE6.mjs.map → ChatWidget-Z5QXDZP3.mjs.map} +1 -1
- package/dist/EngageWidget-BKEY5TPO.mjs +12 -0
- package/dist/{EngageWidget-2VUJADIU.mjs.map → EngageWidget-BKEY5TPO.mjs.map} +1 -1
- package/dist/EngageWidget-VT4DYXVO.js +21 -0
- package/dist/{EngageWidget-Z7RC2INM.js.map → EngageWidget-VT4DYXVO.js.map} +1 -1
- package/dist/{FileField-UOQHL25J.js → FileField-62ZWZMQK.js} +6 -6
- package/dist/{FileField-UOQHL25J.js.map → FileField-62ZWZMQK.js.map} +1 -1
- package/dist/{FileField-FSQ7W3A5.mjs → FileField-JJN5QKDL.mjs} +5 -5
- package/dist/{FileField-FSQ7W3A5.mjs.map → FileField-JJN5QKDL.mjs.map} +1 -1
- package/dist/{FormSpotlight-RHL5FWM2.mjs → FormSpotlight-OTFB6QM5.mjs} +3 -3
- package/dist/{FormSpotlight-RHL5FWM2.mjs.map → FormSpotlight-OTFB6QM5.mjs.map} +1 -1
- package/dist/{FormSpotlight-TED32NHP.js → FormSpotlight-URS4XRS7.js} +15 -15
- package/dist/{FormSpotlight-TED32NHP.js.map → FormSpotlight-URS4XRS7.js.map} +1 -1
- package/dist/{FormStage-PFEBKHGY.js → FormStage-FVKMIV73.js} +13 -13
- package/dist/{FormStage-PFEBKHGY.js.map → FormStage-FVKMIV73.js.map} +1 -1
- package/dist/{FormStage-DINIRFOX.mjs → FormStage-VPGOCMAV.mjs} +3 -3
- package/dist/{FormStage-DINIRFOX.mjs.map → FormStage-VPGOCMAV.mjs.map} +1 -1
- package/dist/ManagedForm-CXVDJMHN.mjs +14 -0
- package/dist/{ManagedForm-545YAUFC.mjs.map → ManagedForm-CXVDJMHN.mjs.map} +1 -1
- package/dist/ManagedForm-FGNTDGED.js +23 -0
- package/dist/{ManagedForm-43WLCUAK.js.map → ManagedForm-FGNTDGED.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-I3QN57HB.js → ManagedNewsletterForm-3O5L44AZ.js} +8 -8
- package/dist/{ManagedNewsletterForm-I3QN57HB.js.map → ManagedNewsletterForm-3O5L44AZ.js.map} +1 -1
- package/dist/{ManagedNewsletterForm-ZPY5RRKX.mjs → ManagedNewsletterForm-SQYB4BZU.mjs} +7 -7
- package/dist/{ManagedNewsletterForm-ZPY5RRKX.mjs.map → ManagedNewsletterForm-SQYB4BZU.mjs.map} +1 -1
- package/dist/{SignalCore-EEH5IM4U.mjs → SignalCore-M2PKKIGH.mjs} +5 -5
- package/dist/{SignalCore-EEH5IM4U.mjs.map → SignalCore-M2PKKIGH.mjs.map} +1 -1
- package/dist/{SignalCore-M4AXIMV4.js → SignalCore-RFBOBNLQ.js} +11 -11
- package/dist/{SignalCore-M4AXIMV4.js.map → SignalCore-RFBOBNLQ.js.map} +1 -1
- package/dist/SitemapSync-4OVMIIGC.mjs +9 -0
- package/dist/{SitemapSync-46G7LVZS.mjs.map → SitemapSync-4OVMIIGC.mjs.map} +1 -1
- package/dist/SitemapSync-RK3SQ4M2.js +18 -0
- package/dist/{SitemapSync-XK4JKCS7.js.map → SitemapSync-RK3SQ4M2.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +4 -4
- package/dist/blog/index.js +20 -20
- package/dist/blog/index.mjs +3 -3
- package/dist/blog/metadata-images.test.d.ts +2 -0
- package/dist/blog/metadata-images.test.d.ts.map +1 -0
- package/dist/blog/server-core.d.ts +31 -6
- package/dist/blog/server-core.d.ts.map +1 -1
- package/dist/blog/server-ui.js +16 -16
- package/dist/blog/server-ui.mjs +3 -3
- package/dist/blog/server.d.ts +31 -6
- package/dist/blog/server.d.ts.map +1 -1
- package/dist/blog/server.js +40 -40
- package/dist/blog/server.mjs +1 -1
- package/dist/blog/static-params.test.d.ts +2 -0
- package/dist/blog/static-params.test.d.ts.map +1 -0
- package/dist/{chunk-XR32C47O.js → chunk-2N27LCZH.js} +5 -5
- package/dist/{chunk-XR32C47O.js.map → chunk-2N27LCZH.js.map} +1 -1
- package/dist/{chunk-GPLCPMVD.mjs → chunk-3CLP35TT.mjs} +7 -7
- package/dist/{chunk-GPLCPMVD.mjs.map → chunk-3CLP35TT.mjs.map} +1 -1
- package/dist/{chunk-S4RC6VAQ.js → chunk-3S5JN6KL.js} +6 -6
- package/dist/{chunk-S4RC6VAQ.js.map → chunk-3S5JN6KL.js.map} +1 -1
- package/dist/chunk-3UC6JETG.js +32 -0
- package/dist/chunk-3UC6JETG.js.map +1 -0
- package/dist/{chunk-B64AZC6P.js → chunk-3YQILJKJ.js} +14 -14
- package/dist/{chunk-B64AZC6P.js.map → chunk-3YQILJKJ.js.map} +1 -1
- package/dist/{chunk-7C7XO5HX.mjs → chunk-47XQWV4S.mjs} +3 -3
- package/dist/{chunk-7C7XO5HX.mjs.map → chunk-47XQWV4S.mjs.map} +1 -1
- package/dist/{chunk-CQS5ZYI6.mjs → chunk-4A5V73SR.mjs} +8 -8
- package/dist/{chunk-CQS5ZYI6.mjs.map → chunk-4A5V73SR.mjs.map} +1 -1
- package/dist/{chunk-53KMRZT7.js → chunk-4UVM7E2W.js} +3 -3
- package/dist/{chunk-53KMRZT7.js.map → chunk-4UVM7E2W.js.map} +1 -1
- package/dist/{chunk-YYN4YZYZ.js → chunk-4WBTM6YE.js} +4 -4
- package/dist/{chunk-YYN4YZYZ.js.map → chunk-4WBTM6YE.js.map} +1 -1
- package/dist/{chunk-VHZ4LHQT.mjs → chunk-57AFHENV.mjs} +3 -3
- package/dist/{chunk-VHZ4LHQT.mjs.map → chunk-57AFHENV.mjs.map} +1 -1
- package/dist/chunk-5TXXTYXL.js +8 -0
- package/dist/{chunk-KSL3WA2I.js.map → chunk-5TXXTYXL.js.map} +1 -1
- package/dist/{chunk-RU54J2PY.mjs → chunk-6FC5Q4KU.mjs} +3 -3
- package/dist/{chunk-RU54J2PY.mjs.map → chunk-6FC5Q4KU.mjs.map} +1 -1
- package/dist/{chunk-AHZR4VGY.mjs → chunk-7ZX6TO6C.mjs} +4 -4
- package/dist/{chunk-AHZR4VGY.mjs.map → chunk-7ZX6TO6C.mjs.map} +1 -1
- package/dist/{chunk-K2V3ZW36.mjs → chunk-ABZGEHTC.mjs} +3 -3
- package/dist/{chunk-K2V3ZW36.mjs.map → chunk-ABZGEHTC.mjs.map} +1 -1
- package/dist/chunk-AWK57R5S.mjs +29 -0
- package/dist/chunk-AWK57R5S.mjs.map +1 -0
- package/dist/{chunk-EEQYKMGH.mjs → chunk-BFJOZ3MU.mjs} +23 -17
- package/dist/chunk-BFJOZ3MU.mjs.map +1 -0
- package/dist/{chunk-KY6M76JW.js → chunk-BFM5PEFV.js} +3 -3
- package/dist/{chunk-KY6M76JW.js.map → chunk-BFM5PEFV.js.map} +1 -1
- package/dist/{chunk-JNABXCLY.mjs → chunk-BQGEVMIR.mjs} +4 -4
- package/dist/{chunk-JNABXCLY.mjs.map → chunk-BQGEVMIR.mjs.map} +1 -1
- package/dist/{chunk-5KIEZHVK.mjs → chunk-BUJWXSYZ.mjs} +4 -4
- package/dist/{chunk-5KIEZHVK.mjs.map → chunk-BUJWXSYZ.mjs.map} +1 -1
- package/dist/{chunk-B6O7D5U4.js → chunk-C4PZ2R3B.js} +10 -10
- package/dist/{chunk-B6O7D5U4.js.map → chunk-C4PZ2R3B.js.map} +1 -1
- package/dist/{chunk-5UFDHGFE.mjs → chunk-C563AHZZ.mjs} +3 -3
- package/dist/{chunk-5UFDHGFE.mjs.map → chunk-C563AHZZ.mjs.map} +1 -1
- package/dist/{chunk-746RKQHA.js → chunk-CPY74A4F.js} +23 -17
- package/dist/chunk-CPY74A4F.js.map +1 -0
- package/dist/{chunk-N2PGTPWN.js → chunk-D553G64G.js} +11 -11
- package/dist/{chunk-N2PGTPWN.js.map → chunk-D553G64G.js.map} +1 -1
- package/dist/{chunk-KPKQKFT4.js → chunk-DOB37PV4.js} +3 -3
- package/dist/{chunk-KPKQKFT4.js.map → chunk-DOB37PV4.js.map} +1 -1
- package/dist/{chunk-H3D3ZGOJ.js → chunk-ELQ4SRRR.js} +15 -15
- package/dist/{chunk-H3D3ZGOJ.js.map → chunk-ELQ4SRRR.js.map} +1 -1
- package/dist/{chunk-X5TCH7VZ.js → chunk-F3AKYZOH.js} +3 -3
- package/dist/{chunk-X5TCH7VZ.js.map → chunk-F3AKYZOH.js.map} +1 -1
- package/dist/{chunk-LCSYJXIO.mjs → chunk-FBDHKYNF.mjs} +3 -3
- package/dist/{chunk-LCSYJXIO.mjs.map → chunk-FBDHKYNF.mjs.map} +1 -1
- package/dist/{chunk-JE5DWAE6.js → chunk-FEWWGEQF.js} +4 -4
- package/dist/{chunk-JE5DWAE6.js.map → chunk-FEWWGEQF.js.map} +1 -1
- package/dist/{chunk-NZSFOZJV.js → chunk-FO4KGPGF.js} +2 -2
- package/dist/{chunk-NZSFOZJV.js.map → chunk-FO4KGPGF.js.map} +1 -1
- package/dist/{chunk-OC7AO7XS.js → chunk-H65OX263.js} +15 -15
- package/dist/{chunk-OC7AO7XS.js.map → chunk-H65OX263.js.map} +1 -1
- package/dist/{chunk-46BMNWE6.js → chunk-H6YVT3BL.js} +2 -2
- package/dist/{chunk-46BMNWE6.js.map → chunk-H6YVT3BL.js.map} +1 -1
- package/dist/{chunk-GJ6NOLGC.mjs → chunk-HBN4A2N4.mjs} +3 -3
- package/dist/{chunk-GJ6NOLGC.mjs.map → chunk-HBN4A2N4.mjs.map} +1 -1
- package/dist/{chunk-AJQI3WTN.mjs → chunk-ILNCUSXW.mjs} +2 -2
- package/dist/{chunk-AJQI3WTN.mjs.map → chunk-ILNCUSXW.mjs.map} +1 -1
- package/dist/{chunk-473WDGQZ.mjs → chunk-JNAXDFC4.mjs} +3 -3
- package/dist/{chunk-473WDGQZ.mjs.map → chunk-JNAXDFC4.mjs.map} +1 -1
- package/dist/{chunk-7AUDKXY5.mjs → chunk-JQ7M6CVL.mjs} +3 -3
- package/dist/{chunk-7AUDKXY5.mjs.map → chunk-JQ7M6CVL.mjs.map} +1 -1
- package/dist/{chunk-BZLIOT7Q.js → chunk-JTCQJKJE.js} +18 -18
- package/dist/{chunk-BZLIOT7Q.js.map → chunk-JTCQJKJE.js.map} +1 -1
- package/dist/{chunk-OA7KKOAK.mjs → chunk-JTF4DFUF.mjs} +3 -3
- package/dist/{chunk-OA7KKOAK.mjs.map → chunk-JTF4DFUF.mjs.map} +1 -1
- package/dist/{chunk-5KIO6FXE.js → chunk-KXGD4E7G.js} +5 -5
- package/dist/{chunk-5KIO6FXE.js.map → chunk-KXGD4E7G.js.map} +1 -1
- package/dist/chunk-L4V6TKMJ.mjs +94 -0
- package/dist/chunk-L4V6TKMJ.mjs.map +1 -0
- package/dist/{chunk-DHIWR7CG.js → chunk-L7ACQ6PC.js} +4 -4
- package/dist/{chunk-DHIWR7CG.js.map → chunk-L7ACQ6PC.js.map} +1 -1
- package/dist/{chunk-RIYAMYLV.mjs → chunk-M5GY2AI3.mjs} +3 -3
- package/dist/{chunk-RIYAMYLV.mjs.map → chunk-M5GY2AI3.mjs.map} +1 -1
- package/dist/{chunk-YCI36ZUS.mjs → chunk-MW2M6O7A.mjs} +4 -4
- package/dist/{chunk-YCI36ZUS.mjs.map → chunk-MW2M6O7A.mjs.map} +1 -1
- package/dist/{chunk-BWSMUSDB.js → chunk-NOU3JQJK.js} +8 -8
- package/dist/{chunk-BWSMUSDB.js.map → chunk-NOU3JQJK.js.map} +1 -1
- package/dist/{chunk-IYCLN3XS.mjs → chunk-O2VJZOR2.mjs} +3 -3
- package/dist/{chunk-IYCLN3XS.mjs.map → chunk-O2VJZOR2.mjs.map} +1 -1
- package/dist/{chunk-T5VTQUNF.js → chunk-OYOO2OO5.js} +8 -8
- package/dist/{chunk-T5VTQUNF.js.map → chunk-OYOO2OO5.js.map} +1 -1
- package/dist/chunk-P4TB4ROG.js +110 -0
- package/dist/chunk-P4TB4ROG.js.map +1 -0
- package/dist/{chunk-6OP5XSMM.mjs → chunk-Q7347KP6.mjs} +3 -3
- package/dist/{chunk-6OP5XSMM.mjs.map → chunk-Q7347KP6.mjs.map} +1 -1
- package/dist/chunk-QRBPT6Z6.mjs +6 -0
- package/dist/{chunk-DQUBETXH.mjs.map → chunk-QRBPT6Z6.mjs.map} +1 -1
- package/dist/{chunk-USKIL6V6.mjs → chunk-R2SXXFXZ.mjs} +3 -3
- package/dist/{chunk-USKIL6V6.mjs.map → chunk-R2SXXFXZ.mjs.map} +1 -1
- package/dist/{chunk-UU47DGHE.js → chunk-RCSTDJUH.js} +5 -5
- package/dist/{chunk-UU47DGHE.js.map → chunk-RCSTDJUH.js.map} +1 -1
- package/dist/{chunk-SYGGZZMU.js → chunk-RNAGCAIB.js} +7 -7
- package/dist/{chunk-SYGGZZMU.js.map → chunk-RNAGCAIB.js.map} +1 -1
- package/dist/{chunk-AEARU24Q.mjs → chunk-RVRN5U7W.mjs} +2 -2
- package/dist/{chunk-AEARU24Q.mjs.map → chunk-RVRN5U7W.mjs.map} +1 -1
- package/dist/{chunk-C2MSD2UM.mjs → chunk-TDJKGN5Q.mjs} +4 -4
- package/dist/{chunk-C2MSD2UM.mjs.map → chunk-TDJKGN5Q.mjs.map} +1 -1
- package/dist/{chunk-R3KTBKSW.js → chunk-TSZIACRC.js} +4 -4
- package/dist/{chunk-R3KTBKSW.js.map → chunk-TSZIACRC.js.map} +1 -1
- package/dist/{chunk-H44XZUOV.mjs → chunk-UQ5YULFU.mjs} +4 -4
- package/dist/{chunk-H44XZUOV.mjs.map → chunk-UQ5YULFU.mjs.map} +1 -1
- package/dist/{chunk-QNPVVWR7.mjs → chunk-V5THCFPG.mjs} +3 -3
- package/dist/{chunk-QNPVVWR7.mjs.map → chunk-V5THCFPG.mjs.map} +1 -1
- package/dist/{chunk-CQRLKNHQ.js → chunk-VFGEY6FJ.js} +12 -12
- package/dist/{chunk-CQRLKNHQ.js.map → chunk-VFGEY6FJ.js.map} +1 -1
- package/dist/{chunk-HIHAXEPD.mjs → chunk-XLPU3TEE.mjs} +4 -4
- package/dist/{chunk-HIHAXEPD.mjs.map → chunk-XLPU3TEE.mjs.map} +1 -1
- package/dist/{chunk-AY7JBGYC.js → chunk-YKUEFRZI.js} +14 -14
- package/dist/{chunk-AY7JBGYC.js.map → chunk-YKUEFRZI.js.map} +1 -1
- package/dist/{chunk-XK5AIWQG.js → chunk-YYDZ2TYR.js} +3 -3
- package/dist/{chunk-XK5AIWQG.js.map → chunk-YYDZ2TYR.js.map} +1 -1
- package/dist/cli/agent/checks.d.ts.map +1 -1
- package/dist/cli/commands/api-routes.d.ts.map +1 -1
- package/dist/cli/commands/geo.d.ts +4 -0
- package/dist/cli/commands/geo.d.ts.map +1 -1
- package/dist/cli/commands/geo.test.d.ts +2 -0
- package/dist/cli/commands/geo.test.d.ts.map +1 -0
- package/dist/cli/commands/og.d.ts +10 -1
- package/dist/cli/commands/og.d.ts.map +1 -1
- package/dist/cli/commands/scaffold.d.ts +1 -2
- package/dist/cli/commands/scaffold.d.ts.map +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/generators/index.d.ts +5 -0
- package/dist/cli/generators/index.d.ts.map +1 -1
- package/dist/cli/generators/index.test.d.ts +2 -0
- package/dist/cli/generators/index.test.d.ts.map +1 -0
- package/dist/cli/index.js +360 -266
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +356 -262
- package/dist/cli/index.mjs.map +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/commerce/index.js +56 -56
- package/dist/commerce/index.mjs +5 -5
- package/dist/discover-FGTKWOL3.mjs +4 -0
- package/dist/{discover-BEJRYNFF.mjs.map → discover-FGTKWOL3.mjs.map} +1 -1
- package/dist/discover-NJZPWTDL.js +21 -0
- package/dist/{discover-WVDYDUJX.js.map → discover-NJZPWTDL.js.map} +1 -1
- package/dist/engage/index.js +10 -10
- package/dist/engage/index.mjs +7 -7
- package/dist/fleet/index.js +8 -8
- package/dist/fleet/index.mjs +4 -4
- package/dist/forms/index.js +16 -16
- package/dist/forms/index.mjs +9 -9
- package/dist/forms/server.js +10 -10
- package/dist/forms/server.mjs +8 -8
- package/dist/forms/static.js +7 -7
- package/dist/forms/static.mjs +6 -6
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +4 -4
- package/dist/index.js +68 -68
- package/dist/index.mjs +10 -10
- package/dist/layout/client.js +8 -8
- package/dist/layout/client.mjs +7 -7
- package/dist/layout/index.js +10 -10
- package/dist/layout/index.mjs +8 -8
- package/dist/llms/aiRobots.d.ts +4 -1
- package/dist/llms/aiRobots.d.ts.map +1 -1
- package/dist/llms/handlers.d.ts +20 -2
- package/dist/llms/handlers.d.ts.map +1 -1
- package/dist/llms/index.js +25 -18
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +15 -8
- package/dist/llms/index.mjs.map +1 -1
- package/dist/llms/wiring.d.ts +81 -0
- package/dist/llms/wiring.d.ts.map +1 -0
- package/dist/llms/wiring.test.d.ts +2 -0
- package/dist/llms/wiring.test.d.ts.map +1 -0
- package/dist/maps/index.js +5 -5
- package/dist/maps/index.mjs +3 -3
- package/dist/og/wiring.d.ts +5 -1
- package/dist/og/wiring.d.ts.map +1 -1
- package/dist/proxy/index.d.ts +16 -11
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +3 -3
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/index.mjs +1 -1
- package/dist/proxy/index.mjs.map +1 -1
- package/dist/redirects/index.d.ts +1 -1
- package/dist/redirects/index.js +8 -8
- package/dist/redirects/index.mjs +1 -1
- package/dist/redirects/not-found.d.ts +14 -29
- package/dist/redirects/not-found.d.ts.map +1 -1
- package/dist/redirects/not-found.js +12 -5
- package/dist/redirects/not-found.js.map +1 -1
- package/dist/redirects/not-found.mjs +8 -1
- package/dist/redirects/not-found.mjs.map +1 -1
- package/dist/robots/index.d.ts +5 -1
- package/dist/robots/index.d.ts.map +1 -1
- package/dist/robots/index.js +7 -1
- package/dist/robots/index.js.map +1 -1
- package/dist/robots/index.mjs +4 -1
- package/dist/robots/index.mjs.map +1 -1
- package/dist/robots/index.test.d.ts +2 -0
- package/dist/robots/index.test.d.ts.map +1 -0
- package/dist/robots/next-internals.d.ts +22 -0
- package/dist/robots/next-internals.d.ts.map +1 -0
- package/dist/search/index.js +4 -4
- package/dist/search/index.mjs +3 -3
- package/dist/seo/client.js +5 -5
- package/dist/seo/client.mjs +4 -4
- package/dist/seo/index.js +14 -14
- package/dist/seo/index.mjs +6 -6
- package/dist/seo/register-sitemap-cli.js +4 -4
- package/dist/seo/register-sitemap-cli.mjs +1 -1
- package/dist/seo/server.js +5 -5
- package/dist/seo/server.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +2 -2
- package/dist/shared/next-files.d.ts +35 -0
- package/dist/shared/next-files.d.ts.map +1 -0
- package/dist/shared/next-files.test.d.ts +2 -0
- package/dist/shared/next-files.test.d.ts.map +1 -0
- package/dist/shared/version.d.ts +1 -1
- package/dist/signal/index.js +11 -11
- package/dist/signal/index.mjs +2 -2
- package/dist/sitemap/discover.d.ts.map +1 -1
- package/dist/sitemap/index.d.ts +6 -1
- package/dist/sitemap/index.d.ts.map +1 -1
- package/dist/sitemap/index.js +5 -12
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +4 -11
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/sync/index.js +17 -17
- package/dist/sync/index.mjs +4 -4
- package/package.json +19 -21
- package/dist/AnalyticsProvider-6PXC7UDP.js +0 -32
- package/dist/AnalyticsProvider-FVQIYSLY.mjs +0 -11
- package/dist/ChatWidget-2TQWCXWP.js +0 -22
- package/dist/ChatWidget-DG52ZIE6.mjs +0 -13
- package/dist/EngageWidget-2VUJADIU.mjs +0 -12
- package/dist/EngageWidget-Z7RC2INM.js +0 -21
- package/dist/ManagedForm-43WLCUAK.js +0 -23
- package/dist/ManagedForm-545YAUFC.mjs +0 -14
- package/dist/SitemapSync-46G7LVZS.mjs +0 -9
- package/dist/SitemapSync-XK4JKCS7.js +0 -18
- package/dist/chunk-746RKQHA.js.map +0 -1
- package/dist/chunk-DQUBETXH.mjs +0 -6
- package/dist/chunk-EEQYKMGH.mjs.map +0 -1
- package/dist/chunk-KSL3WA2I.js +0 -8
- package/dist/chunk-LOS5D6B3.js +0 -72
- package/dist/chunk-LOS5D6B3.js.map +0 -1
- package/dist/chunk-XIJ4F6IE.mjs +0 -63
- package/dist/chunk-XIJ4F6IE.mjs.map +0 -1
- package/dist/discover-BEJRYNFF.mjs +0 -4
- package/dist/discover-WVDYDUJX.js +0 -21
package/dist/cli/index.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { traverse, isJSXIdentifier, isJSXAttribute, isFunctionDeclaration, isVar
|
|
|
3
3
|
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
|
-
import { findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-
|
|
7
|
-
import { SITE_KIT_VERSION } from '../chunk-
|
|
6
|
+
import { findAppDirForDiscovery, NEXT_PROXY_FILES, NEXT_MIDDLEWARE_FILES, findConventionFile, NEXT_APP_DIRS, findSitemapRoute, findProxyFiles, findRootLayout, discoverNextJsRoutes, hasPageFile } from '../chunk-L4V6TKMJ.mjs';
|
|
7
|
+
import { SITE_KIT_VERSION } from '../chunk-QRBPT6Z6.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';
|
|
@@ -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 fs30 = (0, node_1.default)();
|
|
6206
6206
|
const handler = (err, buffer) => {
|
|
6207
6207
|
if (fd) {
|
|
6208
|
-
|
|
6208
|
+
fs30.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 = fs30.openSync(filepath, "r");
|
|
6221
6221
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
6222
|
-
|
|
6222
|
+
fs30.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
|
+
fs30.readFile(filepath, handler);
|
|
6235
6235
|
});
|
|
6236
6236
|
exports.detectFile = detectFile;
|
|
6237
6237
|
var detectFileSync = (filepath, opts = {}) => {
|
|
6238
|
-
const
|
|
6238
|
+
const fs30 = (0, node_1.default)();
|
|
6239
6239
|
if (opts && opts.sampleSize) {
|
|
6240
|
-
const fd =
|
|
6240
|
+
const fd = fs30.openSync(filepath, "r");
|
|
6241
6241
|
let sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
6242
|
-
const bytesRead =
|
|
6242
|
+
const bytesRead = fs30.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
|
+
fs30.closeSync(fd);
|
|
6247
6247
|
return (0, exports.detect)(sample);
|
|
6248
6248
|
}
|
|
6249
|
-
return (0, exports.detect)(
|
|
6249
|
+
return (0, exports.detect)(fs30.readFileSync(filepath));
|
|
6250
6250
|
};
|
|
6251
6251
|
exports.detectFileSync = detectFileSync;
|
|
6252
6252
|
exports.default = {
|
|
@@ -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(path30) {
|
|
13240
|
+
if (path30 === void 0) return this._executableDir;
|
|
13241
|
+
this._executableDir = path30;
|
|
13242
13242
|
return this;
|
|
13243
13243
|
}
|
|
13244
13244
|
/**
|
|
@@ -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, path30 = "", value) => {
|
|
20349
20349
|
let pointer = obj;
|
|
20350
|
-
|
|
20350
|
+
path30.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, path30 = "", defaultValue) => {
|
|
20362
|
+
const travel = (regexp) => String.prototype.split.call(path30, 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
|
|
@@ -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(path30) {
|
|
20720
|
+
const opening = path30.node.openingElement;
|
|
20721
20721
|
if (isJSXIdentifier(opening.name) && opening.name.name === "form") {
|
|
20722
|
-
const fields = extractFieldsFromForm(
|
|
20722
|
+
const fields = extractFieldsFromForm(path30);
|
|
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 = path30.node.loc?.start.line || 0;
|
|
20728
|
+
const endLine = path30.node.loc?.end.line || 0;
|
|
20729
20729
|
let componentName = "UnknownForm";
|
|
20730
|
-
let current =
|
|
20730
|
+
let current = path30.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(path30);
|
|
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: path30.node.loc?.start.line || 0,
|
|
20775
|
+
endLine: path30.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(path30) {
|
|
20794
|
+
const opening = path30.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
|
+
path30.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(path30) {
|
|
20917
|
+
const opening = path30.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(path30) {
|
|
21037
|
+
const opening = path30.node.openingElement;
|
|
21038
21038
|
if (isJSXIdentifier(opening.name) && opening.name.name === "Head") {
|
|
21039
21039
|
hasHeadComponent = true;
|
|
21040
|
-
|
|
21040
|
+
path30.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(path30) {
|
|
21076
|
+
const opening = path30.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: path30.node.loc?.start.line || 0,
|
|
21092
|
+
endLine: path30.node.loc?.end.line || 0
|
|
21093
21093
|
});
|
|
21094
21094
|
}
|
|
21095
21095
|
}
|
|
@@ -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(path30) {
|
|
21232
|
+
const opening = path30.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: path30.node.loc?.start.line || 0,
|
|
21260
|
+
endLine: path30.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(path30) {
|
|
21294
|
+
const opening = path30.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: path30.node.loc?.start.line || 0,
|
|
21308
|
+
endLine: path30.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
|
+
path30.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: path30.node.loc?.start.line || 0,
|
|
21333
|
+
endLine: path30.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(path30) {
|
|
21457
|
+
const opening = path30.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: path30.node.loc?.start.line || 0,
|
|
21486
|
+
endLine: path30.node.loc?.end.line || 0
|
|
21487
21487
|
});
|
|
21488
21488
|
}
|
|
21489
21489
|
}
|
|
@@ -22374,18 +22374,18 @@ async function migrateFile(filePath, options) {
|
|
|
22374
22374
|
let componentName = "Form";
|
|
22375
22375
|
const traverse2 = (await import('../lib-RSDMEKDQ.mjs')).default;
|
|
22376
22376
|
traverse2(ast, {
|
|
22377
|
-
ExportNamedDeclaration(
|
|
22378
|
-
const decl =
|
|
22377
|
+
ExportNamedDeclaration(path30) {
|
|
22378
|
+
const decl = path30.node.declaration;
|
|
22379
22379
|
if (decl && decl.type === "FunctionDeclaration" && decl.id) {
|
|
22380
22380
|
componentName = decl.id.name;
|
|
22381
|
-
|
|
22381
|
+
path30.stop();
|
|
22382
22382
|
}
|
|
22383
22383
|
},
|
|
22384
|
-
ExportDefaultDeclaration(
|
|
22385
|
-
const decl =
|
|
22384
|
+
ExportDefaultDeclaration(path30) {
|
|
22385
|
+
const decl = path30.node.declaration;
|
|
22386
22386
|
if (decl && decl.type === "FunctionDeclaration" && decl.id) {
|
|
22387
22387
|
componentName = decl.id.name;
|
|
22388
|
-
|
|
22388
|
+
path30.stop();
|
|
22389
22389
|
}
|
|
22390
22390
|
}
|
|
22391
22391
|
});
|
|
@@ -22501,7 +22501,7 @@ function addImportSafely2(content, importStatement) {
|
|
|
22501
22501
|
async function generateLayout() {
|
|
22502
22502
|
const layoutPath = await findLayoutFile();
|
|
22503
22503
|
if (!layoutPath) {
|
|
22504
|
-
throw new Error("Could not find layout.tsx
|
|
22504
|
+
throw new Error("Could not find a root layout (app/layout.tsx, .jsx, .ts or .js)");
|
|
22505
22505
|
}
|
|
22506
22506
|
const content = await fs3.readFile(layoutPath, "utf-8");
|
|
22507
22507
|
if (content.includes("SiteKitLayout") || content.includes("SiteKitProvider")) {
|
|
@@ -22535,22 +22535,7 @@ async function generateLayout() {
|
|
|
22535
22535
|
await fs3.writeFile(layoutPath, newContent, "utf-8");
|
|
22536
22536
|
}
|
|
22537
22537
|
async function findLayoutFile() {
|
|
22538
|
-
|
|
22539
|
-
"src/app/layout.tsx",
|
|
22540
|
-
"app/layout.tsx",
|
|
22541
|
-
"src/app/layout.jsx",
|
|
22542
|
-
"app/layout.jsx"
|
|
22543
|
-
];
|
|
22544
|
-
for (const relativePath of possiblePaths) {
|
|
22545
|
-
const fullPath = path12.join(process.cwd(), relativePath);
|
|
22546
|
-
try {
|
|
22547
|
-
await fs3.access(fullPath);
|
|
22548
|
-
return fullPath;
|
|
22549
|
-
} catch {
|
|
22550
|
-
continue;
|
|
22551
|
-
}
|
|
22552
|
-
}
|
|
22553
|
-
return null;
|
|
22538
|
+
return findRootLayout(process.cwd());
|
|
22554
22539
|
}
|
|
22555
22540
|
var isDockerCached;
|
|
22556
22541
|
function hasDockerEnv() {
|
|
@@ -22712,15 +22697,15 @@ var wslDefaultBrowser = async () => {
|
|
|
22712
22697
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
22713
22698
|
return stdout.trim();
|
|
22714
22699
|
};
|
|
22715
|
-
var convertWslPathToWindows = async (
|
|
22716
|
-
if (/^[a-z]+:\/\//i.test(
|
|
22717
|
-
return
|
|
22700
|
+
var convertWslPathToWindows = async (path30) => {
|
|
22701
|
+
if (/^[a-z]+:\/\//i.test(path30)) {
|
|
22702
|
+
return path30;
|
|
22718
22703
|
}
|
|
22719
22704
|
try {
|
|
22720
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
22705
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path30], { encoding: "utf8" });
|
|
22721
22706
|
return stdout.trim();
|
|
22722
22707
|
} catch {
|
|
22723
|
-
return
|
|
22708
|
+
return path30;
|
|
22724
22709
|
}
|
|
22725
22710
|
};
|
|
22726
22711
|
|
|
@@ -25208,8 +25193,8 @@ async function templateCommand(sourcePath, options) {
|
|
|
25208
25193
|
const slots = [];
|
|
25209
25194
|
const componentNames = [];
|
|
25210
25195
|
traverse(ast, {
|
|
25211
|
-
JSXElement(
|
|
25212
|
-
const openingElement =
|
|
25196
|
+
JSXElement(path30) {
|
|
25197
|
+
const openingElement = path30.node.openingElement;
|
|
25213
25198
|
if (isJSXIdentifier(openingElement.name)) {
|
|
25214
25199
|
const componentName = openingElement.name.name;
|
|
25215
25200
|
if (componentName[0] === componentName[0].toUpperCase()) {
|
|
@@ -26333,8 +26318,7 @@ async function uploadSchemas(pages, globalSchema, config2) {
|
|
|
26333
26318
|
}
|
|
26334
26319
|
}
|
|
26335
26320
|
}
|
|
26336
|
-
var
|
|
26337
|
-
var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
|
|
26321
|
+
var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp|tsx|ts|jsx|js)$/i;
|
|
26338
26322
|
function safeExists(p) {
|
|
26339
26323
|
try {
|
|
26340
26324
|
return fs__default.existsSync(p);
|
|
@@ -26358,14 +26342,14 @@ function findPageCards(cwd) {
|
|
|
26358
26342
|
else if (CARD_FILE.test(entry.name)) found.push(full);
|
|
26359
26343
|
}
|
|
26360
26344
|
};
|
|
26361
|
-
for (const rel of
|
|
26345
|
+
for (const rel of NEXT_APP_DIRS) walk(path12.join(cwd, rel));
|
|
26362
26346
|
return found;
|
|
26363
26347
|
}
|
|
26364
26348
|
function readOgWiring(cwd) {
|
|
26365
26349
|
const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
|
|
26366
26350
|
(rel) => safeExists(path12.join(cwd, rel))
|
|
26367
26351
|
);
|
|
26368
|
-
const layoutPath =
|
|
26352
|
+
const layoutPath = findRootLayout(cwd);
|
|
26369
26353
|
let layout = "";
|
|
26370
26354
|
if (layoutPath) {
|
|
26371
26355
|
try {
|
|
@@ -26385,7 +26369,12 @@ function readOgWiring(cwd) {
|
|
|
26385
26369
|
function judgeOgWiring(facts) {
|
|
26386
26370
|
const problems = [];
|
|
26387
26371
|
if (!facts.layoutFound) {
|
|
26388
|
-
return [
|
|
26372
|
+
return [
|
|
26373
|
+
{
|
|
26374
|
+
message: "no root layout (app/layout.{tsx,ts,jsx,js} or src/app/layout.*) found to verify metadata",
|
|
26375
|
+
fix: "Run this from the site root."
|
|
26376
|
+
}
|
|
26377
|
+
];
|
|
26389
26378
|
}
|
|
26390
26379
|
if (!facts.siteCard && !facts.pageCards.length) {
|
|
26391
26380
|
return [
|
|
@@ -26440,26 +26429,6 @@ async function readFileOrNull(p) {
|
|
|
26440
26429
|
return null;
|
|
26441
26430
|
}
|
|
26442
26431
|
}
|
|
26443
|
-
async function findFirst(cwd, candidates) {
|
|
26444
|
-
for (const rel of candidates) {
|
|
26445
|
-
const full = path12.join(cwd, rel);
|
|
26446
|
-
if (await readFileOrNull(full)) return full;
|
|
26447
|
-
}
|
|
26448
|
-
return null;
|
|
26449
|
-
}
|
|
26450
|
-
var LAYOUT_CANDIDATES = [
|
|
26451
|
-
"app/layout.tsx",
|
|
26452
|
-
"app/layout.jsx",
|
|
26453
|
-
"src/app/layout.tsx",
|
|
26454
|
-
"src/app/layout.jsx"
|
|
26455
|
-
];
|
|
26456
|
-
var SITEMAP_CANDIDATES = [
|
|
26457
|
-
"app/sitemap.ts",
|
|
26458
|
-
"app/sitemap.tsx",
|
|
26459
|
-
"app/sitemap.js",
|
|
26460
|
-
"src/app/sitemap.ts",
|
|
26461
|
-
"src/app/sitemap.tsx"
|
|
26462
|
-
];
|
|
26463
26432
|
function checkApiKeyEnv() {
|
|
26464
26433
|
const key = process.env.SONOR_API_KEY;
|
|
26465
26434
|
if (key && key.startsWith("sonor_")) {
|
|
@@ -26546,7 +26515,7 @@ async function checkPackageInstalled(cwd) {
|
|
|
26546
26515
|
};
|
|
26547
26516
|
}
|
|
26548
26517
|
async function checkSiteKitLayout(cwd) {
|
|
26549
|
-
const layoutPath =
|
|
26518
|
+
const layoutPath = findRootLayout(cwd);
|
|
26550
26519
|
if (!layoutPath) {
|
|
26551
26520
|
return {
|
|
26552
26521
|
id: "layout.sitekit",
|
|
@@ -26590,8 +26559,8 @@ async function checkSiteKitLayout(cwd) {
|
|
|
26590
26559
|
};
|
|
26591
26560
|
}
|
|
26592
26561
|
async function checkSitemap(cwd) {
|
|
26593
|
-
const
|
|
26594
|
-
if (!
|
|
26562
|
+
const sitemapRel = findSitemapRoute(cwd);
|
|
26563
|
+
if (!sitemapRel) {
|
|
26595
26564
|
return {
|
|
26596
26565
|
id: "sitemap.managed",
|
|
26597
26566
|
title: "Sitemap",
|
|
@@ -26601,7 +26570,7 @@ async function checkSitemap(cwd) {
|
|
|
26601
26570
|
fixCommand: "npx sonor-setup scaffold --yes"
|
|
26602
26571
|
};
|
|
26603
26572
|
}
|
|
26604
|
-
const content = await readFileOrNull(
|
|
26573
|
+
const content = await readFileOrNull(path12.join(cwd, sitemapRel)) || "";
|
|
26605
26574
|
if (content.includes("createSitemap") || content.includes("@sonordev/site-kit")) {
|
|
26606
26575
|
return { id: "sitemap.managed", title: "Sitemap", level: "ok", message: "Using Site-Kit sitemap" };
|
|
26607
26576
|
}
|
|
@@ -26979,8 +26948,7 @@ async function checkSsrRenderFromBuild(cwd) {
|
|
|
26979
26948
|
}
|
|
26980
26949
|
async function checkNetlifyMiddleware(cwd) {
|
|
26981
26950
|
const runtimeRe = /runtime\s*[:=]\s*['"](nodejs|edge)['"]/;
|
|
26982
|
-
const
|
|
26983
|
-
for (const rel of proxyFiles) {
|
|
26951
|
+
for (const rel of NEXT_PROXY_FILES) {
|
|
26984
26952
|
const content = await readFileOrNull(path12.join(cwd, rel));
|
|
26985
26953
|
if (content === null) continue;
|
|
26986
26954
|
if (runtimeRe.test(content)) {
|
|
@@ -26996,8 +26964,7 @@ async function checkNetlifyMiddleware(cwd) {
|
|
|
26996
26964
|
}
|
|
26997
26965
|
return { id: "middleware.netlify", title: "Proxy / middleware", level: "ok", message: `${rel} present` };
|
|
26998
26966
|
}
|
|
26999
|
-
const
|
|
27000
|
-
for (const rel of middlewareFiles) {
|
|
26967
|
+
for (const rel of NEXT_MIDDLEWARE_FILES) {
|
|
27001
26968
|
const content = await readFileOrNull(path12.join(cwd, rel));
|
|
27002
26969
|
if (content === null) continue;
|
|
27003
26970
|
if (/runtime\s*[:=]\s*['"]nodejs['"]/.test(content)) {
|
|
@@ -27192,8 +27159,8 @@ async function statusCommand(options) {
|
|
|
27192
27159
|
|
|
27193
27160
|
// src/og/pages.ts
|
|
27194
27161
|
var DYNAMIC = "*";
|
|
27195
|
-
function pathSegments(
|
|
27196
|
-
return
|
|
27162
|
+
function pathSegments(path30) {
|
|
27163
|
+
return path30.split("/").filter(Boolean);
|
|
27197
27164
|
}
|
|
27198
27165
|
function stripBrandSuffix(title, brand) {
|
|
27199
27166
|
const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
|
|
@@ -27201,13 +27168,13 @@ function stripBrandSuffix(title, brand) {
|
|
|
27201
27168
|
if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
|
|
27202
27169
|
return cleaned;
|
|
27203
27170
|
}
|
|
27204
|
-
function titleFromPath(
|
|
27205
|
-
const last = pathSegments(
|
|
27171
|
+
function titleFromPath(path30) {
|
|
27172
|
+
const last = pathSegments(path30).filter((s) => s !== DYNAMIC).pop();
|
|
27206
27173
|
if (!last) return "Home";
|
|
27207
27174
|
return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
|
|
27208
27175
|
}
|
|
27209
|
-
function kickerFromPath(
|
|
27210
|
-
const parts = pathSegments(
|
|
27176
|
+
function kickerFromPath(path30, fallback) {
|
|
27177
|
+
const parts = pathSegments(path30);
|
|
27211
27178
|
const section = parts.includes(DYNAMIC) ? parts.filter((s) => s !== DYNAMIC) : parts.slice(0, -1);
|
|
27212
27179
|
if (!section.length) return fallback;
|
|
27213
27180
|
return section.join(" / ").replace(/[-_]+/g, " ");
|
|
@@ -27231,8 +27198,8 @@ function kickerIsRedundant(kicker, title) {
|
|
|
27231
27198
|
const titleWords = new Set(t.split(" "));
|
|
27232
27199
|
return k2.split(" ").every((w) => titleWords.has(w));
|
|
27233
27200
|
}
|
|
27234
|
-
function slugForPath(
|
|
27235
|
-
const segments = pathSegments(
|
|
27201
|
+
function slugForPath(path30) {
|
|
27202
|
+
const segments = pathSegments(path30);
|
|
27236
27203
|
if (!segments.length) return "home";
|
|
27237
27204
|
return segments.map((s) => s === DYNAMIC ? "any" : s).join("-").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
|
|
27238
27205
|
}
|
|
@@ -27393,6 +27360,9 @@ async function compressCard(pngPath, cwd) {
|
|
|
27393
27360
|
return pngPath;
|
|
27394
27361
|
}
|
|
27395
27362
|
}
|
|
27363
|
+
function codeOgImageFile(dir) {
|
|
27364
|
+
return findConventionFile(dir, "opengraph-image");
|
|
27365
|
+
}
|
|
27396
27366
|
function discoverDynamicSegments(appDir) {
|
|
27397
27367
|
const found = [];
|
|
27398
27368
|
const walk = (dir, urlSegments, pattern) => {
|
|
@@ -27406,8 +27376,7 @@ function discoverDynamicSegments(appDir) {
|
|
|
27406
27376
|
const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
|
|
27407
27377
|
const nextPattern = isGroup ? pattern : [...pattern, isDynamic ? DYNAMIC : entry.name];
|
|
27408
27378
|
if (isDynamic) {
|
|
27409
|
-
|
|
27410
|
-
if (hasPage) {
|
|
27379
|
+
if (hasPageFile(full)) {
|
|
27411
27380
|
found.push({ dir: full, path: `/${nextPattern.join("/")}`, parent: `/${urlSegments.join("/")}` });
|
|
27412
27381
|
}
|
|
27413
27382
|
}
|
|
@@ -27560,9 +27529,19 @@ async function runOg(options) {
|
|
|
27560
27529
|
});
|
|
27561
27530
|
cardKeyFix = CARD_KEY_FIX;
|
|
27562
27531
|
}
|
|
27563
|
-
const
|
|
27532
|
+
const placed = targets.map((route) => ({ ...route, dir: route.dir ?? routeOutputDir(appDir, route.path) }));
|
|
27533
|
+
const toRender = placed.filter((route) => !codeOgImageFile(route.dir));
|
|
27534
|
+
for (const route of placed.filter((r) => codeOgImageFile(r.dir))) {
|
|
27535
|
+
for (const ext2 of ["png", "jpg", "jpeg"]) {
|
|
27536
|
+
await fs3.rm(path12.join(route.dir, `opengraph-image.${ext2}`), { force: true });
|
|
27537
|
+
}
|
|
27538
|
+
const file = path12.relative(cwd, codeOgImageFile(route.dir));
|
|
27539
|
+
console.log(source_default.gray(` \u21B7 ${route.path} keeps its own ${file}`));
|
|
27540
|
+
checks.push({ id: "og.code-card", title: route.path, level: "ok", message: `Code-based card kept: ${file}` });
|
|
27541
|
+
}
|
|
27542
|
+
const reports = await pooled(toRender, RENDER_CONCURRENCY, async (route, i) => {
|
|
27564
27543
|
const pageConfig = pageCardConfig(config2, route, brand);
|
|
27565
|
-
const dir = route.dir
|
|
27544
|
+
const dir = route.dir;
|
|
27566
27545
|
for (const ext2 of ["png", "jpg", "jpeg"]) {
|
|
27567
27546
|
await fs3.rm(path12.join(dir, `opengraph-image.${ext2}`), { force: true });
|
|
27568
27547
|
}
|
|
@@ -31235,7 +31214,7 @@ async function syncCommand2(options) {
|
|
|
31235
31214
|
}
|
|
31236
31215
|
async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
|
|
31237
31216
|
const spinner = ora("Discovering pages...").start();
|
|
31238
|
-
const appDir =
|
|
31217
|
+
const appDir = findAppDirForDiscovery();
|
|
31239
31218
|
if (!appDir) {
|
|
31240
31219
|
spinner.fail("Could not find app directory");
|
|
31241
31220
|
return;
|
|
@@ -31296,18 +31275,6 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
|
|
|
31296
31275
|
syncSpinner.fail(`Sync failed: ${error2.message}`);
|
|
31297
31276
|
}
|
|
31298
31277
|
}
|
|
31299
|
-
function findAppDir() {
|
|
31300
|
-
const candidates = [
|
|
31301
|
-
path12.join(process.cwd(), "app"),
|
|
31302
|
-
path12.join(process.cwd(), "src", "app")
|
|
31303
|
-
];
|
|
31304
|
-
for (const candidate of candidates) {
|
|
31305
|
-
if (existsSync(candidate)) {
|
|
31306
|
-
return candidate;
|
|
31307
|
-
}
|
|
31308
|
-
}
|
|
31309
|
-
return null;
|
|
31310
|
-
}
|
|
31311
31278
|
function discoverPages(appDir, currentPath = "", pages = []) {
|
|
31312
31279
|
const fullPath = path12.join(appDir, currentPath);
|
|
31313
31280
|
if (!existsSync(fullPath)) {
|
|
@@ -31607,7 +31574,7 @@ async function discoverSchemaUsage(appDir) {
|
|
|
31607
31574
|
return usages;
|
|
31608
31575
|
}
|
|
31609
31576
|
async function syncSchemasToPortal(apiUrl, apiKey, dryRun) {
|
|
31610
|
-
const appDir =
|
|
31577
|
+
const appDir = findAppDirForDiscovery();
|
|
31611
31578
|
if (!appDir) {
|
|
31612
31579
|
console.log(source_default.gray(" No app directory found"));
|
|
31613
31580
|
return;
|
|
@@ -31650,7 +31617,7 @@ async function apiRoutesCommand(options) {
|
|
|
31650
31617
|
console.log("");
|
|
31651
31618
|
console.log(source_default.bold(" Site-Kit API Routes"));
|
|
31652
31619
|
console.log("");
|
|
31653
|
-
const appDir =
|
|
31620
|
+
const appDir = findAppDirForDiscovery();
|
|
31654
31621
|
if (!appDir) {
|
|
31655
31622
|
console.log(source_default.red(" \u2717 Could not find app directory"));
|
|
31656
31623
|
console.log(source_default.gray(" Make sure you are in a Next.js project with an app directory"));
|
|
@@ -31693,18 +31660,6 @@ async function apiRoutesCommand(options) {
|
|
|
31693
31660
|
spinner.fail(`Failed to create API routes: ${error2.message}`);
|
|
31694
31661
|
}
|
|
31695
31662
|
}
|
|
31696
|
-
function findAppDir2() {
|
|
31697
|
-
const candidates = [
|
|
31698
|
-
path12.join(process.cwd(), "app"),
|
|
31699
|
-
path12.join(process.cwd(), "src", "app")
|
|
31700
|
-
];
|
|
31701
|
-
for (const candidate of candidates) {
|
|
31702
|
-
if (existsSync(candidate)) {
|
|
31703
|
-
return candidate;
|
|
31704
|
-
}
|
|
31705
|
-
}
|
|
31706
|
-
return null;
|
|
31707
|
-
}
|
|
31708
31663
|
function generateRouteHandler() {
|
|
31709
31664
|
return `/**
|
|
31710
31665
|
* Sonor API Proxy
|
|
@@ -31919,7 +31874,7 @@ async function scaffoldCommand(options) {
|
|
|
31919
31874
|
);
|
|
31920
31875
|
console.log("");
|
|
31921
31876
|
const cwd = process.cwd();
|
|
31922
|
-
const appDir =
|
|
31877
|
+
const appDir = findAppDirForDiscovery(cwd);
|
|
31923
31878
|
if (!appDir) {
|
|
31924
31879
|
console.log(source_default.red(" \u2717 No app directory found (app/ or src/app/)"));
|
|
31925
31880
|
process.exit(1);
|
|
@@ -31932,8 +31887,8 @@ async function scaffoldCommand(options) {
|
|
|
31932
31887
|
|
|
31933
31888
|
export default createSitemap({
|
|
31934
31889
|
// baseUrl auto-resolved from Portal via API key
|
|
31935
|
-
|
|
31936
|
-
|
|
31890
|
+
// llms.txt stays out of the sitemap on purpose: it's a plain-text duplicate
|
|
31891
|
+
// of these pages, and AI crawlers find it at /llms.txt anyway.
|
|
31937
31892
|
// optimizedLLMsTxt: true, // optional: static build writes optimized llms (CI)
|
|
31938
31893
|
// llmsPublicSummaryOnly: true, // optional: page list from Portal public summaries only
|
|
31939
31894
|
// additionalPaths: async () => [...],
|
|
@@ -31969,13 +31924,13 @@ export const GET = createLLMsFullTxtHandler({ preferStatic: true })
|
|
|
31969
31924
|
files.push(
|
|
31970
31925
|
{
|
|
31971
31926
|
path: path12.join(cwd, "proxy.ts"),
|
|
31972
|
-
label: "Proxy (security headers
|
|
31927
|
+
label: "Proxy (security headers, managed redirects)",
|
|
31973
31928
|
content: `import { createProxy } from '@sonordev/site-kit/proxy'
|
|
31974
31929
|
|
|
31975
|
-
// redirects
|
|
31976
|
-
//
|
|
31977
|
-
//
|
|
31978
|
-
export default createProxy({ redirects:
|
|
31930
|
+
// Sonor-managed redirects apply here. The rule list is cached in memory for
|
|
31931
|
+
// five minutes, so page loads rarely wait on it. Don't move them into
|
|
31932
|
+
// app/not-found.tsx: reading request headers there makes every page dynamic.
|
|
31933
|
+
export default createProxy({ redirects: true })
|
|
31979
31934
|
|
|
31980
31935
|
// Inlined on purpose: Next statically parses \`config.matcher\` at build time
|
|
31981
31936
|
// and rejects an imported value (Turbopack build error). Keep in sync with
|
|
@@ -31997,18 +31952,11 @@ export const GET = createManifest()
|
|
|
31997
31952
|
},
|
|
31998
31953
|
{
|
|
31999
31954
|
path: path12.join(appDir, "not-found.tsx"),
|
|
32000
|
-
label: "404 Page
|
|
32001
|
-
content:
|
|
32002
|
-
|
|
32003
|
-
|
|
32004
|
-
export default
|
|
32005
|
-
// Sonor-managed redirects resolve here, at the only place they can matter:
|
|
32006
|
-
// a URL that would otherwise 404. Successful page loads pay nothing.
|
|
32007
|
-
const managed = await resolveManagedRedirect()
|
|
32008
|
-
if (managed) {
|
|
32009
|
-
;(managed.permanent ? permanentRedirect : redirect)(managed.destination)
|
|
32010
|
-
}
|
|
32011
|
-
|
|
31955
|
+
label: "404 Page",
|
|
31956
|
+
content: `// Keep this component free of request APIs (headers, cookies). Next
|
|
31957
|
+
// renders the root 404 inside every page, so one headers() call here makes
|
|
31958
|
+
// the whole site dynamic. Managed redirects run in proxy.ts instead.
|
|
31959
|
+
export default function NotFound() {
|
|
32012
31960
|
return (
|
|
32013
31961
|
<div style={{ textAlign: 'center', padding: '4rem 1rem' }}>
|
|
32014
31962
|
<h1 style={{ fontSize: '3rem', fontWeight: 700, marginBottom: '0.5rem' }}>404</h1>
|
|
@@ -32128,9 +32076,9 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
|
|
|
32128
32076
|
console.log(source_default.yellow(" [DRY RUN] Would create:"));
|
|
32129
32077
|
for (const f of files) {
|
|
32130
32078
|
const rel = path12.relative(cwd, f.path);
|
|
32131
|
-
const
|
|
32079
|
+
const exists2 = existsSync(f.path);
|
|
32132
32080
|
console.log(
|
|
32133
|
-
source_default.gray(` ${rel}`) + (
|
|
32081
|
+
source_default.gray(` ${rel}`) + (exists2 ? source_default.yellow(" (exists, would skip)") : "")
|
|
32134
32082
|
);
|
|
32135
32083
|
}
|
|
32136
32084
|
console.log("");
|
|
@@ -32194,17 +32142,209 @@ SONOR_API_KEY=sonor_your-project-uuid_your-secret-key
|
|
|
32194
32142
|
console.log("");
|
|
32195
32143
|
}
|
|
32196
32144
|
}
|
|
32197
|
-
|
|
32198
|
-
|
|
32199
|
-
|
|
32200
|
-
|
|
32201
|
-
|
|
32202
|
-
|
|
32203
|
-
|
|
32204
|
-
|
|
32145
|
+
var LLMS_FILES = [
|
|
32146
|
+
{ path: "/llms.txt", handler: "createLLMsTxtHandler" },
|
|
32147
|
+
{ path: "/llms-full.txt", handler: "createLLMsFullTxtHandler" }
|
|
32148
|
+
];
|
|
32149
|
+
var NEXT_CONFIGS = ["next.config.ts", "next.config.mts", "next.config.mjs", "next.config.js", "next.config.cjs"];
|
|
32150
|
+
function read(cwd, rel) {
|
|
32151
|
+
try {
|
|
32152
|
+
return fs__default.readFileSync(path12.join(cwd, rel), "utf-8");
|
|
32153
|
+
} catch {
|
|
32154
|
+
return "";
|
|
32155
|
+
}
|
|
32156
|
+
}
|
|
32157
|
+
function exists(cwd, rel) {
|
|
32158
|
+
try {
|
|
32159
|
+
return fs__default.existsSync(path12.join(cwd, rel));
|
|
32160
|
+
} catch {
|
|
32161
|
+
return false;
|
|
32205
32162
|
}
|
|
32163
|
+
}
|
|
32164
|
+
function patternMatches(pattern, urlPath) {
|
|
32165
|
+
const re2 = pattern.trim().split(/\(\.\*\)|:\w+\*|\*/).map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
32166
|
+
return new RegExp(`^${re2}$`).test(urlPath);
|
|
32167
|
+
}
|
|
32168
|
+
var NOINDEX = /noindex/i;
|
|
32169
|
+
function netlifyTomlNoindex(toml, urlPath) {
|
|
32170
|
+
const blocks = [];
|
|
32171
|
+
for (const line of toml.split("\n")) {
|
|
32172
|
+
const header = line.match(/^\s*\[\[?\s*([^\]]+?)\s*\]\]?\s*$/);
|
|
32173
|
+
if (header && header[1] !== "headers.values") blocks.push(line);
|
|
32174
|
+
else if (blocks.length) blocks[blocks.length - 1] += `
|
|
32175
|
+
${line}`;
|
|
32176
|
+
}
|
|
32177
|
+
return blocks.some((block) => {
|
|
32178
|
+
if (!/^\s*\[\[\s*headers\s*\]\]/.test(block)) return false;
|
|
32179
|
+
const pattern = block.match(/^\s*for\s*=\s*["']([^"']+)["']/m)?.[1];
|
|
32180
|
+
const value = block.match(/^\s*["']?X-Robots-Tag["']?\s*=\s*["']([^"']*)["']/im)?.[1];
|
|
32181
|
+
return !!pattern && !!value && NOINDEX.test(value) && patternMatches(pattern, urlPath);
|
|
32182
|
+
});
|
|
32183
|
+
}
|
|
32184
|
+
function headersFileNoindex(text, urlPath) {
|
|
32185
|
+
let current = null;
|
|
32186
|
+
for (const line of text.split("\n")) {
|
|
32187
|
+
if (!line.trim() || line.trim().startsWith("#")) continue;
|
|
32188
|
+
if (!/^\s/.test(line)) {
|
|
32189
|
+
current = line.trim();
|
|
32190
|
+
continue;
|
|
32191
|
+
}
|
|
32192
|
+
const m = line.match(/^\s+X-Robots-Tag\s*:\s*(.+)$/i);
|
|
32193
|
+
if (current && m && NOINDEX.test(m[1]) && patternMatches(current, urlPath)) return true;
|
|
32194
|
+
}
|
|
32195
|
+
return false;
|
|
32196
|
+
}
|
|
32197
|
+
function vercelJsonNoindex(text, urlPath) {
|
|
32198
|
+
try {
|
|
32199
|
+
const json = JSON.parse(text);
|
|
32200
|
+
return (json.headers ?? []).some(
|
|
32201
|
+
(rule) => !!rule.source && patternMatches(rule.source, urlPath) && (rule.headers ?? []).some((h) => /^x-robots-tag$/i.test(h.key ?? "") && NOINDEX.test(h.value ?? ""))
|
|
32202
|
+
);
|
|
32203
|
+
} catch {
|
|
32204
|
+
return false;
|
|
32205
|
+
}
|
|
32206
|
+
}
|
|
32207
|
+
function findHostNoindex(cwd, urlPath) {
|
|
32208
|
+
const toml = read(cwd, "netlify.toml");
|
|
32209
|
+
if (toml && netlifyTomlNoindex(toml, urlPath)) return "netlify.toml";
|
|
32210
|
+
const headers = read(cwd, "public/_headers");
|
|
32211
|
+
if (headers && headersFileNoindex(headers, urlPath)) return "public/_headers";
|
|
32212
|
+
const vercel = read(cwd, "vercel.json");
|
|
32213
|
+
if (vercel && vercelJsonNoindex(vercel, urlPath)) return "vercel.json";
|
|
32206
32214
|
return null;
|
|
32207
32215
|
}
|
|
32216
|
+
var LINK_DISCOVERY_LINE = /^.*\bLink\b.*(llms[^\n]*describedby|describedby[^\n]*llms).*$/im;
|
|
32217
|
+
function findDiscoverySource(cwd) {
|
|
32218
|
+
for (const rel of findProxyFiles(cwd)) {
|
|
32219
|
+
const src = read(cwd, rel);
|
|
32220
|
+
const viaFactory = /\bcreate(Proxy|Middleware)\s*\(/.test(src) && /\bllmsDiscovery\b(?!\s*:\s*false\b)/.test(src);
|
|
32221
|
+
if (viaFactory) return `${rel} (createProxy llmsDiscovery)`;
|
|
32222
|
+
if (src.includes("buildAiDiscoveryHeaders")) return `${rel} (buildAiDiscoveryHeaders)`;
|
|
32223
|
+
}
|
|
32224
|
+
for (const rel of NEXT_CONFIGS) {
|
|
32225
|
+
const src = read(cwd, rel);
|
|
32226
|
+
if (!src) continue;
|
|
32227
|
+
if (/\bllmsTxtDiscoveryLink\s*:(?!\s*false\b)/.test(src)) return `${rel} (llmsTxtDiscoveryLink)`;
|
|
32228
|
+
if (src.includes("buildAiDiscoveryHeaders")) return `${rel} (buildAiDiscoveryHeaders)`;
|
|
32229
|
+
break;
|
|
32230
|
+
}
|
|
32231
|
+
const layout = findRootLayout(cwd);
|
|
32232
|
+
if (layout) {
|
|
32233
|
+
const src = read(cwd, path12.relative(cwd, layout));
|
|
32234
|
+
if (src.includes("buildAiDiscoveryHeaders") || src.includes("llmsTxtDiscoveryLink")) {
|
|
32235
|
+
return path12.relative(cwd, layout);
|
|
32236
|
+
}
|
|
32237
|
+
}
|
|
32238
|
+
for (const rel of ["netlify.toml", "public/_headers"]) {
|
|
32239
|
+
if (LINK_DISCOVERY_LINE.test(read(cwd, rel))) return rel;
|
|
32240
|
+
}
|
|
32241
|
+
return null;
|
|
32242
|
+
}
|
|
32243
|
+
function readGeoWiring(cwd) {
|
|
32244
|
+
const appDir = NEXT_APP_DIRS.find((rel) => exists(cwd, rel)) ?? null;
|
|
32245
|
+
const sitemap = findSitemapRoute(cwd);
|
|
32246
|
+
const sitemapSrc = sitemap ? read(cwd, sitemap) : "";
|
|
32247
|
+
const sitemapListsLlms = /\bincludeLlms(Full)?TxtInSitemap\s*:\s*true\b/.test(sitemapSrc) || /['"`/]llms(-full)?\.txt['"`]/.test(sitemapSrc);
|
|
32248
|
+
const sitemapWritesStatic = /\bcreateSitemap\s*\(/.test(sitemapSrc);
|
|
32249
|
+
const writesLlms = sitemapWritesStatic && !/\boptimizedLLMsTxt\s*:\s*false\b/.test(sitemapSrc);
|
|
32250
|
+
const writesLlmsFull = writesLlms && /\boptimizedLLMsFullTxt\s*:\s*true\b/.test(sitemapSrc);
|
|
32251
|
+
const llms = LLMS_FILES.map(({ path: urlPath, handler }) => {
|
|
32252
|
+
const file = urlPath.slice(1);
|
|
32253
|
+
const routeAbs = appDir ? findConventionFile(path12.join(cwd, appDir, file), "route") : null;
|
|
32254
|
+
const route = routeAbs ? path12.relative(cwd, routeAbs) : null;
|
|
32255
|
+
const routeSrc = route ? read(cwd, route) : "";
|
|
32256
|
+
const publicFile = exists(cwd, path12.join("public", file));
|
|
32257
|
+
const built = urlPath === "/llms.txt" ? writesLlms : writesLlmsFull;
|
|
32258
|
+
return {
|
|
32259
|
+
path: urlPath,
|
|
32260
|
+
route,
|
|
32261
|
+
routeUsesKitHandler: routeSrc.includes(handler),
|
|
32262
|
+
routeOptsOutOfNoindex: /\bnoindex\s*:\s*false\b/.test(routeSrc),
|
|
32263
|
+
routeSetsNoindex: /X-Robots-Tag/i.test(routeSrc) && NOINDEX.test(routeSrc),
|
|
32264
|
+
servedStatic: publicFile || built,
|
|
32265
|
+
staticReason: publicFile ? `public/${file}` : built ? `public/${file} (written by createSitemap at build)` : null,
|
|
32266
|
+
hostNoindex: findHostNoindex(cwd, urlPath)
|
|
32267
|
+
};
|
|
32268
|
+
});
|
|
32269
|
+
return { appDir, llms, sitemap, sitemapListsLlms, discovery: findDiscoverySource(cwd) };
|
|
32270
|
+
}
|
|
32271
|
+
var DISCOVERY_FIX = "Add llmsDiscovery to the proxy: createProxy({ llmsDiscovery: { siteUrl } }) in proxy.ts. Or withSiteKitConfig({ llmsTxtDiscoveryLink: true }) in next.config.";
|
|
32272
|
+
var SITEMAP_FIX = "Drop includeLlmsTxtInSitemap / includeLlmsFullTxtInSitemap (and any hand-added /llms*.txt entry) from the sitemap. A sitemap lists indexable HTML pages; AI crawlers find llms.txt at /llms.txt.";
|
|
32273
|
+
function hostNoindexFix(urlPath) {
|
|
32274
|
+
return `The CDN serves it before any route handler runs, so set the header in host config. netlify.toml: [[headers]] for = "${urlPath}" [headers.values] X-Robots-Tag = "noindex"`;
|
|
32275
|
+
}
|
|
32276
|
+
function judgeGeoWiring(facts) {
|
|
32277
|
+
const rows = [];
|
|
32278
|
+
for (const f of facts.llms) {
|
|
32279
|
+
const name = f.path.slice(1);
|
|
32280
|
+
const id = f.path === "/llms.txt" ? "llms" : "llms-full";
|
|
32281
|
+
const served = !!f.route || f.servedStatic;
|
|
32282
|
+
rows.push(
|
|
32283
|
+
served ? { id: `${id}.served`, label: `${name} served`, level: "ok", detail: f.route ?? f.staticReason ?? void 0 } : {
|
|
32284
|
+
id: `${id}.served`,
|
|
32285
|
+
label: `${name} served`,
|
|
32286
|
+
level: "fail",
|
|
32287
|
+
detail: `no ${facts.appDir ?? "app"}/${name}/route.* and no public/${name}`,
|
|
32288
|
+
fix: "Run: sonor-setup geo --ensure-routes"
|
|
32289
|
+
}
|
|
32290
|
+
);
|
|
32291
|
+
}
|
|
32292
|
+
if (!facts.sitemap) {
|
|
32293
|
+
rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "info", detail: "no sitemap route to check" });
|
|
32294
|
+
} else if (facts.sitemapListsLlms) {
|
|
32295
|
+
rows.push({
|
|
32296
|
+
id: "geo.sitemap",
|
|
32297
|
+
label: "sitemap leaves llms files out",
|
|
32298
|
+
level: "warn",
|
|
32299
|
+
detail: `${facts.sitemap} lists /llms.txt, inviting search engines to index a thin plain-text duplicate`,
|
|
32300
|
+
fix: SITEMAP_FIX
|
|
32301
|
+
});
|
|
32302
|
+
} else {
|
|
32303
|
+
rows.push({ id: "geo.sitemap", label: "sitemap leaves llms files out", level: "ok", detail: facts.sitemap });
|
|
32304
|
+
}
|
|
32305
|
+
rows.push(
|
|
32306
|
+
facts.discovery ? { id: "geo.discovery", label: 'discovery header (Link rel="describedby")', level: "ok", detail: facts.discovery } : {
|
|
32307
|
+
id: "geo.discovery",
|
|
32308
|
+
label: 'discovery header (Link rel="describedby")',
|
|
32309
|
+
level: "fail",
|
|
32310
|
+
detail: "not wired in proxy, next.config, root layout, or host config",
|
|
32311
|
+
fix: DISCOVERY_FIX
|
|
32312
|
+
}
|
|
32313
|
+
);
|
|
32314
|
+
for (const f of facts.llms) {
|
|
32315
|
+
if (!f.route && !f.servedStatic) continue;
|
|
32316
|
+
const name = f.path.slice(1);
|
|
32317
|
+
const id = `${f.path === "/llms.txt" ? "llms" : "llms-full"}.noindex`;
|
|
32318
|
+
const label = `${name} sends X-Robots-Tag: noindex`;
|
|
32319
|
+
if (f.servedStatic) {
|
|
32320
|
+
rows.push(
|
|
32321
|
+
f.hostNoindex ? { id, label, level: "ok", detail: f.hostNoindex } : { id, label, level: "warn", detail: `${f.staticReason} is served without it`, fix: hostNoindexFix(f.path) }
|
|
32322
|
+
);
|
|
32323
|
+
continue;
|
|
32324
|
+
}
|
|
32325
|
+
if (f.hostNoindex) {
|
|
32326
|
+
rows.push({ id, label, level: "ok", detail: f.hostNoindex });
|
|
32327
|
+
} else if (f.routeUsesKitHandler && !f.routeOptsOutOfNoindex) {
|
|
32328
|
+
rows.push({ id, label, level: "ok", detail: `${f.route} (site-kit handler default)` });
|
|
32329
|
+
} else if (f.routeSetsNoindex) {
|
|
32330
|
+
rows.push({ id, label, level: "ok", detail: f.route });
|
|
32331
|
+
} else {
|
|
32332
|
+
rows.push({
|
|
32333
|
+
id,
|
|
32334
|
+
label,
|
|
32335
|
+
level: "warn",
|
|
32336
|
+
detail: f.routeOptsOutOfNoindex ? `${f.route} passes noindex: false` : `${f.route} doesn't set it`,
|
|
32337
|
+
fix: f.routeOptsOutOfNoindex ? "Drop noindex: false unless you want llms.txt in search results." : "Serve it with createLLMsTxtHandler (sends the header by default), or add X-Robots-Tag: noindex to the response."
|
|
32338
|
+
});
|
|
32339
|
+
}
|
|
32340
|
+
}
|
|
32341
|
+
return rows;
|
|
32342
|
+
}
|
|
32343
|
+
function checkGeoWiring(cwd) {
|
|
32344
|
+
return judgeGeoWiring(readGeoWiring(cwd));
|
|
32345
|
+
}
|
|
32346
|
+
|
|
32347
|
+
// src/cli/commands/geo.ts
|
|
32208
32348
|
var LLMS_ROUTE = `import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'
|
|
32209
32349
|
|
|
32210
32350
|
export const GET = createLLMsTxtHandler({ preferStatic: true })
|
|
@@ -32213,40 +32353,36 @@ var LLMS_FULL_ROUTE = `import { createLLMsFullTxtHandler } from '@sonordev/site-
|
|
|
32213
32353
|
|
|
32214
32354
|
export const GET = createLLMsFullTxtHandler({ preferStatic: true })
|
|
32215
32355
|
`;
|
|
32216
|
-
|
|
32217
|
-
|
|
32218
|
-
|
|
32219
|
-
|
|
32220
|
-
|
|
32221
|
-
|
|
32222
|
-
}
|
|
32223
|
-
}
|
|
32356
|
+
var ICON = {
|
|
32357
|
+
ok: source_default.green(" \u2713 "),
|
|
32358
|
+
info: source_default.gray(" \xB7 "),
|
|
32359
|
+
warn: source_default.yellow(" ! "),
|
|
32360
|
+
fail: source_default.red(" \u2717 ")
|
|
32361
|
+
};
|
|
32224
32362
|
async function ensureLlmsRouteFiles(appDir, dryRun) {
|
|
32225
|
-
const llms = path12.join(appDir, "llms.txt", "route.ts");
|
|
32226
|
-
const llmsFull = path12.join(appDir, "llms-full.txt", "route.ts");
|
|
32227
32363
|
let n5 = 0;
|
|
32228
32364
|
if (dryRun) return 0;
|
|
32229
|
-
|
|
32230
|
-
|
|
32231
|
-
|
|
32232
|
-
|
|
32233
|
-
|
|
32234
|
-
|
|
32235
|
-
await fs3.mkdir(path12.dirname(
|
|
32236
|
-
await fs3.writeFile(
|
|
32365
|
+
for (const [dir, source] of [
|
|
32366
|
+
["llms.txt", LLMS_ROUTE],
|
|
32367
|
+
["llms-full.txt", LLMS_FULL_ROUTE]
|
|
32368
|
+
]) {
|
|
32369
|
+
if (findConventionFile(path12.join(appDir, dir), "route")) continue;
|
|
32370
|
+
const file = path12.join(appDir, dir, "route.ts");
|
|
32371
|
+
await fs3.mkdir(path12.dirname(file), { recursive: true });
|
|
32372
|
+
await fs3.writeFile(file, source, "utf-8");
|
|
32237
32373
|
n5++;
|
|
32238
32374
|
}
|
|
32239
32375
|
return n5;
|
|
32240
32376
|
}
|
|
32241
32377
|
async function geoCommand(options) {
|
|
32242
32378
|
if (options.forInstall) {
|
|
32243
|
-
const appDir2 =
|
|
32379
|
+
const appDir2 = findAppDirForDiscovery();
|
|
32244
32380
|
if (!appDir2) return;
|
|
32245
32381
|
const created = await ensureLlmsRouteFiles(appDir2, options.dryRun);
|
|
32246
32382
|
if (created > 0) {
|
|
32247
32383
|
console.log(
|
|
32248
32384
|
source_default.cyan(
|
|
32249
|
-
`[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL
|
|
32385
|
+
`[@sonordev/site-kit] Created ${created} llms route file(s). Set NEXT_PUBLIC_SITE_URL and add createProxy({ llmsDiscovery: { siteUrl } }) to proxy.ts when ready.`
|
|
32250
32386
|
)
|
|
32251
32387
|
);
|
|
32252
32388
|
}
|
|
@@ -32261,59 +32397,20 @@ async function geoCommand(options) {
|
|
|
32261
32397
|
)
|
|
32262
32398
|
);
|
|
32263
32399
|
console.log("");
|
|
32264
|
-
const appDir =
|
|
32400
|
+
const appDir = findAppDirForDiscovery();
|
|
32265
32401
|
if (!appDir) {
|
|
32266
32402
|
console.log(source_default.red(" \u2717 No app directory (app/ or src/app/)"));
|
|
32267
32403
|
process.exit(1);
|
|
32268
32404
|
}
|
|
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");
|
|
32272
32405
|
let allOk = true;
|
|
32273
|
-
const row
|
|
32274
|
-
if (
|
|
32275
|
-
|
|
32276
|
-
|
|
32277
|
-
)
|
|
32278
|
-
|
|
32279
|
-
row("llms.txt route", existsSync(llms));
|
|
32280
|
-
row("llms-full.txt route", existsSync(llmsFull));
|
|
32281
|
-
let sitemapHasLlms = false;
|
|
32282
|
-
if (existsSync(sitemap)) {
|
|
32283
|
-
const txt = await readIfExists(sitemap);
|
|
32284
|
-
sitemapHasLlms = txt.includes("includeLlmsTxtInSitemap") || txt.includes("includeLlmsFullTxtInSitemap");
|
|
32285
|
-
row("sitemap.ts lists llms URLs", sitemapHasLlms);
|
|
32286
|
-
} else {
|
|
32287
|
-
row("sitemap.ts lists llms URLs", false);
|
|
32288
|
-
}
|
|
32289
|
-
const nextConfigs = [
|
|
32290
|
-
path12.join(cwd, "next.config.ts"),
|
|
32291
|
-
path12.join(cwd, "next.config.mjs"),
|
|
32292
|
-
path12.join(cwd, "next.config.js")
|
|
32293
|
-
];
|
|
32294
|
-
let nextCfg = "";
|
|
32295
|
-
for (const p of nextConfigs) {
|
|
32296
|
-
if (existsSync(p)) {
|
|
32297
|
-
nextCfg = await readIfExists(p);
|
|
32298
|
-
break;
|
|
32406
|
+
for (const row of checkGeoWiring(cwd)) {
|
|
32407
|
+
if (row.level === "fail") allOk = false;
|
|
32408
|
+
const detail = row.detail ? source_default.gray(` ${row.detail}`) : "";
|
|
32409
|
+
console.log(`${ICON[row.level]}${row.label}${detail}`);
|
|
32410
|
+
if (row.fix && (row.level === "fail" || row.level === "warn")) {
|
|
32411
|
+
console.log(source_default.gray(` ${row.fix}`));
|
|
32299
32412
|
}
|
|
32300
32413
|
}
|
|
32301
|
-
const layoutCandidates = [
|
|
32302
|
-
path12.join(appDir, "layout.tsx"),
|
|
32303
|
-
path12.join(appDir, "layout.jsx"),
|
|
32304
|
-
path12.join(appDir, "layout.js")
|
|
32305
|
-
];
|
|
32306
|
-
let layoutTxt = "";
|
|
32307
|
-
for (const p of layoutCandidates) {
|
|
32308
|
-
layoutTxt = await readIfExists(p);
|
|
32309
|
-
if (layoutTxt) break;
|
|
32310
|
-
}
|
|
32311
|
-
const hasLayoutDiscovery = layoutTxt.includes("buildAiDiscoveryHeaders") || layoutTxt.includes("llmsTxtDiscoveryLink");
|
|
32312
|
-
const hasConfigDiscovery = nextCfg.includes("llmsTxtDiscoveryLink");
|
|
32313
|
-
row(
|
|
32314
|
-
"discovery header (next.config or root layout)",
|
|
32315
|
-
hasConfigDiscovery || hasLayoutDiscovery
|
|
32316
|
-
);
|
|
32317
32414
|
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL?.trim() || process.env.SITE_BASE_URL?.trim() || (process.env.VERCEL_URL?.trim() ? `https://${process.env.VERCEL_URL.replace(/\/$/, "")}` : "");
|
|
32318
32415
|
if (siteUrl) {
|
|
32319
32416
|
console.log(source_default.gray(` Public origin (env): ${siteUrl}`));
|
|
@@ -32339,19 +32436,16 @@ async function geoCommand(options) {
|
|
|
32339
32436
|
console.log(source_default.bold(" Automation"));
|
|
32340
32437
|
console.log("");
|
|
32341
32438
|
console.log(
|
|
32342
|
-
source_default.gray(
|
|
32343
|
-
" \u2022 next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })"
|
|
32344
|
-
)
|
|
32439
|
+
source_default.gray(' \u2022 proxy.ts: createProxy({ llmsDiscovery: { siteUrl } }) (Link rel="describedby")')
|
|
32345
32440
|
);
|
|
32346
32441
|
console.log(
|
|
32347
|
-
source_default.gray(
|
|
32348
|
-
" (If you define your own headers() on nextConfig, merge Link manually.)"
|
|
32349
|
-
)
|
|
32442
|
+
source_default.gray(" or next.config: withSiteKitConfig({ llmsTxtDiscoveryLink: true })")
|
|
32350
32443
|
);
|
|
32351
32444
|
console.log(
|
|
32352
|
-
source_default.gray(
|
|
32353
|
-
|
|
32354
|
-
|
|
32445
|
+
source_default.gray(" \u2022 createLLMsTxtHandler sends X-Robots-Tag: noindex; a static public/llms.txt needs it in netlify.toml")
|
|
32446
|
+
);
|
|
32447
|
+
console.log(
|
|
32448
|
+
source_default.gray(" \u2022 Keep llms.txt out of the sitemap: AI crawlers find it at /llms.txt")
|
|
32355
32449
|
);
|
|
32356
32450
|
console.log(
|
|
32357
32451
|
source_default.gray(" \u2022 npx sonor-setup scaffold --minimal (routes + sitemap template)")
|