fundus 0.0.4 → 0.2.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 +49 -8
- package/build/client/_app/immutable/assets/0.inkPq3ni.css +1 -0
- package/build/client/_app/immutable/assets/0.inkPq3ni.css.br +0 -0
- package/build/client/_app/immutable/assets/0.inkPq3ni.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.ChSpCG-T.css +1 -0
- package/build/client/_app/immutable/assets/3.ChSpCG-T.css.br +0 -0
- package/build/client/_app/immutable/assets/3.ChSpCG-T.css.gz +0 -0
- package/build/client/_app/immutable/assets/{LibraryContextMenu.CMefGNE2.css → LibraryContextMenu.BYvU4SY7.css} +1 -1
- package/build/client/_app/immutable/assets/LibraryContextMenu.BYvU4SY7.css.br +0 -0
- package/build/client/_app/immutable/assets/LibraryContextMenu.BYvU4SY7.css.gz +0 -0
- package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css +1 -0
- package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css.br +0 -0
- package/build/client/_app/immutable/assets/ManifestSelector.Il8p28r8.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BAEZPv6c.js +1 -0
- package/build/client/_app/immutable/chunks/BAEZPv6c.js.br +0 -0
- package/build/client/_app/immutable/chunks/BAEZPv6c.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DVEQFclp.js → ByVSyIj7.js} +1 -1
- package/build/client/_app/immutable/chunks/ByVSyIj7.js.br +1 -0
- package/build/client/_app/immutable/chunks/ByVSyIj7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C8W3KwDq.js +1 -0
- package/build/client/_app/immutable/chunks/C8W3KwDq.js.br +0 -0
- package/build/client/_app/immutable/chunks/C8W3KwDq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CP-bnOxU.js +1 -0
- package/build/client/_app/immutable/chunks/CP-bnOxU.js.br +0 -0
- package/build/client/_app/immutable/chunks/CP-bnOxU.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CNRz3sSw.js → D65cSBhe.js} +2 -2
- package/build/client/_app/immutable/chunks/D65cSBhe.js.br +0 -0
- package/build/client/_app/immutable/chunks/D65cSBhe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Db8LRH6X.js +108 -0
- package/build/client/_app/immutable/chunks/Db8LRH6X.js.br +0 -0
- package/build/client/_app/immutable/chunks/Db8LRH6X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/TZFh8bT7.js +1 -0
- package/build/client/_app/immutable/chunks/TZFh8bT7.js.br +0 -0
- package/build/client/_app/immutable/chunks/TZFh8bT7.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.nM6SgHKJ.js +2 -0
- package/build/client/_app/immutable/entry/app.nM6SgHKJ.js.br +0 -0
- package/build/client/_app/immutable/entry/app.nM6SgHKJ.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DNXvkhtP.js +1 -0
- package/build/client/_app/immutable/entry/start.DNXvkhtP.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DNXvkhtP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.QeXQNCp2.js +2 -0
- package/build/client/_app/immutable/nodes/0.QeXQNCp2.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.QeXQNCp2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.dMklHTc2.js +1 -0
- package/build/client/_app/immutable/nodes/1.dMklHTc2.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.dMklHTc2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CW4VMcIP.js +3 -0
- package/build/client/_app/immutable/nodes/2.CW4VMcIP.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CW4VMcIP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CTiY_pbK.js +1 -0
- package/build/client/_app/immutable/nodes/3.CTiY_pbK.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CTiY_pbK.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js +2 -0
- package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.Dgxx52FJ.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/client/favicon.svg +4 -0
- package/build/client/favicon.svg.br +0 -0
- package/build/client/favicon.svg.gz +0 -0
- package/build/handler.js +7 -7
- package/build/index.js +7 -7
- package/build/server/chunks/chunks/{context.js-BUZqFfWG.js → context.js-B77ZAVLi.js} +405 -31
- package/build/server/chunks/chunks/context.js-B77ZAVLi.js.map +1 -0
- package/build/server/chunks/chunks/{core.js-xfrkaQpS.js → core.js-EA_ysb1J.js} +130 -3
- package/build/server/chunks/chunks/core.js-EA_ysb1J.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-C0rwMMtk.js → exports.js-DvhE7Ffd.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-C0rwMMtk.js.map → exports.js-DvhE7Ffd.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-DvopzwKh.js → http.js-DyoR9XRI.js} +5 -3
- package/build/server/chunks/chunks/http.js-DyoR9XRI.js.map +1 -0
- package/build/server/chunks/chunks/{internal.js-DGo2jPcg.js → internal.js-Dn37LrAW.js} +4 -4
- package/build/server/chunks/chunks/{internal.js-DGo2jPcg.js.map → internal.js-Dn37LrAW.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{library-store.js-ZLudCJlT.js → library-store.js-DJ-JRE-g.js} +388 -20
- package/build/server/chunks/chunks/library-store.js-DJ-JRE-g.js.map +1 -0
- package/build/server/chunks/chunks/{shared.js-B1gC9MiJ.js → shared.js-Dob0TlTu.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-B1gC9MiJ.js.map → shared.js-Dob0TlTu.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-DnEJ3UjO.js → utils.js-B4YimMxv.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-DnEJ3UjO.js.map → utils.js-B4YimMxv.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Cq5gXVQT.js → _server.ts.js-H4Pq1KAE.js} +4 -5
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Cq5gXVQT.js.map → _server.ts.js-H4Pq1KAE.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-RXbedi8q.js → _server.ts.js-BI3KHSfE.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-RXbedi8q.js.map → _server.ts.js-BI3KHSfE.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/_server.ts.js-BlNYUbXX.js +34 -0
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/_server.ts.js-BlNYUbXX.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-D7Qae9vU.js → _server.ts.js-j-_N540j.js} +9 -7
- package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-j-_N540j.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DtO20kgB.js → _server.ts.js-BHKobzAg.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-DtO20kgB.js.map → _server.ts.js-BHKobzAg.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BUebPbd5.js → _server.ts.js-BFKjIOCv.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BUebPbd5.js.map → _server.ts.js-BFKjIOCv.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BjT2qPMT.js → _server.ts.js-BxZeVw8y.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BjT2qPMT.js.map → _server.ts.js-BxZeVw8y.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DYRLsoT7.js → _server.ts.js-CO36U_CT.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DYRLsoT7.js.map → _server.ts.js-CO36U_CT.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-BbN2fGNN.js → _server.ts.js-CBlg1Bkl.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-BbN2fGNN.js.map → _server.ts.js-CBlg1Bkl.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-b_MKZ41b.js → _server.ts.js-DcGLCjIs.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-b_MKZ41b.js.map → _server.ts.js-DcGLCjIs.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/_server.ts.js-AqhtjOiL.js +32 -0
- package/build/server/chunks/entries/endpoints/api/raw/adopt/_server.ts.js-AqhtjOiL.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/_server.ts.js-CSa6-DcU.js +30 -0
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/_server.ts.js-CSa6-DcU.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/_server.ts.js-DnzZUoAo.js +30 -0
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/_server.ts.js-DnzZUoAo.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/reconcile/_server.ts.js-B0KMprKq.js +33 -0
- package/build/server/chunks/entries/endpoints/api/reconcile/_server.ts.js-B0KMprKq.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-evEfMpvn.js → _server.ts.js-B1N9o1Ne.js} +5 -6
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-evEfMpvn.js.map → _server.ts.js-B1N9o1Ne.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-C04XE_1w.js → _server.ts.js-B6HbnRqq.js} +4 -5
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-C04XE_1w.js.map → _server.ts.js-B6HbnRqq.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DB8TdoEv.js → _server.ts.js-7wzPyG9v.js} +5 -6
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-DB8TdoEv.js.map → _server.ts.js-7wzPyG9v.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BrpaijZO.js → _server.ts.js-BWztxYge.js} +5 -6
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BrpaijZO.js.map → _server.ts.js-BWztxYge.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-BJJwZW_I.js → hooks.server.js-CVKLksJ1.js} +4 -5
- package/build/server/chunks/entries/{hooks.server.js-BJJwZW_I.js.map → hooks.server.js-CVKLksJ1.js.map} +1 -1
- package/build/server/chunks/{handler-DnbS2t1B.js → handler-DZ2Sps4a.js} +5 -5
- package/build/server/chunks/{handler-DnbS2t1B.js.map → handler-DZ2Sps4a.js.map} +1 -1
- package/build/server/chunks/{index.js-g77q3Boj.js → index.js-CdmTWQz8.js} +5 -5
- package/build/server/chunks/{index.js-g77q3Boj.js.map → index.js-CdmTWQz8.js.map} +1 -1
- package/build/server/chunks/{manifest.js-qmEXbstS.js → manifest.js-GhfNr35x.js} +57 -22
- package/build/server/chunks/manifest.js-GhfNr35x.js.map +1 -0
- package/build/server/chunks/nodes/0.js-DGT86_i-.js +11 -0
- package/build/server/chunks/nodes/0.js-DGT86_i-.js.map +1 -0
- package/build/server/chunks/nodes/1.js-DQgYreU0.js +7 -0
- package/build/server/chunks/nodes/{1.js-H-qwo4GJ.js.map → 1.js-DQgYreU0.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-DItreSrX.js +7 -0
- package/build/server/chunks/nodes/2.js-DItreSrX.js.map +1 -0
- package/build/server/chunks/nodes/3.js-bE1dJ_6v.js +7 -0
- package/build/server/chunks/nodes/3.js-bE1dJ_6v.js.map +1 -0
- package/build/server/chunks/nodes/4.js-BebbMVXy.js +7 -0
- package/build/server/chunks/nodes/{4.js-BKL7LSSm.js.map → 4.js-BebbMVXy.js.map} +1 -1
- package/dist/cli.js +32 -9
- package/dist/core/api-types.d.ts +39 -1
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.js +2 -1
- package/dist/core/ingest.d.ts +2 -0
- package/dist/core/ingest.js +7 -0
- package/dist/core/raw-path.d.ts +8 -0
- package/dist/core/raw-path.js +63 -0
- package/dist/server/build.js +11 -2
- package/dist/server/check.d.ts +5 -1
- package/dist/server/check.js +80 -28
- package/dist/server/cli-commands.d.ts +3 -2
- package/dist/server/cli-commands.js +47 -4
- package/dist/server/cli-init.d.ts +1 -1
- package/dist/server/cli-init.js +38 -5
- package/dist/server/http.js +5 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/library-store.d.ts +23 -0
- package/dist/server/library-store.js +82 -14
- package/dist/server/operations.d.ts +12 -2
- package/dist/server/operations.js +391 -31
- package/dist/server/processing/processor.js +3 -0
- package/dist/server/raw-reconciliation.d.ts +53 -0
- package/dist/server/raw-reconciliation.js +338 -0
- package/dist/server/raw-safety.d.ts +10 -0
- package/dist/server/raw-safety.js +73 -0
- package/dist/server/start.d.ts +4 -2
- package/dist/server/start.js +43 -11
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/0.DLhIsYA_.css +0 -1
- package/build/client/_app/immutable/assets/0.DLhIsYA_.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DLhIsYA_.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.JwgtcTEd.css +0 -1
- package/build/client/_app/immutable/assets/3.JwgtcTEd.css.br +0 -0
- package/build/client/_app/immutable/assets/3.JwgtcTEd.css.gz +0 -0
- package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.br +0 -0
- package/build/client/_app/immutable/assets/LibraryContextMenu.CMefGNE2.css.gz +0 -0
- package/build/client/_app/immutable/chunks/CNRz3sSw.js.br +0 -0
- package/build/client/_app/immutable/chunks/CNRz3sSw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CO4RBJfa.js +0 -1
- package/build/client/_app/immutable/chunks/CO4RBJfa.js.br +0 -0
- package/build/client/_app/immutable/chunks/CO4RBJfa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DOpBpjxS.js +0 -108
- package/build/client/_app/immutable/chunks/DOpBpjxS.js.br +0 -0
- package/build/client/_app/immutable/chunks/DOpBpjxS.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DVEQFclp.js.br +0 -1
- package/build/client/_app/immutable/chunks/DVEQFclp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DiFoWL2c.js +0 -1
- package/build/client/_app/immutable/chunks/DiFoWL2c.js.br +0 -0
- package/build/client/_app/immutable/chunks/DiFoWL2c.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DkADHpZF.js +0 -1
- package/build/client/_app/immutable/chunks/DkADHpZF.js.br +0 -0
- package/build/client/_app/immutable/chunks/DkADHpZF.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CKgtYXQb.js +0 -2
- package/build/client/_app/immutable/entry/app.CKgtYXQb.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CKgtYXQb.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.CYZu5qE1.js +0 -1
- package/build/client/_app/immutable/entry/start.CYZu5qE1.js.br +0 -0
- package/build/client/_app/immutable/entry/start.CYZu5qE1.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.I_1SApYQ.js +0 -2
- package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.I_1SApYQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.v6eUTnWq.js +0 -1
- package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.br +0 -2
- package/build/client/_app/immutable/nodes/1.v6eUTnWq.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js +0 -3
- package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DoA7Dfl-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.C-DO70Bs.js +0 -1
- package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.C-DO70Bs.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.CALOuSyz.js +0 -2
- package/build/client/_app/immutable/nodes/4.CALOuSyz.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.CALOuSyz.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-BUZqFfWG.js.map +0 -1
- package/build/server/chunks/chunks/core.js-xfrkaQpS.js.map +0 -1
- package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js +0 -64
- package/build/server/chunks/chunks/folder-path.js-ytx9ucgg.js.map +0 -1
- package/build/server/chunks/chunks/http.js-DvopzwKh.js.map +0 -1
- package/build/server/chunks/chunks/library-store.js-ZLudCJlT.js.map +0 -1
- package/build/server/chunks/entries/endpoints/api/assets/_server.ts.js-D7Qae9vU.js.map +0 -1
- package/build/server/chunks/manifest.js-qmEXbstS.js.map +0 -1
- package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js +0 -11
- package/build/server/chunks/nodes/0.js-Bk6IZ-vD.js.map +0 -1
- package/build/server/chunks/nodes/1.js-H-qwo4GJ.js +0 -7
- package/build/server/chunks/nodes/2.js-DRpXVLwp.js +0 -7
- package/build/server/chunks/nodes/2.js-DRpXVLwp.js.map +0 -1
- package/build/server/chunks/nodes/3.js-CDEzNFeU.js +0 -7
- package/build/server/chunks/nodes/3.js-CDEzNFeU.js.map +0 -1
- package/build/server/chunks/nodes/4.js-BKL7LSSm.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal2.js-BlXt2rfE.js","sources":["../../../../.svelte-kit/output/server/chunks/internal2.js"],"sourcesContent":["//#region node_modules/@sveltejs/kit/src/runtime/app/paths/internal/server.js\nvar base = \"\";\nvar assets = base;\nvar app_dir = \"_app\";\nvar initial = {\n\tbase,\n\tassets\n};\n/**\n* `base` could be overridden during rendering to be relative;\n* this one's the original non-relative base path\n*/\nvar initial_base = initial.base;\n/**\n* @param {{ base: string, assets: string }} paths\n*/\nfunction override(paths) {\n\tbase = paths.base;\n\tassets = paths.assets;\n}\nfunction reset() {\n\tbase = initial.base;\n\tassets = initial.assets;\n}\n/** @param {string} path */\nfunction set_assets(path) {\n\tassets = initial.assets = path;\n}\n//#endregion\n//#region node_modules/@sveltejs/kit/src/runtime/app/env/internal.js\nvar version = \"
|
|
1
|
+
{"version":3,"file":"internal2.js-BlXt2rfE.js","sources":["../../../../.svelte-kit/output/server/chunks/internal2.js"],"sourcesContent":["//#region node_modules/@sveltejs/kit/src/runtime/app/paths/internal/server.js\nvar base = \"\";\nvar assets = base;\nvar app_dir = \"_app\";\nvar initial = {\n\tbase,\n\tassets\n};\n/**\n* `base` could be overridden during rendering to be relative;\n* this one's the original non-relative base path\n*/\nvar initial_base = initial.base;\n/**\n* @param {{ base: string, assets: string }} paths\n*/\nfunction override(paths) {\n\tbase = paths.base;\n\tassets = paths.assets;\n}\nfunction reset() {\n\tbase = initial.base;\n\tassets = initial.assets;\n}\n/** @param {string} path */\nfunction set_assets(path) {\n\tassets = initial.assets = path;\n}\n//#endregion\n//#region node_modules/@sveltejs/kit/src/runtime/app/env/internal.js\nvar version = \"1784103096725\";\nvar prerendering = false;\nfunction set_building() {}\nfunction set_prerendering() {\n\tprerendering = true;\n}\n//#endregion\nexport { app_dir as a, initial_base as c, set_assets as d, version as i, override as l, set_building as n, assets as o, set_prerendering as r, base as s, prerendering as t, reset as u };\n"],"names":[],"mappings":"AAAA;AACG,IAAC,IAAI,GAAG;AACR,IAAC,MAAM,GAAG;AACV,IAAC,OAAO,GAAG;AACd,IAAI,OAAO,GAAG;AACd,CAAC,IAAI;AACL,CAAC;AACD,CAAC;AAMD;AACA;AACA;AACA,SAAS,QAAQ,CAAC,KAAK,EAAE;AACzB,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI;AAClB,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;AACtB;AACA,SAAS,KAAK,GAAG;AACjB,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI;AACpB,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;AACxB;;;;"}
|
package/build/server/chunks/chunks/{library-store.js-ZLudCJlT.js → library-store.js-DJ-JRE-g.js}
RENAMED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { p as plugins, a as audioPlugin, c as chromaKeyVideoPlugin, v as videoPlugin, s as slicePlugin, i as imagePlugin, b as assetIdError, d as
|
|
2
|
-
import { n as normalizeFolderPath, f as folderOfRawPath, r as rawFileNameOfPath, a as folderPathError, p as parentFolderPath, b as folderNameError, j as joinFolderPath, c as folderNameOf, i as isFolderOrDescendant, d as replaceFolderPrefix, e as portableFolderPathKey, F as FOLDER_SENTINEL } from './folder-path.js-ytx9ucgg.js';
|
|
1
|
+
import { p as plugins, a as audioPlugin, c as chromaKeyVideoPlugin, v as videoPlugin, s as slicePlugin, i as imagePlugin, b as assetIdError, n as normalizeFolderPath, f as folderOfRawPath, r as rawFileNameOfPath, d as folderPathError, e as parentFolderPath, g as folderNameError, j as joinFolderPath, h as folderNameOf, k as isFolderOrDescendant, l as replaceFolderPrefix, m as portableFolderPathKey, o as defaultInsetsForSize, q as manifestNameError, F as FOLDER_SENTINEL, t as rawFilePathError, u as portableRawPathKey, w as isFundusTransactionName, x as isAssetReference, y as validateVideoPreset, V as VIDEO_BUILT_IN_PRESETS, z as validateAudioPreset, A as AUDIO_BUILT_IN_PRESETS, B as validateImagePreset, I as IMAGE_BUILT_IN_PRESETS, S as SLICE_BUILT_IN_PRESETS } from './core.js-EA_ysb1J.js';
|
|
3
2
|
import { m as manifestColorError, a as manifestEmojiError } from './manifest-appearance.js-DTk355LQ.js';
|
|
4
3
|
import { join, extname, dirname, basename, isAbsolute, resolve } from 'node:path';
|
|
5
|
-
import { existsSync } from 'node:fs';
|
|
6
|
-
import { readFile, mkdir, writeFile, rename,
|
|
4
|
+
import { existsSync, constants } from 'node:fs';
|
|
5
|
+
import { readFile, mkdir, writeFile, rename, unlink, rm, stat, readdir, open, lstat } from 'node:fs/promises';
|
|
7
6
|
import ffmpegStaticPath from 'ffmpeg-static';
|
|
8
7
|
import { path } from 'ffprobe-static';
|
|
9
8
|
import { execFile } from 'node:child_process';
|
|
@@ -1004,6 +1003,310 @@ function encodeRelativePathForUrl(path) {
|
|
|
1004
1003
|
return path.split("/").map(encodeURIComponent).join("/");
|
|
1005
1004
|
}
|
|
1006
1005
|
//#endregion
|
|
1006
|
+
//#region src/lib/server/raw-reconciliation.ts
|
|
1007
|
+
function objectIdentity(value) {
|
|
1008
|
+
return `${value.dev}:${value.ino}:${value.mode}`;
|
|
1009
|
+
}
|
|
1010
|
+
function fileIdentity(value) {
|
|
1011
|
+
return `${objectIdentity(value)}:${value.size}:${value.mtimeNs}:${value.ctimeNs}`;
|
|
1012
|
+
}
|
|
1013
|
+
function pathMatchesHandle(pathStat, handleStat) {
|
|
1014
|
+
return pathStat.isFile() && objectIdentity(pathStat) === objectIdentity(handleStat);
|
|
1015
|
+
}
|
|
1016
|
+
/** Hash one regular file without following its final path component. */
|
|
1017
|
+
async function stableRawFileHash(path) {
|
|
1018
|
+
let lastProblem;
|
|
1019
|
+
for (let attempt = 0; attempt < 3; attempt++) try {
|
|
1020
|
+
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
1021
|
+
try {
|
|
1022
|
+
const before = await handle.stat({ bigint: true });
|
|
1023
|
+
const pathBefore = await lstat(path, { bigint: true });
|
|
1024
|
+
if (!before.isFile() || !pathMatchesHandle(pathBefore, before)) throw new Error("path is not the opened regular file");
|
|
1025
|
+
const hash = createHash("sha256");
|
|
1026
|
+
for await (const chunk of handle.createReadStream({ autoClose: false })) hash.update(chunk);
|
|
1027
|
+
const after = await handle.stat({ bigint: true });
|
|
1028
|
+
const pathAfter = await lstat(path, { bigint: true });
|
|
1029
|
+
if (fileIdentity(before) === fileIdentity(after) && pathMatchesHandle(pathAfter, after)) return hash.digest("hex");
|
|
1030
|
+
lastProblem = /* @__PURE__ */ new Error("changed while it was being hashed");
|
|
1031
|
+
} finally {
|
|
1032
|
+
await handle.close().catch(() => {});
|
|
1033
|
+
}
|
|
1034
|
+
} catch (cause) {
|
|
1035
|
+
lastProblem = cause;
|
|
1036
|
+
}
|
|
1037
|
+
throw lastProblem instanceof Error ? lastProblem : new Error(String(lastProblem));
|
|
1038
|
+
}
|
|
1039
|
+
async function verifyStableRawFile(path, expectedHash) {
|
|
1040
|
+
const actualHash = await stableRawFileHash(path);
|
|
1041
|
+
if (actualHash !== expectedHash) throw new Error(`Raw source changed (expected ${expectedHash}, found ${actualHash}).`);
|
|
1042
|
+
}
|
|
1043
|
+
/** Enumerate without following symlinks and retain structural scan completeness. */
|
|
1044
|
+
async function scanRawDirectory(rawDir, includeFile = () => true) {
|
|
1045
|
+
const files = [];
|
|
1046
|
+
const blockers = [];
|
|
1047
|
+
const diagnostics = [];
|
|
1048
|
+
const occupiedPaths = /* @__PURE__ */ new Set();
|
|
1049
|
+
const entryKinds = /* @__PURE__ */ new Map();
|
|
1050
|
+
const ignoredRegularPaths = [];
|
|
1051
|
+
let complete = true;
|
|
1052
|
+
function markIncomplete(path, reason) {
|
|
1053
|
+
complete = false;
|
|
1054
|
+
diagnostics.push({
|
|
1055
|
+
path,
|
|
1056
|
+
reason
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
async function visit(folder) {
|
|
1060
|
+
const absolutePath = join(rawDir, folder);
|
|
1061
|
+
let before;
|
|
1062
|
+
try {
|
|
1063
|
+
before = await lstat(absolutePath, { bigint: true });
|
|
1064
|
+
} catch (cause) {
|
|
1065
|
+
markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} cannot be read: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
if (!before.isDirectory() || before.isSymbolicLink()) {
|
|
1069
|
+
markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} is not a regular directory.`);
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
1072
|
+
let entries;
|
|
1073
|
+
try {
|
|
1074
|
+
entries = await readdir(absolutePath, { withFileTypes: true });
|
|
1075
|
+
} catch (cause) {
|
|
1076
|
+
markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} cannot be traversed: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
for (const entry of entries.sort((a, b) => compareCodeUnits(a.name, b.name))) {
|
|
1080
|
+
const path = folder === "" ? entry.name : `${folder}/${entry.name}`;
|
|
1081
|
+
if (entry.name === ".gitkeep" || isFundusTransactionName(entry.name)) continue;
|
|
1082
|
+
if (entry.isDirectory()) {
|
|
1083
|
+
occupiedPaths.add(path);
|
|
1084
|
+
entryKinds.set(path, "directory");
|
|
1085
|
+
const problem = folderPathError(path);
|
|
1086
|
+
if (problem) blockers.push({
|
|
1087
|
+
path,
|
|
1088
|
+
reason: problem
|
|
1089
|
+
});
|
|
1090
|
+
else await visit(path);
|
|
1091
|
+
continue;
|
|
1092
|
+
}
|
|
1093
|
+
if (entry.isFile()) {
|
|
1094
|
+
if (!includeFile(path)) {
|
|
1095
|
+
ignoredRegularPaths.push(path);
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
occupiedPaths.add(path);
|
|
1099
|
+
entryKinds.set(path, "file");
|
|
1100
|
+
const problem = rawFilePathError(path);
|
|
1101
|
+
if (problem) {
|
|
1102
|
+
blockers.push({
|
|
1103
|
+
path,
|
|
1104
|
+
reason: problem
|
|
1105
|
+
});
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
try {
|
|
1109
|
+
files.push({
|
|
1110
|
+
path,
|
|
1111
|
+
hash: await stableRawFileHash(join(rawDir, path))
|
|
1112
|
+
});
|
|
1113
|
+
} catch (cause) {
|
|
1114
|
+
blockers.push({
|
|
1115
|
+
path,
|
|
1116
|
+
reason: `Could not obtain a stable file hash: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
continue;
|
|
1120
|
+
}
|
|
1121
|
+
const kind = entry.isSymbolicLink() ? "symlink" : "special";
|
|
1122
|
+
occupiedPaths.add(path);
|
|
1123
|
+
entryKinds.set(path, kind);
|
|
1124
|
+
blockers.push({
|
|
1125
|
+
path,
|
|
1126
|
+
reason: "Symlinks and special files are not supported."
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
try {
|
|
1130
|
+
const after = await lstat(absolutePath, { bigint: true });
|
|
1131
|
+
if (!after.isDirectory() || objectIdentity(before) !== objectIdentity(after)) markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} changed during traversal.`);
|
|
1132
|
+
} catch (cause) {
|
|
1133
|
+
markIncomplete(folder, `${folder === "" ? "Raw directory" : `Directory "${folder}"`} changed during traversal: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
await visit("");
|
|
1137
|
+
const collisions = /* @__PURE__ */ new Map();
|
|
1138
|
+
for (const path of [...occupiedPaths].sort(compareCodeUnits)) {
|
|
1139
|
+
const key = portableRawPathKey(path);
|
|
1140
|
+
const previous = collisions.get(key);
|
|
1141
|
+
if (previous !== void 0 && previous !== path) {
|
|
1142
|
+
const reason = `Raw paths "${previous}" and "${path}" collide portably.`;
|
|
1143
|
+
blockers.push({
|
|
1144
|
+
path: previous,
|
|
1145
|
+
reason
|
|
1146
|
+
});
|
|
1147
|
+
blockers.push({
|
|
1148
|
+
path,
|
|
1149
|
+
reason
|
|
1150
|
+
});
|
|
1151
|
+
} else collisions.set(key, path);
|
|
1152
|
+
}
|
|
1153
|
+
const blockersByPath = /* @__PURE__ */ new Map();
|
|
1154
|
+
for (const blocker of blockers) if (!blockersByPath.has(blocker.path)) blockersByPath.set(blocker.path, blocker);
|
|
1155
|
+
const sortedBlockers = [...blockersByPath.values()].sort((a, b) => compareCodeUnits(a.path, b.path));
|
|
1156
|
+
const blocked = new Set(sortedBlockers.map((entry) => entry.path));
|
|
1157
|
+
return {
|
|
1158
|
+
complete,
|
|
1159
|
+
diagnostics: diagnostics.sort((a, b) => compareCodeUnits(a.path, b.path)),
|
|
1160
|
+
files: files.filter((entry) => !blocked.has(entry.path)).sort((a, b) => compareCodeUnits(a.path, b.path)),
|
|
1161
|
+
blockers: sortedBlockers,
|
|
1162
|
+
occupiedPaths,
|
|
1163
|
+
entryKinds,
|
|
1164
|
+
ignoredRegularPaths: ignoredRegularPaths.sort(compareCodeUnits)
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
/** Pure deterministic matching: exact path first, then only 1:1 hash groups. */
|
|
1168
|
+
function classifyRawFiles(library, scan) {
|
|
1169
|
+
const filesByPath = new Map(scan.files.map((file) => [file.path, file]));
|
|
1170
|
+
const remainingFiles = new Map(filesByPath);
|
|
1171
|
+
const remainingRecords = /* @__PURE__ */ new Map();
|
|
1172
|
+
const unchangedAssetIds = [];
|
|
1173
|
+
const edited = [];
|
|
1174
|
+
const blockers = [...scan.blockers];
|
|
1175
|
+
const excludedPrefixes = [];
|
|
1176
|
+
for (const assetId of Object.keys(library.assets).sort(compareCodeUnits)) {
|
|
1177
|
+
const record = library.assets[assetId];
|
|
1178
|
+
const kind = scan.entryKinds.get(record.raw);
|
|
1179
|
+
if (kind !== void 0 && kind !== "file") {
|
|
1180
|
+
const existing = blockers.find((blocker) => blocker.path === record.raw);
|
|
1181
|
+
if (existing) existing.assetId = assetId;
|
|
1182
|
+
else blockers.push({
|
|
1183
|
+
assetId,
|
|
1184
|
+
path: record.raw,
|
|
1185
|
+
reason: `Managed raw path is occupied by a ${kind}.`
|
|
1186
|
+
});
|
|
1187
|
+
excludedPrefixes.push(record.raw);
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
const exact = filesByPath.get(record.raw);
|
|
1191
|
+
if (exact) {
|
|
1192
|
+
remainingFiles.delete(record.raw);
|
|
1193
|
+
if (exact.hash === record.rawHash) unchangedAssetIds.push(assetId);
|
|
1194
|
+
else edited.push({
|
|
1195
|
+
assetId,
|
|
1196
|
+
...exact
|
|
1197
|
+
});
|
|
1198
|
+
} else if (scan.complete && !scan.occupiedPaths.has(record.raw) && !scan.blockers.some((blocker) => record.raw === blocker.path || record.raw.startsWith(`${blocker.path}/`))) remainingRecords.set(assetId, {
|
|
1199
|
+
path: record.raw,
|
|
1200
|
+
hash: record.rawHash
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
for (const path of remainingFiles.keys()) if (excludedPrefixes.some((prefix) => path.startsWith(`${prefix}/`))) remainingFiles.delete(path);
|
|
1204
|
+
const recordsByHash = /* @__PURE__ */ new Map();
|
|
1205
|
+
for (const [assetId, record] of remainingRecords) recordsByHash.set(record.hash, [...recordsByHash.get(record.hash) ?? [], assetId]);
|
|
1206
|
+
const filesByHash = /* @__PURE__ */ new Map();
|
|
1207
|
+
for (const file of remainingFiles.values()) filesByHash.set(file.hash, [...filesByHash.get(file.hash) ?? [], file]);
|
|
1208
|
+
const moves = [];
|
|
1209
|
+
if (scan.complete) for (const [hash, assetIds] of recordsByHash) {
|
|
1210
|
+
const candidates = filesByHash.get(hash) ?? [];
|
|
1211
|
+
if (assetIds.length !== 1 || candidates.length !== 1) continue;
|
|
1212
|
+
const assetId = assetIds[0];
|
|
1213
|
+
const file = candidates[0];
|
|
1214
|
+
moves.push({
|
|
1215
|
+
assetId,
|
|
1216
|
+
from: remainingRecords.get(assetId)?.path ?? "",
|
|
1217
|
+
...file
|
|
1218
|
+
});
|
|
1219
|
+
remainingRecords.delete(assetId);
|
|
1220
|
+
remainingFiles.delete(file.path);
|
|
1221
|
+
}
|
|
1222
|
+
const blockerKeys = /* @__PURE__ */ new Set();
|
|
1223
|
+
const uniqueBlockers = blockers.filter((blocker) => {
|
|
1224
|
+
const key = `${blocker.assetId ?? ""}|${blocker.path}`;
|
|
1225
|
+
if (blockerKeys.has(key)) return false;
|
|
1226
|
+
blockerKeys.add(key);
|
|
1227
|
+
return true;
|
|
1228
|
+
});
|
|
1229
|
+
return {
|
|
1230
|
+
complete: scan.complete,
|
|
1231
|
+
diagnostics: scan.diagnostics,
|
|
1232
|
+
unchangedAssetIds,
|
|
1233
|
+
edited: edited.sort((a, b) => compareCodeUnits(a.path, b.path)),
|
|
1234
|
+
moves: scan.complete ? moves.sort((a, b) => compareCodeUnits(a.path, b.path)) : [],
|
|
1235
|
+
deletions: scan.complete ? [...remainingRecords].map(([assetId, record]) => ({
|
|
1236
|
+
assetId,
|
|
1237
|
+
path: record.path
|
|
1238
|
+
})) : [],
|
|
1239
|
+
unmanaged: [...remainingFiles.values()].sort((a, b) => compareCodeUnits(a.path, b.path)),
|
|
1240
|
+
blockers: uniqueBlockers.sort((a, b) => compareCodeUnits(a.path, b.path))
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
async function classifyRawDirectory(rawDir, library, includeExternalFile = () => true) {
|
|
1244
|
+
const managedPaths = new Set(Object.values(library.assets).map((record) => record.raw));
|
|
1245
|
+
const scan = await scanRawDirectory(rawDir, (path) => managedPaths.has(path) || includeExternalFile(path));
|
|
1246
|
+
const classification = classifyRawFiles(library, scan);
|
|
1247
|
+
if (!classification.complete || classification.deletions.length === 0) return classification;
|
|
1248
|
+
const ignoredByHash = /* @__PURE__ */ new Map();
|
|
1249
|
+
for (const path of scan.ignoredRegularPaths) try {
|
|
1250
|
+
const hash = await stableRawFileHash(join(rawDir, path));
|
|
1251
|
+
ignoredByHash.set(hash, [...ignoredByHash.get(hash) ?? [], path]);
|
|
1252
|
+
} catch (cause) {
|
|
1253
|
+
return {
|
|
1254
|
+
...classification,
|
|
1255
|
+
complete: false,
|
|
1256
|
+
diagnostics: [...classification.diagnostics, {
|
|
1257
|
+
path,
|
|
1258
|
+
reason: `Could not safely check ignored raw file "${path}" while managed files were missing: ${cause instanceof Error ? cause.message : String(cause)}`
|
|
1259
|
+
}].sort((a, b) => compareCodeUnits(a.path, b.path)),
|
|
1260
|
+
moves: [],
|
|
1261
|
+
deletions: []
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
const missingByHash = /* @__PURE__ */ new Map();
|
|
1265
|
+
for (const deletion of classification.deletions) {
|
|
1266
|
+
const hash = library.assets[deletion.assetId].rawHash;
|
|
1267
|
+
missingByHash.set(hash, [...missingByHash.get(hash) ?? [], deletion]);
|
|
1268
|
+
}
|
|
1269
|
+
const supportedByHash = /* @__PURE__ */ new Map();
|
|
1270
|
+
for (const file of classification.unmanaged) supportedByHash.set(file.hash, [...supportedByHash.get(file.hash) ?? [], file.path]);
|
|
1271
|
+
const protectedAssetIds = /* @__PURE__ */ new Set();
|
|
1272
|
+
const unsupportedBlockers = [];
|
|
1273
|
+
const ambiguityDiagnostics = [];
|
|
1274
|
+
for (const [hash, ignoredPaths] of ignoredByHash) {
|
|
1275
|
+
const missing = missingByHash.get(hash) ?? [];
|
|
1276
|
+
if (missing.length === 0) continue;
|
|
1277
|
+
const candidatePaths = [...supportedByHash.get(hash) ?? [], ...ignoredPaths].sort(compareCodeUnits);
|
|
1278
|
+
const sortedMissing = [...missing].sort((a, b) => compareCodeUnits(a.assetId, b.assetId));
|
|
1279
|
+
if (sortedMissing.length === 1 && ignoredPaths.length === 1 && candidatePaths.length === 1) {
|
|
1280
|
+
const [{ assetId, path: oldPath }] = sortedMissing;
|
|
1281
|
+
const [destination] = ignoredPaths;
|
|
1282
|
+
protectedAssetIds.add(assetId);
|
|
1283
|
+
unsupportedBlockers.push({
|
|
1284
|
+
assetId,
|
|
1285
|
+
path: destination,
|
|
1286
|
+
reason: `Asset "${assetId}" was moved from "${oldPath}" to unsupported path "${destination}". Rename it externally to a supported extension.`
|
|
1287
|
+
});
|
|
1288
|
+
continue;
|
|
1289
|
+
}
|
|
1290
|
+
ambiguityDiagnostics.push({
|
|
1291
|
+
path: candidatePaths[0] ?? "",
|
|
1292
|
+
reason: `Ignored raw files ambiguously match missing assets [${sortedMissing.map((entry) => entry.assetId).join(", ")}] and candidate paths [${candidatePaths.join(", ")}]. Restore or reduce the external files until the match is unique.`
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
if (ambiguityDiagnostics.length > 0) return {
|
|
1296
|
+
...classification,
|
|
1297
|
+
complete: false,
|
|
1298
|
+
diagnostics: [...classification.diagnostics, ...ambiguityDiagnostics].sort((a, b) => compareCodeUnits(`${a.path}|${a.reason}`, `${b.path}|${b.reason}`)),
|
|
1299
|
+
moves: [],
|
|
1300
|
+
deletions: [],
|
|
1301
|
+
blockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))
|
|
1302
|
+
};
|
|
1303
|
+
return {
|
|
1304
|
+
...classification,
|
|
1305
|
+
deletions: classification.deletions.filter((deletion) => !protectedAssetIds.has(deletion.assetId)),
|
|
1306
|
+
blockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
//#endregion
|
|
1007
1310
|
//#region src/lib/server/processing/processor.ts
|
|
1008
1311
|
/**
|
|
1009
1312
|
* The processing pipeline: every delivered asset gets exactly one
|
|
@@ -1094,6 +1397,7 @@ async function processAssetFile(record, rawPath, proxyPath, config, registry) {
|
|
|
1094
1397
|
const stem = basename(proxyPath, extension);
|
|
1095
1398
|
const temporaryPath = join(dirname(proxyPath), `.${stem}.${crypto.randomUUID()}.tmp${extension}`);
|
|
1096
1399
|
try {
|
|
1400
|
+
await verifyStableRawFile(rawPath, record.rawHash);
|
|
1097
1401
|
const output = await plugin.process({
|
|
1098
1402
|
sourcePath: rawPath,
|
|
1099
1403
|
targetPath: temporaryPath,
|
|
@@ -1101,6 +1405,7 @@ async function processAssetFile(record, rawPath, proxyPath, config, registry) {
|
|
|
1101
1405
|
preset: plugin.resolvePreset(parameters, config),
|
|
1102
1406
|
config
|
|
1103
1407
|
});
|
|
1408
|
+
await verifyStableRawFile(rawPath, record.rawHash);
|
|
1104
1409
|
await rename(temporaryPath, proxyPath);
|
|
1105
1410
|
return output;
|
|
1106
1411
|
} catch (cause) {
|
|
@@ -1165,22 +1470,10 @@ async function processAssets(config, library, registry = serverPluginsByType) {
|
|
|
1165
1470
|
* is always the current truth. Proxy files are the pipeline's business — this
|
|
1166
1471
|
* store only removes them on asset deletion (the pipeline also prunes orphans).
|
|
1167
1472
|
*/
|
|
1168
|
-
/** A single path segment with no traversal — guards against `../` escapes. */
|
|
1169
|
-
var SAFE_SEGMENT = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
1170
|
-
function assertSafeFileName(fileName) {
|
|
1171
|
-
if (!SAFE_SEGMENT.test(fileName) || fileName.includes("/") || fileName.includes("\\")) throw new Error(`Unsafe file name "${fileName}".`);
|
|
1172
|
-
}
|
|
1173
1473
|
/** Validate a persisted/served file path without allowing traversal outside its root. */
|
|
1174
1474
|
function assertSafeRelativeFilePath(filePath) {
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
if (segments.length === 0) throw new Error(`Unsafe file path "${filePath}".`);
|
|
1178
|
-
assertSafeFileName(segments.at(-1) ?? "");
|
|
1179
|
-
const folder = segments.slice(0, -1).join("/");
|
|
1180
|
-
if (folder !== "") {
|
|
1181
|
-
const problem = folderPathError(folder);
|
|
1182
|
-
if (problem) throw new Error(problem);
|
|
1183
|
-
}
|
|
1475
|
+
const problem = rawFilePathError(filePath);
|
|
1476
|
+
if (problem) throw new Error(problem);
|
|
1184
1477
|
}
|
|
1185
1478
|
/**
|
|
1186
1479
|
* Turn an arbitrary uploaded file name (spaces, umlauts, parentheses, nested
|
|
@@ -1232,6 +1525,30 @@ var LibraryStore = class {
|
|
|
1232
1525
|
await rename(temporaryPath, this.#config.library);
|
|
1233
1526
|
}
|
|
1234
1527
|
/**
|
|
1528
|
+
* Candidate-first source transaction used for externally-owned raw files.
|
|
1529
|
+
* The callback runs after entering the store queue and may scan the raw tree;
|
|
1530
|
+
* Fundus writes only the library candidate and never touches external bytes.
|
|
1531
|
+
*/
|
|
1532
|
+
async transactCandidate(change) {
|
|
1533
|
+
return this.#enqueue(async () => {
|
|
1534
|
+
const current = await this.read();
|
|
1535
|
+
const before = serializeLibrary(current);
|
|
1536
|
+
const candidate = structuredClone(current);
|
|
1537
|
+
const value = await change(candidate, current);
|
|
1538
|
+
const changed = serializeLibrary(candidate) !== before;
|
|
1539
|
+
if (changed) await this.write(candidate);
|
|
1540
|
+
return {
|
|
1541
|
+
library: candidate,
|
|
1542
|
+
value,
|
|
1543
|
+
changed
|
|
1544
|
+
};
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
/** Remove derived proxies after a source record was externally deleted/moved. */
|
|
1548
|
+
async deleteProxiesOf(assetId) {
|
|
1549
|
+
await this.#deleteProxiesOf(assetId);
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1235
1552
|
* Ingest a new asset: write the raw file into `rawDir` (under a sanitized,
|
|
1236
1553
|
* non-colliding name), hash its content, and create the library record with
|
|
1237
1554
|
* the owning plugin's default parameters. Returns the updated library.
|
|
@@ -1264,6 +1581,57 @@ var LibraryStore = class {
|
|
|
1264
1581
|
await this.write(library);
|
|
1265
1582
|
return library;
|
|
1266
1583
|
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Replace one asset's raw file while preserving its identity and authored
|
|
1586
|
+
* metadata. The replacement stays in the current folder, receives a safe
|
|
1587
|
+
* non-colliding name, and must be accepted by the asset's existing type.
|
|
1588
|
+
*/
|
|
1589
|
+
async replaceRawFile(id, options) {
|
|
1590
|
+
return this.#enqueue(() => this.#replaceRawFile(id, options));
|
|
1591
|
+
}
|
|
1592
|
+
async #replaceRawFile(id, options) {
|
|
1593
|
+
const library = await this.read();
|
|
1594
|
+
const record = this.#requireAsset(library, id);
|
|
1595
|
+
const sanitizedName = sanitizeFileName(options.fileName);
|
|
1596
|
+
const extension = extname(sanitizedName).slice(1).toLowerCase();
|
|
1597
|
+
const plugin = serverPluginForType(record.type, this.#registry);
|
|
1598
|
+
if (!plugin.descriptor.accepts.includes(extension)) throw new Error(`The ${record.type} type does not accept ".${extension}" files (accepts: ${plugin.descriptor.accepts.join(", ")}).`);
|
|
1599
|
+
const previousRaw = record.raw;
|
|
1600
|
+
const previousHash = record.rawHash;
|
|
1601
|
+
const folder = folderOfRawPath(previousRaw);
|
|
1602
|
+
const previousName = rawFileNameOfPath(previousRaw);
|
|
1603
|
+
const storedName = sanitizedName === previousName ? previousName : this.#uniqueRawName(sanitizedName, folder);
|
|
1604
|
+
const nextRaw = folder === "" ? storedName : `${folder}/${storedName}`;
|
|
1605
|
+
const previousPath = join(this.#config.rawDir, previousRaw);
|
|
1606
|
+
const nextPath = join(this.#config.rawDir, nextRaw);
|
|
1607
|
+
const token = crypto.randomUUID();
|
|
1608
|
+
const temporaryPath = join(this.#config.rawDir, folder, `.fundus-replace-${token}.tmp`);
|
|
1609
|
+
const backupPath = `${previousPath}.fundus-replace-${token}`;
|
|
1610
|
+
let previousStaged = false;
|
|
1611
|
+
let replacementInstalled = false;
|
|
1612
|
+
await mkdir(dirname(temporaryPath), { recursive: true });
|
|
1613
|
+
try {
|
|
1614
|
+
await writeFile(temporaryPath, options.bytes);
|
|
1615
|
+
if (existsSync(previousPath)) {
|
|
1616
|
+
await rename(previousPath, backupPath);
|
|
1617
|
+
previousStaged = true;
|
|
1618
|
+
}
|
|
1619
|
+
await rename(temporaryPath, nextPath);
|
|
1620
|
+
replacementInstalled = true;
|
|
1621
|
+
record.raw = nextRaw;
|
|
1622
|
+
record.rawHash = sha256Hex(options.bytes);
|
|
1623
|
+
await this.write(library);
|
|
1624
|
+
} catch (cause) {
|
|
1625
|
+
record.raw = previousRaw;
|
|
1626
|
+
record.rawHash = previousHash;
|
|
1627
|
+
if (replacementInstalled) await unlink(nextPath).catch(() => {});
|
|
1628
|
+
if (previousStaged) await rename(backupPath, previousPath);
|
|
1629
|
+
await unlink(temporaryPath).catch(() => {});
|
|
1630
|
+
throw cause;
|
|
1631
|
+
}
|
|
1632
|
+
if (previousStaged) await unlink(backupPath).catch(() => {});
|
|
1633
|
+
return library;
|
|
1634
|
+
}
|
|
1267
1635
|
/** Replace an asset's parameters (validated by the owning plugin). */
|
|
1268
1636
|
async updateParameters(id, parameters) {
|
|
1269
1637
|
return this.#enqueue(() => this.#updateParameters(id, parameters));
|
|
@@ -1764,5 +2132,5 @@ var LibraryStore = class {
|
|
|
1764
2132
|
}
|
|
1765
2133
|
};
|
|
1766
2134
|
|
|
1767
|
-
export { LibraryStore as L, serverPluginForType as a, computeLibraryMembership as b, collectAllReferences as c, descriptorsByType as d, allDeliveredAssetIds as e, compareCodeUnits as f, generateManifestModules as g, encodeRelativePathForUrl as h, isRecord as i,
|
|
1768
|
-
//# sourceMappingURL=library-store.js-
|
|
2135
|
+
export { LibraryStore as L, serverPluginForType as a, computeLibraryMembership as b, collectAllReferences as c, descriptorsByType as d, allDeliveredAssetIds as e, compareCodeUnits as f, generateManifestModules as g, encodeRelativePathForUrl as h, isRecord as i, classifyRawDirectory as j, assertSafeRelativeFilePath as k, processAssets as p, readCurrentProxy as r, serverPluginsByType as s, verifyStableRawFile as v };
|
|
2136
|
+
//# sourceMappingURL=library-store.js-DJ-JRE-g.js.map
|