@sonordev/site-kit 1.5.5 → 2.0.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/dist/AnalyticsProvider-J7UMCBCJ.mjs +4 -0
- package/dist/{AnalyticsProvider-BBLU4U2T.mjs.map → AnalyticsProvider-J7UMCBCJ.mjs.map} +1 -1
- package/dist/AnalyticsProvider-PPDJIGWY.js +25 -0
- package/dist/{AnalyticsProvider-EMDIAAWR.js.map → AnalyticsProvider-PPDJIGWY.js.map} +1 -1
- package/dist/EngageWidget-IDBEBGQR.js +13 -0
- package/dist/{EngageWidget-UHWXXCAX.js.map → EngageWidget-IDBEBGQR.js.map} +1 -1
- package/dist/EngageWidget-SRRI4W7U.mjs +4 -0
- package/dist/{EngageWidget-CVZMTSB6.mjs.map → EngageWidget-SRRI4W7U.mjs.map} +1 -1
- package/dist/SignalBridge-D6W6OLVG.mjs +4 -0
- package/dist/{SignalBridge-WGHMEILW.mjs.map → SignalBridge-D6W6OLVG.mjs.map} +1 -1
- package/dist/SignalBridge-THATXU2R.js +33 -0
- package/dist/{SignalBridge-6UYUZ2CN.js.map → SignalBridge-THATXU2R.js.map} +1 -1
- package/dist/analytics/index.js +9 -9
- package/dist/analytics/index.mjs +2 -2
- package/dist/blog/index.js +75 -75
- package/dist/blog/index.js.map +1 -1
- package/dist/blog/index.mjs +75 -75
- package/dist/blog/index.mjs.map +1 -1
- package/dist/blog/server.js +2 -2
- package/dist/blog/server.js.map +1 -1
- package/dist/blog/server.mjs +2 -2
- package/dist/blog/server.mjs.map +1 -1
- package/dist/brand.css +87 -0
- package/dist/{chunk-ZU6YPEAF.mjs → chunk-2OJCYWSQ.mjs} +85 -73
- package/dist/chunk-2OJCYWSQ.mjs.map +1 -0
- package/dist/{chunk-PM2KQ6YK.mjs → chunk-3CXAWGUP.mjs} +3 -3
- package/dist/{chunk-PM2KQ6YK.mjs.map → chunk-3CXAWGUP.mjs.map} +1 -1
- package/dist/{chunk-36Y7OWES.mjs → chunk-3YQCPLGP.mjs} +4 -4
- package/dist/chunk-3YQCPLGP.mjs.map +1 -0
- package/dist/{chunk-XWWBUC2I.js → chunk-6ZGM7S5O.js} +77 -61
- package/dist/chunk-6ZGM7S5O.js.map +1 -0
- package/dist/{chunk-XFOL6JDF.mjs → chunk-7LAOWIWE.mjs} +4 -4
- package/dist/chunk-7LAOWIWE.mjs.map +1 -0
- package/dist/{chunk-YBTYDBWY.js → chunk-7M3FNAS5.js} +6 -8
- package/dist/chunk-7M3FNAS5.js.map +1 -0
- package/dist/{chunk-4QHHFCAA.mjs → chunk-AOIG5PVY.mjs} +6 -8
- package/dist/chunk-AOIG5PVY.mjs.map +1 -0
- package/dist/{chunk-VZMDH3R4.mjs → chunk-B22WSN4L.mjs} +4 -4
- package/dist/chunk-B22WSN4L.mjs.map +1 -0
- package/dist/{chunk-ELDJDBQL.js → chunk-BVUOATPG.js} +7 -7
- package/dist/chunk-BVUOATPG.js.map +1 -0
- package/dist/{chunk-N24BPFF6.mjs → chunk-CU6OGBKK.mjs} +6 -6
- package/dist/chunk-CU6OGBKK.mjs.map +1 -0
- package/dist/{chunk-NRNK7LXK.mjs → chunk-DWI5ZKPM.mjs} +4 -4
- package/dist/chunk-DWI5ZKPM.mjs.map +1 -0
- package/dist/{chunk-KRPFLF62.mjs → chunk-F5NXD7VQ.mjs} +10 -12
- package/dist/{chunk-KRPFLF62.mjs.map → chunk-F5NXD7VQ.mjs.map} +1 -1
- package/dist/{chunk-PTTDKFL7.js → chunk-FCXQECM7.js} +6 -6
- package/dist/chunk-FCXQECM7.js.map +1 -0
- package/dist/{chunk-DY4K6X3A.js → chunk-GCPPXUAI.js} +6 -6
- package/dist/chunk-GCPPXUAI.js.map +1 -0
- package/dist/{chunk-KJN2C6YE.js → chunk-I34XL5VJ.js} +5 -5
- package/dist/chunk-I34XL5VJ.js.map +1 -0
- package/dist/{chunk-G6VGUAK2.js → chunk-IFVMZFNT.js} +4 -4
- package/dist/chunk-IFVMZFNT.js.map +1 -0
- package/dist/{chunk-FMB2RZDH.mjs → chunk-J4U3IEXL.mjs} +6 -6
- package/dist/chunk-J4U3IEXL.mjs.map +1 -0
- package/dist/{chunk-EUNL6GAL.js → chunk-JP5WGL75.js} +4 -4
- package/dist/chunk-JP5WGL75.js.map +1 -0
- package/dist/{chunk-MG23BS36.js → chunk-L3UB4B74.js} +5 -5
- package/dist/chunk-L3UB4B74.js.map +1 -0
- package/dist/{chunk-FVCQBTNK.mjs → chunk-MSRLAD7F.mjs} +77 -61
- package/dist/chunk-MSRLAD7F.mjs.map +1 -0
- package/dist/{chunk-M5FLRLHI.mjs → chunk-OM6R7CDP.mjs} +3 -3
- package/dist/chunk-OM6R7CDP.mjs.map +1 -0
- package/dist/{chunk-4X5TFGKD.mjs → chunk-P3POHQWW.mjs} +422 -426
- package/dist/chunk-P3POHQWW.mjs.map +1 -0
- package/dist/{chunk-GJD4CFHN.js → chunk-RLNG67S5.js} +7 -7
- package/dist/chunk-RLNG67S5.js.map +1 -0
- package/dist/{chunk-FTSXKDP3.js → chunk-RO6DHV6S.js} +10 -12
- package/dist/{chunk-FTSXKDP3.js.map → chunk-RO6DHV6S.js.map} +1 -1
- package/dist/{chunk-WW7UM7XY.js → chunk-TZAD7CZD.js} +424 -428
- package/dist/chunk-TZAD7CZD.js.map +1 -0
- package/dist/{chunk-TXZNP76P.js → chunk-UD5447TC.js} +13 -15
- package/dist/chunk-UD5447TC.js.map +1 -0
- package/dist/{chunk-TC6TOW2T.js → chunk-UJ757WGI.js} +4 -4
- package/dist/{chunk-TC6TOW2T.js.map → chunk-UJ757WGI.js.map} +1 -1
- package/dist/{chunk-C3A5HXHX.mjs → chunk-V6V6OXS2.mjs} +5 -5
- package/dist/chunk-V6V6OXS2.mjs.map +1 -0
- package/dist/{chunk-X4J33XQD.js → chunk-W6K7MQCC.js} +6 -6
- package/dist/chunk-W6K7MQCC.js.map +1 -0
- package/dist/{chunk-FI2ME55T.mjs → chunk-W7RZ3OTA.mjs} +7 -7
- package/dist/chunk-W7RZ3OTA.mjs.map +1 -0
- package/dist/{chunk-IJ2LWZID.js → chunk-WETCVFIK.js} +85 -73
- package/dist/chunk-WETCVFIK.js.map +1 -0
- package/dist/{chunk-VNAJQKYG.mjs → chunk-WN2PUL6B.mjs} +13 -15
- package/dist/chunk-WN2PUL6B.mjs.map +1 -0
- package/dist/cli/index.js +19339 -3461
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +19331 -3452
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cms/index.d.mts +1 -1
- package/dist/cms/index.d.ts +1 -1
- package/dist/cms/index.js +3 -3
- package/dist/cms/index.js.map +1 -1
- package/dist/cms/index.mjs +2 -2
- package/dist/cms/index.mjs.map +1 -1
- package/dist/cms/server.js +4 -4
- package/dist/cms/server.mjs +1 -1
- package/dist/commerce/index.js +47 -47
- package/dist/commerce/index.mjs +3 -3
- package/dist/engage/index.js +6 -6
- package/dist/engage/index.js.map +1 -1
- package/dist/engage/index.mjs +3 -3
- package/dist/engage/index.mjs.map +1 -1
- package/dist/forms/index.js +379 -84
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +375 -65
- package/dist/forms/index.mjs.map +1 -1
- package/dist/forms/styles.css +312 -0
- package/dist/images/index.js +11 -11
- package/dist/images/index.mjs +2 -2
- package/dist/images/server.js +4 -4
- package/dist/images/server.mjs +1 -1
- package/dist/index.d.mts +4 -131
- package/dist/index.d.ts +4 -131
- package/dist/index.js +85 -1373
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -1294
- package/dist/index.mjs.map +1 -1
- package/dist/layout/client.js +2 -2
- package/dist/layout/client.mjs +1 -1
- package/dist/layout/index.js +21 -11
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/index.mjs +17 -7
- package/dist/layout/index.mjs.map +1 -1
- package/dist/llms/index.d.mts +3 -3
- package/dist/llms/index.d.ts +3 -3
- package/dist/llms/index.js +12 -12
- package/dist/llms/index.js.map +1 -1
- package/dist/llms/index.mjs +2 -2
- package/dist/llms/index.mjs.map +1 -1
- package/dist/manifest/index.js +4 -4
- package/dist/manifest/index.js.map +1 -1
- package/dist/manifest/index.mjs +3 -3
- package/dist/manifest/index.mjs.map +1 -1
- package/dist/middleware/index.js +3 -3
- package/dist/middleware/index.mjs +2 -2
- package/dist/redirects/index.js +6 -6
- package/dist/redirects/index.mjs +2 -2
- package/dist/robots/index.js +3 -3
- package/dist/robots/index.js.map +1 -1
- package/dist/robots/index.mjs +2 -2
- package/dist/robots/index.mjs.map +1 -1
- package/dist/{routing-DZYzyDHw.d.ts → routing-DQ_Et-OP.d.mts} +4 -4
- package/dist/{routing-B5XS-6_W.d.mts → routing-IYiJNIIX.d.ts} +4 -4
- package/dist/seo/index.d.mts +3 -5
- package/dist/seo/index.d.ts +3 -5
- package/dist/seo/index.js +77 -76
- package/dist/seo/index.js.map +1 -1
- package/dist/seo/index.mjs +41 -40
- package/dist/seo/index.mjs.map +1 -1
- package/dist/seo/register-sitemap-cli.js +3 -3
- package/dist/seo/register-sitemap-cli.js.map +1 -1
- package/dist/seo/register-sitemap-cli.mjs +3 -3
- package/dist/seo/register-sitemap-cli.mjs.map +1 -1
- package/dist/seo/server.d.mts +3 -3
- package/dist/seo/server.d.ts +3 -3
- package/dist/seo/server.js +7 -7
- package/dist/seo/server.js.map +1 -1
- package/dist/seo/server.mjs +5 -5
- package/dist/seo/server.mjs.map +1 -1
- package/dist/{server-api-XGKRGUMG.js → server-api-36R24YWN.js} +21 -21
- package/dist/{server-api-XGKRGUMG.js.map → server-api-36R24YWN.js.map} +1 -1
- package/dist/{server-api-COVFLFZ2.mjs → server-api-UIZU4JM3.mjs} +3 -3
- package/dist/{server-api-COVFLFZ2.mjs.map → server-api-UIZU4JM3.mjs.map} +1 -1
- package/dist/setup/index.d.mts +2 -5
- package/dist/setup/index.d.ts +2 -5
- package/dist/setup/index.js +0 -31
- package/dist/setup/index.mjs +1 -4
- package/dist/site-config/index.js +3 -3
- package/dist/site-config/index.mjs +1 -1
- package/dist/sitemap/index.js +10 -9
- package/dist/sitemap/index.js.map +1 -1
- package/dist/sitemap/index.mjs +8 -7
- package/dist/sitemap/index.mjs.map +1 -1
- package/dist/sync/index.js +13 -13
- package/dist/sync/index.mjs +1 -1
- package/dist/{types-KZP_VWZp.d.mts → types-CGkyylOa.d.mts} +2 -2
- package/dist/{types-KZP_VWZp.d.ts → types-CGkyylOa.d.ts} +2 -2
- package/package.json +4 -12
- package/dist/AnalyticsProvider-BBLU4U2T.mjs +0 -4
- package/dist/AnalyticsProvider-EMDIAAWR.js +0 -25
- package/dist/EngageWidget-CVZMTSB6.mjs +0 -4
- package/dist/EngageWidget-UHWXXCAX.js +0 -13
- package/dist/SetupWizard-Cki06kB0.d.mts +0 -12
- package/dist/SetupWizard-Cki06kB0.d.ts +0 -12
- package/dist/SignalBridge-6UYUZ2CN.js +0 -33
- package/dist/SignalBridge-WGHMEILW.mjs +0 -4
- package/dist/chunk-36Y7OWES.mjs.map +0 -1
- package/dist/chunk-373TK6TZ.js +0 -321
- package/dist/chunk-373TK6TZ.js.map +0 -1
- package/dist/chunk-4MOJJSNA.js +0 -14867
- package/dist/chunk-4MOJJSNA.js.map +0 -1
- package/dist/chunk-4QHHFCAA.mjs.map +0 -1
- package/dist/chunk-4X5TFGKD.mjs.map +0 -1
- package/dist/chunk-5YDPPOUU.mjs +0 -810
- package/dist/chunk-5YDPPOUU.mjs.map +0 -1
- package/dist/chunk-7FKPJQVS.mjs +0 -289
- package/dist/chunk-7FKPJQVS.mjs.map +0 -1
- package/dist/chunk-C3A5HXHX.mjs.map +0 -1
- package/dist/chunk-DY4K6X3A.js.map +0 -1
- package/dist/chunk-ELDJDBQL.js.map +0 -1
- package/dist/chunk-EUNL6GAL.js.map +0 -1
- package/dist/chunk-FI2ME55T.mjs.map +0 -1
- package/dist/chunk-FMB2RZDH.mjs.map +0 -1
- package/dist/chunk-FVCQBTNK.mjs.map +0 -1
- package/dist/chunk-G6VGUAK2.js.map +0 -1
- package/dist/chunk-GJD4CFHN.js.map +0 -1
- package/dist/chunk-GVXZWXQ7.js +0 -814
- package/dist/chunk-GVXZWXQ7.js.map +0 -1
- package/dist/chunk-HF2FWDBJ.mjs +0 -968
- package/dist/chunk-HF2FWDBJ.mjs.map +0 -1
- package/dist/chunk-IFAW7JFO.js +0 -1429
- package/dist/chunk-IFAW7JFO.js.map +0 -1
- package/dist/chunk-IJ2LWZID.js.map +0 -1
- package/dist/chunk-IKIJEKU3.mjs +0 -1427
- package/dist/chunk-IKIJEKU3.mjs.map +0 -1
- package/dist/chunk-JFTGG6HK.mjs +0 -14848
- package/dist/chunk-JFTGG6HK.mjs.map +0 -1
- package/dist/chunk-JM3ZR6LB.js +0 -981
- package/dist/chunk-JM3ZR6LB.js.map +0 -1
- package/dist/chunk-KJN2C6YE.js.map +0 -1
- package/dist/chunk-M5FLRLHI.mjs.map +0 -1
- package/dist/chunk-MCGLYYAR.mjs +0 -341
- package/dist/chunk-MCGLYYAR.mjs.map +0 -1
- package/dist/chunk-MG23BS36.js.map +0 -1
- package/dist/chunk-N24BPFF6.mjs.map +0 -1
- package/dist/chunk-NRNK7LXK.mjs.map +0 -1
- package/dist/chunk-PTTDKFL7.js.map +0 -1
- package/dist/chunk-S7FRYNSU.mjs +0 -315
- package/dist/chunk-S7FRYNSU.mjs.map +0 -1
- package/dist/chunk-SLB5V4RT.js +0 -302
- package/dist/chunk-SLB5V4RT.js.map +0 -1
- package/dist/chunk-TXZNP76P.js.map +0 -1
- package/dist/chunk-VNAJQKYG.mjs.map +0 -1
- package/dist/chunk-VZMDH3R4.mjs.map +0 -1
- package/dist/chunk-WW7UM7XY.js.map +0 -1
- package/dist/chunk-X4J33XQD.js.map +0 -1
- package/dist/chunk-XFOL6JDF.mjs.map +0 -1
- package/dist/chunk-XWWBUC2I.js.map +0 -1
- package/dist/chunk-YBTYDBWY.js.map +0 -1
- package/dist/chunk-ZQO6FZZB.js +0 -343
- package/dist/chunk-ZQO6FZZB.js.map +0 -1
- package/dist/chunk-ZU6YPEAF.mjs.map +0 -1
- package/dist/generators-DOFWGRXS.js +0 -37
- package/dist/generators-DOFWGRXS.js.map +0 -1
- package/dist/generators-R62APO62.mjs +0 -4
- package/dist/generators-R62APO62.mjs.map +0 -1
- package/dist/migrator-3WQB3KQ2.mjs +0 -4
- package/dist/migrator-3WQB3KQ2.mjs.map +0 -1
- package/dist/migrator-HFVQYK5R.js +0 -37
- package/dist/migrator-HFVQYK5R.js.map +0 -1
- package/dist/scanner-AF7YUCFG.mjs +0 -4
- package/dist/scanner-AF7YUCFG.mjs.map +0 -1
- package/dist/scanner-DBD5K6F7.js +0 -53
- package/dist/scanner-DBD5K6F7.js.map +0 -1
- package/dist/setup/client.d.mts +0 -60
- package/dist/setup/client.d.ts +0 -60
- package/dist/setup/client.js +0 -31
- package/dist/setup/client.js.map +0 -1
- package/dist/setup/client.mjs +0 -6
- package/dist/setup/client.mjs.map +0 -1
- package/dist/setup/server.d.mts +0 -14
- package/dist/setup/server.d.ts +0 -14
- package/dist/setup/server.js +0 -13
- package/dist/setup/server.js.map +0 -1
- package/dist/setup/server.mjs +0 -4
- package/dist/setup/server.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sitemap/index.ts"],"names":["pathToFileURL","join","existsSync","readdirSync","statSync","resolve","getSiteConfig","writeLLMsTxtToPublic"],"mappings":";;;;;;;;;AA6EA,IAAM,eAAA,GAAkB;AAAA,EACtB,KAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA;AAGA,IAAM,UAAA,GAAa,CAAC,UAAA,EAAY,UAAA,EAAY,WAAW,SAAS,CAAA;AAKhE,SAAS,UAAA,CAAW,MAAc,QAAA,EAA6B;AAC7D,EAAA,OAAO,QAAA,CAAS,KAAK,CAAA,OAAA,KAAW;AAC9B,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAClC,MAAA,OAAO,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IAC/B;AACA,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACzB,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAClC,MAAA,OAAO,IAAA,CAAK,WAAW,MAAM,CAAA;AAAA,IAC/B;AACA,IAAA,OAAO,IAAA,KAAS,OAAA;AAAA,EAClB,CAAC,CAAA;AACH;AAMA,SAAS,UAAU,MAAA,EAAwB;AACzC,EAAA,IAAI,UAAU,GAAA,GAAM,MAAA;AAEpB,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,cAAA,EAAgB,EAAE,CAAA;AAE5C,EAAA,OAAA,GAAU,OAAA,CAAQ,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAA;AACrC,EAAA,IAAI,OAAA,KAAY,GAAA,IAAO,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC5C,IAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,OAAA;AACT;AAMA,eAAe,wBACb,YAAA,EAC+C;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,OAAA,GAAUA,iBAAA,CAAc,YAAY,CAAA,CAAE,IAAA;AAE5C,IAAA,MAAM,gBAAgB,OAAO,OAAA,CAAA;AAC7B,IAAA,MAAM,iBAAiB,IAAI,OAAA;AAAA,MAAe,CAAC,CAAA,EAAG,MAAA,KAC5C,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,4CAA4C,CAAC,CAAA,EAAG,GAAI;AAAA,KACxF;AACA,IAAA,MAAM,MAAM,MAAM,OAAA,CAAQ,KAAK,CAAC,aAAA,EAAe,cAAc,CAAC,CAAA;AAE9D,IAAA,IAAI,OAAO,GAAA,CAAI,oBAAA,KAAyB,UAAA,EAAY;AAClD,MAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,sBAAsB,CAAA;AAChE,MAAA,MAAM,gBAAgB,IAAI,OAAA;AAAA,QAAe,CAAC,CAAA,EAAG,MAAA,KAC3C,UAAA,CAAW,MAAM,MAAA,CAAO,IAAI,KAAA,CAAM,2CAA2C,CAAC,CAAA,EAAG,GAAK;AAAA,OACxF;AACA,MAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,KAAK,CAAC,aAAA,EAAe,aAAa,CAAC,CAAA;AAChE,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AACzB,QAAA,OAAO,MAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF,SAAS,GAAA,EAAK;AACZ,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,0DAA0D,YAAY,CAAA,CAAA,CAAA;AAAA,MACrE,GAAA,CAAc;AAAA,KACjB;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAaA,eAAe,aAAA,CACb,QACA,WAAA,GAAsB,EAAA,EACtB,QAAkB,EAAC,EACnB,OAAA,GAAgC,EAAC,EACd;AACnB,EAAA,MAAM,QAAA,GAAWC,SAAA,CAAK,MAAA,EAAQ,WAAW,CAAA;AAEzC,EAAA,IAAI,CAACC,aAAA,CAAW,QAAQ,CAAA,EAAG;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAUC,eAAY,QAAQ,CAAA;AAGpC,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,CAAK,WAAS,UAAA,CAAW,QAAA,CAAS,KAAK,CAAC,CAAA;AAEhE,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,OAAA,GAAU,UAAU,WAAW,CAAA;AAErC,IAAA,IAAI,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,MAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAAA,IACpB;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,IAAA,MAAM,SAAA,GAAYF,SAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AACtC,IAAA,MAAM,IAAA,GAAOG,YAAS,SAAS,CAAA;AAE/B,IAAA,IAAI,IAAA,CAAK,aAAY,EAAG;AAEtB,MAAA,MAAM,UAAA,GAAa,MAAM,WAAA,EAAY;AACrC,MAAA,IAAI,gBAAgB,IAAA,CAAK,CAAA,OAAA,KAAW,WAAW,QAAA,CAAS,OAAO,CAAC,CAAA,EAAG;AACjE,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AACzB,QAAA;AAAA,MACF;AAGA,MAAA,IAAI,MAAM,UAAA,CAAW,GAAG,KAAK,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AAChD,QAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACnC,QAAA,IAAI,WAAA,GAA+B,IAAA;AAGnC,QAAA,IAAI,QAAQ,aAAA,EAAe;AAEzB,UAAA,WAAA,GAAc,QAAQ,aAAA,CAAc,KAAK,KAAK,OAAA,CAAQ,aAAA,CAAc,SAAS,CAAA,IAAK,IAAA;AAAA,QACpF;AAGA,QAAA,IAAI,CAAC,WAAA,IAAe,OAAA,CAAQ,2BAAA,KAAgC,KAAA,EAAO;AAEjE,UAAA,MAAM,cAAA,GAAiBH,SAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AAC3C,UAAA,MAAM,QAAA,GAAW,WAAW,IAAA,CAAK,CAAA,EAAA,KAAMC,cAAWD,SAAA,CAAK,cAAA,EAAgB,EAAE,CAAC,CAAC,CAAA;AAE3E,UAAA,IAAI,QAAA,EAAU;AACZ,YAAA,MAAM,YAAA,GAAeI,YAAA,CAAQ,cAAA,EAAgB,QAAQ,CAAA;AACrD,YAAA,MAAM,MAAA,GAAS,MAAM,uBAAA,CAAwB,YAAY,CAAA;AACzD,YAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAE/B,cAAA,WAAA,GAAc,MAAA,CACX,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,CAAC,CAAA,CACrB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAQ,CAAA;AAAA,YACrD;AAAA,UACF;AAAA,QACF;AAEA,QAAA,IAAI,WAAA,IAAe,WAAA,CAAY,MAAA,GAAS,CAAA,EAAG;AACzC,UAAA,MAAM,cAAA,GAAiBJ,SAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AAC3C,UAAA,MAAM,cAAA,GAAiBE,eAAY,cAAc,CAAA;AAGjD,UAAA,MAAM,iBAAiB,cAAA,CAAe,IAAA,CAAK,OAAK,UAAA,CAAW,QAAA,CAAS,CAAC,CAAC,CAAA;AAEtE,UAAA,KAAA,MAAW,SAAS,WAAA,EAAa;AAE/B,YAAA,IAAI,cAAA,EAAgB;AAClB,cAAA,MAAM,YAAA,GAAe,SAAA,CAAUF,SAAA,CAAK,WAAA,EAAa,KAAK,CAAC,CAAA;AACvD,cAAA,IAAI,CAAC,YAAA,CAAa,QAAA,CAAS,GAAG,CAAA,EAAG;AAC/B,gBAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AAAA,cACzB;AAAA,YACF;AAIA,YAAA,KAAA,MAAW,YAAY,cAAA,EAAgB;AACrC,cAAA,IAAI,UAAA,CAAW,QAAA,CAAS,QAAQ,CAAA,EAAG;AACnC,cAAA,MAAM,YAAA,GAAeA,SAAA,CAAK,cAAA,EAAgB,QAAQ,CAAA;AAClD,cAAA,IAAIG,WAAA,CAAS,YAAY,CAAA,CAAE,WAAA,EAAY,EAAG;AAIxC,gBAAA,MAAM,qBAAA;AAAA,kBACJ,cAAA;AAAA,kBACA,QAAA;AAAA,kBACAH,SAAA,CAAK,aAAa,KAAK,CAAA;AAAA,kBACvB,KAAA;AAAA,kBACA;AAAA,iBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ,IAAA;AAAA,YACN,CAAA,qCAAA,EAAwC,KAAK,CAAA,MAAA,EAAS,WAAW,CAAA,sGAAA;AAAA,WAEnE;AAAA,QACF;AACA,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,cAAc,MAAA,EAAQA,SAAA,CAAK,aAAa,KAAK,CAAA,EAAG,OAAO,OAAO,CAAA;AAAA,IACtE;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAOA,eAAe,qBAAA,CACb,UAAA,EACA,SAAA,EACA,aAAA,EACA,OACA,OAAA,EACe;AACf,EAAA,MAAM,QAAA,GAAWA,SAAA,CAAK,UAAA,EAAY,SAAS,CAAA;AAC3C,EAAA,IAAI,CAACC,cAAW,QAAQ,CAAA,IAAK,CAACE,WAAA,CAAS,QAAQ,CAAA,CAAE,WAAA,EAAY,EAAG;AAEhE,EAAA,MAAM,OAAA,GAAUD,eAAY,QAAQ,CAAA;AACpC,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,CAAK,OAAK,UAAA,CAAW,QAAA,CAAS,CAAC,CAAC,CAAA;AACxD,EAAA,MAAM,OAAA,GAAU,SAAA,CAAUF,SAAA,CAAK,aAAA,EAAe,SAAS,CAAC,CAAA;AAExD,EAAA,IAAI,OAAA,IAAW,CAAC,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AACrC,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAAA,EACpB;AAEA,EAAA,KAAA,MAAW,OAAO,OAAA,EAAS;AACzB,IAAA,IAAI,UAAA,CAAW,QAAA,CAAS,GAAG,CAAA,EAAG;AAC9B,IAAA,MAAM,OAAA,GAAUA,SAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AAClC,IAAA,IAAI,CAACG,WAAA,CAAS,OAAO,CAAA,CAAE,aAAY,EAAG;AAEtC,IAAA,MAAM,UAAA,GAAa,IAAI,WAAA,EAAY;AACnC,IAAA,IAAI,gBAAgB,IAAA,CAAK,CAAA,OAAA,KAAW,WAAW,QAAA,CAAS,OAAO,CAAC,CAAA,EAAG;AACnE,IAAA,IAAI,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AAEzB,IAAA,IAAI,IAAI,UAAA,CAAW,GAAG,KAAK,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AAE5C,MAAA,MAAM,WAAA,GAAc,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACnC,MAAA,IAAI,YAAA,GAAgC,IAAA;AAEpC,MAAA,IAAI,QAAQ,aAAA,EAAe;AACzB,QAAA,YAAA,GAAe,QAAQ,aAAA,CAAc,GAAG,KAAK,OAAA,CAAQ,aAAA,CAAc,WAAW,CAAA,IAAK,IAAA;AAAA,MACrF;AAEA,MAAA,IAAI,CAAC,YAAA,IAAgB,OAAA,CAAQ,2BAAA,KAAgC,KAAA,EAAO;AAClE,QAAA,MAAM,SAAA,GAAYH,SAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AACpC,QAAA,MAAM,QAAA,GAAW,WAAW,IAAA,CAAK,CAAA,EAAA,KAAMC,cAAWD,SAAA,CAAK,SAAA,EAAW,EAAE,CAAC,CAAC,CAAA;AACtE,QAAA,IAAI,QAAA,EAAU;AACZ,UAAA,MAAM,SAAS,MAAM,uBAAA,CAAwBI,YAAA,CAAQ,SAAA,EAAW,QAAQ,CAAC,CAAA;AACzE,UAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AAC/B,YAAA,YAAA,GAAe,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,WAAW,CAAC,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAQ,CAAA;AAAA,UACjG;AAAA,QACF;AAAA,MACF;AAEA,MAAA,IAAI,YAAA,IAAgB,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG;AAC3C,QAAA,MAAM,SAAA,GAAYJ,SAAA,CAAK,QAAA,EAAU,GAAG,CAAA;AACpC,QAAA,MAAM,aAAA,GAAgBE,eAAY,SAAS,CAAA;AAC3C,QAAA,MAAM,gBAAgB,aAAA,CAAc,IAAA,CAAK,OAAK,UAAA,CAAW,QAAA,CAAS,CAAC,CAAC,CAAA;AACpE,QAAA,KAAA,MAAW,OAAO,YAAA,EAAc;AAC9B,UAAA,IAAI,aAAA,EAAe;AACjB,YAAA,MAAM,WAAW,SAAA,CAAUF,SAAA,CAAK,aAAA,EAAe,SAAA,EAAW,GAAG,CAAC,CAAA;AAC9D,YAAA,IAAI,CAAC,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG,KAAA,CAAM,KAAK,QAAQ,CAAA;AAAA,UAClD;AACA,UAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,YAAA,IAAI,UAAA,CAAW,QAAA,CAAS,SAAS,CAAA,EAAG;AACpC,YAAA,MAAM,aAAA,GAAgBA,SAAA,CAAK,SAAA,EAAW,SAAS,CAAA;AAC/C,YAAA,IAAIG,WAAA,CAAS,aAAa,CAAA,CAAE,WAAA,EAAY,EAAG;AACzC,cAAA,MAAM,qBAAA,CAAsB,WAAW,SAAA,EAAWH,SAAA,CAAK,eAAe,SAAA,EAAW,GAAG,CAAA,EAAG,KAAA,EAAO,OAAO,CAAA;AAAA,YACvG;AAAA,UACF;AAAA,QACF;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,qBAAA,CAAsB,UAAU,GAAA,EAAKA,SAAA,CAAK,eAAe,SAAS,CAAA,EAAG,OAAO,OAAO,CAAA;AAAA,EAC3F;AACF;AAKA,SAAS,UAAA,GAAqB;AAC5B,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,EAAI;AAGxB,EAAA,MAAM,UAAA,GAAa;AAAA,IACjBA,SAAA,CAAK,KAAK,KAAK,CAAA;AAAA,IACfA,SAAA,CAAK,GAAA,EAAK,KAAA,EAAO,KAAK;AAAA,GACxB;AAEA,EAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,IAAA,IAAIC,aAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,OAAO,SAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,KAAA;AAAA,IACR;AAAA,GACF;AACF;AAKA,SAAS,WAAA,CAAY,MAAc,MAAA,EAA+B;AAEhE,EAAA,IAAI,OAAO,UAAA,EAAY;AACrB,IAAA,KAAA,MAAW,CAAC,SAAS,QAAQ,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA,EAAG;AACnE,MAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AAC1B,QAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAClC,QAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAM,CAAA,EAAG,OAAO,QAAA;AAAA,MACtC,CAAA,MAAA,IAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,OAAO,QAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,IAAA,KAAS,KAAK,OAAO,CAAA;AAGzB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA;AAC9C,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,GAAA;AACxB,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,GAAA;AAExB,EAAA,OAAO,OAAO,eAAA,IAAmB,GAAA;AACnC;AAaA,eAAsB,mBAAA,CACpB,OAAA,EACA,MAAA,EACA,MAAA,EACA,OAAA,EACiE;AACjE,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAA,CAAQ,KAAK,uDAAuD,CAAA;AACpE,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,EAClD;AAEA,EAAA,MAAM,iBAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,CAAA,KAAA,KAAS;AAC7C,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAA,GAAO,GAAA,CAAI,QAAA;AAAA,IACb,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,GAAO,KAAA,CAAM,IAAI,UAAA,CAAW,GAAG,IAAI,KAAA,CAAM,GAAA,GAAM,CAAA,CAAA,EAAI,KAAA,CAAM,GAAG,CAAA,CAAA;AAAA,IAC9D;AAEA,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,YAAY,KAAA,CAAM;AAAA,KACpB;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAgC,EAAE,OAAA,EAAS,iBAAA,EAAmB,MAAM,cAAA,EAAe;AACzF,IAAA,IAAI,OAAA,EAAS,YAAA,KAAiB,KAAA,CAAA,EAAW,IAAA,CAAK,gBAAgB,OAAA,CAAQ,YAAA;AACtE,IAAA,IAAI,OAAA,EAAS,SAAA,KAAc,KAAA,CAAA,EAAW,IAAA,CAAK,aAAa,OAAA,CAAQ,SAAA;AAEhE,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,gCAAA,CAAA,EAAoC;AAAA,MACxE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,WAAA,EAAa;AAAA,OACf;AAAA,MACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,KAC1B,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,MAAM,iCAAA,EAAmC,QAAA,CAAS,QAAQ,MAAM,QAAA,CAAS,MAAM,CAAA;AACvF,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,IAClD;AAEA,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,IAAA,EAAK;AAEnC,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,OAAA,EAAS,OAAO,OAAA,IAAW,CAAA;AAAA,MAC3B,OAAA,EAAS,OAAO,OAAA,IAAW;AAAA,KAC7B;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,kCAAkC,KAAK,CAAA;AACrD,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,EAAE;AAAA,EAClD;AACF;AAgBO,SAAS,cAAc,MAAA,EAAuE;AACnG,EAAA,OAAO,YAAY;AACjB,IAAA,MAAM,EAAE,OAAA,GAAU,EAAC,EAAG,sBAAA,GAAyB,UAAS,GAAI,MAAA;AAG5D,IAAA,IAAI,UAAU,MAAA,CAAO,OAAA;AACrB,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,iBAAiB,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,GAAA,CAAI,2BAAA;AACxG,MAAA,MAAM,IAAA,GAAO,MAAMI,8BAAA,CAAc,EAAE,QAAQ,MAAA,EAAQ,MAAA,CAAO,QAAQ,CAAA;AAClE,MAAA,OAAA,GAAU,IAAA,EAAM,QAAA,IAAY,OAAA,CAAQ,GAAA,CAAI,oBAAA,IAAwB,qBAAA;AAAA,IAClE;AACA,IAAA,MAAM,iBAAA,GAAoB,QAAQ,QAAA,CAAS,GAAG,IAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,OAAA;AAGzE,IAAA,MAAM,aAAA,GAAgB;AAAA,MACpB,QAAA;AAAA,MACA,UAAA;AAAA,MACA,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,YAAA;AAAA,MACA,GAAG;AAAA,KACL;AAGA,IAAA,IAAI,QAAkB,EAAC;AACvB,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,UAAA,EAAW;AAC1B,MAAA,KAAA,GAAQ,MAAM,aAAA,CAAc,MAAA,EAAQ,EAAA,EAAI,EAAC,EAAG;AAAA,QAC1C,eAAe,MAAA,CAAO,aAAA;AAAA,QACtB,6BAA6B,MAAA,CAAO;AAAA,OACrC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,IAAA,CAAK,wCAAwC,KAAK,CAAA;AAE1D,MAAA,KAAA,GAAQ,CAAC,GAAG,CAAA;AAAA,IACd;AAGA,IAAA,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA,CAAE,MAAA,CAAO,CAAA,IAAA,KAAQ,CAAC,UAAA,CAAW,IAAA,EAAM,aAAa,CAAC,CAAA;AAGlF,IAAA,MAAM,OAAA,GAA0B,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,MACjD,GAAA,EAAK,CAAA,EAAG,iBAAiB,CAAA,EAAG,IAAI,CAAA,CAAA;AAAA,MAChC,YAAA,sBAAkB,IAAA,EAAK;AAAA,MACvB,eAAA,EAAiB,sBAAA;AAAA,MACjB,QAAA,EAAU,WAAA,CAAY,IAAA,EAAM,MAAM;AAAA,KACpC,CAAE,CAAA;AAGF,IAAA,IAAI,OAAO,eAAA,EAAiB;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,GAAG,CAAC,CAAA;AACpD,QAAA,MAAM,UAAA,GAAa,MAAM,MAAA,CAAO,eAAA,EAAgB;AAChD,QAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,UAAA,MAAM,OAAA,GAAU,CAAA,EAAG,iBAAiB,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA;AAChD,UAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,IAAA,EAAM,aAAa,KAAK,CAAC,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA,EAAG;AACvE,YAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,cACX,GAAA,EAAK,OAAA;AAAA,cACL,YAAA,sBAAkB,IAAA,EAAK;AAAA,cACvB,eAAA,EAAiB,KAAK,eAAA,IAAmB,sBAAA;AAAA,cACzC,UAAU,IAAA,CAAK,QAAA,IAAY,WAAA,CAAY,IAAA,CAAK,MAAM,MAAM;AAAA,aACzD,CAAA;AACD,YAAA,YAAA,CAAa,IAAI,OAAO,CAAA;AAAA,UAC1B;AAAA,QACF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,8CAA8C,KAAK,CAAA;AAAA,MAClE;AAAA,IACF;AAGA,IAAA,IAAI,OAAO,mBAAA,EAAqB;AAC9B,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,aAAA,IAAiB,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,GAAA,CAAI,2BAAA,IAA+B,EAAA;AACvI,QAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,KAAA,CAAM,qCAAqC,CAAA;AACzE,QAAA,MAAM,SAAA,GAAY,cAAA,GAAiB,cAAA,CAAe,CAAC,CAAA,GAAI,IAAA;AAEvD,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,MAAM,YAAA,GAAe,QAAQ,GAAA,CAAI,gBAAA,IAAoB,QAAQ,GAAA,CAAI,cAAA,IAAkB,OAAA,CAAQ,GAAA,CAAI,0BAAA,IAA8B,yBAAA;AAC7H,UAAA,MAAM,cAAc,MAAM,KAAA,CAAM,GAAG,YAAY,CAAA,uBAAA,EAA0B,SAAS,CAAA,CAAA,EAAI;AAAA,YACpF,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,aAAa,MAAA;AAAO,WACpE,CAAA,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AAEnB,UAAA,IAAI,aAAa,EAAA,EAAI;AACnB,YAAA,MAAM,OAAA,GAAU,MAAM,WAAA,CAAY,IAAA,EAAK;AACvC,YAAA,MAAM,MAAA,GAAU,SAAS,IAAA,IAAQ,OAAA;AACjC,YAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,CAAC,CAAA,CAAE,SAAA,EAAW,CAAA,CAAE,aAAa,CAAC,CAAC,CAAA;AAExE,YAAA,IAAI,YAAA,GAAe,CAAA;AACnB,YAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,cAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,QAAA;AAChC,cAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAClC,cAAA,IAAI,aAAa,KAAA,CAAA,EAAW;AAC1B,gBAAA,MAAM,aAAa,IAAA,KAAS,GAAA,GAAM,CAAA,GAAM,IAAA,CAAK,IAAI,GAAA,EAAK,CAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,SAAS,IAAK,CAAA;AAE3G,gBAAA,KAAA,CAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAA,CAAO,QAAA,GAAW,GAAA,GAAM,UAAA,GAAa,GAAA,GAAA,CAAO,KAAA,CAAM,QAAA,IAAY,GAAA,IAAO,GAAA,IAAO,GAAG,CAAA,GAAI,GAAA;AACzG,gBAAA,YAAA,EAAA;AAAA,cACF;AAAA,YACF;AACA,YAAA,IAAI,eAAe,CAAA,EAAG;AACpB,cAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,6CAAA,EAAgD,YAAY,CAAA,kBAAA,CAAoB,CAAA;AAAA,YAC9F;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAGA,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,EAAE,QAAA,IAAY,CAAA,KAAM,CAAA,CAAE,QAAA,IAAY,CAAA,CAAE,CAAA;AAE5D,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,kCAAA,EAAqC,OAAA,CAAQ,MAAM,CAAA,MAAA,CAAQ,CAAA;AAGvE,IAAA,IAAI,CAAC,OAAO,WAAA,EAAa;AACvB,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,aAAA,IAAiB,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,GAAA,CAAI,2BAAA,IAA+B,sBAAA;AAEvI,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,IAAU,OAAA,CAAQ,GAAA,CAAI,iBAAiB,OAAA,CAAQ,GAAA,CAAI,eAAA,IAAmB,OAAA,CAAQ,GAAA,CAAI,2BAAA;AAExG,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,IAAI;AACF,UAAA,MAAM,cAAkC,EAAC;AACzC,UAAA,IAAI,OAAO,qBAAA,EAAuB;AAChC,YAAA,WAAA,CAAY,YAAA,GAAe,IAAA;AAC3B,YAAA,WAAA,CAAY,SAAA,GAAY,IAAA;AAAA,UAC1B;AACA,UAAA,MAAM,SAAS,MAAM,mBAAA,CAAoB,OAAA,EAAS,MAAA,EAAQ,QAAQ,WAAW,CAAA;AAC7E,UAAA,IAAI,OAAO,OAAA,EAAS;AAClB,YAAA,OAAA,CAAQ,IAAI,CAAA,iCAAA,EAAoC,MAAA,CAAO,OAAO,CAAA,UAAA,EAAa,MAAA,CAAO,OAAO,CAAA,QAAA,CAAU,CAAA;AAGnG,YAAA,IAAI,OAAO,qBAAA,EAAuB;AAChC,cAAA,IAAI;AACF,gBAAA,MAAM,aAAA,GAAgB,MAAM,KAAA,CAAM,CAAA,EAAG,MAAM,CAAA,qBAAA,CAAA,EAAyB;AAAA,kBAClE,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,aAAa,MAAA;AAAO,iBACpE,CAAA;AACD,gBAAA,IAAI,cAAc,EAAA,EAAI;AACpB,kBAAA,MAAM,SAAA,GAAY,MAAM,aAAA,CAAc,IAAA,EAAK;AAC3C,kBAAA,MAAM,QAAA,GAAiF,SAAA,EAAW,KAAA,IAAS,SAAA,EAAW,QAAQ,EAAC;AAC/H,kBAAA,MAAM,YAAY,QAAA,CAAS,MAAA,CAAO,OAAK,CAAA,CAAE,aAAA,IAAiB,EAAE,wBAAwB,CAAA;AACpF,kBAAA,OAAA,CAAQ,IAAI,CAAA,uCAAA,EAA0C,SAAA,CAAU,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,MAAM,CAAA,QAAA,EAAW,QAAA,CAAS,SAAS,IAAA,CAAK,KAAA,CAAO,UAAU,MAAA,GAAS,QAAA,CAAS,SAAU,GAAG,CAAA,GAAI,CAAC,CAAA,EAAA,CAAI,CAAA;AAAA,gBACtL;AAAA,cACF,CAAA,CAAA,MAAQ;AACN,gBAAA,OAAA,CAAQ,KAAK,wDAAwD,CAAA;AAAA,cACvE;AAAA,YACF;AAAA,UACF;AAGA,UAAA,IAAI,MAAA,CAAO,qBAAqB,KAAA,EAAO;AACrC,YAAA,IAAI;AACF,cAAA,MAAM,WAAA,GAAc,MAAMC,qCAAA,CAAqB;AAAA,gBAC7C,MAAA;AAAA,gBACA,MAAA;AAAA,gBACA,IAAA,EAAM,OAAO,oBAAA,IAAwB,KAAA;AAAA,gBACrC,eAAA,EAAiB,IAAA;AAAA,gBACjB,cAAc,MAAA,CAAO;AAAA,eACtB,CAAA;AACD,cAAA,IAAI,YAAY,OAAA,EAAS;AACvB,gBAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,qCAAA,EAAwC,WAAA,CAAY,SAAS,CAAA,CAAA,CAAG,CAAA;AAAA,cAC9E;AAAA,YACF,SAAS,GAAA,EAAK;AACZ,cAAA,OAAA,CAAQ,IAAA,CAAK,sCAAA,EAAyC,GAAA,CAAc,OAAO,CAAA;AAAA,YAC7E;AAAA,UACF;AAAA,QACF,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,IAAA,CAAK,kDAAA,EAAqD,GAAA,CAAc,OAAO,CAAA;AAAA,QACzF;AAAA,MACF,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ,IAAI,uDAAuD,CAAA;AAAA,MACrE;AAAA,IACF;AAEA,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AACF","file":"index.js","sourcesContent":["/**\n * @sonordev/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\nimport { getSiteConfig } from '../site-config'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (optional when apiKey is set; then resolved from Portal project-info) */\n baseUrl?: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /**\n * Explicit values for dynamic route segments.\n * Keys are the segment names (e.g. '[slug]') and values are arrays of param values.\n * This is a simpler alternative to relying on generateStaticParams auto-discovery.\n * @example { '[slug]': ['seo', 'analytics', 'crm', 'echo'] }\n */\n dynamicRoutes?: Record<string, string[]>\n /** When true (default), attempt to import generateStaticParams from dynamic route pages at build time */\n resolveGenerateStaticParams?: boolean\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to SONOR_API_URL or https://api.sonor.io) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to SONOR_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n /** Use Signal AI visibility scores to compute page priority (40% visibility + 30% depth + 30% base) */\n intelligentPriority?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'sonor-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Convert a file-system path (relative to appDir) into a URL path,\n * stripping route groups and cleaning slashes.\n */\nfunction toUrlPath(fsPath: string): string {\n let urlPath = '/' + fsPath\n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n return urlPath\n}\n\n/**\n * Attempt to call generateStaticParams from a dynamic route page module.\n * Returns the param objects, or null if unavailable.\n */\nasync function tryGenerateStaticParams(\n pageFilePath: string\n): Promise<Array<Record<string, string>> | null> {\n try {\n const fileUrl = pathToFileURL(pageFilePath).href\n // Use a timeout to guard against slow external API calls\n const importPromise = import(fileUrl)\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams import timed out (5s)')), 5000)\n )\n const mod = await Promise.race([importPromise, timeoutPromise])\n\n if (typeof mod.generateStaticParams === 'function') {\n const resultPromise = Promise.resolve(mod.generateStaticParams())\n const resultTimeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams call timed out (10s)')), 10000)\n )\n const params = await Promise.race([resultPromise, resultTimeout])\n if (Array.isArray(params)) {\n return params as Array<Record<string, string>>\n }\n }\n } catch (err) {\n console.warn(\n `[site-kit] Could not resolve generateStaticParams from ${pageFilePath}:`,\n (err as Error).message\n )\n }\n return null\n}\n\ninterface DiscoverPagesOptions {\n /** Explicit param values for dynamic segments, keyed by segment name e.g. '[slug]' */\n dynamicRoutes?: Record<string, string[]>\n /** Whether to attempt auto-import of generateStaticParams (default true) */\n resolveGenerateStaticParams?: boolean\n}\n\n/**\n * Recursively discover pages from the app directory.\n * Handles dynamic route segments via explicit config or generateStaticParams auto-discovery.\n */\nasync function discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = [],\n options: DiscoverPagesOptions = {}\n): Promise<string[]> {\n const fullPath = join(appDir, currentPath)\n\n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n\n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n\n if (hasPage) {\n const urlPath = toUrlPath(currentPath)\n // Only add if the path has no unresolved dynamic segments\n if (!urlPath.includes('[')) {\n pages.push(urlPath)\n }\n }\n\n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n\n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n\n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n\n // Handle dynamic route segments\n if (entry.startsWith('[') && entry.endsWith(']')) {\n const paramName = entry.slice(1, -1) // e.g. 'slug' from '[slug]'\n let paramValues: string[] | null = null\n\n // 1. Check explicit dynamicRoutes config first\n if (options.dynamicRoutes) {\n // Match by full segment name '[slug]' or bare param name 'slug'\n paramValues = options.dynamicRoutes[entry] ?? options.dynamicRoutes[paramName] ?? null\n }\n\n // 2. Fall back to auto-importing generateStaticParams\n if (!paramValues && options.resolveGenerateStaticParams !== false) {\n // Find the page file inside the dynamic directory\n const dynamicDirPath = join(fullPath, entry)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(dynamicDirPath, pf)))\n\n if (pageFile) {\n const pageFilePath = resolve(dynamicDirPath, pageFile)\n const params = await tryGenerateStaticParams(pageFilePath)\n if (params && params.length > 0) {\n // Extract the values for this specific param\n paramValues = params\n .map(p => p[paramName])\n .filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (paramValues && paramValues.length > 0) {\n const dynamicDirPath = join(fullPath, entry)\n const dynamicEntries = readdirSync(dynamicDirPath)\n\n // Check if the dynamic directory itself has a page file\n const dynamicHasPage = dynamicEntries.some(e => PAGE_FILES.includes(e))\n\n for (const value of paramValues) {\n // If the dynamic dir has a page, add the resolved path\n if (dynamicHasPage) {\n const resolvedPath = toUrlPath(join(currentPath, value))\n if (!resolvedPath.includes('[')) {\n pages.push(resolvedPath)\n }\n }\n\n // Recurse into subdirectories inside the dynamic segment,\n // mapping [param] on disk to the resolved value in the URL\n for (const subEntry of dynamicEntries) {\n if (PAGE_FILES.includes(subEntry)) continue // skip page files\n const subEntryPath = join(dynamicDirPath, subEntry)\n if (statSync(subEntryPath).isDirectory()) {\n // For nested dynamic segments or regular subdirs, recurse\n // We need a custom appDir-relative path that uses the resolved value\n // but reads from the dynamic dir on disk\n await discoverPagesFromDisk(\n dynamicDirPath,\n subEntry,\n join(currentPath, value),\n pages,\n options\n )\n }\n }\n }\n } else {\n console.warn(\n `[site-kit] Skipping dynamic segment \"${entry}\" at /${currentPath} — no params resolved. ` +\n `Provide dynamicRoutes config or export generateStaticParams from the page.`\n )\n }\n continue\n }\n\n await discoverPages(appDir, join(currentPath, entry), pages, options)\n }\n }\n\n return pages\n}\n\n/**\n * Discover pages starting from a disk path that differs from the URL path.\n * Used when traversing inside dynamic route segments where the filesystem\n * directory name (e.g. [slug]) differs from the URL segment (e.g. 'seo').\n */\nasync function discoverPagesFromDisk(\n diskParent: string,\n diskEntry: string,\n urlParentPath: string,\n pages: string[],\n options: DiscoverPagesOptions\n): Promise<void> {\n const diskPath = join(diskParent, diskEntry)\n if (!existsSync(diskPath) || !statSync(diskPath).isDirectory()) return\n\n const entries = readdirSync(diskPath)\n const hasPage = entries.some(e => PAGE_FILES.includes(e))\n const urlPath = toUrlPath(join(urlParentPath, diskEntry))\n\n if (hasPage && !urlPath.includes('[')) {\n pages.push(urlPath)\n }\n\n for (const sub of entries) {\n if (PAGE_FILES.includes(sub)) continue\n const subPath = join(diskPath, sub)\n if (!statSync(subPath).isDirectory()) continue\n\n const folderName = sub.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) continue\n if (sub.startsWith('_')) continue\n\n if (sub.startsWith('[') && sub.endsWith(']')) {\n // Nested dynamic segment — resolve its params too\n const nestedParam = sub.slice(1, -1)\n let nestedValues: string[] | null = null\n\n if (options.dynamicRoutes) {\n nestedValues = options.dynamicRoutes[sub] ?? options.dynamicRoutes[nestedParam] ?? null\n }\n\n if (!nestedValues && options.resolveGenerateStaticParams !== false) {\n const nestedDir = join(diskPath, sub)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(nestedDir, pf)))\n if (pageFile) {\n const params = await tryGenerateStaticParams(resolve(nestedDir, pageFile))\n if (params && params.length > 0) {\n nestedValues = params.map(p => p[nestedParam]).filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (nestedValues && nestedValues.length > 0) {\n const nestedDir = join(diskPath, sub)\n const nestedEntries = readdirSync(nestedDir)\n const nestedHasPage = nestedEntries.some(e => PAGE_FILES.includes(e))\n for (const val of nestedValues) {\n if (nestedHasPage) {\n const resolved = toUrlPath(join(urlParentPath, diskEntry, val))\n if (!resolved.includes('[')) pages.push(resolved)\n }\n for (const nestedSub of nestedEntries) {\n if (PAGE_FILES.includes(nestedSub)) continue\n const nestedSubPath = join(nestedDir, nestedSub)\n if (statSync(nestedSubPath).isDirectory()) {\n await discoverPagesFromDisk(nestedDir, nestedSub, join(urlParentPath, diskEntry, val), pages, options)\n }\n }\n }\n }\n continue\n }\n\n await discoverPagesFromDisk(diskPath, sub, join(urlParentPath, diskEntry), pages, options)\n }\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries, mode: 'full-replace' }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Resolve baseUrl: from config, or from Portal via apiKey/env\n let baseUrl = config.baseUrl\n if (!baseUrl) {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? process.env.UPTRADE_API_KEY ?? process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n const site = await getSiteConfig({ apiKey, apiUrl: config.apiUrl })\n baseUrl = site?.site_url ?? process.env.NEXT_PUBLIC_SITE_URL ?? 'https://example.com'\n }\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/sonor-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory (including dynamic routes)\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = await discoverPages(appDir, '', [], {\n dynamicRoutes: config.dynamicRoutes,\n resolveGenerateStaticParams: config.resolveGenerateStaticParams,\n })\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Deduplicate and filter out excluded pages\n pages = Array.from(new Set(pages)).filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided (deduplicating against discovered pages)\n if (config.additionalPaths) {\n try {\n const existingUrls = new Set(entries.map(e => e.url))\n const additional = await config.additionalPaths()\n for (const item of additional) {\n const fullUrl = `${normalizedBaseUrl}${item.path}`\n if (!isExcluded(item.path, allExclusions) && !existingUrls.has(fullUrl)) {\n entries.push({\n url: fullUrl,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n existingUrls.add(fullUrl)\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Intelligent priority: blend visibility scores with depth-based priority\n if (config.intelligentPriority) {\n try {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? process.env.UPTRADE_API_KEY ?? process.env.NEXT_PUBLIC_UPTRADE_API_KEY ?? ''\n const projectIdMatch = apiKey.match(/^(?:sonor|uptrade)_([0-9a-f-]{36})_/)\n const projectId = projectIdMatch ? projectIdMatch[1] : null\n\n if (projectId) {\n const signalApiUrl = process.env.SONOR_SIGNAL_URL || process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.sonor.io'\n const visResponse = await fetch(`${signalApiUrl}/skills/seo/visibility/${projectId}`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n }).catch(() => null)\n\n if (visResponse?.ok) {\n const visData = await visResponse.json()\n const scores = (visData?.data || visData) as Array<{ page_path: string; overall_score: number }>\n const scoreMap = new Map(scores.map(s => [s.page_path, s.overall_score]))\n\n let appliedCount = 0\n for (const entry of entries) {\n const path = new URL(entry.url).pathname\n const visScore = scoreMap.get(path)\n if (visScore !== undefined) {\n const depthBonus = path === '/' ? 1.0 : Math.max(0.3, 1.0 - (path.split('/').filter(Boolean).length * 0.15))\n // 40% visibility + 30% depth + 30% base\n entry.priority = Math.round((visScore * 0.4 + depthBonus * 0.3 + (entry.priority ?? 0.5) * 0.3) * 100) / 100\n appliedCount++\n }\n }\n if (appliedCount > 0) {\n console.log(`[site-kit] Applied intelligent priority from ${appliedCount} visibility scores`)\n }\n }\n }\n } catch {\n // Signal API unavailable — fall back to static priority\n }\n }\n\n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.SONOR_API_URL || process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.sonor.io'\n // Server-side operations prefer SONOR_API_KEY\n const apiKey = config.apiKey || process.env.SONOR_API_KEY || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n\n // Verification: report meta optimization coverage after sync\n if (config.awaitMetaOptimization) {\n try {\n const pagesResponse = await fetch(`${apiUrl}/api/public/seo/pages`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n })\n if (pagesResponse.ok) {\n const pagesData = await pagesResponse.json()\n const allPages: Array<{ managed_title?: string; managed_meta_description?: string }> = pagesData?.pages || pagesData?.data || []\n const optimized = allPages.filter(p => p.managed_title && p.managed_meta_description)\n console.log(`[site-kit] Meta optimization coverage: ${optimized.length}/${allPages.length} pages (${allPages.length ? Math.round((optimized.length / allPages.length) * 100) : 0}%)`)\n }\n } catch {\n console.warn('[site-kit] Could not verify meta optimization coverage')\n }\n }\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/sitemap/index.ts"],"names":["pathToFileURL","join","existsSync","readdirSync","statSync","resolve","getSiteConfig","writeLLMsTxtToPublic"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @sonordev/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\nimport { getSiteConfig } from '../site-config'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (optional when apiKey is set; then resolved from Portal project-info) */\n baseUrl?: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /**\n * Explicit values for dynamic route segments.\n * Keys are the segment names (e.g. '[slug]') and values are arrays of param values.\n * This is a simpler alternative to relying on generateStaticParams auto-discovery.\n * @example { '[slug]': ['seo', 'analytics', 'crm', 'echo'] }\n */\n dynamicRoutes?: Record<string, string[]>\n /** When true (default), attempt to import generateStaticParams from dynamic route pages at build time */\n resolveGenerateStaticParams?: boolean\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to SONOR_API_URL or https://api.sonor.io) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to SONOR_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n /** Use Signal AI visibility scores to compute page priority (40% visibility + 30% depth + 30% base) */\n intelligentPriority?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'sonor-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Convert a file-system path (relative to appDir) into a URL path,\n * stripping route groups and cleaning slashes.\n */\nfunction toUrlPath(fsPath: string): string {\n let urlPath = '/' + fsPath\n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n return urlPath\n}\n\n/**\n * Attempt to call generateStaticParams from a dynamic route page module.\n * Returns the param objects, or null if unavailable.\n */\nasync function tryGenerateStaticParams(\n pageFilePath: string\n): Promise<Array<Record<string, string>> | null> {\n try {\n const fileUrl = pathToFileURL(pageFilePath).href\n // Use a timeout to guard against slow external API calls\n const importPromise = import(fileUrl)\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams import timed out (5s)')), 5000)\n )\n const mod = await Promise.race([importPromise, timeoutPromise])\n\n if (typeof mod.generateStaticParams === 'function') {\n const resultPromise = Promise.resolve(mod.generateStaticParams())\n const resultTimeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams call timed out (10s)')), 10000)\n )\n const params = await Promise.race([resultPromise, resultTimeout])\n if (Array.isArray(params)) {\n return params as Array<Record<string, string>>\n }\n }\n } catch (err) {\n console.warn(\n `[site-kit] Could not resolve generateStaticParams from ${pageFilePath}:`,\n (err as Error).message\n )\n }\n return null\n}\n\ninterface DiscoverPagesOptions {\n /** Explicit param values for dynamic segments, keyed by segment name e.g. '[slug]' */\n dynamicRoutes?: Record<string, string[]>\n /** Whether to attempt auto-import of generateStaticParams (default true) */\n resolveGenerateStaticParams?: boolean\n}\n\n/**\n * Recursively discover pages from the app directory.\n * Handles dynamic route segments via explicit config or generateStaticParams auto-discovery.\n */\nasync function discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = [],\n options: DiscoverPagesOptions = {}\n): Promise<string[]> {\n const fullPath = join(appDir, currentPath)\n\n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n\n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n\n if (hasPage) {\n const urlPath = toUrlPath(currentPath)\n // Only add if the path has no unresolved dynamic segments\n if (!urlPath.includes('[')) {\n pages.push(urlPath)\n }\n }\n\n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n\n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n\n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n\n // Handle dynamic route segments\n if (entry.startsWith('[') && entry.endsWith(']')) {\n const paramName = entry.slice(1, -1) // e.g. 'slug' from '[slug]'\n let paramValues: string[] | null = null\n\n // 1. Check explicit dynamicRoutes config first\n if (options.dynamicRoutes) {\n // Match by full segment name '[slug]' or bare param name 'slug'\n paramValues = options.dynamicRoutes[entry] ?? options.dynamicRoutes[paramName] ?? null\n }\n\n // 2. Fall back to auto-importing generateStaticParams\n if (!paramValues && options.resolveGenerateStaticParams !== false) {\n // Find the page file inside the dynamic directory\n const dynamicDirPath = join(fullPath, entry)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(dynamicDirPath, pf)))\n\n if (pageFile) {\n const pageFilePath = resolve(dynamicDirPath, pageFile)\n const params = await tryGenerateStaticParams(pageFilePath)\n if (params && params.length > 0) {\n // Extract the values for this specific param\n paramValues = params\n .map(p => p[paramName])\n .filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (paramValues && paramValues.length > 0) {\n const dynamicDirPath = join(fullPath, entry)\n const dynamicEntries = readdirSync(dynamicDirPath)\n\n // Check if the dynamic directory itself has a page file\n const dynamicHasPage = dynamicEntries.some(e => PAGE_FILES.includes(e))\n\n for (const value of paramValues) {\n // If the dynamic dir has a page, add the resolved path\n if (dynamicHasPage) {\n const resolvedPath = toUrlPath(join(currentPath, value))\n if (!resolvedPath.includes('[')) {\n pages.push(resolvedPath)\n }\n }\n\n // Recurse into subdirectories inside the dynamic segment,\n // mapping [param] on disk to the resolved value in the URL\n for (const subEntry of dynamicEntries) {\n if (PAGE_FILES.includes(subEntry)) continue // skip page files\n const subEntryPath = join(dynamicDirPath, subEntry)\n if (statSync(subEntryPath).isDirectory()) {\n // For nested dynamic segments or regular subdirs, recurse\n // We need a custom appDir-relative path that uses the resolved value\n // but reads from the dynamic dir on disk\n await discoverPagesFromDisk(\n dynamicDirPath,\n subEntry,\n join(currentPath, value),\n pages,\n options\n )\n }\n }\n }\n } else {\n console.warn(\n `[site-kit] Skipping dynamic segment \"${entry}\" at /${currentPath} — no params resolved. ` +\n `Provide dynamicRoutes config or export generateStaticParams from the page.`\n )\n }\n continue\n }\n\n await discoverPages(appDir, join(currentPath, entry), pages, options)\n }\n }\n\n return pages\n}\n\n/**\n * Discover pages starting from a disk path that differs from the URL path.\n * Used when traversing inside dynamic route segments where the filesystem\n * directory name (e.g. [slug]) differs from the URL segment (e.g. 'seo').\n */\nasync function discoverPagesFromDisk(\n diskParent: string,\n diskEntry: string,\n urlParentPath: string,\n pages: string[],\n options: DiscoverPagesOptions\n): Promise<void> {\n const diskPath = join(diskParent, diskEntry)\n if (!existsSync(diskPath) || !statSync(diskPath).isDirectory()) return\n\n const entries = readdirSync(diskPath)\n const hasPage = entries.some(e => PAGE_FILES.includes(e))\n const urlPath = toUrlPath(join(urlParentPath, diskEntry))\n\n if (hasPage && !urlPath.includes('[')) {\n pages.push(urlPath)\n }\n\n for (const sub of entries) {\n if (PAGE_FILES.includes(sub)) continue\n const subPath = join(diskPath, sub)\n if (!statSync(subPath).isDirectory()) continue\n\n const folderName = sub.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) continue\n if (sub.startsWith('_')) continue\n\n if (sub.startsWith('[') && sub.endsWith(']')) {\n // Nested dynamic segment — resolve its params too\n const nestedParam = sub.slice(1, -1)\n let nestedValues: string[] | null = null\n\n if (options.dynamicRoutes) {\n nestedValues = options.dynamicRoutes[sub] ?? options.dynamicRoutes[nestedParam] ?? null\n }\n\n if (!nestedValues && options.resolveGenerateStaticParams !== false) {\n const nestedDir = join(diskPath, sub)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(nestedDir, pf)))\n if (pageFile) {\n const params = await tryGenerateStaticParams(resolve(nestedDir, pageFile))\n if (params && params.length > 0) {\n nestedValues = params.map(p => p[nestedParam]).filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (nestedValues && nestedValues.length > 0) {\n const nestedDir = join(diskPath, sub)\n const nestedEntries = readdirSync(nestedDir)\n const nestedHasPage = nestedEntries.some(e => PAGE_FILES.includes(e))\n for (const val of nestedValues) {\n if (nestedHasPage) {\n const resolved = toUrlPath(join(urlParentPath, diskEntry, val))\n if (!resolved.includes('[')) pages.push(resolved)\n }\n for (const nestedSub of nestedEntries) {\n if (PAGE_FILES.includes(nestedSub)) continue\n const nestedSubPath = join(nestedDir, nestedSub)\n if (statSync(nestedSubPath).isDirectory()) {\n await discoverPagesFromDisk(nestedDir, nestedSub, join(urlParentPath, diskEntry, val), pages, options)\n }\n }\n }\n }\n continue\n }\n\n await discoverPagesFromDisk(diskPath, sub, join(urlParentPath, diskEntry), pages, options)\n }\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries, mode: 'full-replace' }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Resolve baseUrl: from config, or from Portal via apiKey/env\n let baseUrl = config.baseUrl\n if (!baseUrl) {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY\n const site = await getSiteConfig({ apiKey, apiUrl: config.apiUrl })\n baseUrl = site?.site_url ?? process.env.NEXT_PUBLIC_SITE_URL ?? 'https://example.com'\n }\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/sonor-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory (including dynamic routes)\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = await discoverPages(appDir, '', [], {\n dynamicRoutes: config.dynamicRoutes,\n resolveGenerateStaticParams: config.resolveGenerateStaticParams,\n })\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Deduplicate and filter out excluded pages\n pages = Array.from(new Set(pages)).filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided (deduplicating against discovered pages)\n if (config.additionalPaths) {\n try {\n const existingUrls = new Set(entries.map(e => e.url))\n const additional = await config.additionalPaths()\n for (const item of additional) {\n const fullUrl = `${normalizedBaseUrl}${item.path}`\n if (!isExcluded(item.path, allExclusions) && !existingUrls.has(fullUrl)) {\n entries.push({\n url: fullUrl,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n existingUrls.add(fullUrl)\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Intelligent priority: blend visibility scores with depth-based priority\n if (config.intelligentPriority) {\n try {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? ''\n const projectIdMatch = apiKey.match(/^(?:sonor|uptrade)_([0-9a-f-]{36})_/)\n const projectId = projectIdMatch ? projectIdMatch[1] : null\n\n if (projectId) {\n const signalApiUrl = process.env.SONOR_SIGNAL_URL || process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.sonor.io'\n const visResponse = await fetch(`${signalApiUrl}/skills/seo/visibility/${projectId}`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n }).catch(() => null)\n\n if (visResponse?.ok) {\n const visData = await visResponse.json()\n const scores = (visData?.data || visData) as Array<{ page_path: string; overall_score: number }>\n const scoreMap = new Map(scores.map(s => [s.page_path, s.overall_score]))\n\n let appliedCount = 0\n for (const entry of entries) {\n const path = new URL(entry.url).pathname\n const visScore = scoreMap.get(path)\n if (visScore !== undefined) {\n const depthBonus = path === '/' ? 1.0 : Math.max(0.3, 1.0 - (path.split('/').filter(Boolean).length * 0.15))\n // 40% visibility + 30% depth + 30% base\n entry.priority = Math.round((visScore * 0.4 + depthBonus * 0.3 + (entry.priority ?? 0.5) * 0.3) * 100) / 100\n appliedCount++\n }\n }\n if (appliedCount > 0) {\n console.log(`[site-kit] Applied intelligent priority from ${appliedCount} visibility scores`)\n }\n }\n }\n } catch {\n // Signal API unavailable — fall back to static priority\n }\n }\n\n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time only (skip in dev — sitemap.xml is re-rendered on every request)\n const isDev = process.env.NODE_ENV === 'development'\n if (!config.disableSync && !isDev) {\n const apiUrl = config.apiUrl || process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = config.apiKey || process.env.SONOR_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n\n // Verification: report meta optimization coverage after sync\n if (config.awaitMetaOptimization) {\n try {\n const pagesResponse = await fetch(`${apiUrl}/api/public/seo/pages`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n })\n if (pagesResponse.ok) {\n const pagesData = await pagesResponse.json()\n const allPages: Array<{ managed_title?: string; managed_meta_description?: string }> = pagesData?.pages || pagesData?.data || []\n const optimized = allPages.filter(p => p.managed_title && p.managed_meta_description)\n console.log(`[site-kit] Meta optimization coverage: ${optimized.length}/${allPages.length} pages (${allPages.length ? Math.round((optimized.length / allPages.length) * 100) : 0}%)`)\n }\n } catch {\n console.warn('[site-kit] Could not verify meta optimization coverage')\n }\n }\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
|
package/dist/sitemap/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { writeLLMsTxtToPublic } from '../chunk-
|
|
2
|
-
import { getSiteConfig } from '../chunk-
|
|
1
|
+
import { writeLLMsTxtToPublic } from '../chunk-W7RZ3OTA.mjs';
|
|
2
|
+
import { getSiteConfig } from '../chunk-B22WSN4L.mjs';
|
|
3
3
|
import '../chunk-4XPGGLVP.mjs';
|
|
4
4
|
import { existsSync, readdirSync, statSync } from 'fs';
|
|
5
5
|
import { join, resolve } from 'path';
|
|
@@ -279,7 +279,7 @@ function createSitemap(config) {
|
|
|
279
279
|
const { exclude = [], defaultChangeFrequency = "weekly" } = config;
|
|
280
280
|
let baseUrl = config.baseUrl;
|
|
281
281
|
if (!baseUrl) {
|
|
282
|
-
const apiKey = config.apiKey ?? process.env.SONOR_API_KEY
|
|
282
|
+
const apiKey = config.apiKey ?? process.env.SONOR_API_KEY;
|
|
283
283
|
const site = await getSiteConfig({ apiKey, apiUrl: config.apiUrl });
|
|
284
284
|
baseUrl = site?.site_url ?? process.env.NEXT_PUBLIC_SITE_URL ?? "https://example.com";
|
|
285
285
|
}
|
|
@@ -332,7 +332,7 @@ function createSitemap(config) {
|
|
|
332
332
|
}
|
|
333
333
|
if (config.intelligentPriority) {
|
|
334
334
|
try {
|
|
335
|
-
const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ??
|
|
335
|
+
const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? "";
|
|
336
336
|
const projectIdMatch = apiKey.match(/^(?:sonor|uptrade)_([0-9a-f-]{36})_/);
|
|
337
337
|
const projectId = projectIdMatch ? projectIdMatch[1] : null;
|
|
338
338
|
if (projectId) {
|
|
@@ -364,9 +364,10 @@ function createSitemap(config) {
|
|
|
364
364
|
}
|
|
365
365
|
entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
366
366
|
console.log(`[site-kit] Generated sitemap with ${entries.length} pages`);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
const
|
|
367
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
368
|
+
if (!config.disableSync && !isDev) {
|
|
369
|
+
const apiUrl = config.apiUrl || process.env.SONOR_API_URL || "https://api.sonor.io";
|
|
370
|
+
const apiKey = config.apiKey || process.env.SONOR_API_KEY;
|
|
370
371
|
if (apiKey) {
|
|
371
372
|
try {
|
|
372
373
|
const syncOptions = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\nimport { getSiteConfig } from '../site-config'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (optional when apiKey is set; then resolved from Portal project-info) */\n baseUrl?: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /**\n * Explicit values for dynamic route segments.\n * Keys are the segment names (e.g. '[slug]') and values are arrays of param values.\n * This is a simpler alternative to relying on generateStaticParams auto-discovery.\n * @example { '[slug]': ['seo', 'analytics', 'crm', 'echo'] }\n */\n dynamicRoutes?: Record<string, string[]>\n /** When true (default), attempt to import generateStaticParams from dynamic route pages at build time */\n resolveGenerateStaticParams?: boolean\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to SONOR_API_URL or https://api.sonor.io) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to SONOR_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n /** Use Signal AI visibility scores to compute page priority (40% visibility + 30% depth + 30% base) */\n intelligentPriority?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'sonor-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Convert a file-system path (relative to appDir) into a URL path,\n * stripping route groups and cleaning slashes.\n */\nfunction toUrlPath(fsPath: string): string {\n let urlPath = '/' + fsPath\n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n return urlPath\n}\n\n/**\n * Attempt to call generateStaticParams from a dynamic route page module.\n * Returns the param objects, or null if unavailable.\n */\nasync function tryGenerateStaticParams(\n pageFilePath: string\n): Promise<Array<Record<string, string>> | null> {\n try {\n const fileUrl = pathToFileURL(pageFilePath).href\n // Use a timeout to guard against slow external API calls\n const importPromise = import(fileUrl)\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams import timed out (5s)')), 5000)\n )\n const mod = await Promise.race([importPromise, timeoutPromise])\n\n if (typeof mod.generateStaticParams === 'function') {\n const resultPromise = Promise.resolve(mod.generateStaticParams())\n const resultTimeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams call timed out (10s)')), 10000)\n )\n const params = await Promise.race([resultPromise, resultTimeout])\n if (Array.isArray(params)) {\n return params as Array<Record<string, string>>\n }\n }\n } catch (err) {\n console.warn(\n `[site-kit] Could not resolve generateStaticParams from ${pageFilePath}:`,\n (err as Error).message\n )\n }\n return null\n}\n\ninterface DiscoverPagesOptions {\n /** Explicit param values for dynamic segments, keyed by segment name e.g. '[slug]' */\n dynamicRoutes?: Record<string, string[]>\n /** Whether to attempt auto-import of generateStaticParams (default true) */\n resolveGenerateStaticParams?: boolean\n}\n\n/**\n * Recursively discover pages from the app directory.\n * Handles dynamic route segments via explicit config or generateStaticParams auto-discovery.\n */\nasync function discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = [],\n options: DiscoverPagesOptions = {}\n): Promise<string[]> {\n const fullPath = join(appDir, currentPath)\n\n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n\n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n\n if (hasPage) {\n const urlPath = toUrlPath(currentPath)\n // Only add if the path has no unresolved dynamic segments\n if (!urlPath.includes('[')) {\n pages.push(urlPath)\n }\n }\n\n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n\n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n\n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n\n // Handle dynamic route segments\n if (entry.startsWith('[') && entry.endsWith(']')) {\n const paramName = entry.slice(1, -1) // e.g. 'slug' from '[slug]'\n let paramValues: string[] | null = null\n\n // 1. Check explicit dynamicRoutes config first\n if (options.dynamicRoutes) {\n // Match by full segment name '[slug]' or bare param name 'slug'\n paramValues = options.dynamicRoutes[entry] ?? options.dynamicRoutes[paramName] ?? null\n }\n\n // 2. Fall back to auto-importing generateStaticParams\n if (!paramValues && options.resolveGenerateStaticParams !== false) {\n // Find the page file inside the dynamic directory\n const dynamicDirPath = join(fullPath, entry)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(dynamicDirPath, pf)))\n\n if (pageFile) {\n const pageFilePath = resolve(dynamicDirPath, pageFile)\n const params = await tryGenerateStaticParams(pageFilePath)\n if (params && params.length > 0) {\n // Extract the values for this specific param\n paramValues = params\n .map(p => p[paramName])\n .filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (paramValues && paramValues.length > 0) {\n const dynamicDirPath = join(fullPath, entry)\n const dynamicEntries = readdirSync(dynamicDirPath)\n\n // Check if the dynamic directory itself has a page file\n const dynamicHasPage = dynamicEntries.some(e => PAGE_FILES.includes(e))\n\n for (const value of paramValues) {\n // If the dynamic dir has a page, add the resolved path\n if (dynamicHasPage) {\n const resolvedPath = toUrlPath(join(currentPath, value))\n if (!resolvedPath.includes('[')) {\n pages.push(resolvedPath)\n }\n }\n\n // Recurse into subdirectories inside the dynamic segment,\n // mapping [param] on disk to the resolved value in the URL\n for (const subEntry of dynamicEntries) {\n if (PAGE_FILES.includes(subEntry)) continue // skip page files\n const subEntryPath = join(dynamicDirPath, subEntry)\n if (statSync(subEntryPath).isDirectory()) {\n // For nested dynamic segments or regular subdirs, recurse\n // We need a custom appDir-relative path that uses the resolved value\n // but reads from the dynamic dir on disk\n await discoverPagesFromDisk(\n dynamicDirPath,\n subEntry,\n join(currentPath, value),\n pages,\n options\n )\n }\n }\n }\n } else {\n console.warn(\n `[site-kit] Skipping dynamic segment \"${entry}\" at /${currentPath} — no params resolved. ` +\n `Provide dynamicRoutes config or export generateStaticParams from the page.`\n )\n }\n continue\n }\n\n await discoverPages(appDir, join(currentPath, entry), pages, options)\n }\n }\n\n return pages\n}\n\n/**\n * Discover pages starting from a disk path that differs from the URL path.\n * Used when traversing inside dynamic route segments where the filesystem\n * directory name (e.g. [slug]) differs from the URL segment (e.g. 'seo').\n */\nasync function discoverPagesFromDisk(\n diskParent: string,\n diskEntry: string,\n urlParentPath: string,\n pages: string[],\n options: DiscoverPagesOptions\n): Promise<void> {\n const diskPath = join(diskParent, diskEntry)\n if (!existsSync(diskPath) || !statSync(diskPath).isDirectory()) return\n\n const entries = readdirSync(diskPath)\n const hasPage = entries.some(e => PAGE_FILES.includes(e))\n const urlPath = toUrlPath(join(urlParentPath, diskEntry))\n\n if (hasPage && !urlPath.includes('[')) {\n pages.push(urlPath)\n }\n\n for (const sub of entries) {\n if (PAGE_FILES.includes(sub)) continue\n const subPath = join(diskPath, sub)\n if (!statSync(subPath).isDirectory()) continue\n\n const folderName = sub.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) continue\n if (sub.startsWith('_')) continue\n\n if (sub.startsWith('[') && sub.endsWith(']')) {\n // Nested dynamic segment — resolve its params too\n const nestedParam = sub.slice(1, -1)\n let nestedValues: string[] | null = null\n\n if (options.dynamicRoutes) {\n nestedValues = options.dynamicRoutes[sub] ?? options.dynamicRoutes[nestedParam] ?? null\n }\n\n if (!nestedValues && options.resolveGenerateStaticParams !== false) {\n const nestedDir = join(diskPath, sub)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(nestedDir, pf)))\n if (pageFile) {\n const params = await tryGenerateStaticParams(resolve(nestedDir, pageFile))\n if (params && params.length > 0) {\n nestedValues = params.map(p => p[nestedParam]).filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (nestedValues && nestedValues.length > 0) {\n const nestedDir = join(diskPath, sub)\n const nestedEntries = readdirSync(nestedDir)\n const nestedHasPage = nestedEntries.some(e => PAGE_FILES.includes(e))\n for (const val of nestedValues) {\n if (nestedHasPage) {\n const resolved = toUrlPath(join(urlParentPath, diskEntry, val))\n if (!resolved.includes('[')) pages.push(resolved)\n }\n for (const nestedSub of nestedEntries) {\n if (PAGE_FILES.includes(nestedSub)) continue\n const nestedSubPath = join(nestedDir, nestedSub)\n if (statSync(nestedSubPath).isDirectory()) {\n await discoverPagesFromDisk(nestedDir, nestedSub, join(urlParentPath, diskEntry, val), pages, options)\n }\n }\n }\n }\n continue\n }\n\n await discoverPagesFromDisk(diskPath, sub, join(urlParentPath, diskEntry), pages, options)\n }\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries, mode: 'full-replace' }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Resolve baseUrl: from config, or from Portal via apiKey/env\n let baseUrl = config.baseUrl\n if (!baseUrl) {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? process.env.UPTRADE_API_KEY ?? process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n const site = await getSiteConfig({ apiKey, apiUrl: config.apiUrl })\n baseUrl = site?.site_url ?? process.env.NEXT_PUBLIC_SITE_URL ?? 'https://example.com'\n }\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/sonor-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory (including dynamic routes)\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = await discoverPages(appDir, '', [], {\n dynamicRoutes: config.dynamicRoutes,\n resolveGenerateStaticParams: config.resolveGenerateStaticParams,\n })\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Deduplicate and filter out excluded pages\n pages = Array.from(new Set(pages)).filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided (deduplicating against discovered pages)\n if (config.additionalPaths) {\n try {\n const existingUrls = new Set(entries.map(e => e.url))\n const additional = await config.additionalPaths()\n for (const item of additional) {\n const fullUrl = `${normalizedBaseUrl}${item.path}`\n if (!isExcluded(item.path, allExclusions) && !existingUrls.has(fullUrl)) {\n entries.push({\n url: fullUrl,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n existingUrls.add(fullUrl)\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Intelligent priority: blend visibility scores with depth-based priority\n if (config.intelligentPriority) {\n try {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? process.env.UPTRADE_API_KEY ?? process.env.NEXT_PUBLIC_UPTRADE_API_KEY ?? ''\n const projectIdMatch = apiKey.match(/^(?:sonor|uptrade)_([0-9a-f-]{36})_/)\n const projectId = projectIdMatch ? projectIdMatch[1] : null\n\n if (projectId) {\n const signalApiUrl = process.env.SONOR_SIGNAL_URL || process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.sonor.io'\n const visResponse = await fetch(`${signalApiUrl}/skills/seo/visibility/${projectId}`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n }).catch(() => null)\n\n if (visResponse?.ok) {\n const visData = await visResponse.json()\n const scores = (visData?.data || visData) as Array<{ page_path: string; overall_score: number }>\n const scoreMap = new Map(scores.map(s => [s.page_path, s.overall_score]))\n\n let appliedCount = 0\n for (const entry of entries) {\n const path = new URL(entry.url).pathname\n const visScore = scoreMap.get(path)\n if (visScore !== undefined) {\n const depthBonus = path === '/' ? 1.0 : Math.max(0.3, 1.0 - (path.split('/').filter(Boolean).length * 0.15))\n // 40% visibility + 30% depth + 30% base\n entry.priority = Math.round((visScore * 0.4 + depthBonus * 0.3 + (entry.priority ?? 0.5) * 0.3) * 100) / 100\n appliedCount++\n }\n }\n if (appliedCount > 0) {\n console.log(`[site-kit] Applied intelligent priority from ${appliedCount} visibility scores`)\n }\n }\n }\n } catch {\n // Signal API unavailable — fall back to static priority\n }\n }\n\n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time (unless disabled)\n if (!config.disableSync) {\n const apiUrl = config.apiUrl || process.env.SONOR_API_URL || process.env.UPTRADE_API_URL || process.env.NEXT_PUBLIC_UPTRADE_API_URL || 'https://api.sonor.io'\n // Server-side operations prefer SONOR_API_KEY\n const apiKey = config.apiKey || process.env.SONOR_API_KEY || process.env.UPTRADE_API_KEY || process.env.NEXT_PUBLIC_UPTRADE_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n\n // Verification: report meta optimization coverage after sync\n if (config.awaitMetaOptimization) {\n try {\n const pagesResponse = await fetch(`${apiUrl}/api/public/seo/pages`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n })\n if (pagesResponse.ok) {\n const pagesData = await pagesResponse.json()\n const allPages: Array<{ managed_title?: string; managed_meta_description?: string }> = pagesData?.pages || pagesData?.data || []\n const optimized = allPages.filter(p => p.managed_title && p.managed_meta_description)\n console.log(`[site-kit] Meta optimization coverage: ${optimized.length}/${allPages.length} pages (${allPages.length ? Math.round((optimized.length / allPages.length) * 100) : 0}%)`)\n }\n } catch {\n console.warn('[site-kit] Could not verify meta optimization coverage')\n }\n }\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/sitemap/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit - Sitemap Generator\n * \n * Automatically generates sitemap.xml from Next.js app directory structure.\n * Works at build time to discover all pages and sync them to Portal API.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com',\n * // Optional: exclude patterns\n * exclude: ['/admin/*', '/api/*'],\n * // Optional: additional dynamic routes\n * additionalPaths: async () => [\n * { path: '/blog/post-1', priority: 0.7 },\n * ]\n * })\n * ```\n */\n\nimport { readdirSync, statSync, existsSync } from 'fs'\nimport { join, resolve } from 'path'\nimport { pathToFileURL } from 'url'\nimport { writeLLMsTxtToPublic } from '../llms/writeLLMsTxt'\nimport { getSiteConfig } from '../site-config'\n\nexport interface SitemapEntry {\n url: string\n lastModified?: Date | string\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\nexport interface SitemapConfig {\n /** Base URL for the site (optional when apiKey is set; then resolved from Portal project-info) */\n baseUrl?: string\n /** Glob patterns to exclude (e.g., ['/admin/*', '/api/*']) */\n exclude?: string[]\n /** Default priority for pages */\n defaultPriority?: number\n /** Default change frequency */\n defaultChangeFrequency?: SitemapEntry['changeFrequency']\n /** Additional paths to include (for dynamic routes) */\n additionalPaths?: () => Promise<Array<{ path: string; priority?: number; changeFrequency?: SitemapEntry['changeFrequency'] }>>\n /**\n * Explicit values for dynamic route segments.\n * Keys are the segment names (e.g. '[slug]') and values are arrays of param values.\n * This is a simpler alternative to relying on generateStaticParams auto-discovery.\n * @example { '[slug]': ['seo', 'analytics', 'crm', 'echo'] }\n */\n dynamicRoutes?: Record<string, string[]>\n /** When true (default), attempt to import generateStaticParams from dynamic route pages at build time */\n resolveGenerateStaticParams?: boolean\n /** Priority overrides by path pattern */\n priorities?: Record<string, number>\n /** Portal API URL for syncing (defaults to SONOR_API_URL or https://api.sonor.io) */\n apiUrl?: string\n /** Portal API key for syncing (defaults to SONOR_API_KEY) */\n apiKey?: string\n /** Disable auto-sync to Portal API */\n disableSync?: boolean\n /** When true, await meta optimization before build completes (for build-time llms.txt with managed_llm_schema) */\n awaitMetaOptimization?: boolean\n /** When true (default when API key present), write AI-optimized llms.txt to public/llms.txt after sitemap sync */\n optimizedLLMsTxt?: boolean\n /** When true with optimizedLLMsTxt, also write public/llms-full.txt */\n optimizedLLMsFullTxt?: boolean\n /** When Portal returns empty services, use this to supply local site data for llms.txt */\n getLocalData?: () => Promise<import('../llms/types').LLMsDataResponse | null>\n /** Use Signal AI visibility scores to compute page priority (40% visibility + 30% depth + 30% base) */\n intelligentPriority?: boolean\n}\n\n// Route groups and special folders to ignore\nconst IGNORED_FOLDERS = [\n 'api',\n 'admin',\n '_uptrade',\n '%5Fuptrade', // URL-encoded _uptrade\n 'sonor-setup',\n 'offline',\n]\n\n// File patterns that indicate a page\nconst PAGE_FILES = ['page.tsx', 'page.jsx', 'page.js', 'page.ts']\n\n/**\n * Check if a path matches any exclude pattern\n */\nfunction isExcluded(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n return path.startsWith(prefix)\n }\n if (pattern.endsWith('*')) {\n const prefix = pattern.slice(0, -1)\n return path.startsWith(prefix)\n }\n return path === pattern\n })\n}\n\n/**\n * Convert a file-system path (relative to appDir) into a URL path,\n * stripping route groups and cleaning slashes.\n */\nfunction toUrlPath(fsPath: string): string {\n let urlPath = '/' + fsPath\n // Handle route groups (parentheses) - remove them from URL\n urlPath = urlPath.replace(/\\/\\([^)]+\\)/g, '')\n // Clean up path\n urlPath = urlPath.replace(/\\/+/g, '/') // Remove double slashes\n if (urlPath !== '/' && urlPath.endsWith('/')) {\n urlPath = urlPath.slice(0, -1) // Remove trailing slash\n }\n return urlPath\n}\n\n/**\n * Attempt to call generateStaticParams from a dynamic route page module.\n * Returns the param objects, or null if unavailable.\n */\nasync function tryGenerateStaticParams(\n pageFilePath: string\n): Promise<Array<Record<string, string>> | null> {\n try {\n const fileUrl = pathToFileURL(pageFilePath).href\n // Use a timeout to guard against slow external API calls\n const importPromise = import(fileUrl)\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams import timed out (5s)')), 5000)\n )\n const mod = await Promise.race([importPromise, timeoutPromise])\n\n if (typeof mod.generateStaticParams === 'function') {\n const resultPromise = Promise.resolve(mod.generateStaticParams())\n const resultTimeout = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error('generateStaticParams call timed out (10s)')), 10000)\n )\n const params = await Promise.race([resultPromise, resultTimeout])\n if (Array.isArray(params)) {\n return params as Array<Record<string, string>>\n }\n }\n } catch (err) {\n console.warn(\n `[site-kit] Could not resolve generateStaticParams from ${pageFilePath}:`,\n (err as Error).message\n )\n }\n return null\n}\n\ninterface DiscoverPagesOptions {\n /** Explicit param values for dynamic segments, keyed by segment name e.g. '[slug]' */\n dynamicRoutes?: Record<string, string[]>\n /** Whether to attempt auto-import of generateStaticParams (default true) */\n resolveGenerateStaticParams?: boolean\n}\n\n/**\n * Recursively discover pages from the app directory.\n * Handles dynamic route segments via explicit config or generateStaticParams auto-discovery.\n */\nasync function discoverPages(\n appDir: string,\n currentPath: string = '',\n pages: string[] = [],\n options: DiscoverPagesOptions = {}\n): Promise<string[]> {\n const fullPath = join(appDir, currentPath)\n\n if (!existsSync(fullPath)) {\n return pages\n }\n\n const entries = readdirSync(fullPath)\n\n // Check if this directory has a page file\n const hasPage = entries.some(entry => PAGE_FILES.includes(entry))\n\n if (hasPage) {\n const urlPath = toUrlPath(currentPath)\n // Only add if the path has no unresolved dynamic segments\n if (!urlPath.includes('[')) {\n pages.push(urlPath)\n }\n }\n\n // Recurse into subdirectories\n for (const entry of entries) {\n const entryPath = join(fullPath, entry)\n const stat = statSync(entryPath)\n\n if (stat.isDirectory()) {\n // Skip ignored folders\n const folderName = entry.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) {\n continue\n }\n\n // Skip private folders\n if (entry.startsWith('_')) {\n continue\n }\n\n // Handle dynamic route segments\n if (entry.startsWith('[') && entry.endsWith(']')) {\n const paramName = entry.slice(1, -1) // e.g. 'slug' from '[slug]'\n let paramValues: string[] | null = null\n\n // 1. Check explicit dynamicRoutes config first\n if (options.dynamicRoutes) {\n // Match by full segment name '[slug]' or bare param name 'slug'\n paramValues = options.dynamicRoutes[entry] ?? options.dynamicRoutes[paramName] ?? null\n }\n\n // 2. Fall back to auto-importing generateStaticParams\n if (!paramValues && options.resolveGenerateStaticParams !== false) {\n // Find the page file inside the dynamic directory\n const dynamicDirPath = join(fullPath, entry)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(dynamicDirPath, pf)))\n\n if (pageFile) {\n const pageFilePath = resolve(dynamicDirPath, pageFile)\n const params = await tryGenerateStaticParams(pageFilePath)\n if (params && params.length > 0) {\n // Extract the values for this specific param\n paramValues = params\n .map(p => p[paramName])\n .filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (paramValues && paramValues.length > 0) {\n const dynamicDirPath = join(fullPath, entry)\n const dynamicEntries = readdirSync(dynamicDirPath)\n\n // Check if the dynamic directory itself has a page file\n const dynamicHasPage = dynamicEntries.some(e => PAGE_FILES.includes(e))\n\n for (const value of paramValues) {\n // If the dynamic dir has a page, add the resolved path\n if (dynamicHasPage) {\n const resolvedPath = toUrlPath(join(currentPath, value))\n if (!resolvedPath.includes('[')) {\n pages.push(resolvedPath)\n }\n }\n\n // Recurse into subdirectories inside the dynamic segment,\n // mapping [param] on disk to the resolved value in the URL\n for (const subEntry of dynamicEntries) {\n if (PAGE_FILES.includes(subEntry)) continue // skip page files\n const subEntryPath = join(dynamicDirPath, subEntry)\n if (statSync(subEntryPath).isDirectory()) {\n // For nested dynamic segments or regular subdirs, recurse\n // We need a custom appDir-relative path that uses the resolved value\n // but reads from the dynamic dir on disk\n await discoverPagesFromDisk(\n dynamicDirPath,\n subEntry,\n join(currentPath, value),\n pages,\n options\n )\n }\n }\n }\n } else {\n console.warn(\n `[site-kit] Skipping dynamic segment \"${entry}\" at /${currentPath} — no params resolved. ` +\n `Provide dynamicRoutes config or export generateStaticParams from the page.`\n )\n }\n continue\n }\n\n await discoverPages(appDir, join(currentPath, entry), pages, options)\n }\n }\n\n return pages\n}\n\n/**\n * Discover pages starting from a disk path that differs from the URL path.\n * Used when traversing inside dynamic route segments where the filesystem\n * directory name (e.g. [slug]) differs from the URL segment (e.g. 'seo').\n */\nasync function discoverPagesFromDisk(\n diskParent: string,\n diskEntry: string,\n urlParentPath: string,\n pages: string[],\n options: DiscoverPagesOptions\n): Promise<void> {\n const diskPath = join(diskParent, diskEntry)\n if (!existsSync(diskPath) || !statSync(diskPath).isDirectory()) return\n\n const entries = readdirSync(diskPath)\n const hasPage = entries.some(e => PAGE_FILES.includes(e))\n const urlPath = toUrlPath(join(urlParentPath, diskEntry))\n\n if (hasPage && !urlPath.includes('[')) {\n pages.push(urlPath)\n }\n\n for (const sub of entries) {\n if (PAGE_FILES.includes(sub)) continue\n const subPath = join(diskPath, sub)\n if (!statSync(subPath).isDirectory()) continue\n\n const folderName = sub.toLowerCase()\n if (IGNORED_FOLDERS.some(ignored => folderName.includes(ignored))) continue\n if (sub.startsWith('_')) continue\n\n if (sub.startsWith('[') && sub.endsWith(']')) {\n // Nested dynamic segment — resolve its params too\n const nestedParam = sub.slice(1, -1)\n let nestedValues: string[] | null = null\n\n if (options.dynamicRoutes) {\n nestedValues = options.dynamicRoutes[sub] ?? options.dynamicRoutes[nestedParam] ?? null\n }\n\n if (!nestedValues && options.resolveGenerateStaticParams !== false) {\n const nestedDir = join(diskPath, sub)\n const pageFile = PAGE_FILES.find(pf => existsSync(join(nestedDir, pf)))\n if (pageFile) {\n const params = await tryGenerateStaticParams(resolve(nestedDir, pageFile))\n if (params && params.length > 0) {\n nestedValues = params.map(p => p[nestedParam]).filter((v): v is string => typeof v === 'string')\n }\n }\n }\n\n if (nestedValues && nestedValues.length > 0) {\n const nestedDir = join(diskPath, sub)\n const nestedEntries = readdirSync(nestedDir)\n const nestedHasPage = nestedEntries.some(e => PAGE_FILES.includes(e))\n for (const val of nestedValues) {\n if (nestedHasPage) {\n const resolved = toUrlPath(join(urlParentPath, diskEntry, val))\n if (!resolved.includes('[')) pages.push(resolved)\n }\n for (const nestedSub of nestedEntries) {\n if (PAGE_FILES.includes(nestedSub)) continue\n const nestedSubPath = join(nestedDir, nestedSub)\n if (statSync(nestedSubPath).isDirectory()) {\n await discoverPagesFromDisk(nestedDir, nestedSub, join(urlParentPath, diskEntry, val), pages, options)\n }\n }\n }\n }\n continue\n }\n\n await discoverPagesFromDisk(diskPath, sub, join(urlParentPath, diskEntry), pages, options)\n }\n}\n\n/**\n * Find the app directory from the current working directory\n */\nfunction findAppDir(): string {\n const cwd = process.cwd()\n \n // Try common locations\n const candidates = [\n join(cwd, 'app'),\n join(cwd, 'src', 'app'),\n ]\n \n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate\n }\n }\n \n throw new Error(\n '[site-kit] Could not find app directory. Ensure you have an \"app\" or \"src/app\" folder.'\n )\n}\n\n/**\n * Get priority for a path based on config\n */\nfunction getPriority(path: string, config: SitemapConfig): number {\n // Check priority overrides\n if (config.priorities) {\n for (const [pattern, priority] of Object.entries(config.priorities)) {\n if (pattern.endsWith('/*')) {\n const prefix = pattern.slice(0, -2)\n if (path.startsWith(prefix)) return priority\n } else if (path === pattern) {\n return priority\n }\n }\n }\n \n // Home page gets highest priority\n if (path === '/') return 1.0\n \n // Shallow pages get higher priority\n const depth = path.split('/').filter(Boolean).length\n if (depth === 1) return 0.8\n if (depth === 2) return 0.6\n \n return config.defaultPriority ?? 0.5\n}\n\nexport interface SyncSitemapOptions {\n /** Trigger Signal AI meta optimization after sync */\n optimizeMeta?: boolean\n /** When true, wait for meta optimization to complete (for build-time llms.txt) */\n awaitMeta?: boolean\n}\n\n/**\n * Sync sitemap entries to Portal API\n * Called automatically by createSitemap at build time\n */\nexport async function syncSitemapToPortal(\n entries: SitemapEntry[],\n apiUrl: string,\n apiKey: string,\n options?: SyncSitemapOptions\n): Promise<{ success: boolean; created: number; updated: number }> {\n if (!apiKey) {\n console.warn('[site-kit] No API key provided, skipping sitemap sync')\n return { success: false, created: 0, updated: 0 }\n }\n \n const normalizedEntries = entries.map(entry => {\n let path: string\n try {\n const url = new URL(entry.url)\n path = url.pathname\n } catch {\n path = entry.url.startsWith('/') ? entry.url : `/${entry.url}`\n }\n \n return {\n path,\n priority: entry.priority,\n changefreq: entry.changeFrequency,\n }\n })\n \n try {\n const body: Record<string, unknown> = { entries: normalizedEntries, mode: 'full-replace' }\n if (options?.optimizeMeta !== undefined) body.optimize_meta = options.optimizeMeta\n if (options?.awaitMeta !== undefined) body.await_meta = options.awaitMeta\n\n const response = await fetch(`${apiUrl}/api/public/seo/register-sitemap`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n },\n body: JSON.stringify(body),\n })\n \n if (!response.ok) {\n console.error('[site-kit] Sitemap sync failed:', response.status, await response.text())\n return { success: false, created: 0, updated: 0 }\n }\n \n const result = await response.json()\n \n return {\n success: true,\n created: result.created || 0,\n updated: result.updated || 0,\n }\n } catch (error) {\n console.error('[site-kit] Sitemap sync error:', error)\n return { success: false, created: 0, updated: 0 }\n }\n}\n\n/**\n * Create a sitemap generator function for Next.js\n * Automatically syncs to Portal API at build time.\n * \n * @example\n * ```ts\n * // app/sitemap.ts\n * import { createSitemap } from '@sonordev/site-kit/sitemap'\n * \n * export default createSitemap({\n * baseUrl: 'https://example.com'\n * })\n * ```\n */\nexport function createSitemap(config: SitemapConfig): () => SitemapEntry[] | Promise<SitemapEntry[]> {\n return async () => {\n const { exclude = [], defaultChangeFrequency = 'weekly' } = config\n \n // Resolve baseUrl: from config, or from Portal via apiKey/env\n let baseUrl = config.baseUrl\n if (!baseUrl) {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY\n const site = await getSiteConfig({ apiKey, apiUrl: config.apiUrl })\n baseUrl = site?.site_url ?? process.env.NEXT_PUBLIC_SITE_URL ?? 'https://example.com'\n }\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n \n // Default exclusions\n const allExclusions = [\n '/api/*',\n '/admin/*',\n '/_uptrade/*',\n '/sonor-setup/*',\n '/offline/*',\n ...exclude,\n ]\n \n // Discover pages from app directory (including dynamic routes)\n let pages: string[] = []\n try {\n const appDir = findAppDir()\n pages = await discoverPages(appDir, '', [], {\n dynamicRoutes: config.dynamicRoutes,\n resolveGenerateStaticParams: config.resolveGenerateStaticParams,\n })\n } catch (error) {\n console.warn('[site-kit] Failed to discover pages:', error)\n // Fall back to just the home page\n pages = ['/']\n }\n \n // Deduplicate and filter out excluded pages\n pages = Array.from(new Set(pages)).filter(page => !isExcluded(page, allExclusions))\n \n // Build sitemap entries\n const entries: SitemapEntry[] = pages.map(path => ({\n url: `${normalizedBaseUrl}${path}`,\n lastModified: new Date(),\n changeFrequency: defaultChangeFrequency,\n priority: getPriority(path, config),\n }))\n \n // Add additional dynamic paths if provided (deduplicating against discovered pages)\n if (config.additionalPaths) {\n try {\n const existingUrls = new Set(entries.map(e => e.url))\n const additional = await config.additionalPaths()\n for (const item of additional) {\n const fullUrl = `${normalizedBaseUrl}${item.path}`\n if (!isExcluded(item.path, allExclusions) && !existingUrls.has(fullUrl)) {\n entries.push({\n url: fullUrl,\n lastModified: new Date(),\n changeFrequency: item.changeFrequency ?? defaultChangeFrequency,\n priority: item.priority ?? getPriority(item.path, config),\n })\n existingUrls.add(fullUrl)\n }\n }\n } catch (error) {\n console.warn('[site-kit] Failed to get additional paths:', error)\n }\n }\n \n // Intelligent priority: blend visibility scores with depth-based priority\n if (config.intelligentPriority) {\n try {\n const apiKey = config.apiKey ?? process.env.SONOR_API_KEY ?? ''\n const projectIdMatch = apiKey.match(/^(?:sonor|uptrade)_([0-9a-f-]{36})_/)\n const projectId = projectIdMatch ? projectIdMatch[1] : null\n\n if (projectId) {\n const signalApiUrl = process.env.SONOR_SIGNAL_URL || process.env.SIGNAL_API_URL || process.env.NEXT_PUBLIC_SIGNAL_API_URL || 'https://signal.sonor.io'\n const visResponse = await fetch(`${signalApiUrl}/skills/seo/visibility/${projectId}`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n }).catch(() => null)\n\n if (visResponse?.ok) {\n const visData = await visResponse.json()\n const scores = (visData?.data || visData) as Array<{ page_path: string; overall_score: number }>\n const scoreMap = new Map(scores.map(s => [s.page_path, s.overall_score]))\n\n let appliedCount = 0\n for (const entry of entries) {\n const path = new URL(entry.url).pathname\n const visScore = scoreMap.get(path)\n if (visScore !== undefined) {\n const depthBonus = path === '/' ? 1.0 : Math.max(0.3, 1.0 - (path.split('/').filter(Boolean).length * 0.15))\n // 40% visibility + 30% depth + 30% base\n entry.priority = Math.round((visScore * 0.4 + depthBonus * 0.3 + (entry.priority ?? 0.5) * 0.3) * 100) / 100\n appliedCount++\n }\n }\n if (appliedCount > 0) {\n console.log(`[site-kit] Applied intelligent priority from ${appliedCount} visibility scores`)\n }\n }\n }\n } catch {\n // Signal API unavailable — fall back to static priority\n }\n }\n\n // Sort by priority descending\n entries.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))\n\n console.log(`[site-kit] Generated sitemap with ${entries.length} pages`)\n \n // Auto-sync to Portal API at build time only (skip in dev — sitemap.xml is re-rendered on every request)\n const isDev = process.env.NODE_ENV === 'development'\n if (!config.disableSync && !isDev) {\n const apiUrl = config.apiUrl || process.env.SONOR_API_URL || 'https://api.sonor.io'\n const apiKey = config.apiKey || process.env.SONOR_API_KEY\n \n if (apiKey) {\n try {\n const syncOptions: SyncSitemapOptions = {}\n if (config.awaitMetaOptimization) {\n syncOptions.optimizeMeta = true\n syncOptions.awaitMeta = true\n }\n const result = await syncSitemapToPortal(entries, apiUrl, apiKey, syncOptions)\n if (result.success) {\n console.log(`[site-kit] Synced to Portal API: ${result.created} created, ${result.updated} updated`)\n\n // Verification: report meta optimization coverage after sync\n if (config.awaitMetaOptimization) {\n try {\n const pagesResponse = await fetch(`${apiUrl}/api/public/seo/pages`, {\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey },\n })\n if (pagesResponse.ok) {\n const pagesData = await pagesResponse.json()\n const allPages: Array<{ managed_title?: string; managed_meta_description?: string }> = pagesData?.pages || pagesData?.data || []\n const optimized = allPages.filter(p => p.managed_title && p.managed_meta_description)\n console.log(`[site-kit] Meta optimization coverage: ${optimized.length}/${allPages.length} pages (${allPages.length ? Math.round((optimized.length / allPages.length) * 100) : 0}%)`)\n }\n } catch {\n console.warn('[site-kit] Could not verify meta optimization coverage')\n }\n }\n }\n\n // Write AI-optimized llms.txt after sync (default true when API key present)\n if (config.optimizedLLMsTxt !== false) {\n try {\n const writeResult = await writeLLMsTxtToPublic({\n apiUrl,\n apiKey,\n full: config.optimizedLLMsFullTxt ?? false,\n fallbackToLocal: true,\n getLocalData: config.getLocalData,\n })\n if (writeResult.success) {\n console.log(`[site-kit] Wrote llms.txt (optimized=${writeResult.optimized})`)\n }\n } catch (err) {\n console.warn('[site-kit] Failed to write llms.txt:', (err as Error).message)\n }\n }\n } catch (err) {\n console.warn('[site-kit] Failed to sync sitemap to Portal API:', (err as Error).message)\n }\n } else {\n console.log('[site-kit] No API key found, skipping Portal API sync')\n }\n }\n \n return entries\n }\n}\n"]}
|
package/dist/sync/index.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkWETCVFIK_js = require('../chunk-WETCVFIK.js');
|
|
4
4
|
require('../chunk-ZSMWDLMK.js');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
Object.defineProperty(exports, "BookingWidget", {
|
|
9
9
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
10
|
+
get: function () { return chunkWETCVFIK_js.BookingWidget; }
|
|
11
11
|
});
|
|
12
12
|
Object.defineProperty(exports, "createBooking", {
|
|
13
13
|
enumerable: true,
|
|
14
|
-
get: function () { return
|
|
14
|
+
get: function () { return chunkWETCVFIK_js.createBooking; }
|
|
15
15
|
});
|
|
16
16
|
Object.defineProperty(exports, "createSlotHold", {
|
|
17
17
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
18
|
+
get: function () { return chunkWETCVFIK_js.createSlotHold; }
|
|
19
19
|
});
|
|
20
20
|
Object.defineProperty(exports, "detectTimezone", {
|
|
21
21
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
22
|
+
get: function () { return chunkWETCVFIK_js.detectTimezone; }
|
|
23
23
|
});
|
|
24
24
|
Object.defineProperty(exports, "fetchAvailability", {
|
|
25
25
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
26
|
+
get: function () { return chunkWETCVFIK_js.fetchAvailability; }
|
|
27
27
|
});
|
|
28
28
|
Object.defineProperty(exports, "fetchAvailableDates", {
|
|
29
29
|
enumerable: true,
|
|
30
|
-
get: function () { return
|
|
30
|
+
get: function () { return chunkWETCVFIK_js.fetchAvailableDates; }
|
|
31
31
|
});
|
|
32
32
|
Object.defineProperty(exports, "fetchBookingTypeDetails", {
|
|
33
33
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
34
|
+
get: function () { return chunkWETCVFIK_js.fetchBookingTypeDetails; }
|
|
35
35
|
});
|
|
36
36
|
Object.defineProperty(exports, "fetchBookingTypes", {
|
|
37
37
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
38
|
+
get: function () { return chunkWETCVFIK_js.fetchBookingTypes; }
|
|
39
39
|
});
|
|
40
40
|
Object.defineProperty(exports, "formatDate", {
|
|
41
41
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
42
|
+
get: function () { return chunkWETCVFIK_js.formatDate; }
|
|
43
43
|
});
|
|
44
44
|
Object.defineProperty(exports, "formatDuration", {
|
|
45
45
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
46
|
+
get: function () { return chunkWETCVFIK_js.formatDuration; }
|
|
47
47
|
});
|
|
48
48
|
Object.defineProperty(exports, "formatTime", {
|
|
49
49
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
50
|
+
get: function () { return chunkWETCVFIK_js.formatTime; }
|
|
51
51
|
});
|
|
52
52
|
Object.defineProperty(exports, "releaseSlotHold", {
|
|
53
53
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
54
|
+
get: function () { return chunkWETCVFIK_js.releaseSlotHold; }
|
|
55
55
|
});
|
|
56
56
|
//# sourceMappingURL=index.js.map
|
|
57
57
|
//# sourceMappingURL=index.js.map
|
package/dist/sync/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, releaseSlotHold } from '../chunk-
|
|
1
|
+
export { BookingWidget, createBooking, createSlotHold, detectTimezone, fetchAvailability, fetchAvailableDates, fetchBookingTypeDetails, fetchBookingTypes, formatDate, formatDuration, formatTime, releaseSlotHold } from '../chunk-2OJCYWSQ.mjs';
|
|
2
2
|
import '../chunk-4XPGGLVP.mjs';
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
|
4
4
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Metadata } from 'next';
|
|
2
2
|
|
|
3
|
-
interface
|
|
3
|
+
interface SonorSEOConfig {
|
|
4
4
|
/** @deprecated Project is resolved from API key by the portal; no longer required */
|
|
5
5
|
projectId?: string;
|
|
6
6
|
supabaseUrl?: string;
|
|
@@ -263,4 +263,4 @@ interface GetSitemapEntriesOptions {
|
|
|
263
263
|
publishedOnly?: boolean;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
export type { ABTest as A, FAQItem as F, GetManagedMetadataOptions as G, ManagedMetadataResult as M, RedirectResult as R,
|
|
266
|
+
export type { ABTest as A, FAQItem as F, GetManagedMetadataOptions as G, ManagedMetadataResult as M, RedirectResult as R, SonorSEOConfig as S, SEOPageData as a, SchemaMarkup as b, ManagedSchemaProps as c, ManagedFAQData as d, ManagedFAQProps as e, ManagedLink as f, ManagedInternalLinksProps as g, ManagedContentBlock as h, ManagedContentProps as i, SEOEntity as j, ABTestResult as k, GetABVariantOptions as l, ManagedRedirect as m, GetRedirectOptions as n, ManagedScript as o, ManagedScriptsProps as p, RobotsDirective as q, GetRobotsOptions as r, SitemapEntry as s, GetSitemapEntriesOptions as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Metadata } from 'next';
|
|
2
2
|
|
|
3
|
-
interface
|
|
3
|
+
interface SonorSEOConfig {
|
|
4
4
|
/** @deprecated Project is resolved from API key by the portal; no longer required */
|
|
5
5
|
projectId?: string;
|
|
6
6
|
supabaseUrl?: string;
|
|
@@ -263,4 +263,4 @@ interface GetSitemapEntriesOptions {
|
|
|
263
263
|
publishedOnly?: boolean;
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
-
export type { ABTest as A, FAQItem as F, GetManagedMetadataOptions as G, ManagedMetadataResult as M, RedirectResult as R,
|
|
266
|
+
export type { ABTest as A, FAQItem as F, GetManagedMetadataOptions as G, ManagedMetadataResult as M, RedirectResult as R, SonorSEOConfig as S, SEOPageData as a, SchemaMarkup as b, ManagedSchemaProps as c, ManagedFAQData as d, ManagedFAQProps as e, ManagedLink as f, ManagedInternalLinksProps as g, ManagedContentBlock as h, ManagedContentProps as i, SEOEntity as j, ABTestResult as k, GetABVariantOptions as l, ManagedRedirect as m, GetRedirectOptions as n, ManagedScript as o, ManagedScriptsProps as p, RobotsDirective as q, GetRobotsOptions as r, SitemapEntry as s, GetSitemapEntriesOptions as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sonordev/site-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Complete client-side integration kit for Sonor - SEO, Analytics, Engage, Forms, Blog",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -77,16 +77,6 @@
|
|
|
77
77
|
"import": "./dist/setup/index.mjs",
|
|
78
78
|
"require": "./dist/setup/index.js"
|
|
79
79
|
},
|
|
80
|
-
"./setup/client": {
|
|
81
|
-
"types": "./dist/setup/client.d.ts",
|
|
82
|
-
"import": "./dist/setup/client.mjs",
|
|
83
|
-
"require": "./dist/setup/client.js"
|
|
84
|
-
},
|
|
85
|
-
"./setup/server": {
|
|
86
|
-
"types": "./dist/setup/server.d.ts",
|
|
87
|
-
"import": "./dist/setup/server.mjs",
|
|
88
|
-
"require": "./dist/setup/server.js"
|
|
89
|
-
},
|
|
90
80
|
"./sitemap": {
|
|
91
81
|
"types": "./dist/sitemap/index.d.ts",
|
|
92
82
|
"import": "./dist/sitemap/index.mjs",
|
|
@@ -156,7 +146,9 @@
|
|
|
156
146
|
"types": "./dist/cms/server.d.ts",
|
|
157
147
|
"import": "./dist/cms/server.mjs",
|
|
158
148
|
"require": "./dist/cms/server.js"
|
|
159
|
-
}
|
|
149
|
+
},
|
|
150
|
+
"./brand.css": "./dist/brand.css",
|
|
151
|
+
"./forms/styles.css": "./dist/forms/styles.css"
|
|
160
152
|
},
|
|
161
153
|
"files": [
|
|
162
154
|
"dist",
|