fundus 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -0
- package/build/client/_app/immutable/assets/2.X44Wyac-.css +1 -0
- package/build/client/_app/immutable/assets/2.X44Wyac-.css.br +0 -0
- package/build/client/_app/immutable/assets/2.X44Wyac-.css.gz +0 -0
- package/build/client/_app/immutable/assets/{3.C6xo25uI.css → 3.66PJT3JC.css} +1 -1
- package/build/client/_app/immutable/assets/3.66PJT3JC.css.br +0 -0
- package/build/client/_app/immutable/assets/3.66PJT3JC.css.gz +0 -0
- package/build/client/_app/immutable/assets/{AssetSourceMenu.IjDdjx3o.css → AssetSourceMenu.B5fzYfym.css} +1 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.B5fzYfym.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.B5fzYfym.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B06eqbax.js +108 -0
- package/build/client/_app/immutable/chunks/B06eqbax.js.br +0 -0
- package/build/client/_app/immutable/chunks/B06eqbax.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{dNO-9VOT.js → B97y-eFA.js} +1 -1
- package/build/client/_app/immutable/chunks/B97y-eFA.js.br +0 -0
- package/build/client/_app/immutable/chunks/B97y-eFA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BmOjTxFk.js +1 -0
- package/build/client/_app/immutable/chunks/BmOjTxFk.js.br +0 -0
- package/build/client/_app/immutable/chunks/BmOjTxFk.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C9MzfQz6.js +2 -0
- package/build/client/_app/immutable/chunks/C9MzfQz6.js.br +0 -0
- package/build/client/_app/immutable/chunks/C9MzfQz6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CcuyGBqj.js +1 -0
- package/build/client/_app/immutable/chunks/CcuyGBqj.js.br +0 -0
- package/build/client/_app/immutable/chunks/CcuyGBqj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{77p2oEJ1.js → D6c2mfMB.js} +1 -1
- package/build/client/_app/immutable/chunks/D6c2mfMB.js.br +2 -0
- package/build/client/_app/immutable/chunks/D6c2mfMB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DY9QjkXW.js +1 -0
- package/build/client/_app/immutable/chunks/DY9QjkXW.js.br +0 -0
- package/build/client/_app/immutable/chunks/DY9QjkXW.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Z8rcWjXZ.js +3 -0
- package/build/client/_app/immutable/chunks/Z8rcWjXZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/Z8rcWjXZ.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.V1MmmICK.js +2 -0
- package/build/client/_app/immutable/entry/app.V1MmmICK.js.br +0 -0
- package/build/client/_app/immutable/entry/app.V1MmmICK.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BbyflZUw.js +1 -0
- package/build/client/_app/immutable/entry/start.BbyflZUw.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BbyflZUw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js +1 -0
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BqoPRvUU.js +1 -0
- package/build/client/_app/immutable/nodes/1.BqoPRvUU.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BqoPRvUU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js +3 -0
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js +1 -0
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js +2 -0
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/handler.js +8 -7
- package/build/handler.js.map +1 -1
- package/build/index.js +8 -7
- package/build/index.js.map +1 -1
- package/build/server/chunks/chunks/{context.js-CVuTSPjH.js → context.js-BXaBgcZT.js} +627 -134
- package/build/server/chunks/chunks/context.js-BXaBgcZT.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-itFN0Gon.js → contract.js-IY1F-HE_.js} +94 -58
- package/build/server/chunks/chunks/contract.js-IY1F-HE_.js.map +1 -0
- package/build/server/chunks/chunks/{core.js-CABVXpby.js → core.js-D1sYC_78.js} +144 -143
- package/build/server/chunks/chunks/core.js-D1sYC_78.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-B13PkE0J.js → exports.js-B5DLeNXr.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-B13PkE0J.js.map → exports.js-B5DLeNXr.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-ChQRRKfZ.js → http.js-CzB9Igb0.js} +2 -2
- package/build/server/chunks/chunks/{http.js-ChQRRKfZ.js.map → http.js-CzB9Igb0.js.map} +1 -1
- package/build/server/chunks/chunks/{internal.js-DlKoWKM-.js → internal.js-HE35Pm1C.js} +5 -3
- package/build/server/chunks/chunks/internal.js-HE35Pm1C.js.map +1 -0
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{manifest-membership.js-BnSECWpJ.js → manifest-membership.js-Cm_2fU-Z.js} +2 -2
- package/build/server/chunks/chunks/{manifest-membership.js-BnSECWpJ.js.map → manifest-membership.js-Cm_2fU-Z.js.map} +1 -1
- package/build/server/chunks/chunks/{raw-reconciliation.js-ZEOCk_jA.js → raw-reconciliation.js-1_IwPhKb.js} +3 -3
- package/build/server/chunks/chunks/raw-reconciliation.js-1_IwPhKb.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CscuoBC2.js → raw-reconciliation2.js-CcO9li5n.js} +2 -2
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CscuoBC2.js.map → raw-reconciliation2.js-CcO9li5n.js.map} +1 -1
- package/build/server/chunks/chunks/{shared.js-DKt4pwWi.js → shared.js-MR8sPPTu.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-DKt4pwWi.js.map → shared.js-MR8sPPTu.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-BYMC-4Wt.js → utils.js-C2UFBITa.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-BYMC-4Wt.js.map → utils.js-C2UFBITa.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-z988EDp2.js → _server.ts.js-BnRJ5Qnd.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-z988EDp2.js.map → _server.ts.js-BnRJ5Qnd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-C68ru6gS.js → _server.ts.js-BZPR6n5n.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-C68ru6gS.js.map → _server.ts.js-BZPR6n5n.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-C0tk6RFk.js → _server.ts.js-DiBS3A0C.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-C0tk6RFk.js.map → _server.ts.js-DiBS3A0C.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-I03oZuo8.js → _server.ts.js-LOO6qm2-.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-I03oZuo8.js.map → _server.ts.js-LOO6qm2-.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-BsQB8YDq.js → _server.ts.js-CRtJJoSs.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-BsQB8YDq.js.map → _server.ts.js-CRtJJoSs.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CJuFE6Fb.js → _server.ts.js-Ds4zCZ9H.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-CJuFE6Fb.js.map → _server.ts.js-Ds4zCZ9H.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DuOZRRiA.js → _server.ts.js-DD4N8pcj.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DuOZRRiA.js.map → _server.ts.js-DD4N8pcj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DGzYpQbv.js → _server.ts.js-CZev9aYz.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-DGzYpQbv.js.map → _server.ts.js-CZev9aYz.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-B045QoCA.js → _server.ts.js-MBDVW0q1.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-B045QoCA.js.map → _server.ts.js-MBDVW0q1.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-HUkVdz19.js → _server.ts.js-C7naXnsR.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-HUkVdz19.js.map → _server.ts.js-C7naXnsR.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-ry509mom.js → _server.ts.js-DuGyRdf3.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-ry509mom.js.map → _server.ts.js-DuGyRdf3.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DU0J7U25.js → _server.ts.js-0-ZCt0qH.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DU0J7U25.js.map → _server.ts.js-0-ZCt0qH.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AZIV2PIn.js → _server.ts.js-DFYU_sZL.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AZIV2PIn.js.map → _server.ts.js-DFYU_sZL.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CDL0hCfM.js → _server.ts.js-BqJpK0sJ.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CDL0hCfM.js.map → _server.ts.js-BqJpK0sJ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-B13c17fq.js → _server.ts.js--LSqADJp.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-B13c17fq.js.map → _server.ts.js--LSqADJp.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-BCxjyAGC.js → _server.ts.js-DcL8nYDM.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-BCxjyAGC.js.map → _server.ts.js-DcL8nYDM.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-BveeMZc2.js → _server.ts.js-72OcyLfP.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-BveeMZc2.js.map → _server.ts.js-72OcyLfP.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-BZjTd9a0.js → _server.ts.js-D0bOxmG0.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-BZjTd9a0.js.map → _server.ts.js-D0bOxmG0.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BbTfPvC9.js → _server.ts.js-BjDVCRNV.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BbTfPvC9.js.map → _server.ts.js-BjDVCRNV.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-8VPJMLBk.js → _server.ts.js-CndfoXXd.js} +6 -6
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-8VPJMLBk.js.map → _server.ts.js-CndfoXXd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqR2J2sB.js → _server.ts.js-Ck1mgbk5.js} +9 -7
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-BqR2J2sB.js.map → _server.ts.js-Ck1mgbk5.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-DbA28dCY.js → _server.ts.js-lZ9oP8tz.js} +9 -7
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-DbA28dCY.js.map → _server.ts.js-lZ9oP8tz.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-9PBc_3Jh.js → hooks.server.js-DQ6l2RSK.js} +8 -6
- package/build/server/chunks/entries/{hooks.server.js-9PBc_3Jh.js.map → hooks.server.js-DQ6l2RSK.js.map} +1 -1
- package/build/server/chunks/{handler-XxBNCHhb.js → handler-Dfk_4a-r.js} +5 -5
- package/build/server/chunks/{handler-XxBNCHhb.js.map → handler-Dfk_4a-r.js.map} +1 -1
- package/build/server/chunks/{index.js-B_76Gq5Y.js → index.js-O3Wl1zok.js} +5 -5
- package/build/server/chunks/{index.js-B_76Gq5Y.js.map → index.js-O3Wl1zok.js.map} +1 -1
- package/build/server/chunks/{manifest.js-C2MZZt3o.js → manifest.js-51nEZnKQ.js} +29 -29
- package/build/server/chunks/{manifest.js-C2MZZt3o.js.map → manifest.js-51nEZnKQ.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-BLURyWmd.js → 0.js-DjqMfDtB.js} +2 -2
- package/build/server/chunks/nodes/{0.js-BLURyWmd.js.map → 0.js-DjqMfDtB.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-BwfSLYJH.js +7 -0
- package/build/server/chunks/nodes/{1.js-CITI7d3d.js.map → 1.js-BwfSLYJH.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-buHbEytf.js +7 -0
- package/build/server/chunks/nodes/2.js-buHbEytf.js.map +1 -0
- package/build/server/chunks/nodes/3.js-D7_hF0qp.js +7 -0
- package/build/server/chunks/nodes/3.js-D7_hF0qp.js.map +1 -0
- package/build/server/chunks/nodes/4.js-D58M2chZ.js +7 -0
- package/build/server/chunks/nodes/{4.js-BRlAiVnn.js.map → 4.js-D58M2chZ.js.map} +1 -1
- package/dist/config.d.ts +3 -3
- package/dist/config.js +2 -2
- package/dist/core/api-types.d.ts +22 -2
- package/dist/core/config.d.ts +82 -0
- package/dist/core/config.js +9 -0
- package/dist/core/index.d.ts +10 -5
- package/dist/core/index.js +5 -2
- package/dist/core/library-validation.d.ts +13 -0
- package/dist/core/library-validation.js +48 -0
- package/dist/core/library.d.ts +19 -0
- package/dist/core/library.js +4 -4
- package/dist/core/manifest-membership.d.ts +2 -2
- package/dist/core/package-declaration.d.ts +43 -0
- package/dist/core/package-declaration.js +80 -0
- package/dist/core/package-merge.d.ts +65 -0
- package/dist/core/package-merge.js +173 -0
- package/dist/core/reference-graph.d.ts +3 -3
- package/dist/runtime/components/Image.svelte +5 -6
- package/dist/runtime/components/Image.svelte.d.ts +2 -3
- package/dist/server/build.js +26 -11
- package/dist/server/check.d.ts +13 -3
- package/dist/server/check.js +112 -24
- package/dist/server/codegen.d.ts +3 -1
- package/dist/server/codegen.js +18 -0
- package/dist/server/config-loader.d.ts +35 -1
- package/dist/server/config-loader.js +185 -4
- package/dist/server/library-store.d.ts +11 -1
- package/dist/server/library-store.js +42 -60
- package/dist/server/operations.js +162 -47
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css +0 -1
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.br +0 -0
- package/build/client/_app/immutable/assets/2.C-1MfvLQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.C6xo25uI.css.br +0 -0
- package/build/client/_app/immutable/assets/3.C6xo25uI.css.gz +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.IjDdjx3o.css.br +0 -0
- package/build/client/_app/immutable/assets/AssetSourceMenu.IjDdjx3o.css.gz +0 -0
- package/build/client/_app/immutable/chunks/77p2oEJ1.js.br +0 -0
- package/build/client/_app/immutable/chunks/77p2oEJ1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B9HdDE5n.js +0 -1
- package/build/client/_app/immutable/chunks/B9HdDE5n.js.br +0 -0
- package/build/client/_app/immutable/chunks/B9HdDE5n.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B_PWcB6g.js +0 -108
- package/build/client/_app/immutable/chunks/B_PWcB6g.js.br +0 -0
- package/build/client/_app/immutable/chunks/B_PWcB6g.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Q50krHyn.js +0 -2
- package/build/client/_app/immutable/chunks/Q50krHyn.js.br +0 -0
- package/build/client/_app/immutable/chunks/Q50krHyn.js.gz +0 -0
- package/build/client/_app/immutable/chunks/RgXSPQ_h.js +0 -1
- package/build/client/_app/immutable/chunks/RgXSPQ_h.js.br +0 -0
- package/build/client/_app/immutable/chunks/RgXSPQ_h.js.gz +0 -0
- package/build/client/_app/immutable/chunks/YpiA5Xry.js +0 -3
- package/build/client/_app/immutable/chunks/YpiA5Xry.js.br +0 -0
- package/build/client/_app/immutable/chunks/YpiA5Xry.js.gz +0 -0
- package/build/client/_app/immutable/chunks/dNO-9VOT.js.br +0 -0
- package/build/client/_app/immutable/chunks/dNO-9VOT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/hUfV2O0k.js +0 -1
- package/build/client/_app/immutable/chunks/hUfV2O0k.js.br +0 -0
- package/build/client/_app/immutable/chunks/hUfV2O0k.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.BsvwTApt.js +0 -2
- package/build/client/_app/immutable/entry/app.BsvwTApt.js.br +0 -0
- package/build/client/_app/immutable/entry/app.BsvwTApt.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BdjLMMsY.js +0 -1
- package/build/client/_app/immutable/entry/start.BdjLMMsY.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BdjLMMsY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CjQfQrD6.js +0 -1
- package/build/client/_app/immutable/nodes/0.CjQfQrD6.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CjQfQrD6.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DyPcUKIh.js +0 -1
- package/build/client/_app/immutable/nodes/1.DyPcUKIh.js.br +0 -2
- package/build/client/_app/immutable/nodes/1.DyPcUKIh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CworwA2R.js +0 -3
- package/build/client/_app/immutable/nodes/2.CworwA2R.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CworwA2R.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.BKqbML1T.js +0 -1
- package/build/client/_app/immutable/nodes/3.BKqbML1T.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BKqbML1T.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.Cmigd8CT.js +0 -2
- package/build/client/_app/immutable/nodes/4.Cmigd8CT.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.Cmigd8CT.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-CVuTSPjH.js.map +0 -1
- package/build/server/chunks/chunks/contract.js-itFN0Gon.js.map +0 -1
- package/build/server/chunks/chunks/core.js-CABVXpby.js.map +0 -1
- package/build/server/chunks/chunks/internal.js-DlKoWKM-.js.map +0 -1
- package/build/server/chunks/chunks/raw-reconciliation.js-ZEOCk_jA.js.map +0 -1
- package/build/server/chunks/nodes/1.js-CITI7d3d.js +0 -7
- package/build/server/chunks/nodes/2.js-DAls5TjF.js +0 -7
- package/build/server/chunks/nodes/2.js-DAls5TjF.js.map +0 -1
- package/build/server/chunks/nodes/3.js-CesAmg_E.js +0 -7
- package/build/server/chunks/nodes/3.js-CesAmg_E.js.map +0 -1
- package/build/server/chunks/nodes/4.js-BRlAiVnn.js +0 -7
package/dist/server/check.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type Library, type ValidationIssueDto } from '../core/index.js';
|
|
1
|
+
import { type EffectiveLibrary, type Library, type LibraryMembership, type MergeProvenance, type ValidationIssueDto } from '../core/index.js';
|
|
2
2
|
import { type RawClassification } from './raw-reconciliation.js';
|
|
3
3
|
import type { ServerPluginRegistry } from './plugins/contract.js';
|
|
4
4
|
/** One machine-readable check finding (the `--json` failure-list shape, M9). */
|
|
5
5
|
export interface CheckFinding {
|
|
6
6
|
/** The failure category. */
|
|
7
|
-
kind: 'validation' | 'proxy-missing' | 'proxy-unresolvable' | 'proxy-orphaned' | 'module-missing' | 'module-out-of-sync' | 'module-stray' | 'module-regeneration-failed' | 'unreachable-asset' | 'potential-image-duplicate' | 'raw-hash-drift' | 'raw-type-incompatible' | 'raw-scan-incomplete' | 'raw-unmanaged';
|
|
7
|
+
kind: 'validation' | 'proxy-missing' | 'proxy-unresolvable' | 'proxy-orphaned' | 'module-missing' | 'module-out-of-sync' | 'module-stray' | 'module-regeneration-failed' | 'unreachable-asset' | 'potential-image-duplicate' | 'raw-hash-drift' | 'raw-type-incompatible' | 'raw-scan-incomplete' | 'raw-unmanaged' | 'slot-unfilled' | 'slot-unmaterialized' | 'package-conflict' | 'package-type-mismatch';
|
|
8
8
|
message: string;
|
|
9
9
|
/** The asset the finding concerns, where applicable. */
|
|
10
10
|
assetId?: string;
|
|
@@ -26,9 +26,19 @@ export interface CheckReport {
|
|
|
26
26
|
manifestCount: number;
|
|
27
27
|
}
|
|
28
28
|
export interface CheckAdvisory {
|
|
29
|
-
kind: 'usage-not-configured';
|
|
29
|
+
kind: 'usage-not-configured' | 'package-overridden';
|
|
30
30
|
message: string;
|
|
31
|
+
/** The asset a `package-overridden` advisory concerns. */
|
|
32
|
+
assetId?: string;
|
|
31
33
|
}
|
|
32
34
|
export declare function runCheck(projectRoot: string, registry?: ServerPluginRegistry): Promise<CheckReport>;
|
|
33
35
|
/** Pure expansion of a raw classification into canonical hard check findings. */
|
|
34
36
|
export declare function rawCheckFindings(library: Library, raw: RawClassification, registry: ServerPluginRegistry, validationIssues: ValidationIssueDto[]): CheckFinding[];
|
|
37
|
+
/**
|
|
38
|
+
* The delivered-slot contract: a Package slot that is delivered (explicit member
|
|
39
|
+
* or in a delivered manifest's reference closure) but has no host-supplied bytes
|
|
40
|
+
* must be filled. A slot with an `importSource` is `slot-unmaterialized` (run
|
|
41
|
+
* import); a slot with nothing is `slot-unfilled`. Inert (undelivered) slots
|
|
42
|
+
* produce no finding.
|
|
43
|
+
*/
|
|
44
|
+
export declare function packageSlotFindings(library: EffectiveLibrary, provenance: MergeProvenance, membership: LibraryMembership): CheckFinding[];
|
package/dist/server/check.js
CHANGED
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
import { existsSync } from 'node:fs';
|
|
11
11
|
import { readFile } from 'node:fs/promises';
|
|
12
12
|
import { join } from 'node:path';
|
|
13
|
-
import { collectAllReferences, compareCodeUnits, computeLibraryMembership, rawFileNameOfPath, typesForFileName } from '../core/index.js';
|
|
13
|
+
import { allDeliveredAssetIds, collectAllReferences, compareCodeUnits, computeLibraryMembership, flatLibraryIssues, materializeLibrary, mergePackages, rawFileNameOfPath, typesForFileName } from '../core/index.js';
|
|
14
14
|
import { loadConfig, USAGE_NOT_CONFIGURED_MESSAGE } from './config-loader.js';
|
|
15
15
|
import { LibraryStore } from './library-store.js';
|
|
16
16
|
import { classifyRawDirectory } from './raw-reconciliation.js';
|
|
17
|
-
import { buildManifestEntries, manifestModuleFileName, renderManifestModule, strayGeneratedModuleNames } from './codegen.js';
|
|
17
|
+
import { buildManifestEntries, manifestModuleCollisionIssues, manifestModuleFileName, renderManifestModule, strayGeneratedModuleNames } from './codegen.js';
|
|
18
18
|
import { descriptorsByType, serverPluginsByType } from './plugins.js';
|
|
19
|
-
import {
|
|
19
|
+
import { expectedProxyRelativePath, isProxyFileName, readCurrentProxy } from './processing/processor.js';
|
|
20
20
|
import { listRelativeFiles } from './folder-filesystem.js';
|
|
21
21
|
import { ImageDuplicateDetector } from './image-duplicates.js';
|
|
22
22
|
/** The human rendering of a finding — `[assetId] message`, as `fundus check` prints it. */
|
|
@@ -26,18 +26,47 @@ export function formatCheckFinding(finding) {
|
|
|
26
26
|
export async function runCheck(projectRoot, registry = serverPluginsByType) {
|
|
27
27
|
const config = await loadConfig(projectRoot);
|
|
28
28
|
const store = new LibraryStore(config, registry);
|
|
29
|
-
const
|
|
29
|
+
const host = await store.read();
|
|
30
|
+
// Merge Packages under the host into one in-memory effective library. Raw
|
|
31
|
+
// scans stay on the host (it owns the bytes); everything id-space runs over
|
|
32
|
+
// the effective library; processing/codegen run over the materialized subset.
|
|
33
|
+
const { library: effective, provenance, findings: mergeFindings } = mergePackages(host, config.packages ?? []);
|
|
34
|
+
const materialized = materializeLibrary(effective);
|
|
30
35
|
const report = {
|
|
31
36
|
errors: [],
|
|
32
37
|
warnings: [],
|
|
33
38
|
advisories: config.usage === null
|
|
34
39
|
? [{ kind: 'usage-not-configured', message: USAGE_NOT_CONFIGURED_MESSAGE }]
|
|
35
40
|
: [],
|
|
36
|
-
assetCount: Object.keys(
|
|
37
|
-
manifestCount: Object.keys(
|
|
41
|
+
assetCount: Object.keys(effective.assets).length,
|
|
42
|
+
manifestCount: Object.keys(effective.manifests).length
|
|
38
43
|
};
|
|
39
|
-
//
|
|
40
|
-
|
|
44
|
+
// Merge findings: collisions/type-mismatches are hard errors; an active
|
|
45
|
+
// override is an auditable, non-fatal advisory.
|
|
46
|
+
for (const finding of mergeFindings) {
|
|
47
|
+
if (finding.kind === 'package-overridden') {
|
|
48
|
+
report.advisories.push({
|
|
49
|
+
kind: 'package-overridden',
|
|
50
|
+
message: finding.message,
|
|
51
|
+
assetId: finding.assetId
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
report.errors.push({
|
|
56
|
+
kind: finding.kind,
|
|
57
|
+
message: finding.message,
|
|
58
|
+
assetId: finding.assetId
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 1. Library validation. Disk/host checks run on the host library; flat-space
|
|
63
|
+
// checks (id/type/parameters/membership/appearance/references + module
|
|
64
|
+
// collisions) run over the effective library.
|
|
65
|
+
const issues = [
|
|
66
|
+
...(await store.validate(host, { flatSpace: false })),
|
|
67
|
+
...flatLibraryIssues(effective, descriptorsByType(registry)),
|
|
68
|
+
...manifestModuleCollisionIssues(effective.manifests)
|
|
69
|
+
];
|
|
41
70
|
const validationKeys = new Set();
|
|
42
71
|
for (const issue of issues) {
|
|
43
72
|
const key = `${issue.assetId ?? ''}|${issue.message}`;
|
|
@@ -51,16 +80,24 @@ export async function runCheck(projectRoot, registry = serverPluginsByType) {
|
|
|
51
80
|
});
|
|
52
81
|
}
|
|
53
82
|
const descriptors = Object.values(registry).map((plugin) => plugin.descriptor);
|
|
54
|
-
const raw = await classifyRawDirectory(config.rawDir,
|
|
55
|
-
report.errors.push(...rawCheckFindings(
|
|
83
|
+
const raw = await classifyRawDirectory(config.rawDir, host, (path) => typesForFileName(path, descriptors).length > 0);
|
|
84
|
+
report.errors.push(...rawCheckFindings(host, raw, registry, issues));
|
|
85
|
+
// Delivered set + membership over the effective library, so delivered slots
|
|
86
|
+
// are analysed and cross-Package references resolve.
|
|
87
|
+
const referencesByAsset = collectAllReferences(effective, descriptorsByType(registry));
|
|
88
|
+
const membership = computeLibraryMembership(effective, referencesByAsset);
|
|
89
|
+
const delivered = allDeliveredAssetIds(membership);
|
|
90
|
+
report.errors.push(...packageSlotFindings(effective, provenance, membership));
|
|
56
91
|
// 2. Proxies: every delivered asset's expected proxy exists (staleness is a
|
|
57
|
-
// name check), and the proxy directory holds no orphans.
|
|
58
|
-
|
|
92
|
+
// name check), and the proxy directory holds no orphans. Raw-less delivered
|
|
93
|
+
// slots are covered by the slot findings above and skipped here.
|
|
59
94
|
const expectedProxyPaths = new Set();
|
|
60
95
|
const proxies = {};
|
|
61
96
|
let proxiesComplete = true;
|
|
62
97
|
for (const assetId of [...delivered].sort(compareCodeUnits)) {
|
|
63
|
-
const record =
|
|
98
|
+
const record = materialized.assets[assetId];
|
|
99
|
+
if (!record)
|
|
100
|
+
continue;
|
|
64
101
|
let proxy;
|
|
65
102
|
try {
|
|
66
103
|
proxy = await readCurrentProxy(assetId, record, config, registry);
|
|
@@ -108,12 +145,12 @@ export async function runCheck(projectRoot, registry = serverPluginsByType) {
|
|
|
108
145
|
// regeneration. Only meaningful when validation passed and every proxy
|
|
109
146
|
// exists — otherwise regeneration is impossible and already reported.
|
|
110
147
|
if (report.errors.length === 0 && proxiesComplete) {
|
|
111
|
-
await checkGeneratedModules(report,
|
|
112
|
-
await checkStrayModules(report,
|
|
148
|
+
await checkGeneratedModules(report, materialized, config, proxies, registry);
|
|
149
|
+
await checkStrayModules(report, materialized, config);
|
|
113
150
|
}
|
|
114
151
|
// 4. Advisory warnings. Raw drift is always a hard CI failure.
|
|
115
|
-
collectUnreachableAssets(report,
|
|
116
|
-
collectPotentialImageDuplicates(report, await new ImageDuplicateDetector().find(
|
|
152
|
+
collectUnreachableAssets(report, effective, provenance, delivered);
|
|
153
|
+
collectPotentialImageDuplicates(report, await new ImageDuplicateDetector().find(host, config.rawDir));
|
|
117
154
|
report.errors.sort((left, right) => compareCodeUnits(`${left.fileName ?? ''}|${left.assetId ?? ''}|${left.kind}|${left.message}`, `${right.fileName ?? ''}|${right.assetId ?? ''}|${right.kind}|${right.message}`));
|
|
118
155
|
report.warnings.sort((left, right) => compareCodeUnits(`${left.assetId ?? ''}|${left.kind}|${left.message}`, `${right.assetId ?? ''}|${right.kind}|${right.message}`));
|
|
119
156
|
return report;
|
|
@@ -254,15 +291,66 @@ async function checkStrayModules(report, library, config) {
|
|
|
254
291
|
* no explicit membership AND no passive membership in any manifest. An asset
|
|
255
292
|
* that is only passively delivered (referenced by a delivered asset) is fine.
|
|
256
293
|
*/
|
|
257
|
-
function collectUnreachableAssets(report, library, delivered) {
|
|
294
|
+
function collectUnreachableAssets(report, library, provenance, delivered) {
|
|
295
|
+
for (const [assetId, record] of Object.entries(library.assets)) {
|
|
296
|
+
if (record.manifests.length !== 0 || delivered.has(assetId))
|
|
297
|
+
continue;
|
|
298
|
+
// An inert, unfilled Package slot is not a host mistake — a Package ships
|
|
299
|
+
// a superset of slots and the app delivers a subset. Only host/override
|
|
300
|
+
// assets (and filled slots) warn.
|
|
301
|
+
if (record.raw === undefined && provenance[assetId]?.source === 'package')
|
|
302
|
+
continue;
|
|
303
|
+
report.warnings.push({
|
|
304
|
+
kind: 'unreachable-asset',
|
|
305
|
+
message: 'In no manifest and not referenced by any delivered asset — ' +
|
|
306
|
+
'nothing is processed or generated for it.',
|
|
307
|
+
assetId
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* The delivered-slot contract: a Package slot that is delivered (explicit member
|
|
313
|
+
* or in a delivered manifest's reference closure) but has no host-supplied bytes
|
|
314
|
+
* must be filled. A slot with an `importSource` is `slot-unmaterialized` (run
|
|
315
|
+
* import); a slot with nothing is `slot-unfilled`. Inert (undelivered) slots
|
|
316
|
+
* produce no finding.
|
|
317
|
+
*/
|
|
318
|
+
export function packageSlotFindings(library, provenance, membership) {
|
|
319
|
+
const deliveringManifests = new Map();
|
|
320
|
+
for (const [name, manifestMembership] of Object.entries(membership)) {
|
|
321
|
+
for (const assetId of manifestMembership.deliveredAssetIds) {
|
|
322
|
+
const names = deliveringManifests.get(assetId) ?? [];
|
|
323
|
+
names.push(name);
|
|
324
|
+
deliveringManifests.set(assetId, names);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const findings = [];
|
|
258
328
|
for (const [assetId, record] of Object.entries(library.assets)) {
|
|
259
|
-
if (record.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
329
|
+
if (record.raw !== undefined)
|
|
330
|
+
continue;
|
|
331
|
+
const names = deliveringManifests.get(assetId);
|
|
332
|
+
if (!names || names.length === 0)
|
|
333
|
+
continue;
|
|
334
|
+
const originRecord = provenance[assetId];
|
|
335
|
+
const origin = originRecord && originRecord.source !== 'host' ? originRecord.origin : 'a package';
|
|
336
|
+
const deliveredBy = [...names]
|
|
337
|
+
.sort(compareCodeUnits)
|
|
338
|
+
.map((name) => `"${name}"`)
|
|
339
|
+
.join(', ');
|
|
340
|
+
if (record.importSource !== undefined) {
|
|
341
|
+
findings.push({
|
|
342
|
+
kind: 'slot-unmaterialized',
|
|
343
|
+
assetId,
|
|
344
|
+
message: `Slot "${assetId}" (from ${origin}) has an import source but no bytes yet — run import to fill it. Delivered by: ${deliveredBy}.`
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
findings.push({
|
|
349
|
+
kind: 'slot-unfilled',
|
|
350
|
+
assetId,
|
|
351
|
+
message: `Slot "${assetId}" (from ${origin}) has no bytes, import source, or host override. Delivered by: ${deliveredBy}.`
|
|
265
352
|
});
|
|
266
353
|
}
|
|
267
354
|
}
|
|
355
|
+
return findings;
|
|
268
356
|
}
|
package/dist/server/codegen.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AssetRecord, type Library, type ManifestEntry, type ManifestEntryData, type ManifestMembership, type ReferencesByAsset } from '../core/index.js';
|
|
1
|
+
import { type AssetRecord, type Library, type ManifestEntry, type ManifestEntryData, type ManifestMembership, type ManifestName, type ManifestRecord, type ReferencesByAsset, type ValidationIssueDto } from '../core/index.js';
|
|
2
2
|
import type { SourceLocation } from '../core/index.js';
|
|
3
3
|
import type { ResolvedFundusConfig } from './config-loader.js';
|
|
4
4
|
import type { ServerPluginRegistry } from './plugins/contract.js';
|
|
@@ -10,6 +10,8 @@ export declare function locateGeneratedAssetDeclaration(file: string, source: st
|
|
|
10
10
|
export declare function kebabCaseFromCamel(name: string): string;
|
|
11
11
|
/** Generated module file name for a manifest. */
|
|
12
12
|
export declare function manifestModuleFileName(manifestName: string): string;
|
|
13
|
+
/** Two manifest names that would generate the same kebab-case module file. */
|
|
14
|
+
export declare function manifestModuleCollisionIssues(manifests: Record<ManifestName, ManifestRecord>): ValidationIssueDto[];
|
|
13
15
|
/**
|
|
14
16
|
* Build the entry data codegen emits for one asset — delegated to
|
|
15
17
|
* the owning server plugin's `buildManifestEntry`. Reference fields
|
package/dist/server/codegen.js
CHANGED
|
@@ -35,6 +35,24 @@ export function kebabCaseFromCamel(name) {
|
|
|
35
35
|
export function manifestModuleFileName(manifestName) {
|
|
36
36
|
return `${kebabCaseFromCamel(manifestName)}.generated.ts`;
|
|
37
37
|
}
|
|
38
|
+
/** Two manifest names that would generate the same kebab-case module file. */
|
|
39
|
+
export function manifestModuleCollisionIssues(manifests) {
|
|
40
|
+
const issues = [];
|
|
41
|
+
const namesByModuleFile = new Map();
|
|
42
|
+
for (const name of Object.keys(manifests)) {
|
|
43
|
+
const fileName = manifestModuleFileName(name);
|
|
44
|
+
const existingName = namesByModuleFile.get(fileName);
|
|
45
|
+
if (existingName !== undefined) {
|
|
46
|
+
issues.push({
|
|
47
|
+
message: `Manifests "${existingName}" and "${name}" would both generate "${fileName}".`
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
namesByModuleFile.set(fileName, name);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return issues;
|
|
55
|
+
}
|
|
38
56
|
/**
|
|
39
57
|
* Build the entry data codegen emits for one asset — delegated to
|
|
40
58
|
* the owning server plugin's `buildManifestEntry`. Reference fields
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AudioPreset, type FigmaImportScale, type ImagePreset, type PackageDeclaration, type ResolvedVideoPreset, type UsageConfig } from '../core/index.js';
|
|
2
2
|
import type { ServerPluginRegistry } from './plugins/contract.js';
|
|
3
3
|
export interface ResolvedPresetPluginConfig {
|
|
4
4
|
presets: Record<string, ImagePreset>;
|
|
@@ -13,6 +13,27 @@ export interface ResolvedVideoPluginConfig {
|
|
|
13
13
|
export interface ResolvedAudioPluginConfig {
|
|
14
14
|
presets: Record<string, AudioPreset>;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* A `packages` entry after pure normalization (no disk): its declared origin,
|
|
18
|
+
* whether it is a package name or a path, the resolved reference (absolute path
|
|
19
|
+
* for the path form; the bare name for the name form), and an optional raw-root
|
|
20
|
+
* override. Package files are read later, in `loadConfig`.
|
|
21
|
+
*/
|
|
22
|
+
export interface NormalizedPackageSource {
|
|
23
|
+
origin: string;
|
|
24
|
+
kind: 'name' | 'path';
|
|
25
|
+
reference: string;
|
|
26
|
+
rawDirOverride?: string;
|
|
27
|
+
}
|
|
28
|
+
/** A fully resolved Package: its parsed declaration plus provenance. */
|
|
29
|
+
export interface ResolvedPackage {
|
|
30
|
+
origin: string;
|
|
31
|
+
/** Absolute path of the resolved fundus.package.json. */
|
|
32
|
+
file: string;
|
|
33
|
+
/** Absolute raw root (recorded for provenance; unused in v1 slots-only). */
|
|
34
|
+
rawDir: string;
|
|
35
|
+
declaration: PackageDeclaration;
|
|
36
|
+
}
|
|
16
37
|
export interface ResolvedFundusConfig {
|
|
17
38
|
/** Absolute host project directory containing fundus.config.ts. */
|
|
18
39
|
projectRoot: string;
|
|
@@ -39,9 +60,22 @@ export interface ResolvedFundusConfig {
|
|
|
39
60
|
};
|
|
40
61
|
};
|
|
41
62
|
usage: UsageConfig | null;
|
|
63
|
+
/** Normalized `packages` entries (from the pure `resolveConfig`, no disk). */
|
|
64
|
+
packageSources: NormalizedPackageSource[];
|
|
65
|
+
/** Parsed Packages (filled by `loadConfig`; always [] from `resolveConfig`). */
|
|
66
|
+
packages: ResolvedPackage[];
|
|
42
67
|
}
|
|
43
68
|
export declare const USAGE_NOT_CONFIGURED_MESSAGE = "Usage analysis is not configured; add usage.referenceProvider and usage.openLocation to fundus.config.ts.";
|
|
44
69
|
/** Pure resolution step (testable without a config file on disk). */
|
|
45
70
|
export declare function resolveConfig(projectRoot: string, value: unknown, registry?: ServerPluginRegistry): ResolvedFundusConfig;
|
|
71
|
+
/**
|
|
72
|
+
* Read and parse every declared Package from disk. Name entries resolve through
|
|
73
|
+
* the host's module resolver (respecting `exports`), then walk up to the nearest
|
|
74
|
+
* `package.json` that declares the name and read its `"fundus"` field. Path
|
|
75
|
+
* entries point directly at a `fundus.package.json`. Throws a clear,
|
|
76
|
+
* origin-tagged error on any resolution/read/parse failure — Package assembly
|
|
77
|
+
* failures are symmetric with a missing `fundus.config.ts`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function loadPackages(projectRoot: string, sources: NormalizedPackageSource[]): Promise<ResolvedPackage[]>;
|
|
46
80
|
/** Load `fundus.config.ts` from the host project root. */
|
|
47
81
|
export declare function loadConfig(projectRoot: string): Promise<ResolvedFundusConfig>;
|
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
* the shape, resolves all paths to
|
|
4
4
|
* absolute, and merges the built-in plugin preset defaults under the host's.
|
|
5
5
|
*/
|
|
6
|
-
import { existsSync } from 'node:fs';
|
|
7
|
-
import {
|
|
6
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import { createRequire } from 'node:module';
|
|
9
|
+
import { dirname, isAbsolute, join, resolve } from 'node:path';
|
|
10
|
+
import { pathToFileURL } from 'node:url';
|
|
8
11
|
import { createJiti } from 'jiti';
|
|
12
|
+
import { parsePackageDeclaration, validatePackageDeclaration } from '../core/index.js';
|
|
9
13
|
import { serverPluginsByType } from './plugins.js';
|
|
10
14
|
import { isRecord } from './plugins/config.js';
|
|
11
15
|
export const USAGE_NOT_CONFIGURED_MESSAGE = 'Usage analysis is not configured; add usage.referenceProvider and usage.openLocation to fundus.config.ts.';
|
|
@@ -32,6 +36,88 @@ function configDefinitionsFor(registry) {
|
|
|
32
36
|
}
|
|
33
37
|
return [...byNamespace.values()];
|
|
34
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* A string `packages` entry is a *path* when it looks like one (starts with
|
|
41
|
+
* `.`/`/`, is absolute, or ends `.json`), or a bare relative path with a
|
|
42
|
+
* separator; otherwise it is a package *name*. A scoped name (`@scope/pkg`)
|
|
43
|
+
* contains a `/` but is a name.
|
|
44
|
+
*/
|
|
45
|
+
function classifyPackageSpec(spec) {
|
|
46
|
+
if (spec.startsWith('.') || spec.startsWith('/') || isAbsolute(spec))
|
|
47
|
+
return 'path';
|
|
48
|
+
if (DECLARATION_FILE_RE.test(spec))
|
|
49
|
+
return 'path';
|
|
50
|
+
if (spec.startsWith('@'))
|
|
51
|
+
return 'name';
|
|
52
|
+
if (spec.includes('/') || spec.includes('\\'))
|
|
53
|
+
return 'path';
|
|
54
|
+
return 'name';
|
|
55
|
+
}
|
|
56
|
+
/** A declaration file is JSON or a JS/TS module (the latter loaded via jiti). */
|
|
57
|
+
const DECLARATION_FILE_RE = /\.(json|[mc]?[jt]s)$/;
|
|
58
|
+
/**
|
|
59
|
+
* Read a package declaration from its resolved file: a JSON `fundus.package.json`
|
|
60
|
+
* (parsed as text) or a JS/TS module (`fundus.package.ts`) whose default export is
|
|
61
|
+
* the declaration — loaded through the same jiti path as `fundus.config.ts`, which
|
|
62
|
+
* keeps the resource `type`s literal for the package's `PackageAssets<…>` derivation.
|
|
63
|
+
*/
|
|
64
|
+
async function loadPackageDeclaration(file, origin) {
|
|
65
|
+
if (/\.[mc]?[jt]s$/.test(file)) {
|
|
66
|
+
let module;
|
|
67
|
+
try {
|
|
68
|
+
const jiti = createJiti(import.meta.url, { interopDefault: false });
|
|
69
|
+
module = await jiti.import(file);
|
|
70
|
+
}
|
|
71
|
+
catch (cause) {
|
|
72
|
+
throw new Error(`Cannot load fundus package "${origin}" (${file}): ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
73
|
+
}
|
|
74
|
+
const value = isRecord(module) && 'default' in module ? module.default : module;
|
|
75
|
+
return validatePackageDeclaration(value, origin);
|
|
76
|
+
}
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = await readFile(file, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
catch (cause) {
|
|
82
|
+
throw new Error(`Cannot read fundus package "${origin}" (${file}): ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
83
|
+
}
|
|
84
|
+
return parsePackageDeclaration(text, origin);
|
|
85
|
+
}
|
|
86
|
+
function normalizePackageSource(projectRoot, entry) {
|
|
87
|
+
let spec;
|
|
88
|
+
let rawDirOverride;
|
|
89
|
+
if (typeof entry === 'string') {
|
|
90
|
+
spec = entry;
|
|
91
|
+
}
|
|
92
|
+
else if (isRecord(entry) && typeof entry.package === 'string' && entry.package.length > 0) {
|
|
93
|
+
spec = entry.package;
|
|
94
|
+
if (entry.rawDir !== undefined) {
|
|
95
|
+
if (typeof entry.rawDir !== 'string' || entry.rawDir.length === 0) {
|
|
96
|
+
throw new Error('fundus.config: a "packages" entry "rawDir" must be a non-empty string.');
|
|
97
|
+
}
|
|
98
|
+
rawDirOverride = entry.rawDir;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
throw new Error('fundus.config: each "packages" entry must be a package name, a path string, or { package: string; rawDir?: string }.');
|
|
103
|
+
}
|
|
104
|
+
const kind = classifyPackageSpec(spec);
|
|
105
|
+
const reference = kind === 'path' ? resolve(projectRoot, spec) : spec;
|
|
106
|
+
return {
|
|
107
|
+
origin: spec,
|
|
108
|
+
kind,
|
|
109
|
+
reference,
|
|
110
|
+
...(rawDirOverride !== undefined ? { rawDirOverride } : {})
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function resolvePackageSources(projectRoot, value) {
|
|
114
|
+
if (value === undefined)
|
|
115
|
+
return [];
|
|
116
|
+
if (!Array.isArray(value)) {
|
|
117
|
+
throw new Error('fundus.config: "packages" must be an array.');
|
|
118
|
+
}
|
|
119
|
+
return value.map((entry) => normalizePackageSource(projectRoot, entry));
|
|
120
|
+
}
|
|
35
121
|
/** Pure resolution step (testable without a config file on disk). */
|
|
36
122
|
export function resolveConfig(projectRoot, value, registry = serverPluginsByType) {
|
|
37
123
|
if (!isRecord(value)) {
|
|
@@ -95,9 +181,103 @@ export function resolveConfig(projectRoot, value, registry = serverPluginsByType
|
|
|
95
181
|
defaults: { scale }
|
|
96
182
|
}
|
|
97
183
|
},
|
|
98
|
-
usage: usage === undefined ? null : usage
|
|
184
|
+
usage: usage === undefined ? null : usage,
|
|
185
|
+
packageSources: resolvePackageSources(projectRoot, value.packages),
|
|
186
|
+
packages: []
|
|
99
187
|
};
|
|
100
188
|
}
|
|
189
|
+
function nearestNamedPackageJson(entryPath, name) {
|
|
190
|
+
let dir = dirname(entryPath);
|
|
191
|
+
for (;;) {
|
|
192
|
+
const candidate = join(dir, 'package.json');
|
|
193
|
+
if (existsSync(candidate)) {
|
|
194
|
+
try {
|
|
195
|
+
const pkg = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
196
|
+
if (isRecord(pkg) && pkg.name === name)
|
|
197
|
+
return { dir, pkg };
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Malformed package.json — keep walking up.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const parent = dirname(dir);
|
|
204
|
+
if (parent === dir)
|
|
205
|
+
break;
|
|
206
|
+
dir = parent;
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`Cannot find the package.json for fundus package "${name}" (resolved to ${entryPath}).`);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Resolve a name-form Package to its root directory + parsed `package.json`. A
|
|
212
|
+
* declaration-only Package ships no JS entry module, so resolving the bare name
|
|
213
|
+
* would throw `MODULE_NOT_FOUND`; resolve its `package.json` subpath first and
|
|
214
|
+
* only fall back to entry resolution when an `exports` map hides it.
|
|
215
|
+
*/
|
|
216
|
+
function resolvePackageRoot(require, reference, origin) {
|
|
217
|
+
try {
|
|
218
|
+
const manifestPath = require.resolve(`${reference}/package.json`);
|
|
219
|
+
const pkg = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
220
|
+
if (isRecord(pkg))
|
|
221
|
+
return { dir: dirname(manifestPath), pkg };
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// No resolvable ./package.json subpath — fall back to the entry module.
|
|
225
|
+
}
|
|
226
|
+
let entry;
|
|
227
|
+
try {
|
|
228
|
+
entry = require.resolve(reference);
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
throw new Error(`Cannot resolve fundus package "${origin}": no installed package declares it — is it a dependency?`);
|
|
232
|
+
}
|
|
233
|
+
return nearestNamedPackageJson(entry, reference);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Read and parse every declared Package from disk. Name entries resolve through
|
|
237
|
+
* the host's module resolver (respecting `exports`), then walk up to the nearest
|
|
238
|
+
* `package.json` that declares the name and read its `"fundus"` field. Path
|
|
239
|
+
* entries point directly at a `fundus.package.json`. Throws a clear,
|
|
240
|
+
* origin-tagged error on any resolution/read/parse failure — Package assembly
|
|
241
|
+
* failures are symmetric with a missing `fundus.config.ts`.
|
|
242
|
+
*/
|
|
243
|
+
export async function loadPackages(projectRoot, sources) {
|
|
244
|
+
const require = createRequire(pathToFileURL(join(projectRoot, 'fundus.config.ts')).href);
|
|
245
|
+
const packages = [];
|
|
246
|
+
for (const source of sources) {
|
|
247
|
+
let file;
|
|
248
|
+
let defaultRawDir;
|
|
249
|
+
if (source.kind === 'path') {
|
|
250
|
+
file = source.reference;
|
|
251
|
+
if (!existsSync(file)) {
|
|
252
|
+
throw new Error(`Fundus package file not found: ${file} (from "${source.origin}").`);
|
|
253
|
+
}
|
|
254
|
+
defaultRawDir = dirname(file);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
const { dir, pkg } = resolvePackageRoot(require, source.reference, source.origin);
|
|
258
|
+
const fundusField = pkg.fundus;
|
|
259
|
+
if (!isRecord(fundusField) ||
|
|
260
|
+
typeof fundusField.package !== 'string' ||
|
|
261
|
+
fundusField.package.length === 0) {
|
|
262
|
+
throw new Error(`Fundus package "${source.origin}" is missing a "fundus.package" field in its package.json.`);
|
|
263
|
+
}
|
|
264
|
+
file = resolve(dir, fundusField.package);
|
|
265
|
+
if (!existsSync(file)) {
|
|
266
|
+
throw new Error(`Fundus package "${source.origin}" declaration not found: ${file}.`);
|
|
267
|
+
}
|
|
268
|
+
defaultRawDir =
|
|
269
|
+
typeof fundusField.rawDir === 'string' && fundusField.rawDir.length > 0
|
|
270
|
+
? resolve(dir, fundusField.rawDir)
|
|
271
|
+
: dir;
|
|
272
|
+
}
|
|
273
|
+
const declaration = await loadPackageDeclaration(file, source.origin);
|
|
274
|
+
const rawDir = source.rawDirOverride !== undefined
|
|
275
|
+
? resolve(projectRoot, source.rawDirOverride)
|
|
276
|
+
: defaultRawDir;
|
|
277
|
+
packages.push({ origin: source.origin, file, rawDir, declaration });
|
|
278
|
+
}
|
|
279
|
+
return packages;
|
|
280
|
+
}
|
|
101
281
|
/** Load `fundus.config.ts` from the host project root. */
|
|
102
282
|
export async function loadConfig(projectRoot) {
|
|
103
283
|
const root = resolve(projectRoot);
|
|
@@ -113,5 +293,6 @@ export async function loadConfig(projectRoot) {
|
|
|
113
293
|
catch (cause) {
|
|
114
294
|
throw new Error(`Cannot load fundus.config.ts: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
115
295
|
}
|
|
116
|
-
|
|
296
|
+
const config = resolveConfig(root, isRecord(module) && 'default' in module ? module.default : module);
|
|
297
|
+
return { ...config, packages: await loadPackages(root, config.packageSources) };
|
|
117
298
|
}
|
|
@@ -26,6 +26,14 @@ export interface IngestOptions {
|
|
|
26
26
|
export interface CreateAssetOptions extends IngestOptions {
|
|
27
27
|
manifests?: string[];
|
|
28
28
|
importSource?: ImportSourceRecord;
|
|
29
|
+
/**
|
|
30
|
+
* Fill/override a Package slot: store these parameters verbatim as a host
|
|
31
|
+
* override record instead of expanding plugin defaults. Partial by design
|
|
32
|
+
* (only the overridden keys) — the merge deep-merges them over the Package
|
|
33
|
+
* base, and they are schema-validated over the effective library, not here.
|
|
34
|
+
* When set, `prepareParameters` is ignored.
|
|
35
|
+
*/
|
|
36
|
+
parametersOverride?: unknown;
|
|
29
37
|
}
|
|
30
38
|
export interface CreateAssetStaging {
|
|
31
39
|
rawPath: string;
|
|
@@ -124,6 +132,8 @@ export declare class LibraryStore {
|
|
|
124
132
|
* type, dangling raw pointer, invalid parameters, unknown manifest names,
|
|
125
133
|
* and reference errors (dangling target, type mismatch, cycles).
|
|
126
134
|
*/
|
|
127
|
-
validate(library: Library
|
|
135
|
+
validate(library: Library, options?: {
|
|
136
|
+
flatSpace?: boolean;
|
|
137
|
+
}): Promise<ValidationIssueDto[]>;
|
|
128
138
|
syncFolders(library: Library): Promise<void>;
|
|
129
139
|
}
|