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
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flat-space (id-space) library validation — the checks that must run over the
|
|
3
|
+
* *effective* (merged) library, because a host override record stores partial
|
|
4
|
+
* parameters that only validate once merged under its Package base, and a
|
|
5
|
+
* reference may cross the host/Package boundary. Pure and disk-free: id
|
|
6
|
+
* validity, unknown type, plugin parameter schema, manifest membership, manifest
|
|
7
|
+
* appearance tags, and reference errors. Disk/host-only checks (raw pointers,
|
|
8
|
+
* folders, `.gitkeep`) stay in `LibraryStore.validate`.
|
|
9
|
+
*/
|
|
10
|
+
import type { EffectiveLibrary } from './library.js';
|
|
11
|
+
import type { ValidationIssueDto } from './api-types.js';
|
|
12
|
+
import { type PluginDescriptorRegistry } from './reference-graph.js';
|
|
13
|
+
export declare function flatLibraryIssues(library: EffectiveLibrary, plugins: PluginDescriptorRegistry): ValidationIssueDto[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assetIdError, manifestNameError } from './asset-id.js';
|
|
2
|
+
import { manifestColorError, manifestEmojiError } from './manifest-appearance.js';
|
|
3
|
+
import { collectAllReferences, referenceErrors } from './reference-graph.js';
|
|
4
|
+
export function flatLibraryIssues(library, plugins) {
|
|
5
|
+
const issues = [];
|
|
6
|
+
for (const [name, record] of Object.entries(library.manifests)) {
|
|
7
|
+
const nameProblem = manifestNameError(name);
|
|
8
|
+
if (nameProblem)
|
|
9
|
+
issues.push({ message: nameProblem });
|
|
10
|
+
if (record.color !== undefined) {
|
|
11
|
+
const colorProblem = manifestColorError(record.color);
|
|
12
|
+
if (colorProblem)
|
|
13
|
+
issues.push({ message: `Manifest "${name}": ${colorProblem}` });
|
|
14
|
+
}
|
|
15
|
+
if (record.emoji !== undefined) {
|
|
16
|
+
const emojiProblem = manifestEmojiError(record.emoji);
|
|
17
|
+
if (emojiProblem)
|
|
18
|
+
issues.push({ message: `Manifest "${name}": ${emojiProblem}` });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
for (const [assetId, record] of Object.entries(library.assets)) {
|
|
22
|
+
const idProblem = assetIdError(assetId);
|
|
23
|
+
if (idProblem)
|
|
24
|
+
issues.push({ assetId, message: idProblem });
|
|
25
|
+
const plugin = plugins[record.type];
|
|
26
|
+
if (!plugin) {
|
|
27
|
+
issues.push({ assetId, message: `Unknown asset type "${record.type}".` });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
try {
|
|
31
|
+
plugin.validateParameters(record.parameters);
|
|
32
|
+
}
|
|
33
|
+
catch (cause) {
|
|
34
|
+
issues.push({
|
|
35
|
+
assetId,
|
|
36
|
+
message: `Invalid parameters: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const manifest of record.manifests) {
|
|
41
|
+
if (!library.manifests[manifest]) {
|
|
42
|
+
issues.push({ assetId, message: `Unknown manifest "${manifest}".` });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
issues.push(...referenceErrors(library, collectAllReferences(library, plugins)));
|
|
47
|
+
return issues;
|
|
48
|
+
}
|
package/dist/core/library.d.ts
CHANGED
|
@@ -45,8 +45,27 @@ export interface Library {
|
|
|
45
45
|
assets: Record<AssetId, AssetRecord>;
|
|
46
46
|
manifests: Record<ManifestName, ManifestRecord>;
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* An asset record in the merged *effective* library, where `raw`/`rawHash` may
|
|
50
|
+
* be absent — an unfilled Package **slot**. Every `Library` record is a valid
|
|
51
|
+
* `EffectiveAssetRecord` (required fields satisfy optional ones), so single-root
|
|
52
|
+
* callers are unaffected. The effective library lives in memory only and is
|
|
53
|
+
* never serialized (a host `Library` always carries `raw`/`rawHash`).
|
|
54
|
+
*/
|
|
55
|
+
export interface EffectiveAssetRecord extends Omit<AssetRecord, 'raw' | 'rawHash'> {
|
|
56
|
+
raw?: string;
|
|
57
|
+
rawHash?: string;
|
|
58
|
+
}
|
|
59
|
+
/** The host library with all Packages merged under it (host wins). In-memory only. */
|
|
60
|
+
export interface EffectiveLibrary extends Omit<Library, 'assets'> {
|
|
61
|
+
assets: Record<AssetId, EffectiveAssetRecord>;
|
|
62
|
+
}
|
|
48
63
|
/** A fresh, empty library. */
|
|
49
64
|
export declare function createEmptyLibrary(): Library;
|
|
65
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
66
|
+
export declare function assertSafeKey(kind: 'asset' | 'manifest', key: string): void;
|
|
67
|
+
export declare function parseImportSource(id: string, value: unknown): ImportSourceRecord;
|
|
68
|
+
export declare function parseManifestRecord(name: string, value: Record<string, unknown>): ManifestRecord;
|
|
50
69
|
/**
|
|
51
70
|
* Parse and structurally validate a library file's JSON text. Throws with a
|
|
52
71
|
* clear message on any malformed part; plugin parameter validation is a
|
package/dist/core/library.js
CHANGED
|
@@ -3,7 +3,7 @@ import { folderPathError } from './folder-path.js';
|
|
|
3
3
|
export function createEmptyLibrary() {
|
|
4
4
|
return { version: 1, folders: [], assets: {}, manifests: {} };
|
|
5
5
|
}
|
|
6
|
-
function isRecord(value) {
|
|
6
|
+
export function isRecord(value) {
|
|
7
7
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
8
|
}
|
|
9
9
|
/**
|
|
@@ -13,12 +13,12 @@ function isRecord(value) {
|
|
|
13
13
|
* this is a validator concern (reported as issues, not parse failures).
|
|
14
14
|
*/
|
|
15
15
|
const DANGEROUS_KEYS = ['__proto__', 'constructor', 'prototype'];
|
|
16
|
-
function assertSafeKey(kind, key) {
|
|
16
|
+
export function assertSafeKey(kind, key) {
|
|
17
17
|
if (DANGEROUS_KEYS.includes(key)) {
|
|
18
18
|
throw new Error(`Library ${kind} key "${key}" is not allowed.`);
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
function parseImportSource(id, value) {
|
|
21
|
+
export function parseImportSource(id, value) {
|
|
22
22
|
if (!isRecord(value)) {
|
|
23
23
|
throw new Error(`Library asset "${id}" has a non-object "importSource".`);
|
|
24
24
|
}
|
|
@@ -64,7 +64,7 @@ function parseAssetRecord(id, value, version) {
|
|
|
64
64
|
record.importSource = parseImportSource(id, value.importSource);
|
|
65
65
|
return record;
|
|
66
66
|
}
|
|
67
|
-
function parseManifestRecord(name, value) {
|
|
67
|
+
export function parseManifestRecord(name, value) {
|
|
68
68
|
const record = {};
|
|
69
69
|
if ('color' in value && value.color !== undefined) {
|
|
70
70
|
if (typeof value.color !== 'string') {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* picture is computed; server processing, codegen, delivered-size accounting,
|
|
7
7
|
* and the editor state payload all consume it — no parallel closure walks.
|
|
8
8
|
*/
|
|
9
|
-
import type { AssetId,
|
|
9
|
+
import type { AssetId, EffectiveLibrary, ManifestName } from './library.js';
|
|
10
10
|
import { type ReferencesByAsset } from './reference-graph.js';
|
|
11
11
|
/** One derived passive membership, with the attribution that explains it. */
|
|
12
12
|
export interface PassiveMember {
|
|
@@ -47,7 +47,7 @@ export type LibraryMembership = Record<ManifestName, ManifestMembership>;
|
|
|
47
47
|
* (`referenceClosure(explicit) − explicit`) with their via-attribution, and
|
|
48
48
|
* the resulting delivery set.
|
|
49
49
|
*/
|
|
50
|
-
export declare function computeLibraryMembership(library:
|
|
50
|
+
export declare function computeLibraryMembership(library: EffectiveLibrary, referencesByAsset: ReferencesByAsset): LibraryMembership;
|
|
51
51
|
/**
|
|
52
52
|
* Every asset delivered by at least one manifest, explicitly or passively —
|
|
53
53
|
* the processing set (assets outside it are inert). An asset is
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ImportSourceRecord, type ManifestName, type ManifestRecord, type AssetId } from './library.js';
|
|
2
|
+
/**
|
|
3
|
+
* A `fundus.package.json` — a Package's declaration file. Same structural model
|
|
4
|
+
* as a host `Library`, with two relaxations: assets are byte-less **slots**
|
|
5
|
+
* (no `raw`/`rawHash`) that carry an optional `importSource`, and `folders` are
|
|
6
|
+
* ignored (folder organisation is a host-editor concern). A declaration is
|
|
7
|
+
* read-only input — Fundus never writes to it; overriding a Package asset writes
|
|
8
|
+
* an override record into the *host* library.
|
|
9
|
+
*
|
|
10
|
+
* The declaration `version` is the declaration schema version, independent of a
|
|
11
|
+
* host `Library.version` (which gates `importSource` on v2). A Package always
|
|
12
|
+
* declares its `importSource` slots without that gate.
|
|
13
|
+
*/
|
|
14
|
+
export interface PackageAssetDeclaration {
|
|
15
|
+
/** Asset type — which plugin owns this asset ('image' | 'slice' | …). */
|
|
16
|
+
type: string;
|
|
17
|
+
/** Plugin-owned parameter blob. Validated later, over the merged library. */
|
|
18
|
+
parameters: unknown;
|
|
19
|
+
/** Manifest membership. */
|
|
20
|
+
manifests: ManifestName[];
|
|
21
|
+
/** Optional repeatable origin the host (or a slot fill) can materialize. */
|
|
22
|
+
importSource?: ImportSourceRecord;
|
|
23
|
+
}
|
|
24
|
+
export interface PackageDeclaration {
|
|
25
|
+
/** Declaration schema version — currently always 1. */
|
|
26
|
+
version: 1;
|
|
27
|
+
assets: Record<AssetId, PackageAssetDeclaration>;
|
|
28
|
+
manifests: Record<ManifestName, ManifestRecord>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse and structurally validate a `fundus.package.json` (JSON text). Delegates
|
|
32
|
+
* to {@link validatePackageDeclaration} after `JSON.parse`.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parsePackageDeclaration(json: string, origin: string): PackageDeclaration;
|
|
35
|
+
/**
|
|
36
|
+
* Structurally validate an already-parsed package declaration — the shared core of
|
|
37
|
+
* both the JSON path ({@link parsePackageDeclaration}) and the TypeScript-module path
|
|
38
|
+
* (a `fundus.package.ts` default export loaded via jiti). Throws with a clear,
|
|
39
|
+
* origin-tagged message on any malformed part. Plugin parameter validation and
|
|
40
|
+
* id/manifest-name validity are separate steps that run over the merged
|
|
41
|
+
* (effective) library, not here — mirroring `parseLibrary`. `version` defaults to 1.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validatePackageDeclaration(value: unknown, origin: string): PackageDeclaration;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { assertSafeKey, isRecord, parseImportSource, parseManifestRecord } from './library.js';
|
|
2
|
+
function parsePackageAsset(origin, id, value) {
|
|
3
|
+
if (!isRecord(value)) {
|
|
4
|
+
throw new Error(`Package "${origin}" asset "${id}" must be an object.`);
|
|
5
|
+
}
|
|
6
|
+
if (typeof value.type !== 'string' || value.type.length === 0) {
|
|
7
|
+
throw new Error(`Package "${origin}" asset "${id}" is missing a string "type".`);
|
|
8
|
+
}
|
|
9
|
+
if ('raw' in value || 'rawHash' in value) {
|
|
10
|
+
throw new Error(`Package "${origin}" asset "${id}" declares "raw"/"rawHash"; Packages ship byte-less slots only.`);
|
|
11
|
+
}
|
|
12
|
+
if (!Array.isArray(value.manifests) ||
|
|
13
|
+
value.manifests.some((entry) => typeof entry !== 'string')) {
|
|
14
|
+
throw new Error(`Package "${origin}" asset "${id}" must have a "manifests" array of strings.`);
|
|
15
|
+
}
|
|
16
|
+
// `parameters` is optional in the authored declaration — a resource is often just
|
|
17
|
+
// `{ type, manifests }`, a pure contract. Default to `{}`; the app's slot fill (and the
|
|
18
|
+
// merge over the effective library) supplies the real plugin parameters.
|
|
19
|
+
const record = {
|
|
20
|
+
type: value.type,
|
|
21
|
+
parameters: 'parameters' in value ? value.parameters : {},
|
|
22
|
+
manifests: value.manifests
|
|
23
|
+
};
|
|
24
|
+
if (value.importSource !== undefined) {
|
|
25
|
+
record.importSource = parseImportSource(id, value.importSource);
|
|
26
|
+
}
|
|
27
|
+
return record;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse and structurally validate a `fundus.package.json` (JSON text). Delegates
|
|
31
|
+
* to {@link validatePackageDeclaration} after `JSON.parse`.
|
|
32
|
+
*/
|
|
33
|
+
export function parsePackageDeclaration(json, origin) {
|
|
34
|
+
let value;
|
|
35
|
+
try {
|
|
36
|
+
value = JSON.parse(json);
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
throw new Error(`Package "${origin}" declaration is not valid JSON: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
40
|
+
}
|
|
41
|
+
return validatePackageDeclaration(value, origin);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Structurally validate an already-parsed package declaration — the shared core of
|
|
45
|
+
* both the JSON path ({@link parsePackageDeclaration}) and the TypeScript-module path
|
|
46
|
+
* (a `fundus.package.ts` default export loaded via jiti). Throws with a clear,
|
|
47
|
+
* origin-tagged message on any malformed part. Plugin parameter validation and
|
|
48
|
+
* id/manifest-name validity are separate steps that run over the merged
|
|
49
|
+
* (effective) library, not here — mirroring `parseLibrary`. `version` defaults to 1.
|
|
50
|
+
*/
|
|
51
|
+
export function validatePackageDeclaration(value, origin) {
|
|
52
|
+
if (!isRecord(value)) {
|
|
53
|
+
throw new Error(`Package "${origin}" declaration must be an object.`);
|
|
54
|
+
}
|
|
55
|
+
if (value.version !== undefined && value.version !== 1) {
|
|
56
|
+
throw new Error(`Package "${origin}" declaration has unsupported version ${JSON.stringify(value.version)} (expected 1).`);
|
|
57
|
+
}
|
|
58
|
+
if (!isRecord(value.assets)) {
|
|
59
|
+
throw new Error(`Package "${origin}" declaration "assets" must be an object.`);
|
|
60
|
+
}
|
|
61
|
+
if (value.manifests !== undefined && !isRecord(value.manifests)) {
|
|
62
|
+
throw new Error(`Package "${origin}" declaration "manifests" must be an object.`);
|
|
63
|
+
}
|
|
64
|
+
const assets = {};
|
|
65
|
+
for (const [id, record] of Object.entries(value.assets)) {
|
|
66
|
+
assertSafeKey('asset', id);
|
|
67
|
+
assets[id] = parsePackageAsset(origin, id, record);
|
|
68
|
+
}
|
|
69
|
+
const manifests = {};
|
|
70
|
+
if (isRecord(value.manifests)) {
|
|
71
|
+
for (const [name, record] of Object.entries(value.manifests)) {
|
|
72
|
+
assertSafeKey('manifest', name);
|
|
73
|
+
if (!isRecord(record)) {
|
|
74
|
+
throw new Error(`Package "${origin}" manifest "${name}" must be an object.`);
|
|
75
|
+
}
|
|
76
|
+
manifests[name] = parseManifestRecord(name, record);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { version: 1, assets, manifests };
|
|
80
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type AssetId, type EffectiveLibrary, type Library, type ManifestName, type ManifestRecord } from './library.js';
|
|
2
|
+
import type { PackageAssetDeclaration } from './package-declaration.js';
|
|
3
|
+
/** A parsed Package ready to merge: its declaration plus a provenance origin. */
|
|
4
|
+
export interface ParsedPackage {
|
|
5
|
+
origin: string;
|
|
6
|
+
declaration: {
|
|
7
|
+
assets: Record<AssetId, PackageAssetDeclaration>;
|
|
8
|
+
manifests: Record<ManifestName, ManifestRecord>;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Where an effective asset came from — for `check` messages and the editor. */
|
|
12
|
+
export type AssetProvenance = {
|
|
13
|
+
source: 'host';
|
|
14
|
+
} | {
|
|
15
|
+
source: 'package';
|
|
16
|
+
origin: string;
|
|
17
|
+
} | {
|
|
18
|
+
source: 'override';
|
|
19
|
+
origin: string;
|
|
20
|
+
};
|
|
21
|
+
export type MergeProvenance = Record<AssetId, AssetProvenance>;
|
|
22
|
+
/** A merge-time finding. Conflicts/mismatches are errors; overrides are advisory. */
|
|
23
|
+
export type MergeFinding = {
|
|
24
|
+
kind: 'package-conflict';
|
|
25
|
+
assetId: string;
|
|
26
|
+
origins: [string, string];
|
|
27
|
+
message: string;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'package-type-mismatch';
|
|
30
|
+
assetId: string;
|
|
31
|
+
origin: string;
|
|
32
|
+
message: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'package-overridden';
|
|
35
|
+
assetId: string;
|
|
36
|
+
origin: string;
|
|
37
|
+
message: string;
|
|
38
|
+
};
|
|
39
|
+
export interface MergeResult {
|
|
40
|
+
library: EffectiveLibrary;
|
|
41
|
+
provenance: MergeProvenance;
|
|
42
|
+
findings: MergeFinding[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Deep-merge plugin `parameters` — overlay (host) wins. Recurses into plain
|
|
46
|
+
* objects only; arrays are replaced wholesale (host-replace) and `{ $asset }`
|
|
47
|
+
* reference markers are treated as atomic (never merged field-by-field). Applied
|
|
48
|
+
* to `parameters` only — the record-level `manifests` array is unioned by the
|
|
49
|
+
* caller, never routed through here.
|
|
50
|
+
*/
|
|
51
|
+
export declare function deepMergeParameters(base: unknown, overlay: unknown): unknown;
|
|
52
|
+
/**
|
|
53
|
+
* Merge `packages` under `host` (host wins, per-field deep). Returns the merged
|
|
54
|
+
* effective library, per-asset provenance, and merge findings. `host` is an
|
|
55
|
+
* `EffectiveLibrary` so a raw-less host override branch stays reachable/testable
|
|
56
|
+
* and v2-ready; a plain `Library` is assignable.
|
|
57
|
+
*/
|
|
58
|
+
export declare function mergePackages(host: EffectiveLibrary, packages: ParsedPackage[]): MergeResult;
|
|
59
|
+
/**
|
|
60
|
+
* Drop raw-less (unfilled) slots from an effective library, yielding a plain
|
|
61
|
+
* `Library` for processing/codegen. Safe only after the slot/validation gates
|
|
62
|
+
* pass — every remaining delivered asset then has `raw`; dropped slots are
|
|
63
|
+
* provably inert (not delivered).
|
|
64
|
+
*/
|
|
65
|
+
export declare function materializeLibrary(effective: EffectiveLibrary): Library;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure Package merge: fold package-shipped partial libraries **under** the
|
|
3
|
+
* host library into one in-memory *effective* library. Host wins per-field
|
|
4
|
+
* (deep). No disk, no config — testable like `resolveConfig`. The effective
|
|
5
|
+
* library is never serialized (a host `Library` always carries `raw`/`rawHash`);
|
|
6
|
+
* `materializeLibrary` drops raw-less inert slots to hand a plain `Library` to
|
|
7
|
+
* processing/codegen once the slot/validation gates have passed.
|
|
8
|
+
*/
|
|
9
|
+
import { isAssetReference } from './asset-reference.js';
|
|
10
|
+
import { compareCodeUnits } from './canonicalize.js';
|
|
11
|
+
import { isRecord } from './library.js';
|
|
12
|
+
function sortDedupManifests(names) {
|
|
13
|
+
return [...new Set(names)].sort(compareCodeUnits);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Deep-merge plugin `parameters` — overlay (host) wins. Recurses into plain
|
|
17
|
+
* objects only; arrays are replaced wholesale (host-replace) and `{ $asset }`
|
|
18
|
+
* reference markers are treated as atomic (never merged field-by-field). Applied
|
|
19
|
+
* to `parameters` only — the record-level `manifests` array is unioned by the
|
|
20
|
+
* caller, never routed through here.
|
|
21
|
+
*/
|
|
22
|
+
export function deepMergeParameters(base, overlay) {
|
|
23
|
+
if (isRecord(base) &&
|
|
24
|
+
isRecord(overlay) &&
|
|
25
|
+
!isAssetReference(base) &&
|
|
26
|
+
!isAssetReference(overlay)) {
|
|
27
|
+
const result = { ...base };
|
|
28
|
+
for (const [key, value] of Object.entries(overlay)) {
|
|
29
|
+
result[key] = key in base ? deepMergeParameters(base[key], value) : value;
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
return overlay;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Merge `packages` under `host` (host wins, per-field deep). Returns the merged
|
|
37
|
+
* effective library, per-asset provenance, and merge findings. `host` is an
|
|
38
|
+
* `EffectiveLibrary` so a raw-less host override branch stays reachable/testable
|
|
39
|
+
* and v2-ready; a plain `Library` is assignable.
|
|
40
|
+
*/
|
|
41
|
+
export function mergePackages(host, packages) {
|
|
42
|
+
const findings = [];
|
|
43
|
+
// Layer packages in declared order. First declaration of an id/manifest wins;
|
|
44
|
+
// a second package claiming an id is an (ambiguous-by-construction) error.
|
|
45
|
+
const pkgAssets = new Map();
|
|
46
|
+
const pkgManifests = new Map();
|
|
47
|
+
for (const { origin, declaration } of packages) {
|
|
48
|
+
for (const [id, decl] of Object.entries(declaration.assets)) {
|
|
49
|
+
const existing = pkgAssets.get(id);
|
|
50
|
+
if (existing) {
|
|
51
|
+
findings.push({
|
|
52
|
+
kind: 'package-conflict',
|
|
53
|
+
assetId: id,
|
|
54
|
+
origins: [existing.origin, origin],
|
|
55
|
+
message: `Asset "${id}" is declared by two Packages ("${existing.origin}" and "${origin}"); Package ids must be unique.`
|
|
56
|
+
});
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
pkgAssets.set(id, { origin, decl });
|
|
60
|
+
}
|
|
61
|
+
for (const [name, record] of Object.entries(declaration.manifests)) {
|
|
62
|
+
if (!pkgManifests.has(name))
|
|
63
|
+
pkgManifests.set(name, record);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const assets = {};
|
|
67
|
+
const provenance = {};
|
|
68
|
+
// Host assets: host-only pass through; host-over-package become overrides.
|
|
69
|
+
for (const [id, hostRecord] of Object.entries(host.assets)) {
|
|
70
|
+
const pkg = pkgAssets.get(id);
|
|
71
|
+
if (!pkg) {
|
|
72
|
+
assets[id] = { ...hostRecord };
|
|
73
|
+
provenance[id] = { source: 'host' };
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (pkg.decl.type !== hostRecord.type) {
|
|
77
|
+
findings.push({
|
|
78
|
+
kind: 'package-type-mismatch',
|
|
79
|
+
assetId: id,
|
|
80
|
+
origin: pkg.origin,
|
|
81
|
+
message: `Asset "${id}" overrides Package "${pkg.origin}" but changes its type from "${pkg.decl.type}" to "${hostRecord.type}"; changing the type is a different asset, not an override.`
|
|
82
|
+
});
|
|
83
|
+
assets[id] = { ...hostRecord };
|
|
84
|
+
provenance[id] = { source: 'override', origin: pkg.origin };
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const merged = {
|
|
88
|
+
type: hostRecord.type,
|
|
89
|
+
parameters: deepMergeParameters(pkg.decl.parameters, hostRecord.parameters),
|
|
90
|
+
manifests: sortDedupManifests([...pkg.decl.manifests, ...hostRecord.manifests])
|
|
91
|
+
};
|
|
92
|
+
// Source unit (raw + rawHash + importSource) is coherent: if the host
|
|
93
|
+
// supplies bytes or its own import source, take the host's wholesale;
|
|
94
|
+
// otherwise inherit the Package's import source.
|
|
95
|
+
if (hostRecord.raw !== undefined || hostRecord.importSource !== undefined) {
|
|
96
|
+
if (hostRecord.raw !== undefined)
|
|
97
|
+
merged.raw = hostRecord.raw;
|
|
98
|
+
if (hostRecord.rawHash !== undefined)
|
|
99
|
+
merged.rawHash = hostRecord.rawHash;
|
|
100
|
+
if (hostRecord.importSource !== undefined)
|
|
101
|
+
merged.importSource = hostRecord.importSource;
|
|
102
|
+
}
|
|
103
|
+
else if (pkg.decl.importSource !== undefined) {
|
|
104
|
+
merged.importSource = pkg.decl.importSource;
|
|
105
|
+
}
|
|
106
|
+
assets[id] = merged;
|
|
107
|
+
provenance[id] = { source: 'override', origin: pkg.origin };
|
|
108
|
+
findings.push({
|
|
109
|
+
kind: 'package-overridden',
|
|
110
|
+
assetId: id,
|
|
111
|
+
origin: pkg.origin,
|
|
112
|
+
message: `Asset "${id}" from Package "${pkg.origin}" is overridden by the host library.`
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Package-only assets (byte-less slots).
|
|
116
|
+
for (const [id, { origin, decl }] of pkgAssets) {
|
|
117
|
+
if (Object.hasOwn(host.assets, id))
|
|
118
|
+
continue;
|
|
119
|
+
const record = {
|
|
120
|
+
type: decl.type,
|
|
121
|
+
parameters: decl.parameters,
|
|
122
|
+
manifests: sortDedupManifests(decl.manifests)
|
|
123
|
+
};
|
|
124
|
+
if (decl.importSource !== undefined)
|
|
125
|
+
record.importSource = decl.importSource;
|
|
126
|
+
assets[id] = record;
|
|
127
|
+
provenance[id] = { source: 'package', origin };
|
|
128
|
+
}
|
|
129
|
+
// Manifest records: Package declarations first, host overlays per field (host wins).
|
|
130
|
+
const manifests = {};
|
|
131
|
+
for (const [name, record] of pkgManifests)
|
|
132
|
+
manifests[name] = { ...record };
|
|
133
|
+
for (const [name, record] of Object.entries(host.manifests)) {
|
|
134
|
+
manifests[name] = { ...manifests[name], ...record };
|
|
135
|
+
}
|
|
136
|
+
const hasImportSource = Object.values(assets).some((record) => record.importSource !== undefined);
|
|
137
|
+
const library = {
|
|
138
|
+
version: hasImportSource ? 2 : host.version,
|
|
139
|
+
folders: host.folders,
|
|
140
|
+
assets,
|
|
141
|
+
manifests
|
|
142
|
+
};
|
|
143
|
+
return { library, provenance, findings };
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Drop raw-less (unfilled) slots from an effective library, yielding a plain
|
|
147
|
+
* `Library` for processing/codegen. Safe only after the slot/validation gates
|
|
148
|
+
* pass — every remaining delivered asset then has `raw`; dropped slots are
|
|
149
|
+
* provably inert (not delivered).
|
|
150
|
+
*/
|
|
151
|
+
export function materializeLibrary(effective) {
|
|
152
|
+
const assets = {};
|
|
153
|
+
for (const [id, record] of Object.entries(effective.assets)) {
|
|
154
|
+
if (record.raw === undefined || record.rawHash === undefined)
|
|
155
|
+
continue;
|
|
156
|
+
const materialized = {
|
|
157
|
+
type: record.type,
|
|
158
|
+
raw: record.raw,
|
|
159
|
+
rawHash: record.rawHash,
|
|
160
|
+
parameters: record.parameters,
|
|
161
|
+
manifests: record.manifests
|
|
162
|
+
};
|
|
163
|
+
if (record.importSource !== undefined)
|
|
164
|
+
materialized.importSource = record.importSource;
|
|
165
|
+
assets[id] = materialized;
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
version: effective.version,
|
|
169
|
+
folders: effective.folders,
|
|
170
|
+
assets,
|
|
171
|
+
manifests: effective.manifests
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* enumerated (`collectAllReferences`) — no fs, no plugin introspection.
|
|
8
8
|
*/
|
|
9
9
|
import type { CollectedReference } from './asset-reference.js';
|
|
10
|
-
import type { AssetId,
|
|
10
|
+
import type { AssetId, EffectiveLibrary } from './library.js';
|
|
11
11
|
import type { ValidationIssueDto } from './api-types.js';
|
|
12
12
|
import type { AssetTypePluginDescriptor } from './plugins/contract.js';
|
|
13
13
|
/** The plugin registry shape shared by server and tests: type → descriptor. */
|
|
@@ -19,13 +19,13 @@ export type ReferencesByAsset = Record<AssetId, CollectedReference[]>;
|
|
|
19
19
|
* whose type is unknown or whose parameters do not validate contribute no
|
|
20
20
|
* references — those problems are reported by the regular validation pass.
|
|
21
21
|
*/
|
|
22
|
-
export declare function collectAllReferences(library:
|
|
22
|
+
export declare function collectAllReferences(library: EffectiveLibrary, plugins: PluginDescriptorRegistry): ReferencesByAsset;
|
|
23
23
|
/**
|
|
24
24
|
* Reference *errors* (they block build/codegen): a reference to an unknown
|
|
25
25
|
* asset, a target whose type is not among the field's expected types, and
|
|
26
26
|
* cycles (composition is acyclic by nature).
|
|
27
27
|
*/
|
|
28
|
-
export declare function referenceErrors(library:
|
|
28
|
+
export declare function referenceErrors(library: EffectiveLibrary, referencesByAsset: ReferencesByAsset): ValidationIssueDto[];
|
|
29
29
|
/**
|
|
30
30
|
* The transitive reference closure of a set of assets, including the starting
|
|
31
31
|
* set — the assets that must be delivered so the starting set renders as
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
Thin <img> wrapper for an image manifest entry: renders the delivered proxy
|
|
3
3
|
with its intrinsic width/height attributes so layout never shifts while the
|
|
4
|
-
file loads.
|
|
4
|
+
file loads. Every other native <img> attribute passes straight through.
|
|
5
5
|
-->
|
|
6
6
|
<script lang="ts">
|
|
7
|
+
import type { HTMLImgAttributes } from 'svelte/elements';
|
|
7
8
|
import type { ImageManifestEntry } from '../../core/index.js';
|
|
8
9
|
import { logRender } from '../logging.js';
|
|
9
10
|
|
|
10
|
-
interface Props {
|
|
11
|
+
interface Props extends Omit<HTMLImgAttributes, 'src'> {
|
|
11
12
|
src: ImageManifestEntry;
|
|
12
|
-
alt?: string;
|
|
13
|
-
class?: string;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
let { src,
|
|
15
|
+
let { src, ...rest }: Props = $props();
|
|
17
16
|
|
|
18
17
|
$effect(() => logRender(src));
|
|
19
18
|
</script>
|
|
20
19
|
|
|
21
|
-
<img src={src.src} width={src.width} height={src.height} {
|
|
20
|
+
<img src={src.src} width={src.width} height={src.height} {...rest} />
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import type { HTMLImgAttributes } from 'svelte/elements';
|
|
1
2
|
import type { ImageManifestEntry } from '../../core/index.js';
|
|
2
|
-
interface Props {
|
|
3
|
+
interface Props extends Omit<HTMLImgAttributes, 'src'> {
|
|
3
4
|
src: ImageManifestEntry;
|
|
4
|
-
alt?: string;
|
|
5
|
-
class?: string;
|
|
6
5
|
}
|
|
7
6
|
declare const Image: import("svelte").Component<Props, {}, "">;
|
|
8
7
|
type Image = ReturnType<typeof Image>;
|
package/dist/server/build.js
CHANGED
|
@@ -6,29 +6,44 @@
|
|
|
6
6
|
import { loadConfig } from './config-loader.js';
|
|
7
7
|
import { LibraryStore } from './library-store.js';
|
|
8
8
|
import { processAssets } from './processing/processor.js';
|
|
9
|
-
import { generateManifestModules } from './codegen.js';
|
|
10
|
-
import { serverPluginsByType } from './plugins.js';
|
|
11
|
-
import { formatCheckFinding } from './check.js';
|
|
12
|
-
import { typesForFileName } from '../core/index.js';
|
|
9
|
+
import { generateManifestModules, manifestModuleCollisionIssues } from './codegen.js';
|
|
10
|
+
import { descriptorsByType, serverPluginsByType } from './plugins.js';
|
|
11
|
+
import { formatCheckFinding, packageSlotFindings } from './check.js';
|
|
12
|
+
import { collectAllReferences, computeLibraryMembership, flatLibraryIssues, materializeLibrary, mergePackages, typesForFileName } from '../core/index.js';
|
|
13
13
|
import { classifyRawDirectory } from './raw-reconciliation.js';
|
|
14
14
|
import { rawSafetyIssues } from './raw-safety.js';
|
|
15
15
|
export async function runBuild(projectRoot, registry = serverPluginsByType) {
|
|
16
16
|
const config = await loadConfig(projectRoot);
|
|
17
17
|
const store = new LibraryStore(config, registry);
|
|
18
|
-
const
|
|
18
|
+
const host = await store.read();
|
|
19
|
+
// Merge Packages under the host; validate the effective library; process +
|
|
20
|
+
// generate over the materialized (raw-bearing) subset. Raw scans stay host.
|
|
21
|
+
const { library: effective, provenance, findings: mergeFindings } = mergePackages(host, config.packages ?? []);
|
|
22
|
+
const materialized = materializeLibrary(effective);
|
|
19
23
|
const descriptors = Object.values(registry).map((plugin) => plugin.descriptor);
|
|
20
24
|
const compatibleTypes = (path) => typesForFileName(path, descriptors);
|
|
21
|
-
const classification = await classifyRawDirectory(config.rawDir,
|
|
25
|
+
const classification = await classifyRawDirectory(config.rawDir, host, (path) => compatibleTypes(path).length > 0);
|
|
26
|
+
const referencesByAsset = collectAllReferences(effective, descriptorsByType(registry));
|
|
27
|
+
const membership = computeLibraryMembership(effective, referencesByAsset);
|
|
22
28
|
const issues = [
|
|
23
|
-
...
|
|
24
|
-
|
|
29
|
+
...mergeFindings
|
|
30
|
+
.filter((finding) => finding.kind !== 'package-overridden')
|
|
31
|
+
.map((finding) => ({ assetId: finding.assetId, message: finding.message })),
|
|
32
|
+
...(await store.validate(host, { flatSpace: false })),
|
|
33
|
+
...flatLibraryIssues(effective, descriptorsByType(registry)),
|
|
34
|
+
...manifestModuleCollisionIssues(effective.manifests),
|
|
35
|
+
...rawSafetyIssues(host, classification, compatibleTypes),
|
|
36
|
+
...packageSlotFindings(effective, provenance, membership).map((finding) => ({
|
|
37
|
+
assetId: finding.assetId,
|
|
38
|
+
message: finding.message
|
|
39
|
+
}))
|
|
25
40
|
];
|
|
26
41
|
if (issues.length > 0) {
|
|
27
42
|
const lines = issues.map((issue) => ` - ${formatCheckFinding({ kind: 'validation', assetId: issue.assetId, message: issue.message })}`);
|
|
28
43
|
throw new Error(`Library validation failed:\n${lines.join('\n')}`);
|
|
29
44
|
}
|
|
30
|
-
await store.syncFolders(
|
|
31
|
-
const processing = await processAssets(config,
|
|
32
|
-
const codegen = await generateManifestModules(config,
|
|
45
|
+
await store.syncFolders(host);
|
|
46
|
+
const processing = await processAssets(config, materialized, registry);
|
|
47
|
+
const codegen = await generateManifestModules(config, materialized, processing.proxies, registry);
|
|
33
48
|
return { processing, codegen };
|
|
34
49
|
}
|