@jant/core 0.3.40 → 0.3.43
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/README.md +21 -34
- package/bin/commands/assets/upload.js +247 -0
- package/bin/commands/collections.js +268 -0
- package/bin/commands/import-site.js +1169 -343
- package/bin/commands/media.js +302 -0
- package/bin/commands/migrate-text-attachments.js +183 -0
- package/bin/commands/migrate.js +263 -2
- package/bin/commands/posts.js +262 -0
- package/bin/commands/search-reindex.js +175 -0
- package/bin/commands/search.js +53 -0
- package/bin/commands/settings.js +93 -0
- package/bin/commands/site/export.js +34 -33
- package/bin/commands/site/{localize-media.js → pull-media.js} +17 -17
- package/bin/lib/d1-query.js +15 -3
- package/bin/lib/http-api.js +223 -0
- package/bin/lib/hugo-markdown.js +102 -0
- package/bin/lib/media-upload.js +206 -0
- package/bin/lib/migration-runner.js +64 -0
- package/bin/lib/runtime-target.js +7 -2
- package/bin/lib/site-media-parser.js +71 -16
- package/bin/lib/site-pull-media.js +695 -0
- package/bin/lib/site-snapshot.js +0 -1
- package/dist/app-Ctl0T0zO.js +5 -0
- package/dist/{app-CAtsuLLh.js → app-GbfwoeDJ.js} +24357 -23139
- package/dist/client/.vite/manifest.json +3485 -0
- package/dist/client/_assets/chunks/02611a045a7fe83a12014e3debc9f731-BqEDtwXC.woff2 +0 -0
- package/dist/client/_assets/chunks/033466ef683afe931f7f520cfb42d928-BluLHEh9.woff2 +0 -0
- package/dist/client/_assets/chunks/04b8bde59cff68eeee74fb1914eb09c7-D5j2CLTt.woff2 +0 -0
- package/dist/client/_assets/chunks/057a6a98bda7fe57105ddaa99ec82015-DY_AoijT.woff2 +0 -0
- package/dist/client/_assets/chunks/05ac821472e235943ed1435e4bb8ecad-CUm8GiH6.woff2 +0 -0
- package/dist/client/_assets/chunks/05da12edb9d52210581dc6ec4541031f-BXAOx2XP.woff2 +0 -0
- package/dist/client/_assets/chunks/074c1f8483d5a4d8c45c8c5f3e4cbb32-CDqdMQm8.woff2 +0 -0
- package/dist/client/_assets/chunks/0968e4861204b51f62a2f8e9f15dd5e0-D5tLgF_8.woff2 +0 -0
- package/dist/client/_assets/chunks/0acd1fe2b2ea1ad1bfee7ae1fa139d27-BKK1m412.woff2 +0 -0
- package/dist/client/_assets/chunks/0c2ab6b295e55f356f8020d4e7747522-CkCQjQw3.woff2 +0 -0
- package/dist/client/_assets/chunks/0c5f9492af03a4fa42c784de94649de1-CQlJqksa.woff2 +0 -0
- package/dist/client/_assets/chunks/0d5dec931dc885f07fe5cd5af8bed675-C74x-U_U.woff2 +0 -0
- package/dist/client/_assets/chunks/0d9a936885a4c39077438effd3779cbd-Bw0fYF4S.woff2 +0 -0
- package/dist/client/_assets/chunks/0e645da524f7cfc0e8c3c03fb2b08428-BVeI_5Th.woff2 +0 -0
- package/dist/client/_assets/chunks/0f5e1a18987dbc84ca05188c129e1936-B6_lZ6fE.woff2 +0 -0
- package/dist/client/_assets/chunks/1076f0f6f66d28d7a2f16427faad4413-ubiXnD1P.woff2 +0 -0
- package/dist/client/_assets/chunks/112743a4ab5fdd1498dfdf2b11336380-B5FzQxTK.woff2 +0 -0
- package/dist/client/_assets/chunks/1211f03d3ff5759a702631445793f60e-DDcSiyCt.woff2 +0 -0
- package/dist/client/_assets/chunks/12ef1ba76bd20b004b865266a1aa70b3-BwmaD87S.woff2 +0 -0
- package/dist/client/_assets/chunks/135e83b403475c5dc9e49b43501a5b84-C5mE_KZS.woff2 +0 -0
- package/dist/client/_assets/chunks/1380210a722ac9aeef54005ad7b015c9-CjA-MP82.woff2 +0 -0
- package/dist/client/_assets/chunks/13b2c53b30e6a3e4de7132dbc18dbdfc-B9WOB7kv.woff2 +0 -0
- package/dist/client/_assets/chunks/147b24c2f08d03bbed30887d4cb3311c-IeeFCJ13.woff2 +0 -0
- package/dist/client/_assets/chunks/152395634a207579552f8cb54db88599-C2y2JyNZ.woff2 +0 -0
- package/dist/client/_assets/chunks/15d95680dc31cc6ce20e0a5464106dc4-CpD8dqRm.woff2 +0 -0
- package/dist/client/_assets/chunks/16663e567f81f4725a1522f37e18f71f-BNoxS9pQ.woff2 +0 -0
- package/dist/client/_assets/chunks/1733f27476507ca68b68a803bc533cc2-DXL-14Ug.woff2 +0 -0
- package/dist/client/_assets/chunks/17c7f5d0a45e92ede0e5dec3a2c77efa-CNj3jQMl.woff2 +0 -0
- package/dist/client/_assets/chunks/1824321da801e6257b902f3d1d09054c-D4dgdyWB.woff2 +0 -0
- package/dist/client/_assets/chunks/188c2db794f3dd7a45889ddbc81da9bb-C9NbUBBO.woff2 +0 -0
- package/dist/client/_assets/chunks/1a08931435f885e707edb85978ea3bb6-BOiP2u7G.woff2 +0 -0
- package/dist/client/_assets/chunks/1a3a92c7c060a71a6c35819b9ebcdbb9-DFfonQfz.woff2 +0 -0
- package/dist/client/_assets/chunks/1be602ad456b0d75902d352116cb35fd-Bc-XQtQh.woff2 +0 -0
- package/dist/client/_assets/chunks/1cf737900dd49c2e88f1b3221a82a602-CfTmnns3.woff2 +0 -0
- package/dist/client/_assets/chunks/1fba7ec0e412e911bf31841de5a8a4e4-18ELMbFF.woff2 +0 -0
- package/dist/client/_assets/chunks/233d3a685ee18276b319363474599d47-BaFdJ0-G.woff2 +0 -0
- package/dist/client/_assets/chunks/2612c60f9dc5459ac42763591240a1d6-CTD69cq1.woff2 +0 -0
- package/dist/client/_assets/chunks/284b53bbefb06924cf236d24c8ed5641-CPDiuOv6.woff2 +0 -0
- package/dist/client/_assets/chunks/28a97af9ab9d38983d20f39ff09840e1-mFqcT3Jw.woff2 +0 -0
- package/dist/client/_assets/chunks/2a56eaf19d1d38a6b57e2a388f733676-CU52qBlE.woff2 +0 -0
- package/dist/client/_assets/chunks/2ab8cf1f23a5ac7939a7876054e711a7-B4T3dK7A.woff2 +0 -0
- package/dist/client/_assets/chunks/2abfbab82b6a7c04426afc054d2464da-D5PIIHde.woff2 +0 -0
- package/dist/client/_assets/chunks/2bfaadaf3479c72286248e6de0be0ec9-DEpU6O74.woff2 +0 -0
- package/dist/client/_assets/chunks/2c8c55e4cec85ce77e95cac9d330f5cf-BCTA96EZ.woff2 +0 -0
- package/dist/client/_assets/chunks/2e6f4bb71ef6b38765d51acc5a79f638-Mbs6PECD.woff2 +0 -0
- package/dist/client/_assets/chunks/2ed9981d2e8983365bd051159b976b6d-D8gg6NWM.woff2 +0 -0
- package/dist/client/_assets/chunks/2f4c633e923ba30c6ba376367379fc91-CIJCFztv.woff2 +0 -0
- package/dist/client/_assets/chunks/31194d303a67561926a544ed0e072aee-w3-eGYAi.woff2 +0 -0
- package/dist/client/_assets/chunks/31a197213ae61d7043c81013f52d10d6-DXZrrkJP.woff2 +0 -0
- package/dist/client/_assets/chunks/349965eee0a9b6c984a319ab96a4ece9-DByAVmXw.woff2 +0 -0
- package/dist/client/_assets/chunks/34e6750e00c3a911ef87dc66b336594d-DNbWesOu.woff2 +0 -0
- package/dist/client/_assets/chunks/3623d96698132c61e861f984ce11cc23-jqV9ErzX.woff2 +0 -0
- package/dist/client/_assets/chunks/36cda3eae13370b934bba4429fab9078-BPDcUlw9.woff2 +0 -0
- package/dist/client/_assets/chunks/36f3df4730cfca4fc77fe52b52e6a126-BwK10NC0.woff2 +0 -0
- package/dist/client/_assets/chunks/37887deb7a9c466cf2af6ee7ff372ea6-BrAerJB1.woff2 +0 -0
- package/dist/client/_assets/chunks/37dbd564820cce2f7b3331e442da0df3-Cql2kzIi.woff2 +0 -0
- package/dist/client/_assets/chunks/37dc8505b20b37a2477a9121b16d44a7-CoXw6XWV.woff2 +0 -0
- package/dist/client/_assets/chunks/39211b02f24c69cbd1b54f6d41b01933-4Xu7vvnq.woff2 +0 -0
- package/dist/client/_assets/chunks/3aa13f1843d7c8fa16109b6395a9a29d-BQFZUc3B.woff2 +0 -0
- package/dist/client/_assets/chunks/3aba89c4d4281553078de4622b498cbb-8QS1zDYk.woff2 +0 -0
- package/dist/client/_assets/chunks/3ac0a07878cacdc98bb889f40f5970d3-C-BaM6-y.woff2 +0 -0
- package/dist/client/_assets/chunks/3d88558097559d775231194d43745ba7-CR2aqGC7.woff2 +0 -0
- package/dist/client/_assets/chunks/3dc3e8c35524cad2d1236f3393104ccf-9sqBsF7B.woff2 +0 -0
- package/dist/client/_assets/chunks/3e24063b19abd2b051af986a6870046d-TlweM3SW.woff2 +0 -0
- package/dist/client/_assets/chunks/3e2c06bdd9dcab29aeaeb0cfb7fa608a-BaqU-dIt.woff2 +0 -0
- package/dist/client/_assets/chunks/424123f9371ba357087363263eeafcda-C8SVfEJi.woff2 +0 -0
- package/dist/client/_assets/chunks/43b3bbf43055c3e65db9cdf2c5b18c1c-CbHx6-Ki.woff2 +0 -0
- package/dist/client/_assets/chunks/4410f876d27c9821839474b6b1059fd7-ClYz91aY.woff2 +0 -0
- package/dist/client/_assets/chunks/44704471b60c18b3ecec5300a88f1102-DDmmy6-m.woff2 +0 -0
- package/dist/client/_assets/chunks/45140742dfa8686b58db2899ce89f89a-D5IMMzDM.woff2 +0 -0
- package/dist/client/_assets/chunks/46604090efbb99c2db1800928af0a239-JX2fpYX_.woff2 +0 -0
- package/dist/client/_assets/chunks/46998df85d31e629c0142f0556f5e7c5-BIkNG9Wh.woff2 +0 -0
- package/dist/client/_assets/chunks/469d2754e315e77270c12fa0ab28026c-D-y-vsfA.woff2 +0 -0
- package/dist/client/_assets/chunks/479329a39a3eb6c0047e6b0981919855-vZKCRx42.woff2 +0 -0
- package/dist/client/_assets/chunks/491bbba374093fff045f55803a22bfef-DSQXiDCd.woff2 +0 -0
- package/dist/client/_assets/chunks/49902f1c41b281f8eb3771abdd4dccb8-DxVxNg2W.woff2 +0 -0
- package/dist/client/_assets/chunks/4c0760284569b87d8f2290c324953973-Bqd-TKHH.woff2 +0 -0
- package/dist/client/_assets/chunks/4cba92c942694bdc479bc54101bb1aa4-BrfsrgrC.woff2 +0 -0
- package/dist/client/_assets/chunks/4d38e56738156625329d93bd5c8cc74a-DONkMP0y.woff2 +0 -0
- package/dist/client/_assets/chunks/4db4f31a16965baa42cb7dad667a8f04-Dt1Cy4gr.woff2 +0 -0
- package/dist/client/_assets/chunks/4e7d263c30bb48604069a3b4404d4eeb-DNPCkvKD.woff2 +0 -0
- package/dist/client/_assets/chunks/5279c7e465d9871edf51fd02e691eee7-CKhyhvVf.woff2 +0 -0
- package/dist/client/_assets/chunks/527ff336279465617aafbafe1a830632-CC3lv4pm.woff2 +0 -0
- package/dist/client/_assets/chunks/54bfdb6f21f9d6191e5100580239e14f-PGlqYvgl.woff2 +0 -0
- package/dist/client/_assets/chunks/56b40518ea0608e62826bd44ee27f5f9-BD9F9Oss.woff2 +0 -0
- package/dist/client/_assets/chunks/56be5e32fd01668fe5ba814d94905839-CSyFA-9l.woff2 +0 -0
- package/dist/client/_assets/chunks/572b9e28f1e6d89b765a16d809db84a1-BIYMjzEa.woff2 +0 -0
- package/dist/client/_assets/chunks/57e9a86651366c1ba299e47aa7e358c2-BHuZXB4W.woff2 +0 -0
- package/dist/client/_assets/chunks/57f89adeae55aa7fe2add3fc1801ce03-Cy3PNrfx.woff2 +0 -0
- package/dist/client/_assets/chunks/5921cef36750ff6092d94b83a802823b-hF-uymTh.woff2 +0 -0
- package/dist/client/_assets/chunks/59e95d8b5332dcdae894a19946ab767d-ClRfsjWZ.woff2 +0 -0
- package/dist/client/_assets/chunks/5acc7f736217259db79a42bf44241c48-FYQUuFOM.woff2 +0 -0
- package/dist/client/_assets/chunks/5c05f8b75c9d7f25b3c04ca711cf43b3-D-YWPkSq.woff2 +0 -0
- package/dist/client/_assets/chunks/5df9ce98c75f8c50fb4fff7f01a23925-DgoCENyW.woff2 +0 -0
- package/dist/client/_assets/chunks/5e0124c7265f1b4cf0fc797b94efbebc-BTBNHsSB.woff2 +0 -0
- package/dist/client/_assets/chunks/5ec349ff62b9ee5fe0c6dae867704dc4-B4dezhrz.woff2 +0 -0
- package/dist/client/_assets/chunks/60020a830d809c26970cf8e48ba1eeda-B6FDTSik.woff2 +0 -0
- package/dist/client/_assets/chunks/601f812e8b1eafecd5ba585a6a6d7962-gIVBlUU9.woff2 +0 -0
- package/dist/client/_assets/chunks/6025ddaf99d86cc8bfd781006b19fbd6-CS-ze337.woff2 +0 -0
- package/dist/client/_assets/chunks/60bcfa3ea7446eb42394aab02d28be40-C-PQfCu3.woff2 +0 -0
- package/dist/client/_assets/chunks/60f6e28b3f0400b0e8fe32c3c7116102-Dag9L2qU.woff2 +0 -0
- package/dist/client/_assets/chunks/615a7e0d63f257109d599b2a1977de68-D6Y93yoG.woff2 +0 -0
- package/dist/client/_assets/chunks/615b38e0b5bb3ea68426f44f47706e6f-B5yzIIer.woff2 +0 -0
- package/dist/client/_assets/chunks/61a2c80d0c924d5a6187c02e8d1d1642-BY3MmHbZ.woff2 +0 -0
- package/dist/client/_assets/chunks/62fc94f8d4c5a750b7f25e7387539910-3ql2_WDK.woff2 +0 -0
- package/dist/client/_assets/chunks/639c7c6b0b0c27c738702741cfa4b8c0-BCD3OGri.woff2 +0 -0
- package/dist/client/_assets/chunks/63fafcb069520613d0ea35ad3e6b1e42-DP0Rrj4o.woff2 +0 -0
- package/dist/client/_assets/chunks/64a404d675f1d726f0891b7a80794595-DU3L0I9s.woff2 +0 -0
- package/dist/client/_assets/chunks/65a60d87c64228d258a123cbe85f5f31-B4kbf-79.woff2 +0 -0
- package/dist/client/_assets/chunks/65e9c4585d71bf48a5c62f367010da16-CvzgzReN.woff2 +0 -0
- package/dist/client/_assets/chunks/68a3a4bf337f8a0722be76676e20b850-Dnaw8EPD.woff2 +0 -0
- package/dist/client/_assets/chunks/6968e889e18891d912809fe484c2e745-Bj1m5e0s.woff2 +0 -0
- package/dist/client/_assets/chunks/6abdd163d2c4b85698db8aa1ce149361-B5FVGJuo.woff2 +0 -0
- package/dist/client/_assets/chunks/6b75213eb0be40ce84241eb2bb438a2e-CqHmF-NR.woff2 +0 -0
- package/dist/client/_assets/chunks/70714891ad3fbfc3d5f10a8669dacc5a-BWk5nLFN.woff2 +0 -0
- package/dist/client/_assets/chunks/7158022889c6c177062ac85036e7af10-B3D4K22n.woff2 +0 -0
- package/dist/client/_assets/chunks/73b794d885b88f7befb7ea8ab1780a15-D0ZehnEI.woff2 +0 -0
- package/dist/client/_assets/chunks/743f290baf027d4626a86e22f3d44600-DDTDQdRC.woff2 +0 -0
- package/dist/client/_assets/chunks/7520ca6ca8c60eb1e62d50e71c8d30f1-CVRaGu2G.woff2 +0 -0
- package/dist/client/_assets/chunks/757019c01c5e2c2b0f54293cea3b5636-BTovUnoH.woff2 +0 -0
- package/dist/client/_assets/chunks/759a647b77791b1e98f99bc0ab5317a7-CrK6FIFz.woff2 +0 -0
- package/dist/client/_assets/chunks/761d84afca8d7f34eebefe538adba827-DRbiVuwX.woff2 +0 -0
- package/dist/client/_assets/chunks/76e07530323418ec723c5d7634c9bcca-DGtVJTTH.woff2 +0 -0
- package/dist/client/_assets/chunks/76e51630143b95b6322ef93ad330da7a-D-kV82C_.woff2 +0 -0
- package/dist/client/_assets/chunks/76f117a3baacda304a71965a17266a13-DFfvsFUm.woff2 +0 -0
- package/dist/client/_assets/chunks/773819b7b9b8fd404a929867c0fd677e-Bu1xCMZb.woff2 +0 -0
- package/dist/client/_assets/chunks/77747f17625a259fb405b7bbdd84ac4b-o_vNfh-6.woff2 +0 -0
- package/dist/client/_assets/chunks/7817dd16805145d8538ad57590f69f5a-DguSUP3O.woff2 +0 -0
- package/dist/client/_assets/chunks/788498548ddfb710d6ef3c7bff79fa97-3ffoQfRd.woff2 +0 -0
- package/dist/client/_assets/chunks/78ea6c40923ce95367e3517dd1e5a849-DvLDRhX9.woff2 +0 -0
- package/dist/client/_assets/chunks/79aa7c8c842c4a27cf57c0a3a1ffca5a-sDoCeoKI.woff2 +0 -0
- package/dist/client/_assets/chunks/7b59f0ec7792b18458dc5a361e37884c-DWvxkKmT.woff2 +0 -0
- package/dist/client/_assets/chunks/7c3945788a689a69356c1a622d69d48b-1JjIpss2.woff2 +0 -0
- package/dist/client/_assets/chunks/7cc72fd2c9105560422b6a67c6162945-Co3AF5_G.woff2 +0 -0
- package/dist/client/_assets/chunks/7d0ea0690e432462f4d05a23d720ec19-Dx7DK4C3.woff2 +0 -0
- package/dist/client/_assets/chunks/7dffa5c1bec57e0903fd62357401ff1a-DuQHmiiN.woff2 +0 -0
- package/dist/client/_assets/chunks/7e38ca789a9e76ac91d9256374e154f0-BtETgGRe.woff2 +0 -0
- package/dist/client/_assets/chunks/7f9a6c9286b68de9c72b0024f7beeb40-JpXdo4FC.woff2 +0 -0
- package/dist/client/_assets/chunks/815a0b797465190f60d8b1a04656c42e-Spzo94nU.woff2 +0 -0
- package/dist/client/_assets/chunks/823d1bb11097331238d103c7f72138dc-CGN6m2VF.woff2 +0 -0
- package/dist/client/_assets/chunks/82f6ccc063960eed1cdfd1d61ada8862-CsmAqx2a.woff2 +0 -0
- package/dist/client/_assets/chunks/835b6505bb9eea9678925a1fa885353d-C6mSBwUc.woff2 +0 -0
- package/dist/client/_assets/chunks/845b4b67564d62cf5cad242f7ac08ea5-DnvzrloJ.woff2 +0 -0
- package/dist/client/_assets/chunks/84c8e7bc0931008ed91f44ed12dfea94-C2Hvhh-b.woff2 +0 -0
- package/dist/client/_assets/chunks/8726558cf297cbda831cc19514897205-gSFV1vW0.woff2 +0 -0
- package/dist/client/_assets/chunks/8855472f3c02f6c7ebb3216617ebe4af-C1JsWVqq.woff2 +0 -0
- package/dist/client/_assets/chunks/887a11290ba78b1e66c6d2f67043005e-L_A1f5Fz.woff2 +0 -0
- package/dist/client/_assets/chunks/888ba53510213d5d1f6a7deb60e569b6-OP8E-ELN.woff2 +0 -0
- package/dist/client/_assets/chunks/88db1d042074fb6e66821ffc10941930-kZ6K3e62.woff2 +0 -0
- package/dist/client/_assets/chunks/892aa49b2529c89bb4076d4aa51fe30f-Bw0_Km2A.woff2 +0 -0
- package/dist/client/_assets/chunks/8b5c9ef81159f31d2ab35f45ca4373e0-Djw95sKC.woff2 +0 -0
- package/dist/client/_assets/chunks/8b91c7c2ed390f1278b9befa3aa87233-B2C3iFbQ.woff2 +0 -0
- package/dist/client/_assets/chunks/8dc18c0cebe6aa4bf4c45dbb831048ab-bUlANLit.woff2 +0 -0
- package/dist/client/_assets/chunks/8e231d707f0c4f8e3cde90a6b52a79aa-CvwbWlul.woff2 +0 -0
- package/dist/client/_assets/chunks/8fb45117a62d92dce44a80f0b729ead5-Djr4-o5-.woff2 +0 -0
- package/dist/client/_assets/chunks/9064c12fd72c7aba235d8c3881755b91-BnguxT-p.woff2 +0 -0
- package/dist/client/_assets/chunks/90b7848e9b1623b77bdcf155e90b839c-CFvPRnoM.woff2 +0 -0
- package/dist/client/_assets/chunks/911b9e53e9814de2998c60bf3115f560-DmPmj635.woff2 +0 -0
- package/dist/client/_assets/chunks/919a879bd2d580d8491a31a449390689-BY2w-8_Y.woff2 +0 -0
- package/dist/client/_assets/chunks/91da6cb174bebfb96976e2f1316be2fe-DztAJb6W.woff2 +0 -0
- package/dist/client/_assets/chunks/92fdc376bce277874e75db666f175b44-DJUnHEIN.woff2 +0 -0
- package/dist/client/_assets/chunks/930a23430f0eb64480d7fe5f82834e21-2VrDPT7E.woff2 +0 -0
- package/dist/client/_assets/chunks/934dfdbed2bb2c4b6129199d699a34fa-CtpHsjRD.woff2 +0 -0
- package/dist/client/_assets/chunks/93bed0e5f2dd5a21cf73304fcfbc149d-DJiaETX7.woff2 +0 -0
- package/dist/client/_assets/chunks/93f3ea6918533d96d9c252378b9a4af0-D-FJaGi-.woff2 +0 -0
- package/dist/client/_assets/chunks/95a0951d2a2722ff773a1a45e8c474d6-DuZg-BpP.woff2 +0 -0
- package/dist/client/_assets/chunks/95ff41191c76ef893ac70a1043e95e44-C08QDbJO.woff2 +0 -0
- package/dist/client/_assets/chunks/96c75862c8cec51a7c05ff025fea86cd-DBnRwCuW.woff2 +0 -0
- package/dist/client/_assets/chunks/97d7a17234f2b5030ae9697ae00aded2-CkUSaB-p.woff2 +0 -0
- package/dist/client/_assets/chunks/982cd1765ca6bbb3e6547e47834d5148-DkIybx1r.woff2 +0 -0
- package/dist/client/_assets/chunks/985d4d41afa0934a4eb2de35473fb9a2-CF7rgJMw.woff2 +0 -0
- package/dist/client/_assets/chunks/995c4fda62d25c3b79dd5987737df6ae-CY5ri8HW.woff2 +0 -0
- package/dist/client/_assets/chunks/9b0c3caac458c7bc9c9133e40405ddea-DhPrYOcz.woff2 +0 -0
- package/dist/client/_assets/chunks/9b21e8244f5930c48ad5073f83777b6c-CuE9-r-r.woff2 +0 -0
- package/dist/client/_assets/chunks/9bb38fd05201de666b88b82d56a386f7-nMl6lB8X.woff2 +0 -0
- package/dist/client/_assets/chunks/9d0afa53dc2f92ba42024f55f11f6779-Bozpx8bL.woff2 +0 -0
- package/dist/client/_assets/chunks/9e13a47242926f1cd7d68c08d9ef8889-DwKQjc8M.woff2 +0 -0
- package/dist/client/_assets/chunks/9eff2ab2a9d2ced47ab761bf6fdb11ec-D86-Zm1H.woff2 +0 -0
- package/dist/client/_assets/chunks/9f1963fe8d4d6878d717d872a8f3fdb5-DxjITUFq.woff2 +0 -0
- package/dist/client/_assets/chunks/9f3bdab4025dc7c5ba1a5871e62e8918-BqxDEFLJ.woff2 +0 -0
- package/dist/client/_assets/chunks/9fce02d1a09f464c36c9fcfb14a354c5-F2tMAB_j.woff2 +0 -0
- package/dist/client/_assets/chunks/a00e94d4f04df6aa659db9c4954c7efe-CRBKCj_3.woff2 +0 -0
- package/dist/client/_assets/chunks/a0a6755c7e3f9e4cf03387027dd9f16c-BAyRqF2w.woff2 +0 -0
- package/dist/client/_assets/chunks/a0d00fe4816c95a8c7dffd445ef00b03-CxcTiRLJ.woff2 +0 -0
- package/dist/client/_assets/chunks/a0f199077fa1a33bc2a1e01c64de7fe6-IdgVJmZD.woff2 +0 -0
- package/dist/client/_assets/chunks/a2b0597837e382aca19919c4b74e58c8-7iVOBjzI.woff2 +0 -0
- package/dist/client/_assets/chunks/a373e85c96aa0dc303092429fb837e51-Dvmw8mbX.woff2 +0 -0
- package/dist/client/_assets/chunks/a379ada89abd750c587ded29f77e731c-CgPBsEsv.woff2 +0 -0
- package/dist/client/_assets/chunks/a4475c442c6b259354c9eda62e64e7df-TZ0c8vK-.woff2 +0 -0
- package/dist/client/_assets/chunks/a48be56ce5d3a99dc8f8331398004412-BR_ixH1W.woff2 +0 -0
- package/dist/client/_assets/chunks/a4a39b5f048671aa37c2b2a9581ab08a-EDfDYsUd.woff2 +0 -0
- package/dist/client/_assets/chunks/a534449d67561ac9b06489f64e57ad98-C355TCrD.woff2 +0 -0
- package/dist/client/_assets/chunks/a6e044424780a57610833cc856c15bf5-x1b8FE4H.woff2 +0 -0
- package/dist/client/_assets/chunks/a7c35e42a659347e490c3cb7983b2e7f-BWpA0-oz.woff2 +0 -0
- package/dist/client/_assets/chunks/a7c58070d68dc1724e9d4e781afb78db-ql27pT-6.woff2 +0 -0
- package/dist/client/_assets/chunks/a806759e72987951d6d08b7cbdf36a1b-TvLDwB_u.woff2 +0 -0
- package/dist/client/_assets/chunks/a88481ec8bc7be11cb66e46781a79bb9-Ck-r_sGx.woff2 +0 -0
- package/dist/client/_assets/chunks/a919a8c6fec6d7e8bb21177965f2e9d7-CC5uWzwd.woff2 +0 -0
- package/dist/client/_assets/chunks/a9a016d4a93409f65278327e8a8bb38d-dylrNwF8.woff2 +0 -0
- package/dist/client/_assets/chunks/aa662092cf249707123ca4d575e2764b-CSxNsTUL.woff2 +0 -0
- package/dist/client/_assets/chunks/aae1eda193285ab817a2d1b408440326-CjyjBoRm.woff2 +0 -0
- package/dist/client/_assets/chunks/ab92d41062a7644faa45f50bf384454a-Cq0X8a9H.woff2 +0 -0
- package/dist/client/_assets/chunks/accc43762ad05edfbff66ba1380d192a-B5jIykaZ.woff2 +0 -0
- package/dist/client/_assets/chunks/ad47bcd6d4663026d648c132d969318d-BYdIbDge.woff2 +0 -0
- package/dist/client/_assets/chunks/ad67113f88b59582991cb0c5d33ea19f-DOH1vcIZ.woff2 +0 -0
- package/dist/client/_assets/chunks/adb6e613fb99c6dd660b727101f554a8-DJDw_ZZK.woff2 +0 -0
- package/dist/client/_assets/chunks/adc4a98a89870ef984ee8f4b57c8a3a5-D30vw26R.woff2 +0 -0
- package/dist/client/_assets/chunks/af57a2e8c72f9ba0efb1af771d32c124-D5Zwq9pS.woff2 +0 -0
- package/dist/client/_assets/chunks/b0ae5f374e43dac992a4a5d334cebc0b-Ccoi4dPt.woff2 +0 -0
- package/dist/client/_assets/chunks/b0cb664cb2e1371efda8943c0b7dcd1c-YzGFnelF.woff2 +0 -0
- package/dist/client/_assets/chunks/b0d1cdced482352cf0d3ae58638aacb9-IunWfc6R.woff2 +0 -0
- package/dist/client/_assets/chunks/b12379ab782468d725519cd07a7d15bc-IjbydKs2.woff2 +0 -0
- package/dist/client/_assets/chunks/b320f5d185b2cff933ac549c184031c5-IYnPrIz4.woff2 +0 -0
- package/dist/client/_assets/chunks/b326a8a9c33b554db570da94f60bc380-B6dzaCQg.woff2 +0 -0
- package/dist/client/_assets/chunks/b55486f8a459c838fe329d4e79a8c211-DW8q7oGV.woff2 +0 -0
- package/dist/client/_assets/chunks/b6117ff2993b11bb1fdc7ea3588a010c-JoMYL5W_.woff2 +0 -0
- package/dist/client/_assets/chunks/b61982951bd51b724143c30dfaaa9fe9-D3KhBKl6.woff2 +0 -0
- package/dist/client/_assets/chunks/b91234c10fd8b8c8abc88e03afe66a1f-BABNh2la.woff2 +0 -0
- package/dist/client/_assets/chunks/b9317198f118a1dfd8ddf2b82ec028f3-CiMecxeH.woff2 +0 -0
- package/dist/client/_assets/chunks/ba825ae79b1a6f7e0cce5215fcb5c96f-B6EWU_D5.woff2 +0 -0
- package/dist/client/_assets/chunks/ba9c59d7dfa4494db1bb764ada81467d-D0yPcC1m.woff2 +0 -0
- package/dist/client/_assets/chunks/bab547459d514f46206e340c4bb2dc88-YnBqlGhw.woff2 +0 -0
- package/dist/client/_assets/chunks/bb0b15492b8cdbbec57c0bcfa0aa9241-BjIFbEsN.woff2 +0 -0
- package/dist/client/_assets/chunks/bc6183ac08f0fac78c46f80c10cf7c92-B81nbRb3.woff2 +0 -0
- package/dist/client/_assets/chunks/bc8ccea5abf6598cf3cfa97eb59804bb-B_7IbluG.woff2 +0 -0
- package/dist/client/_assets/chunks/bc95a792cbca6639214c9b0da13392ff-CHQe0E-D.woff2 +0 -0
- package/dist/client/_assets/chunks/bcc39eda837bb7a7a3d37c8c60fffb81-CGd1Zk6S.woff2 +0 -0
- package/dist/client/_assets/chunks/bcfa62f35731856246c146d3a6932bf3-DMDq6w4v.woff2 +0 -0
- package/dist/client/_assets/chunks/bd73264d7f98776708d5d6f3c9b78fcc-d9QWWMym.woff2 +0 -0
- package/dist/client/_assets/chunks/bed610b217d500f5975cfc9fe6157570-B5t7s1bw.woff2 +0 -0
- package/dist/client/_assets/chunks/bedc74b423b7293b6ad0bdecc61c42cc-4Nnh7peP.woff2 +0 -0
- package/dist/client/_assets/chunks/bf8901f8f11d4f433ea17dabc9370ea6-B8dkfvGn.woff2 +0 -0
- package/dist/client/_assets/chunks/bfb00d4a4c48661bd0be99f300a0faae-OxsWZ7l-.woff2 +0 -0
- package/dist/client/_assets/chunks/c0098958e20db68cab90097b5e62516f-VpjQo3vV.woff2 +0 -0
- package/dist/client/_assets/chunks/c063897793f593eb26d6ff7b7baaba18-BWeJJ1sH.woff2 +0 -0
- package/dist/client/_assets/chunks/c1b0df29ae41d764904df84e9ac83d1e-D1N934vs.woff2 +0 -0
- package/dist/client/_assets/chunks/c4143bb9f2fe77b6ccf20088a8904650-nHfYM24e.woff2 +0 -0
- package/dist/client/_assets/chunks/c42c67070cfe99cf823df92d81c7fa6e-B_a405Ez.woff2 +0 -0
- package/dist/client/_assets/chunks/c4bfaa5e50798246e3770718b7a7c84a-B-r6Y_o0.woff2 +0 -0
- package/dist/client/_assets/chunks/c4d749e45ecd5a5aed5a0bb3ebfd355d-CkqE1fRi.woff2 +0 -0
- package/dist/client/_assets/chunks/c6c2971ad1f3221f6cf84028aa0f477e-D7BZGIcY.woff2 +0 -0
- package/dist/client/_assets/chunks/c7ff3f6bbdcd5f604b7343602ab904df-Bq7UjVrZ.woff2 +0 -0
- package/dist/client/_assets/chunks/c84598999133455503042e06f4ab79cb-DIXndJX3.woff2 +0 -0
- package/dist/client/_assets/chunks/c945c62368357d05a53206620460fb30-82gFEf6n.woff2 +0 -0
- package/dist/client/_assets/chunks/c96d83978add28b356c22c4c84916733-BL4VaPIE.woff2 +0 -0
- package/dist/client/_assets/chunks/c97f41eef722121d86f55d553c056a39-CjejgQO2.woff2 +0 -0
- package/dist/client/_assets/chunks/ca62704509932d3232d62918de97af3f-CKWF-3mX.woff2 +0 -0
- package/dist/client/_assets/chunks/ca9a533988d7019597a60d4e17127e0c-ClZ6ygZM.woff2 +0 -0
- package/dist/client/_assets/chunks/cb7ccd6494256f7a2977b7c2b0225592-Cxp8XObm.woff2 +0 -0
- package/dist/client/_assets/chunks/ce022e18a1377ac509443c3c3790b431-DpH0t6Tn.woff2 +0 -0
- package/dist/client/_assets/chunks/ce41d70ce6a069a498525c9e15c45cf2-DGtgv-_b.woff2 +0 -0
- package/dist/client/_assets/chunks/cf2b28f90f47276f7e2688a65e88a101-LVbNkXHj.woff2 +0 -0
- package/dist/client/_assets/chunks/cf9cffe56636322f62b40d61130fbc5e-DNCBMqAo.woff2 +0 -0
- package/dist/client/_assets/chunks/d1f064825fa5784b5c930652bd831cce-BU6qwjp8.woff2 +0 -0
- package/dist/client/_assets/chunks/d20d8944bc0b85f5b2aae4b24f343516-oY9l-NmC.woff2 +0 -0
- package/dist/client/_assets/chunks/d2faabcedd19f016e7b21bce073c0ec8-Dv6eFCf5.woff2 +0 -0
- package/dist/client/_assets/chunks/d320171e57480510f87dbbc7d5264b0a-CcCfjaFX.woff2 +0 -0
- package/dist/client/_assets/chunks/d36644d6502527e1fff205d0c7eca434-kVBj8zy_.woff2 +0 -0
- package/dist/client/_assets/chunks/d3a72a99d365dddfbca8d017a8011368-Bgdmhl3M.woff2 +0 -0
- package/dist/client/_assets/chunks/d40ab99c7a38026f411c8f112f742b48-D7Nm7fg6.woff2 +0 -0
- package/dist/client/_assets/chunks/d42aafa0f246ad3b4c16fe96d3a3a432-CRxTqZXU.woff2 +0 -0
- package/dist/client/_assets/chunks/d4aaf23c13ae808a4bed617afd13aa07-d_T1SKe9.woff2 +0 -0
- package/dist/client/_assets/chunks/d509ee5c8241bc7c3de2039d75564fa5-BpNFD9JE.woff2 +0 -0
- package/dist/client/_assets/chunks/d675d717cd329bfd4c0524f76ae1579c-Bd5_ctoQ.woff2 +0 -0
- package/dist/client/_assets/chunks/d689b1861d7e4377dd72ad3013482612-jPsVOU3F.woff2 +0 -0
- package/dist/client/_assets/chunks/d6bb686bddfbe8f38a36a68e609a8667-C_QduS-X.woff2 +0 -0
- package/dist/client/_assets/chunks/d9020ff69a83b2a6ee1f42ae480f7db0-DLBUPMCe.woff2 +0 -0
- package/dist/client/_assets/chunks/d9047070d72a816b3dba9d40c2d85e69-LTQ42vEp.woff2 +0 -0
- package/dist/client/_assets/chunks/da04549f3f4ed28076b01b8cd710d313-CDXOeduw.woff2 +0 -0
- package/dist/client/_assets/chunks/da7af303f8c645f9a9dbae0e6e32dd35-DCkS2jqi.woff2 +0 -0
- package/dist/client/_assets/chunks/da90a9012ab2d98f759e3fa0820ef502-D0D9d1zg.woff2 +0 -0
- package/dist/client/_assets/chunks/dc6e234ded795e91f76d6647f628fbf0-IkooXcRh.woff2 +0 -0
- package/dist/client/_assets/chunks/dc8f6256445e68199540be9ade33529f-umb5tWbZ.woff2 +0 -0
- package/dist/client/_assets/chunks/dd0cfdfdac0866e66d587e2b5a9e9961-bl4ozE0c.woff2 +0 -0
- package/dist/client/_assets/chunks/de304c8a02e45ded4f8dcc479d167198-ClRu89-4.woff2 +0 -0
- package/dist/client/_assets/chunks/df10d94bea357a43313e20da5d84bd30-CmAgh2oA.woff2 +0 -0
- package/dist/client/_assets/chunks/df9568257eb29b156449fdd4bec5ec76-BMz6aLRr.woff2 +0 -0
- package/dist/client/_assets/chunks/e067cd0ed76c90cd0a93c9339253f20b-6RxCQ4jy.woff2 +0 -0
- package/dist/client/_assets/chunks/e08b07772e7bed3cec2832d43f7fd339-CQCkeKsr.woff2 +0 -0
- package/dist/client/_assets/chunks/e12150d5a39b30be8f567968c7a527b0-DjdoWzeQ.woff2 +0 -0
- package/dist/client/_assets/chunks/e34b2b141e472dc776c86fdf8eea23b0-Cjk7H-Ev.woff2 +0 -0
- package/dist/client/_assets/chunks/e444fd88f1390636e603d0d681538ac8-Bx7CPOZh.woff2 +0 -0
- package/dist/client/_assets/chunks/e53fcb2381eee345db4f6f973dd95a3e-DmkkCUWz.woff2 +0 -0
- package/dist/client/_assets/chunks/e5bd313ef81f687d398aacb11cec3069-CwBEbcji.woff2 +0 -0
- package/dist/client/_assets/chunks/e79898628283edc27180fc39d0d769c1-By2pplQz.woff2 +0 -0
- package/dist/client/_assets/chunks/e8c15be62faf978d208925e79ea6a10d-Ct5M9lTP.woff2 +0 -0
- package/dist/client/_assets/chunks/e8c364c16daa04835bf32d293d2598db-3v4Tut_d.woff2 +0 -0
- package/dist/client/_assets/chunks/e91c4d941ed9f5c2f3e27f205a3a225e-BwOJ2Lst.woff2 +0 -0
- package/dist/client/_assets/chunks/e9c566be7a5d38a9085225f7372bc82b-BCtnCVML.woff2 +0 -0
- package/dist/client/_assets/chunks/e9ebc567a711eeb29019ddae3e0ce7fe-CnNhV49O.woff2 +0 -0
- package/dist/client/_assets/chunks/eaf332445a40942928e5f5750c1c3116-qZ5LSRrj.woff2 +0 -0
- package/dist/client/_assets/chunks/eb5afb3d952b8593782caec6026514b6-BXugZF2T.woff2 +0 -0
- package/dist/client/_assets/chunks/ec86e23683052da5cfdc3b77641bd15a-BeLcbcRc.woff2 +0 -0
- package/dist/client/_assets/chunks/ecb8875a56c7b038b35432fda41ae128-BVqgNf1o.woff2 +0 -0
- package/dist/client/_assets/chunks/eda1b0cb6d1719dd9bedcf3216a9e8de-BJTfLL5z.woff2 +0 -0
- package/dist/client/_assets/chunks/edd6a4f608d04fc0351d7688cfc321e4-d3V4U40c.woff2 +0 -0
- package/dist/client/_assets/chunks/ee6fce20b420a480714607c66d7f97e5-DEtC-G5G.woff2 +0 -0
- package/dist/client/_assets/chunks/eee3836d6ac17ebb2c450bbcbc9db121-C5a2TZjQ.woff2 +0 -0
- package/dist/client/_assets/chunks/et-book-bold-line-figures-BFJr2_zv.woff +0 -0
- package/dist/client/_assets/chunks/et-book-display-italic-old-style-figures-CoeRJAe8.woff +0 -0
- package/dist/client/_assets/chunks/et-book-roman-line-figures-CaA40oOf.woff +0 -0
- package/dist/client/_assets/chunks/f1661731474b78bdf81114daf10b254f-KnMKX_U3.woff2 +0 -0
- package/dist/client/_assets/chunks/f2c58dee206ba9355046fc23d05491f7-Cm4tCWav.woff2 +0 -0
- package/dist/client/_assets/chunks/f50ac27ea4358d67fdda403c2bb52467-WCfYHde1.woff2 +0 -0
- package/dist/client/_assets/chunks/f55334112f8e8be82d65db29887a663f-vDq1zH8k.woff2 +0 -0
- package/dist/client/_assets/chunks/f5738255e92d8dd34a46d1bcdf4c4074-tpghTzL1.woff2 +0 -0
- package/dist/client/_assets/chunks/f740e93f3c0277ecc616594103bca683-C4BgW_ko.woff2 +0 -0
- package/dist/client/_assets/chunks/f7633b5af033d76ff2fb3c3c266d77c5-BCkrZxwO.woff2 +0 -0
- package/dist/client/_assets/chunks/f7d8468cba2335a83ee414ea68291bab-CVnotkZU.woff2 +0 -0
- package/dist/client/_assets/chunks/f91cd722855f4269256eae1187df64ec-DJlAx1A_.woff2 +0 -0
- package/dist/client/_assets/chunks/f9695c6c4df2bf6bc03045ff79d4f01f-DDaYGYHT.woff2 +0 -0
- package/dist/client/_assets/chunks/fa6e58ce4b52695e7ae19bbea6336ec8-B30jEpze.woff2 +0 -0
- package/dist/client/_assets/chunks/fada6eaa68ff8816afe43d2a36c5423e-DlGAWNPb.woff2 +0 -0
- package/dist/client/_assets/chunks/fbcc4bf5367218951172bdee6f77d7a6-Dax2VSCd.woff2 +0 -0
- package/dist/client/_assets/chunks/fc895f5ce66b656f4a933097bf2a8775-DjjysNdf.woff2 +0 -0
- package/dist/client/_assets/chunks/fc9ae5b600fb711f2d67e93ce768cba4-D1lx7LBz.woff2 +0 -0
- package/dist/client/_assets/chunks/fca6720fd14c467d29a90f18ef3859b9-B3btrwq3.woff2 +0 -0
- package/dist/client/_assets/chunks/fd1bb507bcbf04856eeb7f7fd47ea579-NR1nGJTt.woff2 +0 -0
- package/dist/client/_assets/chunks/fd1bceb55d3e0183ac2454b8532fec7d-D3t-v6nn.woff2 +0 -0
- package/dist/client/_assets/chunks/fd2069e6e8588c70b4f11364093b81f2-BoXhYVgw.woff2 +0 -0
- package/dist/client/_assets/chunks/{url-CG0eolsk.js → url-pLre2DM_.js} +1 -1
- package/dist/client/_assets/client-C_kImWZj.css +2 -0
- package/dist/client/_assets/client-D95FNDg5.js +272 -0
- package/dist/client/_assets/client-auth-CXILhW1b.js +4547 -0
- package/dist/client/_assets/client-cjk-jp-DZwrTzQC.css +1 -0
- package/dist/client/_assets/client-cjk-kr-_3ZNI2ZP.css +1 -0
- package/dist/env-CgaH9Mut.js +252 -0
- package/dist/github-api-BkRWnqMx.js +176 -0
- package/dist/github-app-WeadXMb8.js +275 -0
- package/dist/github-sync-7y_nTXx1.js +4723 -0
- package/dist/index.js +88 -2
- package/dist/node.js +71 -30
- package/dist/url-umUptr5z.js +334 -0
- package/package.json +16 -12
- package/src/__tests__/bin/content-cli.test.ts +179 -0
- package/src/__tests__/bin/media-cli.test.ts +192 -0
- package/src/__tests__/export-hugo-build.test.ts +178 -0
- package/src/__tests__/export-import-roundtrip.test.ts +265 -0
- package/src/__tests__/export-service.test.ts +763 -510
- package/src/__tests__/helpers/app.ts +15 -4
- package/src/__tests__/helpers/export-fixtures.ts +108 -0
- package/src/__tests__/import-site-command.test.ts +358 -350
- package/src/__tests__/site-pull-media.test.ts +256 -0
- package/src/app.tsx +68 -13
- package/src/client/__tests__/collection-form-bridge.test.ts +87 -7
- package/src/client/__tests__/collection-page-actions.test.ts +4 -4
- package/src/client/__tests__/collection-picker-order.test.ts +53 -0
- package/src/client/__tests__/collection-sort-menu.test.ts +2 -2
- package/src/client/__tests__/compose-bridge.test.ts +305 -13
- package/src/client/__tests__/compose-launch.test.ts +120 -0
- package/src/client/__tests__/compose-shortcuts.test.ts +141 -0
- package/src/client/__tests__/feed-video-player.test.ts +44 -0
- package/src/client/__tests__/site-header-nav.test.ts +250 -0
- package/src/client/__tests__/sortable-list.test.ts +6 -2
- package/src/client/__tests__/thread-context.test.ts +117 -0
- package/src/client/collection-form-bridge.ts +109 -4
- package/src/client/collection-page-actions.ts +3 -1
- package/src/client/collection-picker-order.ts +104 -0
- package/src/client/components/__tests__/{jant-collection-sidebar.test.ts → jant-collection-directory.test.ts} +91 -10
- package/src/client/components/__tests__/jant-collection-form.test.ts +40 -18
- package/src/client/components/__tests__/jant-compose-dialog.test.ts +1285 -66
- package/src/client/components/__tests__/jant-compose-editor.test.ts +254 -19
- package/src/client/components/__tests__/jant-compose-fullscreen.test.ts +127 -1
- package/src/client/components/__tests__/jant-media-lightbox.test.ts +237 -0
- package/src/client/components/__tests__/jant-nav-manager.test.ts +326 -0
- package/src/client/components/__tests__/jant-post-menu.test.ts +372 -2
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +61 -5
- package/src/client/components/__tests__/jant-settings-general.test.ts +29 -28
- package/src/client/components/__tests__/jant-text-preview.test.ts +206 -0
- package/src/client/components/collection-manager-types.ts +18 -1
- package/src/client/components/compose-types.ts +48 -0
- package/src/client/components/jant-collection-directory.ts +1448 -0
- package/src/client/components/jant-collection-form.ts +65 -17
- package/src/client/components/jant-command-palette.ts +544 -0
- package/src/client/components/jant-compose-dialog.ts +2490 -375
- package/src/client/components/jant-compose-editor.ts +420 -75
- package/src/client/components/jant-compose-fullscreen.ts +59 -8
- package/src/client/components/jant-media-lightbox.ts +373 -18
- package/src/client/components/jant-nav-manager.ts +624 -286
- package/src/client/components/jant-post-menu.ts +451 -126
- package/src/client/components/jant-repo-picker-types.ts +39 -0
- package/src/client/components/jant-repo-picker.ts +799 -0
- package/src/client/components/jant-settings-avatar.ts +16 -2
- package/src/client/components/jant-settings-general.ts +137 -35
- package/src/client/components/jant-text-preview.ts +239 -55
- package/src/client/components/nav-manager-types.ts +25 -9
- package/src/client/components/settings-types.ts +13 -2
- package/src/client/compose-bridge.ts +428 -68
- package/src/client/compose-launch.ts +41 -4
- package/src/client/compose-shortcuts.ts +77 -5
- package/src/client/feed-video-player.ts +374 -0
- package/src/client/image-processor.ts +53 -127
- package/src/client/media-lightbox-events.ts +1 -0
- package/src/client/media-scroll-hint.ts +66 -0
- package/src/client/multipart-upload.ts +4 -1
- package/src/client/palette-shortcuts.ts +35 -0
- package/src/client/search-rank.ts +74 -0
- package/src/client/settings-bridge.ts +7 -0
- package/src/client/site-header-nav.d.ts +1 -0
- package/src/client/site-header-nav.js +139 -51
- package/src/client/sortable-list.ts +2 -0
- package/src/client/thread-context.ts +54 -11
- package/src/client/tiptap/__tests__/block-insertion.test.ts +65 -0
- package/src/client/tiptap/__tests__/footnotes.test.ts +692 -0
- package/src/client/tiptap/__tests__/insert-paragraph-around.test.ts +228 -0
- package/src/client/tiptap/__tests__/link-toolbar.test.ts +120 -4
- package/src/client/tiptap/__tests__/markdown-clipboard.test.ts +48 -0
- package/src/client/tiptap/block-insertion.ts +36 -0
- package/src/client/tiptap/bubble-menu.ts +34 -4
- package/src/client/tiptap/create-editor.ts +49 -30
- package/src/client/tiptap/embed-dialog.ts +301 -0
- package/src/client/tiptap/embed-node.ts +373 -0
- package/src/client/tiptap/embed-paste.ts +91 -0
- package/src/client/tiptap/extensions.ts +80 -28
- package/src/client/tiptap/footnotes.ts +718 -0
- package/src/client/tiptap/html-block-node.ts +222 -0
- package/src/client/tiptap/image-node.ts +49 -6
- package/src/client/tiptap/inline-image-upload.ts +200 -40
- package/src/client/tiptap/insert-paragraph-around.ts +79 -0
- package/src/client/tiptap/link-input-rules.ts +50 -16
- package/src/client/tiptap/link-toolbar.ts +156 -133
- package/src/client/tiptap/markdown-clipboard.ts +120 -0
- package/src/client/tiptap/more-break.ts +36 -3
- package/src/client/tiptap/paste-media.ts +6 -0
- package/src/client/tiptap/slash-commands.ts +167 -14
- package/src/client/tiptap/tab-indent.ts +184 -0
- package/src/client/tiptap/toolbar-mode.ts +15 -2
- package/src/client/tiptap/wrapping-input-rules.ts +102 -0
- package/src/client/types/sortablejs.d.ts +9 -1
- package/src/client/upload-session.ts +2 -1
- package/src/client/video-processor.ts +177 -20
- package/src/client-auth.ts +9 -1
- package/src/client-site.ts +15 -0
- package/src/client.ts +2 -0
- package/src/db/__tests__/demo-canonical-snapshot.test.ts +1 -1
- package/src/db/__tests__/migration-rehearsal.test.ts +5 -1
- package/src/db/__tests__/migrations.test.ts +25 -2
- package/src/db/backfills/0001_strip_collection_path_c_prefix.sql +11 -0
- package/src/db/backfills/0002_strip_collection_path_c_prefix_fix.sql +12 -0
- package/src/db/backfills/0003_clear_system_nav_default_labels.sql +15 -0
- package/src/db/dialect.ts +40 -0
- package/src/db/migrations/0005_busy_the_phantom.sql +39 -0
- package/src/db/migrations/0006_adorable_magdalene.sql +3 -0
- package/src/db/migrations/0007_unusual_warstar.sql +1 -0
- package/src/db/migrations/0008_nasty_lockheed.sql +1 -0
- package/src/db/migrations/0009_clear_fixer.sql +31 -0
- package/src/db/migrations/0010_futuristic_preak.sql +31 -0
- package/src/db/migrations/0011_bizarre_smasher.sql +30 -0
- package/src/db/migrations/0012_furry_thena.sql +52 -0
- package/src/db/migrations/0013_mixed_lightspeed.sql +39 -0
- package/src/db/migrations/0014_high_the_santerians.sql +41 -0
- package/src/db/migrations/0015_skinny_shinobi_shaw.sql +1 -0
- package/src/db/migrations/0016_remarkable_nicolaos.sql +17 -0
- package/src/db/migrations/0017_powerful_moonstone.sql +14 -0
- package/src/db/migrations/0018_yummy_franklin_richards.sql +6 -0
- package/src/db/migrations/meta/0005_snapshot.json +1904 -0
- package/src/db/migrations/meta/0006_snapshot.json +1925 -0
- package/src/db/migrations/meta/0007_snapshot.json +1933 -0
- package/src/db/migrations/meta/0008_snapshot.json +1940 -0
- package/src/db/migrations/meta/0009_snapshot.json +1952 -0
- package/src/db/migrations/meta/0010_snapshot.json +1952 -0
- package/src/db/migrations/meta/0011_snapshot.json +1948 -0
- package/src/db/migrations/meta/0012_snapshot.json +1955 -0
- package/src/db/migrations/meta/0013_snapshot.json +1977 -0
- package/src/db/migrations/meta/0014_snapshot.json +1988 -0
- package/src/db/migrations/meta/0015_snapshot.json +1995 -0
- package/src/db/migrations/meta/0016_snapshot.json +2104 -0
- package/src/db/migrations/meta/0017_snapshot.json +2188 -0
- package/src/db/migrations/meta/0018_snapshot.json +2225 -0
- package/src/db/migrations/meta/_journal.json +98 -0
- package/src/db/migrations/pg/0003_motionless_norrin_radd.sql +21 -0
- package/src/db/migrations/pg/0004_nervous_captain_midlands.sql +3 -0
- package/src/db/migrations/pg/0005_romantic_mesmero.sql +1 -0
- package/src/db/migrations/pg/0006_perpetual_bruce_banner.sql +1 -0
- package/src/db/migrations/pg/0007_nav_item_placement.sql +1 -0
- package/src/db/migrations/pg/0008_yielding_frightful_four.sql +3 -0
- package/src/db/migrations/pg/0009_outstanding_ogun.sql +1 -0
- package/src/db/migrations/pg/0010_overjoyed_gertrude_yorkes.sql +28 -0
- package/src/db/migrations/pg/0011_fixed_hulk.sql +19 -0
- package/src/db/migrations/pg/0012_cute_shockwave.sql +2 -0
- package/src/db/migrations/pg/0013_bizarre_obadiah_stane.sql +1 -0
- package/src/db/migrations/pg/0014_tearful_grim_reaper.sql +16 -0
- package/src/db/migrations/pg/0015_daffy_mikhail_rasputin.sql +14 -0
- package/src/db/migrations/pg/0016_familiar_lionheart.sql +6 -0
- package/src/db/migrations/pg/meta/0003_snapshot.json +2482 -0
- package/src/db/migrations/pg/meta/0004_snapshot.json +2500 -0
- package/src/db/migrations/pg/meta/0005_snapshot.json +2507 -0
- package/src/db/migrations/pg/meta/0006_snapshot.json +2513 -0
- package/src/db/migrations/pg/meta/0008_snapshot.json +2524 -0
- package/src/db/migrations/pg/meta/0009_snapshot.json +2520 -0
- package/src/db/migrations/pg/meta/0010_snapshot.json +2526 -0
- package/src/db/migrations/pg/meta/0011_snapshot.json +2563 -0
- package/src/db/migrations/pg/meta/0012_snapshot.json +2573 -0
- package/src/db/migrations/pg/meta/0013_snapshot.json +2579 -0
- package/src/db/migrations/pg/meta/0014_snapshot.json +2702 -0
- package/src/db/migrations/pg/meta/0015_snapshot.json +2803 -0
- package/src/db/migrations/pg/meta/0016_snapshot.json +2840 -0
- package/src/db/migrations/pg/meta/_journal.json +98 -0
- package/src/db/pg/__tests__/node.test.ts +38 -0
- package/src/db/pg/node.ts +149 -0
- package/src/db/pg/schema.ts +148 -12
- package/src/db/rehearsal-fixtures/demo-current.sql +47 -3
- package/src/db/schema.ts +162 -12
- package/src/i18n/Trans.tsx +3 -3
- package/src/i18n/__tests__/context.test.tsx +9 -6
- package/src/i18n/__tests__/detect.test.ts +65 -48
- package/src/i18n/__tests__/fallback.test.ts +40 -0
- package/src/i18n/__tests__/message-placeholders.test.ts +43 -0
- package/src/i18n/__tests__/middleware.test.ts +83 -0
- package/src/i18n/context.tsx +9 -44
- package/src/i18n/detect.ts +95 -28
- package/src/i18n/i18n.ts +41 -17
- package/src/i18n/index.ts +7 -5
- package/src/i18n/locales/{en.po → public/en.po} +284 -1151
- package/src/i18n/locales/public/en.ts +1 -0
- package/src/i18n/locales/public/zh-Hans.po +2327 -0
- package/src/i18n/locales/public/zh-Hans.ts +1 -0
- package/src/i18n/locales/public/zh-Hant.po +2327 -0
- package/src/i18n/locales/public/zh-Hant.ts +1 -0
- package/src/i18n/locales/settings/en.po +1622 -0
- package/src/i18n/locales/settings/en.ts +1 -0
- package/src/i18n/locales/settings/zh-Hans.po +1622 -0
- package/src/i18n/locales/settings/zh-Hans.ts +1 -0
- package/src/i18n/locales/settings/zh-Hant.po +1622 -0
- package/src/i18n/locales/settings/zh-Hant.ts +1 -0
- package/src/i18n/middleware.ts +37 -24
- package/src/index.ts +4 -6
- package/src/lib/__tests__/collection-groups.test.ts +17 -0
- package/src/lib/__tests__/constants.test.ts +2 -24
- package/src/lib/__tests__/csp-builder.test.ts +68 -0
- package/src/lib/__tests__/display-text.test.ts +27 -0
- package/src/lib/__tests__/embed-providers.test.ts +104 -0
- package/src/lib/__tests__/embed-render.test.ts +60 -0
- package/src/lib/__tests__/feed.test.ts +125 -63
- package/src/lib/__tests__/hosted-signin.test.ts +41 -2
- package/src/lib/__tests__/markdown-roundtrip-embed.test.ts +88 -0
- package/src/lib/__tests__/markdown-to-tiptap.test.ts +59 -0
- package/src/lib/__tests__/markdown.test.ts +47 -5
- package/src/lib/__tests__/navigation.test.ts +132 -0
- package/src/lib/__tests__/post-display.test.ts +3 -2
- package/src/lib/__tests__/post-meta.test.ts +3 -0
- package/src/lib/__tests__/rate-limit-d1.test.ts +82 -0
- package/src/lib/__tests__/rate-limit-memory.test.ts +69 -0
- package/src/lib/__tests__/resolve-config.test.ts +30 -25
- package/src/lib/__tests__/schemas.test.ts +20 -3
- package/src/lib/__tests__/summary.test.ts +540 -1
- package/src/lib/__tests__/theme.test.ts +41 -2
- package/src/lib/__tests__/timeline.test.ts +33 -27
- package/src/lib/__tests__/tiptap-render.test.ts +224 -0
- package/src/lib/__tests__/tiptap-to-markdown.test.ts +51 -0
- package/src/lib/__tests__/video-playback.test.ts +48 -0
- package/src/lib/__tests__/view.test.ts +181 -8
- package/src/lib/__tests__/worker-response-cache.test.ts +311 -0
- package/src/lib/__tests__/youtube.test.ts +99 -0
- package/src/lib/api-media.ts +55 -0
- package/src/lib/api-posts.ts +99 -0
- package/src/lib/api-search.ts +47 -0
- package/src/lib/api-settings.ts +122 -0
- package/src/lib/asset-path.ts +20 -2
- package/src/lib/collection-groups.ts +2 -1
- package/src/lib/collection-paths.ts +40 -0
- package/src/lib/constants.ts +3 -24
- package/src/lib/csp-builder.ts +99 -0
- package/src/lib/decorative-quote-mark.ts +11 -0
- package/src/lib/display-text.ts +56 -0
- package/src/lib/embed-providers.ts +289 -0
- package/src/lib/embed-render.ts +151 -0
- package/src/lib/env.ts +70 -1
- package/src/lib/excerpt.ts +11 -2
- package/src/lib/feed.ts +154 -95
- package/src/lib/footnotes.ts +146 -0
- package/src/lib/github-api.ts +423 -0
- package/src/lib/github-app-state.ts +135 -0
- package/src/lib/github-app.ts +487 -0
- package/src/lib/github-sync-queue-handler.ts +69 -0
- package/src/lib/github-sync-site-config.ts +57 -0
- package/src/lib/github-sync-status.tsx +87 -0
- package/src/lib/github-sync-trigger.ts +199 -0
- package/src/lib/github-sync-worker.ts +72 -0
- package/src/lib/hosted-signin.ts +9 -3
- package/src/lib/hugo-markdown.ts +255 -0
- package/src/lib/job-queue-cf.ts +18 -0
- package/src/lib/job-queue-db.ts +149 -0
- package/src/lib/job-queue.ts +35 -0
- package/src/lib/markdown-manager.ts +864 -0
- package/src/lib/markdown-to-tiptap.ts +4 -323
- package/src/lib/markdown.ts +16 -24
- package/src/lib/media-helpers.ts +1 -0
- package/src/lib/navigation.ts +50 -19
- package/src/lib/post-display.ts +10 -22
- package/src/lib/post-meta.ts +20 -2
- package/src/lib/public-storage.ts +6 -1
- package/src/lib/rate-limit-d1.ts +99 -0
- package/src/lib/rate-limit-memory.ts +105 -0
- package/src/lib/rate-limit.ts +63 -0
- package/src/lib/render.tsx +14 -2
- package/src/lib/resolve-config.ts +32 -11
- package/src/lib/rich-image.ts +89 -0
- package/src/lib/schemas.ts +180 -13
- package/src/lib/summary.ts +162 -20
- package/src/lib/theme.ts +119 -0
- package/src/lib/timeline.ts +63 -42
- package/src/lib/tiptap-render.ts +265 -126
- package/src/lib/tiptap-to-markdown.ts +6 -329
- package/src/lib/upload.ts +97 -6
- package/src/lib/url.ts +34 -0
- package/src/lib/version.ts +18 -0
- package/src/lib/video-playback.ts +73 -0
- package/src/lib/view.ts +168 -94
- package/src/lib/webhook-signature.ts +65 -0
- package/src/lib/worker-response-cache.ts +220 -0
- package/src/lib/youtube.ts +119 -0
- package/src/middleware/__tests__/auth.test.ts +44 -4
- package/src/middleware/__tests__/onboarding.test.ts +3 -3
- package/src/middleware/__tests__/rate-limit.test.ts +113 -0
- package/src/middleware/__tests__/secure-headers.test.ts +28 -1
- package/src/middleware/__tests__/session.test.ts +85 -0
- package/src/middleware/auth.ts +62 -25
- package/src/middleware/config.ts +7 -10
- package/src/middleware/cors.ts +49 -0
- package/src/middleware/rate-limit.ts +54 -0
- package/src/middleware/secure-headers.ts +45 -55
- package/src/middleware/session.ts +36 -0
- package/src/node/__tests__/cli-migrate.test.ts +111 -0
- package/src/node/__tests__/cli-runtime-target.test.ts +1 -1
- package/src/node/__tests__/cli-site-token-env.test.ts +2 -2
- package/src/preset.css +316 -12
- package/src/routes/__tests__/compose.test.ts +4 -2
- package/src/routes/api/__tests__/collections.test.ts +81 -27
- package/src/routes/api/__tests__/mcp.test.ts +389 -0
- package/src/routes/api/__tests__/nav-items.test.ts +163 -2
- package/src/routes/api/__tests__/posts.test.ts +190 -0
- package/src/routes/api/__tests__/search.test.ts +48 -0
- package/src/routes/api/__tests__/settings.test.ts +99 -3
- package/src/routes/api/__tests__/upload-multipart.test.ts +21 -6
- package/src/routes/api/__tests__/upload.test.ts +132 -0
- package/src/routes/api/__tests__/uploads.test.ts +5 -3
- package/src/routes/api/collections.ts +67 -26
- package/src/routes/api/custom-urls.ts +1 -0
- package/src/routes/api/export.ts +8 -4
- package/src/routes/api/github-sync.tsx +380 -0
- package/src/routes/api/internal/__tests__/sites.test.ts +45 -2
- package/src/routes/api/internal/search-reindex.ts +40 -0
- package/src/routes/api/internal/sites.ts +2 -0
- package/src/routes/api/internal/text-attachments.ts +60 -0
- package/src/routes/api/internal/uploads.ts +5 -1
- package/src/routes/api/mcp.ts +30 -0
- package/src/routes/api/nav-items.ts +30 -11
- package/src/routes/api/palette.ts +17 -0
- package/src/routes/api/posts.ts +37 -106
- package/src/routes/api/public/__tests__/posts.test.ts +372 -0
- package/src/routes/api/public/posts.ts +302 -0
- package/src/routes/api/search.ts +13 -46
- package/src/routes/api/settings.ts +44 -58
- package/src/routes/api/upload-multipart.ts +15 -5
- package/src/routes/api/upload.ts +62 -49
- package/src/routes/api/uploads.ts +1 -0
- package/src/routes/auth/__tests__/hosted-sso.test.ts +33 -0
- package/src/routes/auth/__tests__/setup.test.ts +29 -4
- package/src/routes/auth/dev.ts +1 -1
- package/src/routes/auth/hosted-sso-expired-page.tsx +89 -0
- package/src/routes/auth/hosted-sso.ts +42 -1
- package/src/routes/auth/reset.tsx +46 -32
- package/src/routes/auth/setup.tsx +53 -43
- package/src/routes/auth/signin.tsx +57 -29
- package/src/routes/compose.tsx +114 -1
- package/src/routes/dash/__tests__/font-theme.test.ts +6 -27
- package/src/routes/dash/__tests__/settings-avatar.test.ts +2 -3
- package/src/routes/dash/custom-urls.tsx +250 -112
- package/src/routes/dash/settings.tsx +1182 -75
- package/src/routes/feed/__tests__/{rss.test.ts → feed.test.ts} +62 -123
- package/src/routes/feed/__tests__/sitemap.test.ts +320 -4
- package/src/routes/feed/feed.ts +386 -0
- package/src/routes/feed/manifest.ts +67 -0
- package/src/routes/feed/sitemap.ts +211 -27
- package/src/routes/pages/__tests__/collection-routing.test.ts +176 -0
- package/src/routes/pages/__tests__/collections.test.ts +2 -3
- package/src/routes/pages/__tests__/featured.test.ts +2 -3
- package/src/routes/pages/__tests__/page-canonical.test.ts +101 -0
- package/src/routes/pages/archive.tsx +523 -127
- package/src/routes/pages/collection.tsx +197 -43
- package/src/routes/pages/collections.tsx +5 -1
- package/src/routes/pages/home.tsx +26 -17
- package/src/routes/pages/latest.tsx +3 -3
- package/src/routes/pages/page.tsx +255 -3
- package/src/routes/pages/partials.tsx +8 -14
- package/src/routes/pages/search.tsx +17 -1
- package/src/routes/pages/theme-sample.tsx +1 -2
- package/src/runtime/__tests__/node.test.ts +1 -1
- package/src/runtime/cloudflare.ts +4 -0
- package/src/runtime/node.ts +16 -0
- package/src/runtime/readiness.ts +1 -1
- package/src/runtime/site.ts +9 -1
- package/src/services/__tests__/collection.test.ts +137 -54
- package/src/services/__tests__/github-app-installations.test.ts +181 -0
- package/src/services/__tests__/github-sync-classify.test.ts +189 -0
- package/src/services/__tests__/github-sync-push.test.ts +159 -0
- package/src/services/__tests__/media.test.ts +444 -7
- package/src/services/__tests__/navigation.test.ts +271 -14
- package/src/services/__tests__/post-timeline.test.ts +31 -21
- package/src/services/__tests__/post.test.ts +288 -9
- package/src/services/__tests__/search.test.ts +44 -0
- package/src/services/__tests__/settings.test.ts +43 -21
- package/src/services/auth.ts +2 -2
- package/src/services/bootstrap.ts +10 -7
- package/src/services/collection.ts +591 -193
- package/src/services/custom-url.ts +34 -7
- package/src/services/export-theme/assets/client-site.css +2 -0
- package/src/services/export-theme/assets/client-site.js +145 -0
- package/src/services/export-theme/layouts/_default/alias.html +49 -0
- package/src/services/export-theme/layouts/_default/baseof.html +21 -0
- package/src/services/export-theme/layouts/_default/list.html +104 -0
- package/src/services/export-theme/layouts/_default/rss.xml +160 -0
- package/src/services/export-theme/layouts/_default/single.html +15 -0
- package/src/services/export-theme/layouts/archive/list.html +31 -0
- package/src/services/export-theme/layouts/collection/single.html +19 -0
- package/src/services/export-theme/layouts/collections/list.html +111 -0
- package/src/services/export-theme/layouts/featured/list.html +28 -0
- package/src/services/export-theme/layouts/index.html +41 -0
- package/src/services/export-theme/layouts/partials/feed-post-content.xml +107 -0
- package/src/services/export-theme/layouts/partials/footer.html +32 -0
- package/src/services/export-theme/layouts/partials/head.html +52 -0
- package/src/services/export-theme/layouts/partials/header.html +115 -0
- package/src/services/export-theme/layouts/partials/media-gallery.html +246 -0
- package/src/services/export-theme/layouts/partials/pagination.html +55 -0
- package/src/services/export-theme/layouts/partials/post-card.html +127 -0
- package/src/services/export-theme/layouts/partials/reply.html +91 -0
- package/src/services/export-theme/layouts/partials/thread-preview.html +82 -0
- package/src/services/export-theme/layouts/post/list.html +129 -0
- package/src/services/export-theme/styles/main.css +1981 -0
- package/src/services/export-theme/theme.toml +12 -0
- package/src/services/export.ts +1372 -2412
- package/src/services/github-app-installations.ts +302 -0
- package/src/services/github-sync.ts +769 -0
- package/src/services/index.ts +15 -0
- package/src/services/mcp.ts +1324 -0
- package/src/services/media.ts +336 -25
- package/src/services/navigation.ts +115 -23
- package/src/services/path.ts +129 -28
- package/src/services/post.ts +858 -197
- package/src/services/search.ts +3 -0
- package/src/services/settings.ts +29 -15
- package/src/services/site-admin.ts +26 -6
- package/src/services/upload-session.ts +69 -34
- package/src/style-cjk-jp.css +3 -0
- package/src/style-cjk-kr.css +3 -0
- package/src/styles/components.css +160 -59
- package/src/styles/fonts/et-book/et-book-bold-line-figures.woff +0 -0
- package/src/styles/fonts/et-book/et-book-display-italic-old-style-figures.woff +0 -0
- package/src/styles/fonts/et-book/et-book-roman-line-figures.woff +0 -0
- package/src/styles/fonts/et-book.css +31 -0
- package/src/styles/fonts/latin.css +1 -0
- package/src/styles/fonts/noto-serif-jp/400/057a6a98bda7fe57105ddaa99ec82015.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/0acd1fe2b2ea1ad1bfee7ae1fa139d27.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/0c2ab6b295e55f356f8020d4e7747522.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/0c5f9492af03a4fa42c784de94649de1.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/0d9a936885a4c39077438effd3779cbd.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/0e645da524f7cfc0e8c3c03fb2b08428.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/135e83b403475c5dc9e49b43501a5b84.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/13b2c53b30e6a3e4de7132dbc18dbdfc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/15d95680dc31cc6ce20e0a5464106dc4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/1733f27476507ca68b68a803bc533cc2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/188c2db794f3dd7a45889ddbc81da9bb.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/1cf737900dd49c2e88f1b3221a82a602.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/233d3a685ee18276b319363474599d47.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/284b53bbefb06924cf236d24c8ed5641.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/2a56eaf19d1d38a6b57e2a388f733676.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/2abfbab82b6a7c04426afc054d2464da.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/2e6f4bb71ef6b38765d51acc5a79f638.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/31194d303a67561926a544ed0e072aee.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/3623d96698132c61e861f984ce11cc23.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/39211b02f24c69cbd1b54f6d41b01933.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/3e24063b19abd2b051af986a6870046d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/4410f876d27c9821839474b6b1059fd7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/479329a39a3eb6c0047e6b0981919855.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/527ff336279465617aafbafe1a830632.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/56b40518ea0608e62826bd44ee27f5f9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/5acc7f736217259db79a42bf44241c48.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/5c05f8b75c9d7f25b3c04ca711cf43b3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/5e0124c7265f1b4cf0fc797b94efbebc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/615a7e0d63f257109d599b2a1977de68.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/61a2c80d0c924d5a6187c02e8d1d1642.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/62fc94f8d4c5a750b7f25e7387539910.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/639c7c6b0b0c27c738702741cfa4b8c0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/68a3a4bf337f8a0722be76676e20b850.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/6abdd163d2c4b85698db8aa1ce149361.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/73b794d885b88f7befb7ea8ab1780a15.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/743f290baf027d4626a86e22f3d44600.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/757019c01c5e2c2b0f54293cea3b5636.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/76f117a3baacda304a71965a17266a13.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/77747f17625a259fb405b7bbdd84ac4b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/788498548ddfb710d6ef3c7bff79fa97.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/78ea6c40923ce95367e3517dd1e5a849.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/7f9a6c9286b68de9c72b0024f7beeb40.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/823d1bb11097331238d103c7f72138dc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/888ba53510213d5d1f6a7deb60e569b6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/892aa49b2529c89bb4076d4aa51fe30f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/95ff41191c76ef893ac70a1043e95e44.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/96c75862c8cec51a7c05ff025fea86cd.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/9b21e8244f5930c48ad5073f83777b6c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/9fce02d1a09f464c36c9fcfb14a354c5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/a0a6755c7e3f9e4cf03387027dd9f16c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/a4475c442c6b259354c9eda62e64e7df.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/a4a39b5f048671aa37c2b2a9581ab08a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/a534449d67561ac9b06489f64e57ad98.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/a919a8c6fec6d7e8bb21177965f2e9d7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/ad67113f88b59582991cb0c5d33ea19f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/adb6e613fb99c6dd660b727101f554a8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/adc4a98a89870ef984ee8f4b57c8a3a5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/b12379ab782468d725519cd07a7d15bc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/b55486f8a459c838fe329d4e79a8c211.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/bb0b15492b8cdbbec57c0bcfa0aa9241.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/bedc74b423b7293b6ad0bdecc61c42cc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/bfb00d4a4c48661bd0be99f300a0faae.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/c1b0df29ae41d764904df84e9ac83d1e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/c42c67070cfe99cf823df92d81c7fa6e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/c4d749e45ecd5a5aed5a0bb3ebfd355d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/c96d83978add28b356c22c4c84916733.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/cb7ccd6494256f7a2977b7c2b0225592.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/ce41d70ce6a069a498525c9e15c45cf2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/d509ee5c8241bc7c3de2039d75564fa5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/d675d717cd329bfd4c0524f76ae1579c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/dc8f6256445e68199540be9ade33529f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/e8c15be62faf978d208925e79ea6a10d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/e91c4d941ed9f5c2f3e27f205a3a225e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/e9c566be7a5d38a9085225f7372bc82b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/e9ebc567a711eeb29019ddae3e0ce7fe.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/ecb8875a56c7b038b35432fda41ae128.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f1661731474b78bdf81114daf10b254f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f2c58dee206ba9355046fc23d05491f7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f50ac27ea4358d67fdda403c2bb52467.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f55334112f8e8be82d65db29887a663f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f740e93f3c0277ecc616594103bca683.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f7633b5af033d76ff2fb3c3c266d77c5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/f7d8468cba2335a83ee414ea68291bab.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/fc9ae5b600fb711f2d67e93ce768cba4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/400/fd1bceb55d3e0183ac2454b8532fec7d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/02611a045a7fe83a12014e3debc9f731.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/0f5e1a18987dbc84ca05188c129e1936.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/112743a4ab5fdd1498dfdf2b11336380.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/1211f03d3ff5759a702631445793f60e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/147b24c2f08d03bbed30887d4cb3311c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/16663e567f81f4725a1522f37e18f71f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/1824321da801e6257b902f3d1d09054c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/1a3a92c7c060a71a6c35819b9ebcdbb9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/1fba7ec0e412e911bf31841de5a8a4e4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/28a97af9ab9d38983d20f39ff09840e1.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/2bfaadaf3479c72286248e6de0be0ec9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/2c8c55e4cec85ce77e95cac9d330f5cf.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/2ed9981d2e8983365bd051159b976b6d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/2f4c633e923ba30c6ba376367379fc91.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/349965eee0a9b6c984a319ab96a4ece9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/36cda3eae13370b934bba4429fab9078.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/3aa13f1843d7c8fa16109b6395a9a29d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/3e2c06bdd9dcab29aeaeb0cfb7fa608a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/424123f9371ba357087363263eeafcda.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/43b3bbf43055c3e65db9cdf2c5b18c1c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/44704471b60c18b3ecec5300a88f1102.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/46604090efbb99c2db1800928af0a239.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/46998df85d31e629c0142f0556f5e7c5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/49902f1c41b281f8eb3771abdd4dccb8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/4db4f31a16965baa42cb7dad667a8f04.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/572b9e28f1e6d89b765a16d809db84a1.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/5921cef36750ff6092d94b83a802823b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/59e95d8b5332dcdae894a19946ab767d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/5ec349ff62b9ee5fe0c6dae867704dc4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/601f812e8b1eafecd5ba585a6a6d7962.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/6025ddaf99d86cc8bfd781006b19fbd6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/60f6e28b3f0400b0e8fe32c3c7116102.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/64a404d675f1d726f0891b7a80794595.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/7158022889c6c177062ac85036e7af10.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/7e38ca789a9e76ac91d9256374e154f0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/815a0b797465190f60d8b1a04656c42e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/8726558cf297cbda831cc19514897205.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/8855472f3c02f6c7ebb3216617ebe4af.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/8e231d707f0c4f8e3cde90a6b52a79aa.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/9064c12fd72c7aba235d8c3881755b91.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/911b9e53e9814de2998c60bf3115f560.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/92fdc376bce277874e75db666f175b44.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/930a23430f0eb64480d7fe5f82834e21.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/93bed0e5f2dd5a21cf73304fcfbc149d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/93f3ea6918533d96d9c252378b9a4af0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/95a0951d2a2722ff773a1a45e8c474d6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/982cd1765ca6bbb3e6547e47834d5148.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/9b0c3caac458c7bc9c9133e40405ddea.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/9f3bdab4025dc7c5ba1a5871e62e8918.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/a00e94d4f04df6aa659db9c4954c7efe.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/a2b0597837e382aca19919c4b74e58c8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/a373e85c96aa0dc303092429fb837e51.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/a6e044424780a57610833cc856c15bf5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/a7c58070d68dc1724e9d4e781afb78db.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/accc43762ad05edfbff66ba1380d192a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/ad47bcd6d4663026d648c132d969318d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/af57a2e8c72f9ba0efb1af771d32c124.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/b0ae5f374e43dac992a4a5d334cebc0b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/b91234c10fd8b8c8abc88e03afe66a1f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/b9317198f118a1dfd8ddf2b82ec028f3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/ba825ae79b1a6f7e0cce5215fcb5c96f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/bc6183ac08f0fac78c46f80c10cf7c92.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/bc8ccea5abf6598cf3cfa97eb59804bb.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/bc95a792cbca6639214c9b0da13392ff.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/bcfa62f35731856246c146d3a6932bf3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/c063897793f593eb26d6ff7b7baaba18.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/c6c2971ad1f3221f6cf84028aa0f477e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/c97f41eef722121d86f55d553c056a39.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/ca62704509932d3232d62918de97af3f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d1f064825fa5784b5c930652bd831cce.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d2faabcedd19f016e7b21bce073c0ec8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d320171e57480510f87dbbc7d5264b0a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d3a72a99d365dddfbca8d017a8011368.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d42aafa0f246ad3b4c16fe96d3a3a432.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d4aaf23c13ae808a4bed617afd13aa07.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d6bb686bddfbe8f38a36a68e609a8667.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/d9020ff69a83b2a6ee1f42ae480f7db0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/da90a9012ab2d98f759e3fa0820ef502.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/df10d94bea357a43313e20da5d84bd30.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/e34b2b141e472dc776c86fdf8eea23b0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/e444fd88f1390636e603d0d681538ac8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/e79898628283edc27180fc39d0d769c1.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/eaf332445a40942928e5f5750c1c3116.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/f91cd722855f4269256eae1187df64ec.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/fc895f5ce66b656f4a933097bf2a8775.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/fca6720fd14c467d29a90f18ef3859b9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/700/fd1bb507bcbf04856eeb7f7fd47ea579.woff2 +0 -0
- package/src/styles/fonts/noto-serif-jp/noto-serif-jp.css +3349 -0
- package/src/styles/fonts/noto-serif-kr/400/033466ef683afe931f7f520cfb42d928.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/05da12edb9d52210581dc6ec4541031f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/0968e4861204b51f62a2f8e9f15dd5e0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/0d5dec931dc885f07fe5cd5af8bed675.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/1076f0f6f66d28d7a2f16427faad4413.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/12ef1ba76bd20b004b865266a1aa70b3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/152395634a207579552f8cb54db88599.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/1a08931435f885e707edb85978ea3bb6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/31a197213ae61d7043c81013f52d10d6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/37dbd564820cce2f7b3331e442da0df3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/37dc8505b20b37a2477a9121b16d44a7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/3ac0a07878cacdc98bb889f40f5970d3.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/491bbba374093fff045f55803a22bfef.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/4d38e56738156625329d93bd5c8cc74a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/57e9a86651366c1ba299e47aa7e358c2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/57f89adeae55aa7fe2add3fc1801ce03.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/5df9ce98c75f8c50fb4fff7f01a23925.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/60020a830d809c26970cf8e48ba1eeda.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/60bcfa3ea7446eb42394aab02d28be40.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/63fafcb069520613d0ea35ad3e6b1e42.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/65a60d87c64228d258a123cbe85f5f31.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/6968e889e18891d912809fe484c2e745.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/70714891ad3fbfc3d5f10a8669dacc5a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/761d84afca8d7f34eebefe538adba827.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/76e07530323418ec723c5d7634c9bcca.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/773819b7b9b8fd404a929867c0fd677e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/7817dd16805145d8538ad57590f69f5a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/7b59f0ec7792b18458dc5a361e37884c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/7c3945788a689a69356c1a622d69d48b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/835b6505bb9eea9678925a1fa885353d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/8b5c9ef81159f31d2ab35f45ca4373e0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/8b91c7c2ed390f1278b9befa3aa87233.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/8fb45117a62d92dce44a80f0b729ead5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/90b7848e9b1623b77bdcf155e90b839c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/985d4d41afa0934a4eb2de35473fb9a2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/9bb38fd05201de666b88b82d56a386f7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/9eff2ab2a9d2ced47ab761bf6fdb11ec.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/9f1963fe8d4d6878d717d872a8f3fdb5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/a0d00fe4816c95a8c7dffd445ef00b03.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/a0f199077fa1a33bc2a1e01c64de7fe6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/a7c35e42a659347e490c3cb7983b2e7f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/aa662092cf249707123ca4d575e2764b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/aae1eda193285ab817a2d1b408440326.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/b0cb664cb2e1371efda8943c0b7dcd1c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/b0d1cdced482352cf0d3ae58638aacb9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/b320f5d185b2cff933ac549c184031c5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/ba9c59d7dfa4494db1bb764ada81467d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/bab547459d514f46206e340c4bb2dc88.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/bcc39eda837bb7a7a3d37c8c60fffb81.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/bd73264d7f98776708d5d6f3c9b78fcc.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/bed610b217d500f5975cfc9fe6157570.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/bf8901f8f11d4f433ea17dabc9370ea6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/c4143bb9f2fe77b6ccf20088a8904650.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/c7ff3f6bbdcd5f604b7343602ab904df.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/c945c62368357d05a53206620460fb30.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/ce022e18a1377ac509443c3c3790b431.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/cf9cffe56636322f62b40d61130fbc5e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/d20d8944bc0b85f5b2aae4b24f343516.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/d36644d6502527e1fff205d0c7eca434.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/d40ab99c7a38026f411c8f112f742b48.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/dc6e234ded795e91f76d6647f628fbf0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/dd0cfdfdac0866e66d587e2b5a9e9961.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/de304c8a02e45ded4f8dcc479d167198.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/e8c364c16daa04835bf32d293d2598db.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/ec86e23683052da5cfdc3b77641bd15a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/eda1b0cb6d1719dd9bedcf3216a9e8de.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/ee6fce20b420a480714607c66d7f97e5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/eee3836d6ac17ebb2c450bbcbc9db121.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/f5738255e92d8dd34a46d1bcdf4c4074.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/fa6e58ce4b52695e7ae19bbea6336ec8.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/400/fd2069e6e8588c70b4f11364093b81f2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/04b8bde59cff68eeee74fb1914eb09c7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/05ac821472e235943ed1435e4bb8ecad.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/074c1f8483d5a4d8c45c8c5f3e4cbb32.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/1380210a722ac9aeef54005ad7b015c9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/17c7f5d0a45e92ede0e5dec3a2c77efa.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/1be602ad456b0d75902d352116cb35fd.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/2612c60f9dc5459ac42763591240a1d6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/2ab8cf1f23a5ac7939a7876054e711a7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/34e6750e00c3a911ef87dc66b336594d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/36f3df4730cfca4fc77fe52b52e6a126.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/37887deb7a9c466cf2af6ee7ff372ea6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/3aba89c4d4281553078de4622b498cbb.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/3d88558097559d775231194d43745ba7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/3dc3e8c35524cad2d1236f3393104ccf.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/45140742dfa8686b58db2899ce89f89a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/469d2754e315e77270c12fa0ab28026c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/4c0760284569b87d8f2290c324953973.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/4cba92c942694bdc479bc54101bb1aa4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/4e7d263c30bb48604069a3b4404d4eeb.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/5279c7e465d9871edf51fd02e691eee7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/54bfdb6f21f9d6191e5100580239e14f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/56be5e32fd01668fe5ba814d94905839.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/615b38e0b5bb3ea68426f44f47706e6f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/65e9c4585d71bf48a5c62f367010da16.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/6b75213eb0be40ce84241eb2bb438a2e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/7520ca6ca8c60eb1e62d50e71c8d30f1.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/759a647b77791b1e98f99bc0ab5317a7.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/76e51630143b95b6322ef93ad330da7a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/79aa7c8c842c4a27cf57c0a3a1ffca5a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/7cc72fd2c9105560422b6a67c6162945.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/7d0ea0690e432462f4d05a23d720ec19.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/7dffa5c1bec57e0903fd62357401ff1a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/82f6ccc063960eed1cdfd1d61ada8862.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/845b4b67564d62cf5cad242f7ac08ea5.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/84c8e7bc0931008ed91f44ed12dfea94.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/887a11290ba78b1e66c6d2f67043005e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/88db1d042074fb6e66821ffc10941930.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/8dc18c0cebe6aa4bf4c45dbb831048ab.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/919a879bd2d580d8491a31a449390689.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/91da6cb174bebfb96976e2f1316be2fe.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/934dfdbed2bb2c4b6129199d699a34fa.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/97d7a17234f2b5030ae9697ae00aded2.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/995c4fda62d25c3b79dd5987737df6ae.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/9d0afa53dc2f92ba42024f55f11f6779.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/9e13a47242926f1cd7d68c08d9ef8889.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/a379ada89abd750c587ded29f77e731c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/a48be56ce5d3a99dc8f8331398004412.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/a806759e72987951d6d08b7cbdf36a1b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/a88481ec8bc7be11cb66e46781a79bb9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/a9a016d4a93409f65278327e8a8bb38d.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/ab92d41062a7644faa45f50bf384454a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/b326a8a9c33b554db570da94f60bc380.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/b6117ff2993b11bb1fdc7ea3588a010c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/b61982951bd51b724143c30dfaaa9fe9.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/c0098958e20db68cab90097b5e62516f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/c4bfaa5e50798246e3770718b7a7c84a.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/c84598999133455503042e06f4ab79cb.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/ca9a533988d7019597a60d4e17127e0c.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/cf2b28f90f47276f7e2688a65e88a101.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/d689b1861d7e4377dd72ad3013482612.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/d9047070d72a816b3dba9d40c2d85e69.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/da04549f3f4ed28076b01b8cd710d313.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/da7af303f8c645f9a9dbae0e6e32dd35.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/df9568257eb29b156449fdd4bec5ec76.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/e067cd0ed76c90cd0a93c9339253f20b.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/e08b07772e7bed3cec2832d43f7fd339.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/e12150d5a39b30be8f567968c7a527b0.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/e53fcb2381eee345db4f6f973dd95a3e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/e5bd313ef81f687d398aacb11cec3069.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/eb5afb3d952b8593782caec6026514b6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/edd6a4f608d04fc0351d7688cfc321e4.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/f9695c6c4df2bf6bc03045ff79d4f01f.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/fada6eaa68ff8816afe43d2a36c5423e.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/700/fbcc4bf5367218951172bdee6f77d7a6.woff2 +0 -0
- package/src/styles/fonts/noto-serif-kr/noto-serif-kr.css +2601 -0
- package/src/styles/site-media.css +823 -0
- package/src/styles/tokens.css +292 -21
- package/src/styles/ui.css +4188 -1857
- package/src/types/app-context.ts +20 -0
- package/src/types/bindings.ts +3 -1
- package/src/types/config.ts +147 -9
- package/src/types/constants.ts +46 -11
- package/src/types/entities.ts +24 -8
- package/src/types/operations.ts +80 -1
- package/src/types/props.ts +10 -9
- package/src/types/raw-assets.d.ts +39 -0
- package/src/types/views.ts +28 -7
- package/src/ui/__tests__/color-themes.test.ts +7 -40
- package/src/ui/__tests__/font-themes.test.ts +30 -11
- package/src/ui/color-themes.ts +311 -270
- package/src/ui/compose/ComposeDialog.tsx +712 -394
- package/src/ui/compose/ComposePrompt.tsx +15 -10
- package/src/ui/dash/ActionButtons.tsx +27 -18
- package/src/ui/dash/DangerZone.tsx +15 -10
- package/src/ui/dash/FormatBadge.tsx +21 -8
- package/src/ui/dash/StatusBadge.tsx +33 -22
- package/src/ui/dash/appearance/AdvancedContent.tsx +44 -30
- package/src/ui/dash/appearance/CodeInjectionContent.tsx +164 -0
- package/src/ui/dash/appearance/ColorThemeContent.tsx +127 -160
- package/src/ui/dash/appearance/FontThemeContent.tsx +20 -15
- package/src/ui/dash/appearance/NavigationContent.tsx +368 -225
- package/src/ui/dash/appearance/__tests__/NavigationContent.test.tsx +54 -0
- package/src/ui/dash/settings/AccountContent.tsx +34 -23
- package/src/ui/dash/settings/AccountMenuContent.tsx +226 -137
- package/src/ui/dash/settings/ApiTokensContent.tsx +122 -79
- package/src/ui/dash/settings/AvatarContent.tsx +73 -45
- package/src/ui/dash/settings/DeleteAccountContent.tsx +106 -66
- package/src/ui/dash/settings/GeneralContent.tsx +274 -157
- package/src/ui/dash/settings/GitHubSyncContent.tsx +558 -0
- package/src/ui/dash/settings/SessionsContent.tsx +79 -38
- package/src/ui/dash/settings/SettingsRootContent.tsx +209 -109
- package/src/ui/dash/settings/__tests__/AccountMenuContent.test.tsx +67 -0
- package/src/ui/dash/settings/__tests__/GeneralContent.test.tsx +75 -0
- package/src/ui/feed/CuratedThreadPreview.tsx +24 -14
- package/src/ui/feed/LinkCard.tsx +116 -84
- package/src/ui/feed/LinkPreview.tsx +75 -0
- package/src/ui/feed/NoteCard.tsx +60 -16
- package/src/ui/feed/PostStatusBadges.tsx +15 -0
- package/src/ui/feed/QuoteCard.tsx +10 -3
- package/src/ui/feed/ThreadPreview.tsx +62 -36
- package/src/ui/feed/TimelineFeed.tsx +2 -1
- package/src/ui/feed/__tests__/thread-preview.test.ts +220 -11
- package/src/ui/feed/__tests__/timeline-cards.test.ts +186 -5
- package/src/ui/feed/thread-preview-state.ts +23 -10
- package/src/ui/font-themes.ts +57 -97
- package/src/ui/layouts/BaseLayout.tsx +230 -136
- package/src/ui/layouts/SiteLayout.tsx +431 -143
- package/src/ui/layouts/__tests__/BaseLayout.test.tsx +76 -6
- package/src/ui/layouts/__tests__/SiteLayout.test.tsx +76 -0
- package/src/ui/pages/ArchivePage.tsx +320 -207
- package/src/ui/pages/BrandPage.tsx +499 -341
- package/src/ui/pages/CollectionEditorPage.tsx +50 -30
- package/src/ui/pages/CollectionPage.tsx +151 -78
- package/src/ui/pages/CollectionsPage.tsx +27 -18
- package/src/ui/pages/ComposePage.tsx +15 -10
- package/src/ui/pages/FeaturedPage.tsx +16 -11
- package/src/ui/pages/HomePage.tsx +15 -10
- package/src/ui/pages/PostPage.tsx +5 -1
- package/src/ui/pages/SearchPage.tsx +93 -43
- package/src/ui/pages/ThemeSamplePage.tsx +758 -520
- package/src/ui/pages/__tests__/ArchivePage.test.tsx +72 -0
- package/src/ui/shared/CollectionDirectory.tsx +215 -34
- package/src/ui/shared/CollectionsManager.tsx +155 -75
- package/src/ui/shared/DecorativeQuoteMark.tsx +12 -9
- package/src/ui/shared/MediaGallery.tsx +350 -256
- package/src/ui/shared/Pagination.tsx +36 -25
- package/src/ui/shared/PostFooter.tsx +139 -96
- package/src/ui/shared/__tests__/media-gallery.test.ts +27 -0
- package/src/ui/shared/__tests__/navigation-labels.test.ts +79 -28
- package/src/ui/shared/__tests__/post-footer.test.ts +42 -17
- package/src/ui/shared/collection-management-labels.ts +109 -33
- package/src/ui/shared/navigation-labels.ts +78 -8
- package/bin/lib/site-localize-media.js +0 -427
- package/dist/client/_assets/client-auth.js +0 -3260
- package/dist/client/_assets/client.css +0 -2
- package/dist/client/_assets/client.js +0 -380
- package/src/__tests__/site-localize-media.test.ts +0 -150
- package/src/client/components/jant-collection-sidebar.ts +0 -816
- package/src/i18n/locales/en.ts +0 -1
- package/src/i18n/locales/zh-Hans.po +0 -3197
- package/src/i18n/locales/zh-Hans.ts +0 -1
- package/src/i18n/locales/zh-Hant.po +0 -3197
- package/src/i18n/locales/zh-Hant.ts +0 -1
- package/src/routes/feed/rss.ts +0 -216
- package/src/types/lingui-react-macro.d.ts +0 -34
- /package/dist/client/_assets/chunks/{heic-to-XcUDQvtx.js → heic-to-DUUaO23q.js} +0 -0
- /package/dist/client/_assets/chunks/{module-ChVQstFd.js → module-DcsAZQZ_.js} +0 -0
- /package/dist/client/_assets/chunks/{native-CR5HLOyf.js → native-DpcrFAPh.js} +0 -0
- /package/dist/client/_assets/{client-cjk.css → client-cjk-B7Z0snDu.css} +0 -0
- /package/dist/client/_assets/{client-cjk-tc.css → client-cjk-tc-BesJYrb2.css} +0 -0
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
stat,
|
|
8
8
|
writeFile,
|
|
9
9
|
} from "node:fs/promises";
|
|
10
|
-
import { resolve, join,
|
|
10
|
+
import { resolve, join, extname, dirname, basename } from "node:path";
|
|
11
11
|
import { tmpdir } from "node:os";
|
|
12
12
|
import { parseArgs } from "node:util";
|
|
13
13
|
import { typeidUnboxed } from "typeid-js";
|
|
@@ -20,37 +20,38 @@ import {
|
|
|
20
20
|
} from "../lib/site-media-parser.js";
|
|
21
21
|
import { openNodeDatabase } from "../lib/node-database.js";
|
|
22
22
|
import { loadNodeRuntime } from "../lib/load-node-runtime.js";
|
|
23
|
+
import { parseFrontMatter as parseFrontMatterShared } from "../lib/hugo-markdown.js";
|
|
23
24
|
|
|
24
25
|
/**
|
|
25
26
|
* Parse front matter from a Markdown file.
|
|
26
|
-
*
|
|
27
|
-
* Returns { frontMatter, body }.
|
|
27
|
+
* Delegates to the shared hugo-markdown module.
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
// Try YAML front matter (---...---)
|
|
31
|
-
const yamlMatch = content.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
|
32
|
-
if (yamlMatch) {
|
|
33
|
-
const { parse } = await import("yaml");
|
|
34
|
-
const frontMatter = parse(yamlMatch[1]) || {};
|
|
35
|
-
return { frontMatter, body: yamlMatch[2] };
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Try TOML front matter (+++...+++)
|
|
39
|
-
const tomlMatch = content.match(/^\+\+\+\n([\s\S]*?)\n\+\+\+\n?([\s\S]*)$/);
|
|
40
|
-
if (tomlMatch) {
|
|
41
|
-
const { parse } = await import("smol-toml");
|
|
42
|
-
const frontMatter = parse(tomlMatch[1]);
|
|
43
|
-
return { frontMatter, body: tomlMatch[2] };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return { frontMatter: {}, body: content };
|
|
47
|
-
}
|
|
29
|
+
const parseFrontMatter = parseFrontMatterShared;
|
|
48
30
|
|
|
49
31
|
async function parseToml(content) {
|
|
50
32
|
const { parse } = await import("smol-toml");
|
|
51
33
|
return parse(content);
|
|
52
34
|
}
|
|
53
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Read custom.css from a Jant Hugo export. Prefers the root
|
|
38
|
+
* `static/custom.css` (user override) and falls back to
|
|
39
|
+
* `themes/jant/static/custom.css` (the default location Jant writes).
|
|
40
|
+
*/
|
|
41
|
+
async function readImportCustomCss(rootDir) {
|
|
42
|
+
const rootCss = await readFile(
|
|
43
|
+
join(rootDir, "static", "custom.css"),
|
|
44
|
+
"utf-8",
|
|
45
|
+
).catch(() => null);
|
|
46
|
+
if (rootCss !== null) {
|
|
47
|
+
return rootCss;
|
|
48
|
+
}
|
|
49
|
+
return readFile(
|
|
50
|
+
join(rootDir, "themes", "jant", "static", "custom.css"),
|
|
51
|
+
"utf-8",
|
|
52
|
+
).catch(() => "");
|
|
53
|
+
}
|
|
54
|
+
|
|
54
55
|
function resolveImportUrl(url, siteConfig) {
|
|
55
56
|
if (typeof url !== "string" || url.trim() === "" || url.startsWith("data:")) {
|
|
56
57
|
return url;
|
|
@@ -216,53 +217,6 @@ async function readMediaSpecAsset(media, field = "src") {
|
|
|
216
217
|
});
|
|
217
218
|
}
|
|
218
219
|
|
|
219
|
-
/**
|
|
220
|
-
* Parse reply markers from post body.
|
|
221
|
-
* Returns array of { attrs, body } segments where the first is the root.
|
|
222
|
-
*/
|
|
223
|
-
function splitReplies(body) {
|
|
224
|
-
const markerRegex = /<!-- jant:reply (.*?) -->/g;
|
|
225
|
-
|
|
226
|
-
// Split body by markers, keeping the marker data
|
|
227
|
-
const markers = [];
|
|
228
|
-
let match;
|
|
229
|
-
while ((match = markerRegex.exec(body)) !== null) {
|
|
230
|
-
// Parse key="value" pairs from the marker
|
|
231
|
-
const attrs = {};
|
|
232
|
-
const attrRegex = /(\w+)="([^"]*)"/g;
|
|
233
|
-
let attrMatch;
|
|
234
|
-
while ((attrMatch = attrRegex.exec(match[1])) !== null) {
|
|
235
|
-
attrs[attrMatch[1]] = attrMatch[2];
|
|
236
|
-
}
|
|
237
|
-
markers.push({
|
|
238
|
-
index: match.index,
|
|
239
|
-
endIndex: match.index + match[0].length,
|
|
240
|
-
attrs,
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (markers.length === 0) {
|
|
245
|
-
return [{ attrs: null, body: body.trim() }];
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const segments = [];
|
|
249
|
-
|
|
250
|
-
// Root segment: everything before the first marker
|
|
251
|
-
segments.push({ attrs: null, body: body.slice(0, markers[0].index).trim() });
|
|
252
|
-
|
|
253
|
-
// Reply segments: between consecutive markers
|
|
254
|
-
for (let i = 0; i < markers.length; i++) {
|
|
255
|
-
const start = markers[i].endIndex;
|
|
256
|
-
const end = i + 1 < markers.length ? markers[i + 1].index : body.length;
|
|
257
|
-
segments.push({
|
|
258
|
-
attrs: markers[i].attrs,
|
|
259
|
-
body: body.slice(start, end).trim(),
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return segments;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
220
|
function normalizeImportPathKey(value) {
|
|
267
221
|
if (typeof value !== "string") {
|
|
268
222
|
return null;
|
|
@@ -284,30 +238,35 @@ function normalizeImportAliasPath(value) {
|
|
|
284
238
|
return pathKey ? `/${pathKey}` : null;
|
|
285
239
|
}
|
|
286
240
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
function getRootAliasPathsForImport(aliases, postSlug, replySlugPaths) {
|
|
241
|
+
/**
|
|
242
|
+
* Resolve the historical root slugs that should become custom-URL aliases
|
|
243
|
+
* pointing at the current root post. Hugo's `aliases:` on a root also
|
|
244
|
+
* contains every reply slug; we strip those (reply slugs are claimed by
|
|
245
|
+
* their own bundles) and keep only entries that aren't the root itself.
|
|
246
|
+
*
|
|
247
|
+
* `root_aliases:` is the authoritative record of the root's own historical
|
|
248
|
+
* slugs (the exporter writes it for round-trip), so when present we prefer
|
|
249
|
+
* it. Otherwise we fall back to `aliases:` minus reply slugs.
|
|
250
|
+
*/
|
|
251
|
+
function getRootAliasPathsForImport(
|
|
252
|
+
aliases,
|
|
253
|
+
rootAliases,
|
|
254
|
+
postSlug,
|
|
255
|
+
replySlugPaths,
|
|
256
|
+
) {
|
|
306
257
|
const rootSlugPath = normalizeImportAliasPath(postSlug);
|
|
307
258
|
const aliasPaths = [];
|
|
308
259
|
const seen = new Set();
|
|
309
260
|
|
|
310
|
-
|
|
261
|
+
// Prefer the explicit `root_aliases:` list when the exporter wrote it.
|
|
262
|
+
const source =
|
|
263
|
+
Array.isArray(rootAliases) && rootAliases.length > 0
|
|
264
|
+
? rootAliases
|
|
265
|
+
: Array.isArray(aliases)
|
|
266
|
+
? aliases
|
|
267
|
+
: [];
|
|
268
|
+
|
|
269
|
+
for (const alias of source) {
|
|
311
270
|
const aliasPath = normalizeImportAliasPath(alias);
|
|
312
271
|
if (!aliasPath) {
|
|
313
272
|
continue;
|
|
@@ -316,9 +275,9 @@ function getRootAliasPathsForImport(aliases, postSlug, replySlugPaths) {
|
|
|
316
275
|
continue;
|
|
317
276
|
}
|
|
318
277
|
if (replySlugPaths.has(aliasPath)) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
278
|
+
// Reply slugs live in their own bundles — never route their URL back
|
|
279
|
+
// to the root as a custom alias.
|
|
280
|
+
continue;
|
|
322
281
|
}
|
|
323
282
|
if (seen.has(aliasPath)) {
|
|
324
283
|
continue;
|
|
@@ -474,6 +433,85 @@ function normalizeImportedBodySegment(markdown) {
|
|
|
474
433
|
};
|
|
475
434
|
}
|
|
476
435
|
|
|
436
|
+
function isAbsoluteUrl(value) {
|
|
437
|
+
return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Resolve a `media:` entry's `src` or `poster` reference to a local disk
|
|
442
|
+
* path when the export bundled the bytes under `static/`. Absolute URLs
|
|
443
|
+
* (remote-linked media) skip the disk lookup — the uploader fetches them
|
|
444
|
+
* directly.
|
|
445
|
+
*/
|
|
446
|
+
async function resolveJantMediaDiskPath(ref, sourceRootDir) {
|
|
447
|
+
if (typeof ref !== "string" || !ref.trim()) return null;
|
|
448
|
+
if (isAbsoluteUrl(ref)) return null;
|
|
449
|
+
const normalized = ref.startsWith("/") ? ref.slice(1) : ref;
|
|
450
|
+
const fullPath = join(sourceRootDir, "static", normalized);
|
|
451
|
+
const fileStat = await stat(fullPath).catch(() => null);
|
|
452
|
+
return fileStat?.isFile() ? fullPath : null;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Build a media spec for upload from a flat `media:` front-matter entry.
|
|
457
|
+
*
|
|
458
|
+
* The entry's `src` is either a site-relative path
|
|
459
|
+
* (`/media/{id}.webp` — bytes live under `static/` in the exported site)
|
|
460
|
+
* or an absolute public URL (the exporter linked to an existing
|
|
461
|
+
* R2/S3/local-proxy host rather than re-bundling the bytes). Poster
|
|
462
|
+
* frames follow the same rule. The import uploader already knows how
|
|
463
|
+
* to handle both forms via `readImportAsset`.
|
|
464
|
+
*/
|
|
465
|
+
async function mediaSpecFromJantMedia(entry, sourceRootDir) {
|
|
466
|
+
if (!entry || typeof entry.src !== "string" || !entry.src.trim()) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
const srcFilePath = await resolveJantMediaDiskPath(entry.src, sourceRootDir);
|
|
471
|
+
if (!srcFilePath && !isAbsoluteUrl(entry.src)) {
|
|
472
|
+
// Relative src but file not on disk — can't upload.
|
|
473
|
+
return null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const poster =
|
|
477
|
+
typeof entry.poster === "string" && entry.poster.trim()
|
|
478
|
+
? entry.poster
|
|
479
|
+
: null;
|
|
480
|
+
const posterFilePath = poster
|
|
481
|
+
? await resolveJantMediaDiskPath(poster, sourceRootDir)
|
|
482
|
+
: null;
|
|
483
|
+
|
|
484
|
+
const originalName =
|
|
485
|
+
typeof entry.original_name === "string" && entry.original_name.trim()
|
|
486
|
+
? entry.original_name
|
|
487
|
+
: srcFilePath
|
|
488
|
+
? basename(srcFilePath)
|
|
489
|
+
: undefined;
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
kind: typeof entry.kind === "string" ? entry.kind : undefined,
|
|
493
|
+
src: entry.src,
|
|
494
|
+
srcFilePath,
|
|
495
|
+
poster,
|
|
496
|
+
posterFilePath,
|
|
497
|
+
mimeType:
|
|
498
|
+
typeof entry.mime_type === "string" ? entry.mime_type : undefined,
|
|
499
|
+
originalName,
|
|
500
|
+
size: typeof entry.size === "number" ? entry.size : undefined,
|
|
501
|
+
width: typeof entry.width === "number" ? entry.width : undefined,
|
|
502
|
+
height: typeof entry.height === "number" ? entry.height : undefined,
|
|
503
|
+
alt: typeof entry.alt === "string" ? entry.alt : undefined,
|
|
504
|
+
position:
|
|
505
|
+
typeof entry.position === "string" ? entry.position : undefined,
|
|
506
|
+
blurhash:
|
|
507
|
+
typeof entry.blurhash === "string" ? entry.blurhash : undefined,
|
|
508
|
+
waveform:
|
|
509
|
+
typeof entry.waveform === "string" ? entry.waveform : undefined,
|
|
510
|
+
summary: typeof entry.summary === "string" ? entry.summary : undefined,
|
|
511
|
+
chars: typeof entry.chars === "number" ? entry.chars : undefined,
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
|
|
477
515
|
async function normalizeMediaSpec(spec, siteConfig, sourceRootDir) {
|
|
478
516
|
if (!spec || typeof spec.src !== "string" || spec.src.trim() === "") {
|
|
479
517
|
return null;
|
|
@@ -488,20 +526,19 @@ async function normalizeMediaSpec(spec, siteConfig, sourceRootDir) {
|
|
|
488
526
|
return {
|
|
489
527
|
kind: spec.kind,
|
|
490
528
|
src,
|
|
491
|
-
srcFilePath:
|
|
492
|
-
spec.
|
|
493
|
-
siteConfig,
|
|
494
|
-
sourceRootDir,
|
|
495
|
-
),
|
|
529
|
+
srcFilePath:
|
|
530
|
+
spec.srcFilePath ??
|
|
531
|
+
(await resolveImportLocalAssetPath(spec.src, siteConfig, sourceRootDir)),
|
|
496
532
|
poster,
|
|
497
533
|
posterFilePath:
|
|
498
|
-
|
|
534
|
+
spec.posterFilePath ??
|
|
535
|
+
(typeof spec.poster === "string"
|
|
499
536
|
? await resolveImportLocalAssetPath(
|
|
500
537
|
spec.poster,
|
|
501
538
|
siteConfig,
|
|
502
539
|
sourceRootDir,
|
|
503
540
|
)
|
|
504
|
-
: null,
|
|
541
|
+
: null),
|
|
505
542
|
mimeType: spec.mimeType || undefined,
|
|
506
543
|
originalName: spec.originalName || undefined,
|
|
507
544
|
size: typeof spec.size === "number" ? spec.size : undefined,
|
|
@@ -516,22 +553,86 @@ async function normalizeMediaSpec(spec, siteConfig, sourceRootDir) {
|
|
|
516
553
|
};
|
|
517
554
|
}
|
|
518
555
|
|
|
519
|
-
|
|
556
|
+
/**
|
|
557
|
+
* Coerce a `<figure data-jant-node="attachment" data-jant-kind="text">` meta
|
|
558
|
+
* block into the shape `createTextAttachment` wants on import.
|
|
559
|
+
*
|
|
560
|
+
* Two source shapes are supported:
|
|
561
|
+
*
|
|
562
|
+
* 1. Inline (legacy exports): the meta JSON carries the markdown itself under
|
|
563
|
+
* `contentFormat: "markdown"` + `content: "..."`. Used before text
|
|
564
|
+
* attachments got their own public URL.
|
|
565
|
+
* 2. Reference (current exports): the meta JSON only carries `kind: "text"`
|
|
566
|
+
* + `src: <url>` pointing at the `.md` artifact. We fetch that URL
|
|
567
|
+
* (falling back to `--pull-media` local disk via
|
|
568
|
+
* `resolveImportLocalAssetPath`, same as images) and use the bytes as
|
|
569
|
+
* the markdown body.
|
|
570
|
+
*
|
|
571
|
+
* Returns `null` when the spec isn't a text attachment or we can't get
|
|
572
|
+
* usable content (unreachable URL, empty body, etc.) — caller drops the
|
|
573
|
+
* attachment rather than creating an empty one.
|
|
574
|
+
*/
|
|
575
|
+
async function normalizeTextAttachmentSpec(spec, siteConfig, sourceRootDir) {
|
|
576
|
+
if (!spec || spec.kind !== "text") {
|
|
577
|
+
return null;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const summary =
|
|
581
|
+
typeof spec.summary === "string" ? spec.summary : undefined;
|
|
582
|
+
|
|
583
|
+
// Legacy inline content path — no network fetch needed.
|
|
520
584
|
if (
|
|
521
|
-
|
|
522
|
-
spec.
|
|
523
|
-
spec.
|
|
524
|
-
typeof spec.content !== "string" ||
|
|
525
|
-
spec.content.trim() === ""
|
|
585
|
+
spec.contentFormat === "markdown" &&
|
|
586
|
+
typeof spec.content === "string" &&
|
|
587
|
+
spec.content.trim() !== ""
|
|
526
588
|
) {
|
|
589
|
+
return {
|
|
590
|
+
type: "text",
|
|
591
|
+
contentFormat: "markdown",
|
|
592
|
+
content: spec.content,
|
|
593
|
+
summary,
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Reference path — fetch the markdown from the stored `src` URL.
|
|
598
|
+
if (typeof spec.src !== "string" || spec.src.trim() === "") {
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
const sourceUrl = resolveImportUrl(spec.src, siteConfig);
|
|
603
|
+
if (typeof sourceUrl !== "string" || sourceUrl.trim() === "") {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
const asset = await readImportAsset({
|
|
608
|
+
sourceUrl,
|
|
609
|
+
sourceFilePath: await resolveImportLocalAssetPath(
|
|
610
|
+
spec.src,
|
|
611
|
+
siteConfig,
|
|
612
|
+
sourceRootDir,
|
|
613
|
+
),
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
if (!asset) {
|
|
617
|
+
return null;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
let markdown;
|
|
621
|
+
try {
|
|
622
|
+
markdown = new TextDecoder("utf-8", { fatal: false }).decode(asset.bytes);
|
|
623
|
+
} catch {
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (markdown.trim() === "") {
|
|
527
628
|
return null;
|
|
528
629
|
}
|
|
529
630
|
|
|
530
631
|
return {
|
|
531
632
|
type: "text",
|
|
532
633
|
contentFormat: "markdown",
|
|
533
|
-
content:
|
|
534
|
-
summary
|
|
634
|
+
content: markdown,
|
|
635
|
+
summary,
|
|
535
636
|
};
|
|
536
637
|
}
|
|
537
638
|
|
|
@@ -557,7 +658,11 @@ async function buildImportedAttachments(
|
|
|
557
658
|
let uploaded = 0;
|
|
558
659
|
|
|
559
660
|
for (const spec of attachmentSpecs) {
|
|
560
|
-
const textAttachment = normalizeTextAttachmentSpec(
|
|
661
|
+
const textAttachment = await normalizeTextAttachmentSpec(
|
|
662
|
+
spec,
|
|
663
|
+
siteConfig,
|
|
664
|
+
sourceRootDir,
|
|
665
|
+
);
|
|
561
666
|
if (textAttachment) {
|
|
562
667
|
attachments.push(textAttachment);
|
|
563
668
|
continue;
|
|
@@ -600,7 +705,16 @@ async function uploadMediaList(mediaSpecs, target, siteConfig, sourceRootDir) {
|
|
|
600
705
|
if (!normalized || normalized.src.startsWith("data:")) continue;
|
|
601
706
|
const result = await target.uploadMedia(normalized);
|
|
602
707
|
if (!result) continue;
|
|
603
|
-
|
|
708
|
+
// Key the rewrite map by the *original* URL as it appears in the body
|
|
709
|
+
// (e.g. `/media/...`). `normalized.src` has been resolved against
|
|
710
|
+
// `siteConfig.base_url` and becomes absolute, which would never match
|
|
711
|
+
// `node.url` from the markdown AST during `rewriteMediaReferences`.
|
|
712
|
+
if (typeof spec.src === "string" && spec.src.trim() !== "") {
|
|
713
|
+
urlMap.set(spec.src, result.url);
|
|
714
|
+
}
|
|
715
|
+
if (normalized.src !== spec.src) {
|
|
716
|
+
urlMap.set(normalized.src, result.url);
|
|
717
|
+
}
|
|
604
718
|
mediaIds.push(result.id);
|
|
605
719
|
uploaded += 1;
|
|
606
720
|
}
|
|
@@ -608,14 +722,190 @@ async function uploadMediaList(mediaSpecs, target, siteConfig, sourceRootDir) {
|
|
|
608
722
|
return { urlMap, mediaIds, uploaded };
|
|
609
723
|
}
|
|
610
724
|
|
|
725
|
+
/**
|
|
726
|
+
* Upload each media spec referenced by a bundle's front matter. Accepts
|
|
727
|
+
* both site-relative entries (bytes on disk under `static/`, via
|
|
728
|
+
* `srcFilePath`) and absolute-URL entries (remote-linked media — the
|
|
729
|
+
* uploader fetches the URL). Returns a `urlMap` (for rewriting in-body
|
|
730
|
+
* references) and an ordered `mediaIds` list for post attachment.
|
|
731
|
+
*/
|
|
732
|
+
async function uploadBundleResources(resourceSpecs, target) {
|
|
733
|
+
const urlMap = new Map();
|
|
734
|
+
const mediaIds = [];
|
|
735
|
+
let uploaded = 0;
|
|
736
|
+
|
|
737
|
+
for (const spec of resourceSpecs) {
|
|
738
|
+
if (!spec) continue;
|
|
739
|
+
if (!spec.srcFilePath && !isAbsoluteUrl(spec.src)) continue;
|
|
740
|
+
const result = await target.uploadMedia(spec);
|
|
741
|
+
if (!result) continue;
|
|
742
|
+
urlMap.set(spec.src, result.url);
|
|
743
|
+
mediaIds.push(result.id);
|
|
744
|
+
uploaded += 1;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
return { urlMap, mediaIds, uploaded };
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
function coerceBoolean(value) {
|
|
751
|
+
if (typeof value === "boolean") return value;
|
|
752
|
+
if (typeof value === "string") {
|
|
753
|
+
const normalized = value.trim().toLowerCase();
|
|
754
|
+
return normalized === "true" || normalized === "1" || normalized === "yes";
|
|
755
|
+
}
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/**
|
|
760
|
+
* Build a unified "site config" object from Hugo's split config files.
|
|
761
|
+
*
|
|
762
|
+
* Hugo writes two sources of truth:
|
|
763
|
+
* - `hugo.toml`: baseURL, title, languageCode, theme params
|
|
764
|
+
* - `data/jant.toml`: everything Jant owns — nav items, branding modes,
|
|
765
|
+
* home_default_view, site_footer, avatar urls, display preferences,
|
|
766
|
+
* and the ordered collections directory under `[[directory]]`.
|
|
767
|
+
*
|
|
768
|
+
* This merger normalizes them into a single shape that downstream helpers
|
|
769
|
+
* (`buildSettingsUpdatesFromConfig`, `normalizeImportedNavItems`,
|
|
770
|
+
* `normalizeImportedCollectionDirectory`, `buildSiteAvatarImport`) already
|
|
771
|
+
* know how to read. The shape is intentionally a superset — nothing
|
|
772
|
+
* depends on `hugo.toml`-only vs `data/jant.toml`-only fields, so extra
|
|
773
|
+
* keys are harmless if they leak through.
|
|
774
|
+
*/
|
|
775
|
+
async function loadSiteConfig(rootDir) {
|
|
776
|
+
const hugoTomlText = await readFile(
|
|
777
|
+
join(rootDir, "hugo.toml"),
|
|
778
|
+
"utf-8",
|
|
779
|
+
).catch(() => null);
|
|
780
|
+
const jantDataText = await readFile(
|
|
781
|
+
join(rootDir, "data", "jant.toml"),
|
|
782
|
+
"utf-8",
|
|
783
|
+
).catch(() => null);
|
|
784
|
+
|
|
785
|
+
if (!hugoTomlText && !jantDataText) {
|
|
786
|
+
return null;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
const hugoToml = hugoTomlText ? await parseToml(hugoTomlText) : {};
|
|
790
|
+
const jantData = jantDataText ? await parseToml(jantDataText) : {};
|
|
791
|
+
|
|
792
|
+
const params = hugoToml.params ?? {};
|
|
793
|
+
|
|
794
|
+
const title =
|
|
795
|
+
(typeof hugoToml.title === "string" && hugoToml.title) ||
|
|
796
|
+
(typeof jantData.site_name === "string" ? jantData.site_name : "");
|
|
797
|
+
const description =
|
|
798
|
+
(typeof params.description === "string" && params.description) ||
|
|
799
|
+
(typeof jantData.site_description === "string"
|
|
800
|
+
? jantData.site_description
|
|
801
|
+
: "");
|
|
802
|
+
const baseUrl =
|
|
803
|
+
typeof hugoToml.baseURL === "string"
|
|
804
|
+
? hugoToml.baseURL
|
|
805
|
+
: typeof hugoToml.baseurl === "string"
|
|
806
|
+
? hugoToml.baseurl
|
|
807
|
+
: "";
|
|
808
|
+
const language =
|
|
809
|
+
(typeof hugoToml.languageCode === "string" && hugoToml.languageCode) ||
|
|
810
|
+
(typeof hugoToml.defaultContentLanguage === "string" &&
|
|
811
|
+
hugoToml.defaultContentLanguage) ||
|
|
812
|
+
(typeof jantData.site_language === "string"
|
|
813
|
+
? jantData.site_language
|
|
814
|
+
: "en");
|
|
815
|
+
|
|
816
|
+
const directoryItems = Array.isArray(jantData.directory)
|
|
817
|
+
? jantData.directory
|
|
818
|
+
: [];
|
|
819
|
+
const directoryExported = Array.isArray(jantData.directory);
|
|
820
|
+
|
|
821
|
+
return {
|
|
822
|
+
// Public base URL (used for resolving relative media URLs).
|
|
823
|
+
base_url: baseUrl,
|
|
824
|
+
title,
|
|
825
|
+
description,
|
|
826
|
+
default_language: language,
|
|
827
|
+
extra: {
|
|
828
|
+
jant: {
|
|
829
|
+
theme_id:
|
|
830
|
+
(typeof params.theme_id === "string" && params.theme_id) ||
|
|
831
|
+
(typeof jantData.theme_id === "string" ? jantData.theme_id : ""),
|
|
832
|
+
default_theme_id:
|
|
833
|
+
(typeof params.default_theme_id === "string" &&
|
|
834
|
+
params.default_theme_id) ||
|
|
835
|
+
(typeof jantData.default_theme_id === "string"
|
|
836
|
+
? jantData.default_theme_id
|
|
837
|
+
: ""),
|
|
838
|
+
font_theme_id:
|
|
839
|
+
(typeof params.font_theme_id === "string" && params.font_theme_id) ||
|
|
840
|
+
(typeof jantData.font_theme_id === "string"
|
|
841
|
+
? jantData.font_theme_id
|
|
842
|
+
: ""),
|
|
843
|
+
theme_mode:
|
|
844
|
+
(typeof params.theme_mode === "string" && params.theme_mode) ||
|
|
845
|
+
(typeof jantData.theme_mode === "string" ? jantData.theme_mode : ""),
|
|
846
|
+
home_default_view:
|
|
847
|
+
(typeof params.home_default_view === "string" &&
|
|
848
|
+
params.home_default_view) ||
|
|
849
|
+
(typeof jantData.home_default_view === "string"
|
|
850
|
+
? jantData.home_default_view
|
|
851
|
+
: ""),
|
|
852
|
+
show_jant_branding_on_home: coerceBoolean(
|
|
853
|
+
params.show_jant_branding_on_home ??
|
|
854
|
+
jantData.show_jant_branding_on_home,
|
|
855
|
+
),
|
|
856
|
+
show_header_avatar: coerceBoolean(
|
|
857
|
+
params.show_header_avatar ?? jantData.show_header_avatar,
|
|
858
|
+
),
|
|
859
|
+
noindex: coerceBoolean(params.noindex ?? jantData.noindex),
|
|
860
|
+
site_footer_markdown:
|
|
861
|
+
typeof jantData.site_footer_markdown === "string"
|
|
862
|
+
? jantData.site_footer_markdown
|
|
863
|
+
: "",
|
|
864
|
+
site_avatar_mode:
|
|
865
|
+
typeof jantData.site_avatar_mode === "string"
|
|
866
|
+
? jantData.site_avatar_mode
|
|
867
|
+
: "none",
|
|
868
|
+
site_avatar_url:
|
|
869
|
+
typeof jantData.site_avatar_url === "string"
|
|
870
|
+
? jantData.site_avatar_url
|
|
871
|
+
: typeof params.site_avatar_url === "string"
|
|
872
|
+
? params.site_avatar_url
|
|
873
|
+
: "",
|
|
874
|
+
favicon_mode:
|
|
875
|
+
typeof jantData.favicon_mode === "string"
|
|
876
|
+
? jantData.favicon_mode
|
|
877
|
+
: "default",
|
|
878
|
+
favicon_url:
|
|
879
|
+
typeof jantData.favicon_path === "string"
|
|
880
|
+
? jantData.favicon_path
|
|
881
|
+
: "/favicon.ico",
|
|
882
|
+
apple_touch_mode:
|
|
883
|
+
typeof jantData.apple_touch_mode === "string"
|
|
884
|
+
? jantData.apple_touch_mode
|
|
885
|
+
: "default",
|
|
886
|
+
apple_touch_icon_url:
|
|
887
|
+
typeof jantData.apple_touch_icon_path === "string"
|
|
888
|
+
? jantData.apple_touch_icon_path
|
|
889
|
+
: "/apple-touch-icon.png",
|
|
890
|
+
nav: Array.isArray(jantData.nav) ? jantData.nav : [],
|
|
891
|
+
nav_exported: Array.isArray(jantData.nav),
|
|
892
|
+
collections_directory: directoryItems,
|
|
893
|
+
collections_directory_exported: directoryExported,
|
|
894
|
+
},
|
|
895
|
+
jant_export: {
|
|
896
|
+
format:
|
|
897
|
+
typeof jantData.format === "string" ? jantData.format : "jant-site",
|
|
898
|
+
},
|
|
899
|
+
},
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
|
|
611
903
|
function buildSettingsUpdatesFromConfig(siteConfig, customCss = "") {
|
|
612
904
|
const jant = siteConfig?.extra?.jant || {};
|
|
613
905
|
const themeId = String(jant.theme_id || "");
|
|
614
906
|
const defaultThemeId = String(jant.default_theme_id || "");
|
|
615
907
|
const fontThemeId = String(jant.font_theme_id || "");
|
|
616
908
|
const themeMode = String(jant.theme_mode || "");
|
|
617
|
-
const headerNavMaxVisible = Number(jant.header_nav_max_visible);
|
|
618
|
-
|
|
619
909
|
return {
|
|
620
910
|
SITE_NAME: String(siteConfig?.title || ""),
|
|
621
911
|
SITE_DESCRIPTION: String(siteConfig?.description || ""),
|
|
@@ -623,10 +913,6 @@ function buildSettingsUpdatesFromConfig(siteConfig, customCss = "") {
|
|
|
623
913
|
SITE_FOOTER: String(jant.site_footer_markdown || ""),
|
|
624
914
|
HOME_DEFAULT_VIEW:
|
|
625
915
|
String(jant.home_default_view || "") === "featured" ? "featured" : "",
|
|
626
|
-
HEADER_NAV_MAX_VISIBLE:
|
|
627
|
-
Number.isFinite(headerNavMaxVisible) && headerNavMaxVisible !== 2
|
|
628
|
-
? String(headerNavMaxVisible)
|
|
629
|
-
: "",
|
|
630
916
|
SHOW_JANT_BRANDING_ON_HOME: jant.show_jant_branding_on_home ? "true" : "",
|
|
631
917
|
NOINDEX: jant.noindex ? "true" : "",
|
|
632
918
|
SHOW_HEADER_AVATAR: jant.show_header_avatar ? "true" : "",
|
|
@@ -637,6 +923,32 @@ function buildSettingsUpdatesFromConfig(siteConfig, customCss = "") {
|
|
|
637
923
|
};
|
|
638
924
|
}
|
|
639
925
|
|
|
926
|
+
/**
|
|
927
|
+
* Internal config keys that the site importer restores via the dedicated
|
|
928
|
+
* `/api/settings/import` route. Must stay in sync with
|
|
929
|
+
* `importableInternalSettingKeys` in `src/lib/api-settings.ts`.
|
|
930
|
+
*/
|
|
931
|
+
const IMPORTABLE_INTERNAL_SETTING_KEYS = new Set([
|
|
932
|
+
"THEME",
|
|
933
|
+
"FONT_THEME",
|
|
934
|
+
"THEME_MODE",
|
|
935
|
+
"CUSTOM_CSS",
|
|
936
|
+
"SHOW_HEADER_AVATAR",
|
|
937
|
+
]);
|
|
938
|
+
|
|
939
|
+
function splitSettingsUpdatesForImport(updates) {
|
|
940
|
+
const editable = {};
|
|
941
|
+
const internal = {};
|
|
942
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
943
|
+
if (IMPORTABLE_INTERNAL_SETTING_KEYS.has(key)) {
|
|
944
|
+
internal[key] = value;
|
|
945
|
+
} else {
|
|
946
|
+
editable[key] = value;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
return { editable, internal };
|
|
950
|
+
}
|
|
951
|
+
|
|
640
952
|
function normalizeImportedNavItems(siteConfig) {
|
|
641
953
|
const jant = siteConfig?.extra?.jant || {};
|
|
642
954
|
const navItems = jant.nav;
|
|
@@ -669,6 +981,58 @@ function normalizeImportedNavItems(siteConfig) {
|
|
|
669
981
|
};
|
|
670
982
|
}
|
|
671
983
|
|
|
984
|
+
function normalizeImportedCollectionDirectory(siteConfig) {
|
|
985
|
+
const jant = siteConfig?.extra?.jant || {};
|
|
986
|
+
const directoryItems = jant.collections_directory;
|
|
987
|
+
if (!Array.isArray(directoryItems)) {
|
|
988
|
+
return {
|
|
989
|
+
exported: Boolean(jant.collections_directory_exported),
|
|
990
|
+
items: [],
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
return {
|
|
995
|
+
exported: true,
|
|
996
|
+
items: directoryItems
|
|
997
|
+
.map((item) => {
|
|
998
|
+
if (!item || typeof item !== "object") return null;
|
|
999
|
+
|
|
1000
|
+
if (
|
|
1001
|
+
item.type === "collection" &&
|
|
1002
|
+
typeof item.slug === "string" &&
|
|
1003
|
+
item.slug.trim()
|
|
1004
|
+
) {
|
|
1005
|
+
return {
|
|
1006
|
+
type: "collection",
|
|
1007
|
+
slug: item.slug.trim(),
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
if (item.type === "divider") {
|
|
1012
|
+
return {
|
|
1013
|
+
type: "divider",
|
|
1014
|
+
label: typeof item.label === "string" ? item.label : null,
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
if (
|
|
1019
|
+
item.type === "link" &&
|
|
1020
|
+
typeof item.label === "string" &&
|
|
1021
|
+
typeof item.url === "string"
|
|
1022
|
+
) {
|
|
1023
|
+
return {
|
|
1024
|
+
type: "link",
|
|
1025
|
+
label: item.label,
|
|
1026
|
+
url: item.url,
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
return null;
|
|
1031
|
+
})
|
|
1032
|
+
.filter(Boolean),
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
|
|
672
1036
|
async function buildSiteAvatarImport(siteConfig, sourceRootDir) {
|
|
673
1037
|
const exportInfo = siteConfig?.extra?.jant_export || {};
|
|
674
1038
|
if (exportInfo.format !== "jant-site") {
|
|
@@ -744,6 +1108,117 @@ async function buildSiteAvatarImport(siteConfig, sourceRootDir) {
|
|
|
744
1108
|
};
|
|
745
1109
|
}
|
|
746
1110
|
|
|
1111
|
+
async function reorderCollectionDirectoryItems(target, orderedIds) {
|
|
1112
|
+
const dedupedIds = [];
|
|
1113
|
+
const seenIds = new Set();
|
|
1114
|
+
for (const id of orderedIds) {
|
|
1115
|
+
if (typeof id !== "string" || !id || seenIds.has(id)) continue;
|
|
1116
|
+
seenIds.add(id);
|
|
1117
|
+
dedupedIds.push(id);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
let moves = 0;
|
|
1121
|
+
|
|
1122
|
+
for (let index = 0; index < dedupedIds.length; index += 1) {
|
|
1123
|
+
const itemId = dedupedIds[index];
|
|
1124
|
+
const currentItems = await target.listCollectionDirectoryItems();
|
|
1125
|
+
const currentIds = currentItems.map((item) => item.id);
|
|
1126
|
+
const currentIndex = currentIds.indexOf(itemId);
|
|
1127
|
+
if (currentIndex === -1) continue;
|
|
1128
|
+
|
|
1129
|
+
if (index === 0) {
|
|
1130
|
+
if (currentIndex === 0) continue;
|
|
1131
|
+
const beforeId = currentIds.find((id) => id !== itemId) ?? null;
|
|
1132
|
+
await target.moveCollectionDirectoryItem(itemId, null, beforeId);
|
|
1133
|
+
moves += 1;
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
const afterId = dedupedIds[index - 1];
|
|
1138
|
+
const afterIndex = currentIds.indexOf(afterId);
|
|
1139
|
+
if (afterIndex === -1) continue;
|
|
1140
|
+
if (currentIds[afterIndex + 1] === itemId) continue;
|
|
1141
|
+
|
|
1142
|
+
const beforeId =
|
|
1143
|
+
currentIds.slice(afterIndex + 1).find((id) => id !== itemId) ?? null;
|
|
1144
|
+
await target.moveCollectionDirectoryItem(itemId, afterId, beforeId);
|
|
1145
|
+
moves += 1;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
return moves;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
async function syncImportedCollectionDirectory(
|
|
1152
|
+
target,
|
|
1153
|
+
importedDirectory,
|
|
1154
|
+
collectionSlugToId,
|
|
1155
|
+
) {
|
|
1156
|
+
if (!importedDirectory.exported) {
|
|
1157
|
+
return { created: 0, deleted: 0, moved: 0 };
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
let deleted = 0;
|
|
1161
|
+
const existingItems = await target.listCollectionDirectoryItems();
|
|
1162
|
+
for (const item of existingItems) {
|
|
1163
|
+
if (item.type === "collection") continue;
|
|
1164
|
+
const removed = await target.deleteCollectionDirectoryItem(item.id);
|
|
1165
|
+
if (removed !== false) {
|
|
1166
|
+
deleted += 1;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
let currentItems = await target.listCollectionDirectoryItems();
|
|
1171
|
+
const collectionItemIds = new Map(
|
|
1172
|
+
currentItems
|
|
1173
|
+
.filter((item) => item.type === "collection" && item.collectionId)
|
|
1174
|
+
.map((item) => [item.collectionId, item.id]),
|
|
1175
|
+
);
|
|
1176
|
+
|
|
1177
|
+
const desiredIds = [];
|
|
1178
|
+
const seenCollectionIds = new Set();
|
|
1179
|
+
let created = 0;
|
|
1180
|
+
|
|
1181
|
+
for (const item of importedDirectory.items) {
|
|
1182
|
+
if (item.type === "collection") {
|
|
1183
|
+
const collectionId = collectionSlugToId.get(item.slug);
|
|
1184
|
+
if (!collectionId || seenCollectionIds.has(collectionId)) {
|
|
1185
|
+
continue;
|
|
1186
|
+
}
|
|
1187
|
+
seenCollectionIds.add(collectionId);
|
|
1188
|
+
const directoryItemId = collectionItemIds.get(collectionId);
|
|
1189
|
+
if (directoryItemId) {
|
|
1190
|
+
desiredIds.push(directoryItemId);
|
|
1191
|
+
}
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
const createdItem = await target.createCollectionDirectoryItem(
|
|
1196
|
+
item.type === "divider"
|
|
1197
|
+
? {
|
|
1198
|
+
type: "divider",
|
|
1199
|
+
...(item.label !== null ? { label: item.label } : {}),
|
|
1200
|
+
}
|
|
1201
|
+
: {
|
|
1202
|
+
type: "link",
|
|
1203
|
+
label: item.label,
|
|
1204
|
+
url: item.url,
|
|
1205
|
+
},
|
|
1206
|
+
);
|
|
1207
|
+
desiredIds.push(createdItem.id);
|
|
1208
|
+
created += 1;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
currentItems = await target.listCollectionDirectoryItems();
|
|
1212
|
+
const currentIds = currentItems.map((item) => item.id);
|
|
1213
|
+
const desiredIdSet = new Set(desiredIds);
|
|
1214
|
+
const moved = await reorderCollectionDirectoryItems(target, [
|
|
1215
|
+
...desiredIds,
|
|
1216
|
+
...currentIds.filter((id) => !desiredIdSet.has(id)),
|
|
1217
|
+
]);
|
|
1218
|
+
|
|
1219
|
+
return { created, deleted, moved };
|
|
1220
|
+
}
|
|
1221
|
+
|
|
747
1222
|
function buildIncompleteSetupError(targetLabel) {
|
|
748
1223
|
return [
|
|
749
1224
|
`${targetLabel} has not completed setup.`,
|
|
@@ -859,6 +1334,9 @@ function createRemoteTarget(apiUrl, token) {
|
|
|
859
1334
|
async updateSettings(updates) {
|
|
860
1335
|
return apiCall("PUT", "/api/settings", apiUrl, token, updates);
|
|
861
1336
|
},
|
|
1337
|
+
async updateImportSettings(updates) {
|
|
1338
|
+
return apiCall("PUT", "/api/settings/import", apiUrl, token, updates);
|
|
1339
|
+
},
|
|
862
1340
|
async listNavItems() {
|
|
863
1341
|
const result = await apiCall("GET", "/api/nav-items", apiUrl, token);
|
|
864
1342
|
return result.navItems || [];
|
|
@@ -945,9 +1423,39 @@ function createRemoteTarget(apiUrl, token) {
|
|
|
945
1423
|
const existing = await apiCall("GET", "/api/collections", apiUrl, token);
|
|
946
1424
|
return existing.collections || [];
|
|
947
1425
|
},
|
|
1426
|
+
async listCollectionDirectoryItems() {
|
|
1427
|
+
const existing = await apiCall("GET", "/api/collections", apiUrl, token);
|
|
1428
|
+
return existing.directoryItems || [];
|
|
1429
|
+
},
|
|
948
1430
|
async createCollection(data) {
|
|
949
1431
|
return apiCall("POST", "/api/collections", apiUrl, token, data);
|
|
950
1432
|
},
|
|
1433
|
+
async createCollectionDirectoryItem(data) {
|
|
1434
|
+
return apiCall(
|
|
1435
|
+
"POST",
|
|
1436
|
+
"/api/collections/directory-items",
|
|
1437
|
+
apiUrl,
|
|
1438
|
+
token,
|
|
1439
|
+
data,
|
|
1440
|
+
);
|
|
1441
|
+
},
|
|
1442
|
+
async moveCollectionDirectoryItem(id, after, before) {
|
|
1443
|
+
return apiCall(
|
|
1444
|
+
"PUT",
|
|
1445
|
+
`/api/collections/directory-items/${id}/move`,
|
|
1446
|
+
apiUrl,
|
|
1447
|
+
token,
|
|
1448
|
+
{ after, before },
|
|
1449
|
+
);
|
|
1450
|
+
},
|
|
1451
|
+
async deleteCollectionDirectoryItem(id) {
|
|
1452
|
+
return apiCall(
|
|
1453
|
+
"DELETE",
|
|
1454
|
+
`/api/collections/directory-items/${id}`,
|
|
1455
|
+
apiUrl,
|
|
1456
|
+
token,
|
|
1457
|
+
);
|
|
1458
|
+
},
|
|
951
1459
|
async createPost(data) {
|
|
952
1460
|
return apiCall(
|
|
953
1461
|
"POST",
|
|
@@ -1002,6 +1510,10 @@ async function createLocalTarget(env = process.env) {
|
|
|
1002
1510
|
await runtime.services.settings.setMany(updates);
|
|
1003
1511
|
return { settings: updates };
|
|
1004
1512
|
},
|
|
1513
|
+
async updateImportSettings(updates) {
|
|
1514
|
+
await runtime.services.settings.setMany(updates);
|
|
1515
|
+
return { success: true };
|
|
1516
|
+
},
|
|
1005
1517
|
async listNavItems() {
|
|
1006
1518
|
return runtime.services.navItems.list();
|
|
1007
1519
|
},
|
|
@@ -1081,9 +1593,21 @@ async function createLocalTarget(env = process.env) {
|
|
|
1081
1593
|
async listCollections() {
|
|
1082
1594
|
return runtime.services.collections.list();
|
|
1083
1595
|
},
|
|
1596
|
+
async listCollectionDirectoryItems() {
|
|
1597
|
+
return runtime.services.collections.listDirectoryItems();
|
|
1598
|
+
},
|
|
1084
1599
|
async createCollection(data) {
|
|
1085
1600
|
return runtime.services.collections.create(data);
|
|
1086
1601
|
},
|
|
1602
|
+
async createCollectionDirectoryItem(data) {
|
|
1603
|
+
return runtime.services.collections.createDirectoryItem(data);
|
|
1604
|
+
},
|
|
1605
|
+
async moveCollectionDirectoryItem(id, after, before) {
|
|
1606
|
+
return runtime.services.collections.moveDirectoryItem(id, after, before);
|
|
1607
|
+
},
|
|
1608
|
+
async deleteCollectionDirectoryItem(id) {
|
|
1609
|
+
return runtime.services.collections.deleteDirectoryItem(id);
|
|
1610
|
+
},
|
|
1087
1611
|
async createPost(data) {
|
|
1088
1612
|
const { attachments, ...postData } = data;
|
|
1089
1613
|
return runtime.services.posts.createWithAttachments(
|
|
@@ -1181,9 +1705,24 @@ async function createLocalTarget(env = process.env) {
|
|
|
1181
1705
|
}
|
|
1182
1706
|
|
|
1183
1707
|
/**
|
|
1184
|
-
*
|
|
1708
|
+
* Walk `content/` and classify each `_index.md` / `index.md` bundle by its
|
|
1709
|
+
* front-matter `type`. Returns ordered root-post bundles (with child reply
|
|
1710
|
+
* bundles attached) and stand-alone collection landing pages.
|
|
1711
|
+
*
|
|
1712
|
+
* Algorithm:
|
|
1713
|
+
* 1. Recurse into `content/` collecting every directory that has either
|
|
1714
|
+
* `_index.md` (branch bundle / section) or `index.md` (leaf bundle).
|
|
1715
|
+
* 2. For each `_index.md`, read front matter. `type: "post"` (or a
|
|
1716
|
+
* missing `type` with post-shaped keys) → root bundle. `type:
|
|
1717
|
+
* "collection"` → collection landing page. Other known section types
|
|
1718
|
+
* (`home`, `featured`, `archive`, `collections`) are recorded and
|
|
1719
|
+
* skipped for post import.
|
|
1720
|
+
* 3. For each root bundle, enumerate immediate child directories; any
|
|
1721
|
+
* child dir containing `index.md` becomes a reply leaf bundle.
|
|
1722
|
+
* 4. Reply bundles are sorted by `frontMatter.date` ascending (fallback:
|
|
1723
|
+
* directory name) so thread order is deterministic.
|
|
1185
1724
|
*/
|
|
1186
|
-
async function
|
|
1725
|
+
async function walkHugoContent(rootDir) {
|
|
1187
1726
|
const contentDir = join(rootDir, "content");
|
|
1188
1727
|
const contentStat = await stat(contentDir).catch(() => null);
|
|
1189
1728
|
if (!contentStat?.isDirectory()) {
|
|
@@ -1191,33 +1730,249 @@ async function walkContent(rootDir, postFiles, collectionFiles) {
|
|
|
1191
1730
|
process.exit(1);
|
|
1192
1731
|
}
|
|
1193
1732
|
|
|
1733
|
+
// Map of absolute dir → { frontMatter, body, kind, slug, dir, children[] }
|
|
1734
|
+
const dirs = new Map();
|
|
1735
|
+
|
|
1736
|
+
async function readBundle(dir, fileName) {
|
|
1737
|
+
const filePath = join(dir, fileName);
|
|
1738
|
+
const content = await readFile(filePath, "utf-8").catch(() => null);
|
|
1739
|
+
if (content === null) return null;
|
|
1740
|
+
const { frontMatter, body } = await parseFrontMatter(content);
|
|
1741
|
+
return { frontMatter, body };
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1194
1744
|
async function walk(dir) {
|
|
1195
|
-
const entries = await readdir(dir, { withFileTypes: true })
|
|
1745
|
+
const entries = await readdir(dir, { withFileTypes: true }).catch(
|
|
1746
|
+
() => null,
|
|
1747
|
+
);
|
|
1748
|
+
if (!entries) return;
|
|
1749
|
+
|
|
1750
|
+
const hasIndex = entries.some(
|
|
1751
|
+
(entry) => entry.isFile() && entry.name === "_index.md",
|
|
1752
|
+
);
|
|
1753
|
+
const hasLeaf = entries.some(
|
|
1754
|
+
(entry) => entry.isFile() && entry.name === "index.md",
|
|
1755
|
+
);
|
|
1756
|
+
|
|
1757
|
+
if (hasIndex) {
|
|
1758
|
+
const parsed = await readBundle(dir, "_index.md");
|
|
1759
|
+
if (parsed) {
|
|
1760
|
+
const type =
|
|
1761
|
+
typeof parsed.frontMatter.type === "string"
|
|
1762
|
+
? parsed.frontMatter.type
|
|
1763
|
+
: null;
|
|
1764
|
+
const slug =
|
|
1765
|
+
typeof parsed.frontMatter.slug === "string"
|
|
1766
|
+
? parsed.frontMatter.slug
|
|
1767
|
+
: basename(dir);
|
|
1768
|
+
dirs.set(dir, {
|
|
1769
|
+
kind: type || "post",
|
|
1770
|
+
slug,
|
|
1771
|
+
dir,
|
|
1772
|
+
frontMatter: parsed.frontMatter,
|
|
1773
|
+
body: parsed.body,
|
|
1774
|
+
file: "_index.md",
|
|
1775
|
+
children: [],
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
} else if (hasLeaf) {
|
|
1779
|
+
const parsed = await readBundle(dir, "index.md");
|
|
1780
|
+
if (parsed) {
|
|
1781
|
+
const slug =
|
|
1782
|
+
typeof parsed.frontMatter.slug === "string"
|
|
1783
|
+
? parsed.frontMatter.slug
|
|
1784
|
+
: basename(dir);
|
|
1785
|
+
dirs.set(dir, {
|
|
1786
|
+
kind: "leaf",
|
|
1787
|
+
slug,
|
|
1788
|
+
dir,
|
|
1789
|
+
frontMatter: parsed.frontMatter,
|
|
1790
|
+
body: parsed.body,
|
|
1791
|
+
file: "index.md",
|
|
1792
|
+
children: [],
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1196
1797
|
for (const entry of entries) {
|
|
1197
|
-
const fullPath = join(dir, entry.name);
|
|
1198
1798
|
if (entry.isDirectory()) {
|
|
1199
|
-
await walk(
|
|
1200
|
-
} else if (entry.name === "index.md" || entry.name === "_index.md") {
|
|
1201
|
-
const relPath = relative(rootDir, fullPath).replace(/\\/g, "/");
|
|
1202
|
-
const content = await readFile(fullPath, "utf-8");
|
|
1203
|
-
if (
|
|
1204
|
-
(relPath.startsWith("content/jant-collections/") ||
|
|
1205
|
-
relPath.startsWith("content/c/")) &&
|
|
1206
|
-
relPath.endsWith("/_index.md")
|
|
1207
|
-
) {
|
|
1208
|
-
collectionFiles.push({ path: relPath, content });
|
|
1209
|
-
} else if (
|
|
1210
|
-
relPath.startsWith("content/") &&
|
|
1211
|
-
relPath.endsWith("/index.md") &&
|
|
1212
|
-
relPath !== "content/_index.md"
|
|
1213
|
-
) {
|
|
1214
|
-
postFiles.push({ path: relPath, content });
|
|
1215
|
-
}
|
|
1799
|
+
await walk(join(dir, entry.name));
|
|
1216
1800
|
}
|
|
1217
1801
|
}
|
|
1218
1802
|
}
|
|
1219
1803
|
|
|
1220
1804
|
await walk(contentDir);
|
|
1805
|
+
|
|
1806
|
+
// Attach leaf children to their parent root bundles.
|
|
1807
|
+
const rootBundles = [];
|
|
1808
|
+
const collectionBundles = [];
|
|
1809
|
+
|
|
1810
|
+
for (const record of dirs.values()) {
|
|
1811
|
+
if (record.kind === "leaf") {
|
|
1812
|
+
const parentDir = dirname(record.dir);
|
|
1813
|
+
const parent = dirs.get(parentDir);
|
|
1814
|
+
if (parent && (parent.kind === "post" || parent.kind === null)) {
|
|
1815
|
+
parent.children.push(record);
|
|
1816
|
+
}
|
|
1817
|
+
continue;
|
|
1818
|
+
}
|
|
1819
|
+
if (record.kind === "collection") {
|
|
1820
|
+
collectionBundles.push(record);
|
|
1821
|
+
continue;
|
|
1822
|
+
}
|
|
1823
|
+
if (record.kind === "post") {
|
|
1824
|
+
rootBundles.push(record);
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
// home / featured / archive / collections / anything else — skip.
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
// Sort replies within each root by `date` asc (fallback: directory name).
|
|
1831
|
+
for (const root of rootBundles) {
|
|
1832
|
+
root.children.sort((a, b) => {
|
|
1833
|
+
const aDate =
|
|
1834
|
+
typeof a.frontMatter.date === "string"
|
|
1835
|
+
? Date.parse(a.frontMatter.date)
|
|
1836
|
+
: NaN;
|
|
1837
|
+
const bDate =
|
|
1838
|
+
typeof b.frontMatter.date === "string"
|
|
1839
|
+
? Date.parse(b.frontMatter.date)
|
|
1840
|
+
: NaN;
|
|
1841
|
+
if (Number.isFinite(aDate) && Number.isFinite(bDate) && aDate !== bDate) {
|
|
1842
|
+
return aDate - bDate;
|
|
1843
|
+
}
|
|
1844
|
+
if (Number.isFinite(aDate) && !Number.isFinite(bDate)) return -1;
|
|
1845
|
+
if (!Number.isFinite(aDate) && Number.isFinite(bDate)) return 1;
|
|
1846
|
+
return basename(a.dir).localeCompare(basename(b.dir));
|
|
1847
|
+
});
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
return { rootBundles, collectionBundles };
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
/**
|
|
1854
|
+
* Resolve the collection memberships listed in a bundle's top-level
|
|
1855
|
+
* `collections:` front-matter array into `{collectionId, createdAt,
|
|
1856
|
+
* position, pinnedAt}` records the post-create APIs expect.
|
|
1857
|
+
*
|
|
1858
|
+
* Drops entries whose slug doesn't map to a known collection — the
|
|
1859
|
+
* importer prints no warning (collections without slugs are already
|
|
1860
|
+
* filtered by the exporter).
|
|
1861
|
+
*/
|
|
1862
|
+
function resolveCollectionMemberships(frontMatter, collectionSlugToId) {
|
|
1863
|
+
const collections = Array.isArray(frontMatter.collections)
|
|
1864
|
+
? frontMatter.collections
|
|
1865
|
+
: [];
|
|
1866
|
+
const entries = [];
|
|
1867
|
+
const ids = [];
|
|
1868
|
+
for (const raw of collections) {
|
|
1869
|
+
if (!raw || typeof raw.slug !== "string") continue;
|
|
1870
|
+
const id = collectionSlugToId.get(raw.slug);
|
|
1871
|
+
if (!id) continue;
|
|
1872
|
+
const entry = { collectionId: id };
|
|
1873
|
+
if (typeof raw.collected_at === "string" && raw.collected_at) {
|
|
1874
|
+
entry.createdAt = Math.floor(
|
|
1875
|
+
new Date(raw.collected_at).getTime() / 1000,
|
|
1876
|
+
);
|
|
1877
|
+
}
|
|
1878
|
+
if (typeof raw.position === "number") {
|
|
1879
|
+
entry.position = raw.position;
|
|
1880
|
+
}
|
|
1881
|
+
if (typeof raw.pinned_at === "string" && raw.pinned_at) {
|
|
1882
|
+
entry.pinnedAt = Math.floor(new Date(raw.pinned_at).getTime() / 1000);
|
|
1883
|
+
}
|
|
1884
|
+
entries.push(entry);
|
|
1885
|
+
ids.push(id);
|
|
1886
|
+
}
|
|
1887
|
+
return { entries, ids };
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
/**
|
|
1891
|
+
* Build the payload for `target.createPost()` from a parsed bundle. Works
|
|
1892
|
+
* for both root bundles (`forReply: false`) and reply leaf bundles — the
|
|
1893
|
+
* front-matter shape is identical aside from `build:` and the parent link.
|
|
1894
|
+
*/
|
|
1895
|
+
function buildPostPayloadFromBundle(bundle, options) {
|
|
1896
|
+
const { frontMatter } = bundle;
|
|
1897
|
+
const format =
|
|
1898
|
+
typeof frontMatter.format === "string" ? frontMatter.format : "note";
|
|
1899
|
+
const slug =
|
|
1900
|
+
typeof frontMatter.slug === "string" ? frontMatter.slug : undefined;
|
|
1901
|
+
const status =
|
|
1902
|
+
frontMatter.status === "draft" || frontMatter.status === "published"
|
|
1903
|
+
? frontMatter.status
|
|
1904
|
+
: frontMatter.draft
|
|
1905
|
+
? "draft"
|
|
1906
|
+
: "published";
|
|
1907
|
+
// Accept every canonical visibility value (see `VISIBILITIES` in
|
|
1908
|
+
// `src/types/constants.ts`). Anything else — or missing — falls back to
|
|
1909
|
+
// the service default (`public`).
|
|
1910
|
+
const visibility =
|
|
1911
|
+
frontMatter.visibility === "public" ||
|
|
1912
|
+
frontMatter.visibility === "latest_hidden" ||
|
|
1913
|
+
frontMatter.visibility === "private"
|
|
1914
|
+
? frontMatter.visibility
|
|
1915
|
+
: undefined;
|
|
1916
|
+
const { entries: collectionEntries, ids: collectionIds } = options.memberships;
|
|
1917
|
+
|
|
1918
|
+
const data = {
|
|
1919
|
+
format,
|
|
1920
|
+
title:
|
|
1921
|
+
format === "quote"
|
|
1922
|
+
? typeof frontMatter.source_name === "string"
|
|
1923
|
+
? frontMatter.source_name
|
|
1924
|
+
: undefined
|
|
1925
|
+
: typeof frontMatter.title === "string"
|
|
1926
|
+
? frontMatter.title
|
|
1927
|
+
: undefined,
|
|
1928
|
+
bodyMarkdown: options.bodyMarkdown || undefined,
|
|
1929
|
+
slug,
|
|
1930
|
+
status,
|
|
1931
|
+
visibility,
|
|
1932
|
+
collectionIds:
|
|
1933
|
+
collectionEntries.length === 0 && collectionIds.length > 0
|
|
1934
|
+
? collectionIds
|
|
1935
|
+
: undefined,
|
|
1936
|
+
collectionEntries:
|
|
1937
|
+
collectionEntries.length > 0 ? collectionEntries : undefined,
|
|
1938
|
+
attachments:
|
|
1939
|
+
options.attachments.length > 0 ? options.attachments : undefined,
|
|
1940
|
+
publishedAt:
|
|
1941
|
+
status === "published" && typeof frontMatter.date === "string"
|
|
1942
|
+
? Math.floor(new Date(frontMatter.date).getTime() / 1000)
|
|
1943
|
+
: undefined,
|
|
1944
|
+
featuredAt:
|
|
1945
|
+
typeof frontMatter.featured_at === "string" && frontMatter.featured_at
|
|
1946
|
+
? Math.floor(new Date(frontMatter.featured_at).getTime() / 1000)
|
|
1947
|
+
: undefined,
|
|
1948
|
+
pinnedAt:
|
|
1949
|
+
typeof frontMatter.pinned_at === "string" && frontMatter.pinned_at
|
|
1950
|
+
? Math.floor(new Date(frontMatter.pinned_at).getTime() / 1000)
|
|
1951
|
+
: undefined,
|
|
1952
|
+
rating:
|
|
1953
|
+
typeof frontMatter.rating === "number" ? frontMatter.rating : undefined,
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
if (options.replyToId) {
|
|
1957
|
+
data.replyToId = options.replyToId;
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
if (format === "link" && typeof frontMatter.link_url === "string") {
|
|
1961
|
+
data.url = frontMatter.link_url;
|
|
1962
|
+
}
|
|
1963
|
+
if (format === "quote") {
|
|
1964
|
+
if (typeof frontMatter.quote_text === "string") {
|
|
1965
|
+
data.quoteText = frontMatter.quote_text;
|
|
1966
|
+
}
|
|
1967
|
+
if (
|
|
1968
|
+
typeof frontMatter.source_url === "string" &&
|
|
1969
|
+
frontMatter.source_url.trim()
|
|
1970
|
+
) {
|
|
1971
|
+
data.url = frontMatter.source_url;
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
return data;
|
|
1221
1976
|
}
|
|
1222
1977
|
|
|
1223
1978
|
export const __test__ = {
|
|
@@ -1227,16 +1982,23 @@ export const __test__ = {
|
|
|
1227
1982
|
normalizeTextAttachmentSpec,
|
|
1228
1983
|
extractAttachmentBlocks,
|
|
1229
1984
|
buildImportedAttachments,
|
|
1985
|
+
uploadMediaList,
|
|
1230
1986
|
buildSettingsUpdatesFromConfig,
|
|
1231
1987
|
normalizeImportedNavItems,
|
|
1988
|
+
normalizeImportedCollectionDirectory,
|
|
1232
1989
|
buildSiteAvatarImport,
|
|
1233
|
-
|
|
1234
|
-
|
|
1990
|
+
reorderCollectionDirectoryItems,
|
|
1991
|
+
syncImportedCollectionDirectory,
|
|
1235
1992
|
getRootAliasPathsForImport,
|
|
1236
1993
|
toRemotePostPayload,
|
|
1237
1994
|
buildIncompleteSetupError,
|
|
1238
1995
|
detectRemoteSetupStatus,
|
|
1239
1996
|
getIncompleteSetupError,
|
|
1997
|
+
loadSiteConfig,
|
|
1998
|
+
walkHugoContent,
|
|
1999
|
+
mediaSpecFromJantMedia,
|
|
2000
|
+
resolveCollectionMemberships,
|
|
2001
|
+
buildPostPayloadFromBundle,
|
|
1240
2002
|
};
|
|
1241
2003
|
|
|
1242
2004
|
export async function run(argv) {
|
|
@@ -1255,7 +2017,7 @@ export async function run(argv) {
|
|
|
1255
2017
|
if (values.help) {
|
|
1256
2018
|
console.log("Usage: jant site import [--url <url>] [options]");
|
|
1257
2019
|
console.log("");
|
|
1258
|
-
console.log("Import a
|
|
2020
|
+
console.log("Import a Hugo export directory or ZIP into a Jant instance.");
|
|
1259
2021
|
console.log("");
|
|
1260
2022
|
console.log("Modes:");
|
|
1261
2023
|
console.log(
|
|
@@ -1320,26 +2082,10 @@ export async function run(argv) {
|
|
|
1320
2082
|
process.exit(1);
|
|
1321
2083
|
}
|
|
1322
2084
|
|
|
1323
|
-
const postFiles = [];
|
|
1324
|
-
const collectionFiles = [];
|
|
1325
|
-
let siteConfig = null;
|
|
1326
|
-
let customCss = "";
|
|
1327
2085
|
let sourceRootDir = inputPath;
|
|
1328
2086
|
let tempSourceRootDir = null;
|
|
1329
2087
|
|
|
1330
|
-
if (inputStat.
|
|
1331
|
-
console.log(`Reading directory ${inputPath}...`);
|
|
1332
|
-
await walkContent(sourceRootDir, postFiles, collectionFiles);
|
|
1333
|
-
const configPath = join(sourceRootDir, "config.toml");
|
|
1334
|
-
const configContent = await readFile(configPath, "utf-8").catch(() => null);
|
|
1335
|
-
if (configContent) {
|
|
1336
|
-
siteConfig = await parseToml(configContent);
|
|
1337
|
-
}
|
|
1338
|
-
customCss = await readFile(
|
|
1339
|
-
join(sourceRootDir, "static", "custom.css"),
|
|
1340
|
-
"utf-8",
|
|
1341
|
-
).catch(() => "");
|
|
1342
|
-
} else {
|
|
2088
|
+
if (inputStat.isFile()) {
|
|
1343
2089
|
console.log(`Reading ZIP ${inputPath}...`);
|
|
1344
2090
|
const zipData = await readFile(inputPath);
|
|
1345
2091
|
const { unzipSync } = await import("fflate");
|
|
@@ -1351,23 +2097,26 @@ export async function run(argv) {
|
|
|
1351
2097
|
await mkdir(dirname(fullPath), { recursive: true });
|
|
1352
2098
|
await writeFile(fullPath, data);
|
|
1353
2099
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
const configPath = join(sourceRootDir, "config.toml");
|
|
1357
|
-
const configContent = await readFile(configPath, "utf-8").catch(() => null);
|
|
1358
|
-
if (configContent) {
|
|
1359
|
-
siteConfig = await parseToml(configContent);
|
|
1360
|
-
}
|
|
1361
|
-
customCss = await readFile(
|
|
1362
|
-
join(sourceRootDir, "static", "custom.css"),
|
|
1363
|
-
"utf-8",
|
|
1364
|
-
).catch(() => "");
|
|
2100
|
+
} else {
|
|
2101
|
+
console.log(`Reading directory ${inputPath}...`);
|
|
1365
2102
|
}
|
|
1366
2103
|
|
|
2104
|
+
const { rootBundles, collectionBundles } =
|
|
2105
|
+
await walkHugoContent(sourceRootDir);
|
|
2106
|
+
const siteConfig = await loadSiteConfig(sourceRootDir);
|
|
2107
|
+
const customCss = await readImportCustomCss(sourceRootDir);
|
|
2108
|
+
|
|
1367
2109
|
try {
|
|
2110
|
+
const replyCount = rootBundles.reduce(
|
|
2111
|
+
(sum, root) => sum + root.children.length,
|
|
2112
|
+
0,
|
|
2113
|
+
);
|
|
1368
2114
|
console.log(
|
|
1369
|
-
`Found ${
|
|
2115
|
+
`Found ${rootBundles.length} posts (+${replyCount} replies) and ${collectionBundles.length} collections`,
|
|
1370
2116
|
);
|
|
2117
|
+
const importedCollectionDirectory = siteConfig
|
|
2118
|
+
? normalizeImportedCollectionDirectory(siteConfig)
|
|
2119
|
+
: { exported: false, items: [] };
|
|
1371
2120
|
|
|
1372
2121
|
if (target) {
|
|
1373
2122
|
const setupError = await getIncompleteSetupError(
|
|
@@ -1408,8 +2157,10 @@ export async function run(argv) {
|
|
|
1408
2157
|
}
|
|
1409
2158
|
}
|
|
1410
2159
|
} else {
|
|
2160
|
+
const { editable, internal } =
|
|
2161
|
+
splitSettingsUpdatesForImport(settingsUpdates);
|
|
1411
2162
|
try {
|
|
1412
|
-
const result = await target.updateSettings(
|
|
2163
|
+
const result = await target.updateSettings(editable);
|
|
1413
2164
|
if (result?.rejectedKeys?.length) {
|
|
1414
2165
|
console.warn(
|
|
1415
2166
|
`Warning: Some site settings were rejected: ${result.rejectedKeys.join(", ")}`,
|
|
@@ -1422,6 +2173,22 @@ export async function run(argv) {
|
|
|
1422
2173
|
process.exit(1);
|
|
1423
2174
|
}
|
|
1424
2175
|
|
|
2176
|
+
if (Object.keys(internal).length > 0) {
|
|
2177
|
+
try {
|
|
2178
|
+
const result = await target.updateImportSettings(internal);
|
|
2179
|
+
if (result?.rejectedKeys?.length) {
|
|
2180
|
+
console.warn(
|
|
2181
|
+
`Warning: Some internal site settings were rejected: ${result.rejectedKeys.join(", ")}`,
|
|
2182
|
+
);
|
|
2183
|
+
}
|
|
2184
|
+
} catch (err) {
|
|
2185
|
+
console.error(
|
|
2186
|
+
`Error applying exported internal site settings: ${err.message}`,
|
|
2187
|
+
);
|
|
2188
|
+
process.exit(1);
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
|
|
1425
2192
|
if (importedNav.exported) {
|
|
1426
2193
|
try {
|
|
1427
2194
|
const existingNavItems = await target.listNavItems();
|
|
@@ -1443,8 +2210,13 @@ export async function run(argv) {
|
|
|
1443
2210
|
avatarImport.mode === "set" ? avatarImport : null,
|
|
1444
2211
|
);
|
|
1445
2212
|
} catch (err) {
|
|
1446
|
-
|
|
1447
|
-
|
|
2213
|
+
// Non-fatal: continue the rest of the import even if the avatar
|
|
2214
|
+
// source asset is unreachable (e.g. unreadable file, stale URL).
|
|
2215
|
+
// The rest of the site data is far more valuable than losing the
|
|
2216
|
+
// entire import over a single image.
|
|
2217
|
+
console.warn(
|
|
2218
|
+
`Warning: Could not import site avatar — continuing without it. (${err.message})`,
|
|
2219
|
+
);
|
|
1448
2220
|
}
|
|
1449
2221
|
}
|
|
1450
2222
|
}
|
|
@@ -1465,12 +2237,8 @@ export async function run(argv) {
|
|
|
1465
2237
|
}
|
|
1466
2238
|
}
|
|
1467
2239
|
|
|
1468
|
-
for (const
|
|
1469
|
-
const
|
|
1470
|
-
const slug = path
|
|
1471
|
-
.replace("content/jant-collections/", "")
|
|
1472
|
-
.replace("content/c/", "")
|
|
1473
|
-
.replace("/_index.md", "");
|
|
2240
|
+
for (const bundle of collectionBundles) {
|
|
2241
|
+
const slug = bundle.slug;
|
|
1474
2242
|
|
|
1475
2243
|
if (collectionSlugToId.has(slug)) {
|
|
1476
2244
|
console.error(
|
|
@@ -1481,83 +2249,117 @@ export async function run(argv) {
|
|
|
1481
2249
|
|
|
1482
2250
|
if (dryRun) {
|
|
1483
2251
|
console.log(
|
|
1484
|
-
`[dry-run] Would create collection: ${frontMatter.title || slug}`,
|
|
2252
|
+
`[dry-run] Would create collection: ${bundle.frontMatter.title || slug}`,
|
|
1485
2253
|
);
|
|
1486
2254
|
collectionSlugToId.set(slug, `dry-run-${slug}`);
|
|
1487
2255
|
continue;
|
|
1488
2256
|
}
|
|
1489
2257
|
|
|
1490
2258
|
try {
|
|
1491
|
-
const collectionExtra = frontMatter.extra || {};
|
|
1492
2259
|
const result = await target.createCollection({
|
|
1493
|
-
title: frontMatter.title || slug,
|
|
2260
|
+
title: bundle.frontMatter.title || slug,
|
|
1494
2261
|
slug,
|
|
1495
|
-
description:
|
|
2262
|
+
description:
|
|
2263
|
+
typeof bundle.frontMatter.summary_text === "string"
|
|
2264
|
+
? bundle.frontMatter.summary_text
|
|
2265
|
+
: undefined,
|
|
1496
2266
|
sortOrder:
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
2267
|
+
typeof bundle.frontMatter.sort_order === "string"
|
|
2268
|
+
? bundle.frontMatter.sort_order
|
|
2269
|
+
: undefined,
|
|
1500
2270
|
});
|
|
1501
2271
|
collectionSlugToId.set(slug, result.id);
|
|
1502
|
-
console.log(`Created collection: ${frontMatter.title || slug}`);
|
|
2272
|
+
console.log(`Created collection: ${bundle.frontMatter.title || slug}`);
|
|
1503
2273
|
} catch (err) {
|
|
1504
2274
|
console.error(`Error creating collection "${slug}": ${err.message}`);
|
|
1505
2275
|
process.exit(1);
|
|
1506
2276
|
}
|
|
1507
2277
|
}
|
|
1508
2278
|
|
|
1509
|
-
|
|
2279
|
+
if (importedCollectionDirectory.exported) {
|
|
2280
|
+
if (dryRun) {
|
|
2281
|
+
console.log(
|
|
2282
|
+
`[dry-run] Would restore collection directory with ${importedCollectionDirectory.items.length} items`,
|
|
2283
|
+
);
|
|
2284
|
+
} else {
|
|
2285
|
+
try {
|
|
2286
|
+
await syncImportedCollectionDirectory(
|
|
2287
|
+
target,
|
|
2288
|
+
importedCollectionDirectory,
|
|
2289
|
+
collectionSlugToId,
|
|
2290
|
+
);
|
|
2291
|
+
} catch (err) {
|
|
2292
|
+
console.error(
|
|
2293
|
+
`Error restoring collections directory: ${err.message}`,
|
|
2294
|
+
);
|
|
2295
|
+
process.exit(1);
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
// 4. Process posts — root bundle first, then each reply leaf, then aliases.
|
|
1510
2301
|
let postsCreated = 0;
|
|
1511
2302
|
let repliesCreated = 0;
|
|
1512
2303
|
let mediaUploaded = 0;
|
|
1513
2304
|
let aliasesCreated = 0;
|
|
1514
2305
|
|
|
1515
|
-
for (const
|
|
1516
|
-
const { frontMatter
|
|
1517
|
-
|
|
1518
|
-
const
|
|
1519
|
-
|
|
1520
|
-
const replySegments = segments.slice(1);
|
|
1521
|
-
const replySlugPaths = collectReplySlugPaths(replySegments);
|
|
1522
|
-
|
|
1523
|
-
// Resolve collection IDs from taxonomy slugs
|
|
1524
|
-
const collectionIds = [];
|
|
1525
|
-
const taxonomyCollections =
|
|
1526
|
-
frontMatter.taxonomies?.c || frontMatter.taxonomies?.collections || [];
|
|
1527
|
-
for (const colSlug of taxonomyCollections) {
|
|
1528
|
-
const id = collectionSlugToId.get(colSlug);
|
|
1529
|
-
if (id) collectionIds.push(id);
|
|
1530
|
-
}
|
|
1531
|
-
|
|
1532
|
-
const extra = frontMatter.extra || {};
|
|
1533
|
-
const format = extra.format || "note";
|
|
1534
|
-
const postSlug =
|
|
1535
|
-
frontMatter.slug != null ? String(frontMatter.slug) : undefined;
|
|
1536
|
-
const postStatus =
|
|
1537
|
-
extra.status === "draft" || extra.status === "published"
|
|
1538
|
-
? extra.status
|
|
1539
|
-
: frontMatter.draft
|
|
1540
|
-
? "draft"
|
|
1541
|
-
: "published";
|
|
1542
|
-
const postVisibility =
|
|
1543
|
-
extra.visibility === "unlisted" || extra.visibility === "private"
|
|
1544
|
-
? extra.visibility
|
|
1545
|
-
: undefined;
|
|
2306
|
+
for (const rootBundle of rootBundles) {
|
|
2307
|
+
const { frontMatter: rootFm } = rootBundle;
|
|
2308
|
+
const postSlug = rootBundle.slug;
|
|
2309
|
+
const format =
|
|
2310
|
+
typeof rootFm.format === "string" ? rootFm.format : "note";
|
|
1546
2311
|
const postLabel =
|
|
1547
|
-
(format === "quote"
|
|
2312
|
+
(format === "quote"
|
|
2313
|
+
? typeof rootFm.source_name === "string"
|
|
2314
|
+
? rootFm.source_name
|
|
2315
|
+
: null
|
|
2316
|
+
: typeof rootFm.title === "string"
|
|
2317
|
+
? rootFm.title
|
|
2318
|
+
: null) ||
|
|
1548
2319
|
postSlug ||
|
|
1549
2320
|
"(untitled)";
|
|
1550
2321
|
|
|
1551
|
-
if (!dryRun
|
|
2322
|
+
if (!dryRun) {
|
|
1552
2323
|
await assertImportSlugAvailable(target, postSlug, postLabel, "post");
|
|
1553
2324
|
}
|
|
1554
2325
|
|
|
1555
|
-
//
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
rootBody = normalizedRootBody.markdown;
|
|
2326
|
+
// Normalize body + extract embedded attachment blocks.
|
|
2327
|
+
const normalizedRoot = normalizeImportedBodySegment(rootBundle.body);
|
|
2328
|
+
let rootBody = normalizedRoot.markdown;
|
|
1559
2329
|
let importedAttachments = [];
|
|
1560
2330
|
|
|
2331
|
+
// Upload media declared in flat `media:` front matter. Each entry's
|
|
2332
|
+
// `src` is either a site-relative path (bytes under `static/`) or an
|
|
2333
|
+
// absolute URL (media still served by the original provider).
|
|
2334
|
+
// Text attachments (`kind: "text"`) live under the same `media:` key
|
|
2335
|
+
// but must be imported via `normalizeTextAttachmentSpec` so the body
|
|
2336
|
+
// is decoded and stored as a text attachment rather than uploaded as
|
|
2337
|
+
// a generic media file.
|
|
2338
|
+
const rootResourceSpecs = [];
|
|
2339
|
+
const rootTextAttachmentEntries = [];
|
|
2340
|
+
if (Array.isArray(rootFm.media)) {
|
|
2341
|
+
for (const entry of rootFm.media) {
|
|
2342
|
+
if (entry && typeof entry === "object" && entry.kind === "text") {
|
|
2343
|
+
rootTextAttachmentEntries.push(entry);
|
|
2344
|
+
continue;
|
|
2345
|
+
}
|
|
2346
|
+
const spec = await mediaSpecFromJantMedia(entry, sourceRootDir);
|
|
2347
|
+
if (spec) rootResourceSpecs.push(spec);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
const rootResourceIds = [];
|
|
2352
|
+
if (!skipMedia && !dryRun && rootResourceSpecs.length > 0) {
|
|
2353
|
+
const result = await uploadBundleResources(rootResourceSpecs, target);
|
|
2354
|
+
mediaUploaded += result.uploaded;
|
|
2355
|
+
if (result.urlMap.size > 0) {
|
|
2356
|
+
rootBody = rewriteMediaReferences(rootBody, result.urlMap);
|
|
2357
|
+
}
|
|
2358
|
+
rootResourceIds.push(...result.mediaIds);
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
// Fallback: rewrite any leftover in-body image URLs (covers hand-
|
|
2362
|
+
// authored Hugo content where the exporter didn't declare resources).
|
|
1561
2363
|
if (!skipMedia && !dryRun) {
|
|
1562
2364
|
const imageMedia = findImageUrls(rootBody).map((src) => ({ src }));
|
|
1563
2365
|
const uploadResult = await uploadMediaList(
|
|
@@ -1567,14 +2369,14 @@ export async function run(argv) {
|
|
|
1567
2369
|
sourceRootDir,
|
|
1568
2370
|
);
|
|
1569
2371
|
mediaUploaded += uploadResult.uploaded;
|
|
1570
|
-
|
|
1571
2372
|
if (uploadResult.urlMap.size > 0) {
|
|
1572
2373
|
rootBody = rewriteMediaReferences(rootBody, uploadResult.urlMap);
|
|
1573
2374
|
}
|
|
1574
2375
|
}
|
|
2376
|
+
|
|
1575
2377
|
if (!dryRun) {
|
|
1576
2378
|
const attachmentResult = await buildImportedAttachments(
|
|
1577
|
-
|
|
2379
|
+
normalizedRoot.attachments,
|
|
1578
2380
|
target,
|
|
1579
2381
|
siteConfig,
|
|
1580
2382
|
sourceRootDir,
|
|
@@ -1584,91 +2386,129 @@ export async function run(argv) {
|
|
|
1584
2386
|
mediaUploaded += attachmentResult.uploaded;
|
|
1585
2387
|
}
|
|
1586
2388
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
? typeof extra.source_name === "string"
|
|
1592
|
-
? extra.source_name
|
|
1593
|
-
: undefined
|
|
1594
|
-
: frontMatter.title != null
|
|
1595
|
-
? String(frontMatter.title)
|
|
1596
|
-
: undefined,
|
|
1597
|
-
bodyMarkdown: rootBody || undefined,
|
|
1598
|
-
slug: postSlug,
|
|
1599
|
-
path: frontMatter.path != null ? String(frontMatter.path) : undefined,
|
|
1600
|
-
status: postStatus,
|
|
1601
|
-
visibility: postVisibility,
|
|
1602
|
-
collectionIds: collectionIds.length > 0 ? collectionIds : undefined,
|
|
1603
|
-
attachments:
|
|
1604
|
-
importedAttachments.length > 0 ? importedAttachments : undefined,
|
|
1605
|
-
publishedAt:
|
|
1606
|
-
postStatus === "published" && frontMatter.date
|
|
1607
|
-
? Math.floor(new Date(frontMatter.date).getTime() / 1000)
|
|
1608
|
-
: undefined,
|
|
1609
|
-
pinned: extra.pinned || undefined,
|
|
1610
|
-
featured: extra.featured || undefined,
|
|
1611
|
-
rating: extra.rating || undefined,
|
|
1612
|
-
};
|
|
1613
|
-
|
|
1614
|
-
if (format === "link" && extra.link_url) {
|
|
1615
|
-
postData.url = extra.link_url;
|
|
2389
|
+
// Also attach every uploaded root page-resource as a media attachment
|
|
2390
|
+
// so the post record carries them even when none appear in body text.
|
|
2391
|
+
for (const mediaId of rootResourceIds) {
|
|
2392
|
+
importedAttachments.push({ type: "media", mediaId });
|
|
1616
2393
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
2394
|
+
|
|
2395
|
+
// Build text attachments declared in the flat `media:` front matter.
|
|
2396
|
+
// These reference a `.md` artifact that holds the full body; the
|
|
2397
|
+
// normalizer fetches the bytes (local disk first, then remote URL)
|
|
2398
|
+
// and decodes them.
|
|
2399
|
+
if (!skipMedia && !dryRun) {
|
|
2400
|
+
for (const textEntry of rootTextAttachmentEntries) {
|
|
2401
|
+
const textAttachment = await normalizeTextAttachmentSpec(
|
|
2402
|
+
textEntry,
|
|
2403
|
+
siteConfig,
|
|
2404
|
+
sourceRootDir,
|
|
2405
|
+
);
|
|
2406
|
+
if (textAttachment) importedAttachments.push(textAttachment);
|
|
1621
2407
|
}
|
|
1622
2408
|
}
|
|
1623
2409
|
|
|
2410
|
+
const memberships = resolveCollectionMemberships(
|
|
2411
|
+
rootFm,
|
|
2412
|
+
collectionSlugToId,
|
|
2413
|
+
);
|
|
2414
|
+
const postData = buildPostPayloadFromBundle(rootBundle, {
|
|
2415
|
+
bodyMarkdown: rootBody,
|
|
2416
|
+
attachments: importedAttachments,
|
|
2417
|
+
memberships,
|
|
2418
|
+
replyToId: null,
|
|
2419
|
+
});
|
|
2420
|
+
|
|
1624
2421
|
if (dryRun) {
|
|
1625
2422
|
console.log(`[dry-run] Would create post: ${postLabel} (${format})`);
|
|
1626
|
-
if (
|
|
1627
|
-
console.log(
|
|
2423
|
+
if (rootBundle.children.length > 0) {
|
|
2424
|
+
console.log(
|
|
2425
|
+
` [dry-run] With ${rootBundle.children.length} replies`,
|
|
2426
|
+
);
|
|
1628
2427
|
}
|
|
1629
2428
|
postsCreated++;
|
|
1630
|
-
repliesCreated +=
|
|
2429
|
+
repliesCreated += rootBundle.children.length;
|
|
1631
2430
|
continue;
|
|
1632
2431
|
}
|
|
1633
2432
|
|
|
1634
|
-
const progress = `[${postsCreated + 1}/${
|
|
1635
|
-
|
|
2433
|
+
const progress = `[${postsCreated + 1}/${rootBundles.length}]`;
|
|
1636
2434
|
let post;
|
|
1637
2435
|
try {
|
|
1638
2436
|
post = await target.createPost(postData);
|
|
1639
2437
|
postsCreated++;
|
|
1640
2438
|
const replyInfo =
|
|
1641
|
-
|
|
2439
|
+
rootBundle.children.length > 0
|
|
2440
|
+
? ` (+${rootBundle.children.length} replies)`
|
|
2441
|
+
: "";
|
|
1642
2442
|
console.log(`${progress} Created: ${postLabel}${replyInfo}`);
|
|
1643
2443
|
} catch (err) {
|
|
1644
2444
|
console.error(`Error creating post "${postLabel}": ${err.message}`);
|
|
1645
2445
|
process.exit(1);
|
|
1646
2446
|
}
|
|
1647
2447
|
|
|
1648
|
-
// Create replies before aliases so reply slugs can claim their
|
|
2448
|
+
// Create replies before aliases so reply slugs can claim their paths.
|
|
1649
2449
|
if (!post) continue;
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
2450
|
+
const replySlugPaths = new Set();
|
|
2451
|
+
// Jant threads are linear: each reply must point at the current end of
|
|
2452
|
+
// the thread, not at the root. Track the tail as we go so the Nth
|
|
2453
|
+
// reply chains after the (N−1)th.
|
|
2454
|
+
let threadTailId = post.id;
|
|
2455
|
+
for (const replyBundle of rootBundle.children) {
|
|
2456
|
+
const replyFm = replyBundle.frontMatter;
|
|
2457
|
+
const replySlug = replyBundle.slug;
|
|
2458
|
+
const replyFormat =
|
|
2459
|
+
typeof replyFm.format === "string" ? replyFm.format : "note";
|
|
1653
2460
|
const replyLabel =
|
|
1654
|
-
|
|
1655
|
-
|
|
2461
|
+
(replyFormat === "quote"
|
|
2462
|
+
? typeof replyFm.source_name === "string"
|
|
2463
|
+
? replyFm.source_name
|
|
2464
|
+
: null
|
|
2465
|
+
: typeof replyFm.title === "string"
|
|
2466
|
+
? replyFm.title
|
|
2467
|
+
: null) ||
|
|
1656
2468
|
replySlug ||
|
|
1657
2469
|
"(untitled reply)";
|
|
1658
|
-
|
|
1659
|
-
|
|
2470
|
+
|
|
2471
|
+
const replySlugPath = normalizeImportAliasPath(replySlug);
|
|
2472
|
+
if (replySlugPath) replySlugPaths.add(replySlugPath);
|
|
2473
|
+
|
|
2474
|
+
await assertImportSlugAvailable(
|
|
2475
|
+
target,
|
|
2476
|
+
replySlug,
|
|
2477
|
+
`${replyLabel} in ${postLabel}`,
|
|
2478
|
+
"reply",
|
|
2479
|
+
);
|
|
2480
|
+
|
|
2481
|
+
const normalizedReply = normalizeImportedBodySegment(replyBundle.body);
|
|
2482
|
+
let replyBody = normalizedReply.markdown;
|
|
2483
|
+
let replyAttachments = [];
|
|
2484
|
+
|
|
2485
|
+
const replyResourceSpecs = [];
|
|
2486
|
+
const replyTextAttachmentEntries = [];
|
|
2487
|
+
if (Array.isArray(replyFm.media)) {
|
|
2488
|
+
for (const entry of replyFm.media) {
|
|
2489
|
+
if (entry && typeof entry === "object" && entry.kind === "text") {
|
|
2490
|
+
replyTextAttachmentEntries.push(entry);
|
|
2491
|
+
continue;
|
|
2492
|
+
}
|
|
2493
|
+
const spec = await mediaSpecFromJantMedia(entry, sourceRootDir);
|
|
2494
|
+
if (spec) replyResourceSpecs.push(spec);
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
const replyResourceIds = [];
|
|
2499
|
+
if (!skipMedia && replyResourceSpecs.length > 0) {
|
|
2500
|
+
const result = await uploadBundleResources(
|
|
2501
|
+
replyResourceSpecs,
|
|
1660
2502
|
target,
|
|
1661
|
-
replySlug,
|
|
1662
|
-
`${replyLabel} in ${postLabel}`,
|
|
1663
|
-
"reply",
|
|
1664
2503
|
);
|
|
2504
|
+
mediaUploaded += result.uploaded;
|
|
2505
|
+
if (result.urlMap.size > 0) {
|
|
2506
|
+
replyBody = rewriteMediaReferences(replyBody, result.urlMap);
|
|
2507
|
+
}
|
|
2508
|
+
replyResourceIds.push(...result.mediaIds);
|
|
1665
2509
|
}
|
|
1666
|
-
let replyBody = replySegment.body || "";
|
|
1667
|
-
const normalizedReplyBody = normalizeImportedBodySegment(replyBody);
|
|
1668
|
-
replyBody = normalizedReplyBody.markdown;
|
|
1669
|
-
let replyAttachments = [];
|
|
1670
2510
|
|
|
1671
|
-
if (!skipMedia
|
|
2511
|
+
if (!skipMedia) {
|
|
1672
2512
|
const imageMedia = findImageUrls(replyBody).map((src) => ({ src }));
|
|
1673
2513
|
const uploadResult = await uploadMediaList(
|
|
1674
2514
|
imageMedia,
|
|
@@ -1677,87 +2517,72 @@ export async function run(argv) {
|
|
|
1677
2517
|
sourceRootDir,
|
|
1678
2518
|
);
|
|
1679
2519
|
mediaUploaded += uploadResult.uploaded;
|
|
1680
|
-
|
|
1681
2520
|
if (uploadResult.urlMap.size > 0) {
|
|
1682
2521
|
replyBody = rewriteMediaReferences(replyBody, uploadResult.urlMap);
|
|
1683
2522
|
}
|
|
1684
2523
|
}
|
|
1685
|
-
if (!dryRun) {
|
|
1686
|
-
const attachmentResult = await buildImportedAttachments(
|
|
1687
|
-
normalizedReplyBody.attachments,
|
|
1688
|
-
target,
|
|
1689
|
-
siteConfig,
|
|
1690
|
-
sourceRootDir,
|
|
1691
|
-
{ skipUploads: skipMedia },
|
|
1692
|
-
);
|
|
1693
|
-
replyAttachments = attachmentResult.attachments;
|
|
1694
|
-
mediaUploaded += attachmentResult.uploaded;
|
|
1695
|
-
}
|
|
1696
2524
|
|
|
1697
|
-
const
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
format: replyFormat,
|
|
1709
|
-
status: replyStatus,
|
|
1710
|
-
title:
|
|
1711
|
-
replyFormat === "quote"
|
|
1712
|
-
? replyAttrs.source_name || undefined
|
|
1713
|
-
: replyAttrs.title || undefined,
|
|
1714
|
-
bodyMarkdown: replyBody || undefined,
|
|
1715
|
-
replyToId: post.id,
|
|
1716
|
-
slug: replySlug,
|
|
1717
|
-
visibility: replyVisibility,
|
|
1718
|
-
attachments:
|
|
1719
|
-
replyAttachments.length > 0 ? replyAttachments : undefined,
|
|
1720
|
-
publishedAt: replyAttrs.date
|
|
1721
|
-
? Math.floor(new Date(replyAttrs.date).getTime() / 1000)
|
|
1722
|
-
: undefined,
|
|
1723
|
-
rating: replyAttrs.rating ? Number(replyAttrs.rating) : undefined,
|
|
1724
|
-
};
|
|
1725
|
-
|
|
1726
|
-
if (replyFormat === "link" && replyAttrs.url) {
|
|
1727
|
-
replyData.url = replyAttrs.url;
|
|
2525
|
+
const attachmentResult = await buildImportedAttachments(
|
|
2526
|
+
normalizedReply.attachments,
|
|
2527
|
+
target,
|
|
2528
|
+
siteConfig,
|
|
2529
|
+
sourceRootDir,
|
|
2530
|
+
{ skipUploads: skipMedia },
|
|
2531
|
+
);
|
|
2532
|
+
replyAttachments = attachmentResult.attachments;
|
|
2533
|
+
mediaUploaded += attachmentResult.uploaded;
|
|
2534
|
+
for (const mediaId of replyResourceIds) {
|
|
2535
|
+
replyAttachments.push({ type: "media", mediaId });
|
|
1728
2536
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
2537
|
+
|
|
2538
|
+
if (!skipMedia) {
|
|
2539
|
+
for (const textEntry of replyTextAttachmentEntries) {
|
|
2540
|
+
const textAttachment = await normalizeTextAttachmentSpec(
|
|
2541
|
+
textEntry,
|
|
2542
|
+
siteConfig,
|
|
2543
|
+
sourceRootDir,
|
|
2544
|
+
);
|
|
2545
|
+
if (textAttachment) replyAttachments.push(textAttachment);
|
|
1733
2546
|
}
|
|
1734
2547
|
}
|
|
1735
2548
|
|
|
2549
|
+
const replyMemberships = resolveCollectionMemberships(
|
|
2550
|
+
replyFm,
|
|
2551
|
+
collectionSlugToId,
|
|
2552
|
+
);
|
|
2553
|
+
const replyData = buildPostPayloadFromBundle(replyBundle, {
|
|
2554
|
+
bodyMarkdown: replyBody,
|
|
2555
|
+
attachments: replyAttachments,
|
|
2556
|
+
memberships: replyMemberships,
|
|
2557
|
+
replyToId: threadTailId,
|
|
2558
|
+
});
|
|
2559
|
+
|
|
1736
2560
|
try {
|
|
1737
|
-
await target.createPost(replyData);
|
|
2561
|
+
const createdReply = await target.createPost(replyData);
|
|
1738
2562
|
repliesCreated++;
|
|
2563
|
+
if (createdReply?.id) {
|
|
2564
|
+
threadTailId = createdReply.id;
|
|
2565
|
+
}
|
|
1739
2566
|
} catch (err) {
|
|
1740
2567
|
console.error(` Error creating reply: ${err.message}`);
|
|
1741
2568
|
process.exit(1);
|
|
1742
2569
|
}
|
|
1743
2570
|
}
|
|
1744
2571
|
|
|
1745
|
-
// Create exported root aliases after replies.
|
|
1746
|
-
//
|
|
2572
|
+
// Create exported root aliases after replies. Historical root slugs
|
|
2573
|
+
// round-trip via `root_aliases:`; reply slugs are handled by their
|
|
2574
|
+
// own bundles so we strip them from the alias list.
|
|
1747
2575
|
const rootTargetSlug = postSlug || post.slug;
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
);
|
|
1759
|
-
process.exit(1);
|
|
1760
|
-
}
|
|
2576
|
+
const aliases = Array.isArray(rootFm.aliases) ? rootFm.aliases : [];
|
|
2577
|
+
const rootAliases = Array.isArray(rootFm.root_aliases)
|
|
2578
|
+
? rootFm.root_aliases
|
|
2579
|
+
: [];
|
|
2580
|
+
const aliasPaths = getRootAliasPathsForImport(
|
|
2581
|
+
aliases,
|
|
2582
|
+
rootAliases,
|
|
2583
|
+
rootTargetSlug,
|
|
2584
|
+
replySlugPaths,
|
|
2585
|
+
);
|
|
1761
2586
|
for (const aliasPath of aliasPaths) {
|
|
1762
2587
|
try {
|
|
1763
2588
|
await target.createAlias(aliasPath, rootTargetSlug);
|
|
@@ -1791,3 +2616,4 @@ export async function run(argv) {
|
|
|
1791
2616
|
}
|
|
1792
2617
|
}
|
|
1793
2618
|
}
|
|
2619
|
+
|