fundus 0.2.0 → 0.4.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 +67 -2
- package/build/client/_app/immutable/assets/2.B5tQm8hR.css +1 -0
- package/build/client/_app/immutable/assets/2.B5tQm8hR.css.br +0 -0
- package/build/client/_app/immutable/assets/2.B5tQm8hR.css.gz +0 -0
- package/build/client/_app/immutable/assets/{3.ChSpCG-T.css → 3.CmXD8k9d.css} +1 -1
- package/build/client/_app/immutable/assets/3.CmXD8k9d.css.br +0 -0
- package/build/client/_app/immutable/assets/3.CmXD8k9d.css.gz +0 -0
- package/build/client/_app/immutable/assets/{LibraryContextMenu.BYvU4SY7.css → LibraryContextMenu.CVb-Lqdf.css} +1 -1
- package/build/client/_app/immutable/assets/LibraryContextMenu.CVb-Lqdf.css.br +0 -0
- package/build/client/_app/immutable/assets/{LibraryContextMenu.BYvU4SY7.css.gz → LibraryContextMenu.CVb-Lqdf.css.gz} +0 -0
- package/build/client/_app/immutable/chunks/{C8W3KwDq.js → BPiGyn-T.js} +1 -1
- package/build/client/_app/immutable/chunks/BPiGyn-T.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPiGyn-T.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CP-bnOxU.js → BoEHtxM8.js} +1 -1
- package/build/client/_app/immutable/chunks/BoEHtxM8.js.br +0 -0
- package/build/client/_app/immutable/chunks/BoEHtxM8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C-T1_s5P.js +1 -0
- package/build/client/_app/immutable/chunks/C-T1_s5P.js.br +0 -0
- package/build/client/_app/immutable/chunks/C-T1_s5P.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{ByVSyIj7.js → CeJsL6hj.js} +1 -1
- package/build/client/_app/immutable/chunks/CeJsL6hj.js.br +0 -0
- package/build/client/_app/immutable/chunks/CeJsL6hj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Db8LRH6X.js → Cq4Yaq35.js} +3 -3
- package/build/client/_app/immutable/chunks/Cq4Yaq35.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cq4Yaq35.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D5sQSsUv.js +1 -0
- package/build/client/_app/immutable/chunks/D5sQSsUv.js.br +0 -0
- package/build/client/_app/immutable/chunks/D5sQSsUv.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.nM6SgHKJ.js → app.BQ4TfPHG.js} +2 -2
- package/build/client/_app/immutable/entry/app.BQ4TfPHG.js.br +0 -0
- package/build/client/_app/immutable/entry/app.BQ4TfPHG.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.COP9tIRH.js +1 -0
- package/build/client/_app/immutable/entry/start.COP9tIRH.js.br +0 -0
- package/build/client/_app/immutable/entry/start.COP9tIRH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.CftchwYV.js +2 -0
- package/build/client/_app/immutable/nodes/0.CftchwYV.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CftchwYV.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.dMklHTc2.js → 1.C8DOqctV.js} +1 -1
- package/build/client/_app/immutable/nodes/1.C8DOqctV.js.br +1 -0
- package/build/client/_app/immutable/nodes/1.C8DOqctV.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BR8OVsS9.js +3 -0
- package/build/client/_app/immutable/nodes/2.BR8OVsS9.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BR8OVsS9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.BO5hcxIH.js +1 -0
- package/build/client/_app/immutable/nodes/3.BO5hcxIH.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BO5hcxIH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.Dgxx52FJ.js → 4.DTaH-k-c.js} +1 -1
- package/build/client/_app/immutable/nodes/4.DTaH-k-c.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.DTaH-k-c.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 +7 -7
- package/build/index.js +7 -7
- package/build/server/chunks/chunks/asset-id.js-CFsW8jeL.js +48 -0
- package/build/server/chunks/chunks/asset-id.js-CFsW8jeL.js.map +1 -0
- package/build/server/chunks/chunks/{context.js-B77ZAVLi.js → context.js-CG2t-ufq.js} +568 -25
- package/build/server/chunks/chunks/context.js-CG2t-ufq.js.map +1 -0
- package/build/server/chunks/chunks/{library-store.js-DJ-JRE-g.js → contract.js-sHny3b-s.js} +133 -359
- package/build/server/chunks/chunks/contract.js-sHny3b-s.js.map +1 -0
- package/build/server/chunks/chunks/{core.js-EA_ysb1J.js → core.js-Clg1CHb6.js} +2 -48
- package/build/server/chunks/chunks/core.js-Clg1CHb6.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-DvhE7Ffd.js → exports.js-rOfFZumP.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-DvhE7Ffd.js.map → exports.js-rOfFZumP.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-DyoR9XRI.js → http.js--6sDZFfm.js} +35 -3
- package/build/server/chunks/chunks/http.js--6sDZFfm.js.map +1 -0
- package/build/server/chunks/chunks/{internal.js-Dn37LrAW.js → internal.js-DnveDsYn.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-Dn37LrAW.js.map → internal.js-DnveDsYn.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/raw-reconciliation.js-DOFtjkgu.js +343 -0
- package/build/server/chunks/chunks/raw-reconciliation.js-DOFtjkgu.js.map +1 -0
- package/build/server/chunks/chunks/raw-reconciliation2.js-DFwky2ou.js +11 -0
- package/build/server/chunks/chunks/raw-reconciliation2.js-DFwky2ou.js.map +1 -0
- package/build/server/chunks/chunks/{shared.js-Dob0TlTu.js → shared.js-DtvIbMLj.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-Dob0TlTu.js.map → shared.js-DtvIbMLj.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-B4YimMxv.js → utils.js-bP1j9RdM.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-B4YimMxv.js.map → utils.js-bP1j9RdM.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-H4Pq1KAE.js → _server.ts.js-CkSErIdC.js} +7 -5
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-H4Pq1KAE.js.map → _server.ts.js-CkSErIdC.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-BI3KHSfE.js → _server.ts.js-BfdsBPWo.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-BI3KHSfE.js.map → _server.ts.js-BfdsBPWo.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BlNYUbXX.js → _server.ts.js-D0aKDq87.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-BlNYUbXX.js.map → _server.ts.js-D0aKDq87.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/_server.ts.js-DsX_m2gc.js +31 -0
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/_server.ts.js-DsX_m2gc.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-j-_N540j.js → _server.ts.js-nfThjRxs.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-j-_N540j.js.map → _server.ts.js-nfThjRxs.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-BHKobzAg.js → _server.ts.js-CseHmsYB.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-BHKobzAg.js.map → _server.ts.js-CseHmsYB.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BFKjIOCv.js → _server.ts.js-CHiICsyC.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-BFKjIOCv.js.map → _server.ts.js-CHiICsyC.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BxZeVw8y.js → _server.ts.js-Dgf46K5u.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-BxZeVw8y.js.map → _server.ts.js-Dgf46K5u.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CO36U_CT.js → _server.ts.js-DwQJUZFa.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-CO36U_CT.js.map → _server.ts.js-DwQJUZFa.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/_server.ts.js-BnKS8nVF.js +37 -0
- package/build/server/chunks/entries/endpoints/api/imports/_server.ts.js-BnKS8nVF.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-CBlg1Bkl.js → _server.ts.js-BrDbLcyO.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-CBlg1Bkl.js.map → _server.ts.js-BrDbLcyO.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DcGLCjIs.js → _server.ts.js-DIUiQuyd.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-DcGLCjIs.js.map → _server.ts.js-DIUiQuyd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AqhtjOiL.js → _server.ts.js-BrReStaf.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-AqhtjOiL.js.map → _server.ts.js-BrReStaf.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CSa6-DcU.js → _server.ts.js-B31iGwJ-.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-CSa6-DcU.js.map → _server.ts.js-B31iGwJ-.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DnzZUoAo.js → _server.ts.js-DeZQFNdj.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DnzZUoAo.js.map → _server.ts.js-DeZQFNdj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-B0KMprKq.js → _server.ts.js-DhDhUU7V.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-B0KMprKq.js.map → _server.ts.js-DhDhUU7V.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/_server.ts.js-DGkPIMcq.js +80 -0
- package/build/server/chunks/entries/endpoints/api/reveal/_server.ts.js-DGkPIMcq.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-B1N9o1Ne.js → _server.ts.js-BTQgWDH1.js} +11 -6
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-B1N9o1Ne.js.map → _server.ts.js-BTQgWDH1.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-B6HbnRqq.js → _server.ts.js-DB3i4juR.js} +7 -5
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-B6HbnRqq.js.map → _server.ts.js-DB3i4juR.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-7wzPyG9v.js → _server.ts.js-kmc-gejQ.js} +11 -6
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-7wzPyG9v.js.map → _server.ts.js-kmc-gejQ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BWztxYge.js → _server.ts.js-B8EE1DD9.js} +11 -6
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-BWztxYge.js.map → _server.ts.js-B8EE1DD9.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-CVKLksJ1.js → hooks.server.js-DbBA5yYQ.js} +10 -5
- package/build/server/chunks/entries/{hooks.server.js-CVKLksJ1.js.map → hooks.server.js-DbBA5yYQ.js.map} +1 -1
- package/build/server/chunks/{handler-DZ2Sps4a.js → handler-J6aKdov3.js} +5 -5
- package/build/server/chunks/{handler-DZ2Sps4a.js.map → handler-J6aKdov3.js.map} +1 -1
- package/build/server/chunks/{index.js-CdmTWQz8.js → index.js-CsvWJ7Qu.js} +5 -5
- package/build/server/chunks/{index.js-CdmTWQz8.js.map → index.js-CsvWJ7Qu.js.map} +1 -1
- package/build/server/chunks/{manifest.js-GhfNr35x.js → manifest.js-wHtZ9vlA.js} +46 -25
- package/build/server/chunks/manifest.js-wHtZ9vlA.js.map +1 -0
- package/build/server/chunks/nodes/0.js-By6-kbk6.js +11 -0
- package/build/server/chunks/nodes/0.js-By6-kbk6.js.map +1 -0
- package/build/server/chunks/nodes/1.js-CrPfmKpN.js +7 -0
- package/build/server/chunks/nodes/{1.js-DQgYreU0.js.map → 1.js-CrPfmKpN.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-C-i3Y5t2.js +7 -0
- package/build/server/chunks/nodes/2.js-C-i3Y5t2.js.map +1 -0
- package/build/server/chunks/nodes/3.js-C1gcIGeV.js +7 -0
- package/build/server/chunks/nodes/3.js-C1gcIGeV.js.map +1 -0
- package/build/server/chunks/nodes/4.js-tgwl3VD3.js +7 -0
- package/build/server/chunks/nodes/{4.js-BebbMVXy.js.map → 4.js-tgwl3VD3.js.map} +1 -1
- package/dist/cli.js +2 -0
- package/dist/config.d.ts +1 -1
- package/dist/core/api-types.d.ts +12 -1
- package/dist/core/config.d.ts +12 -0
- package/dist/core/index.d.ts +3 -2
- package/dist/core/library.d.ts +8 -1
- package/dist/core/library.js +30 -6
- package/dist/server/cli-commands.d.ts +2 -1
- package/dist/server/cli-commands.js +155 -34
- package/dist/server/config-loader.d.ts +9 -1
- package/dist/server/config-loader.js +26 -1
- package/dist/server/file-manager.d.ts +2 -0
- package/dist/server/file-manager.js +17 -0
- package/dist/server/http.d.ts +1 -0
- package/dist/server/http.js +37 -0
- package/dist/server/importers/contract.d.ts +29 -0
- package/dist/server/importers/contract.js +13 -0
- package/dist/server/importers/figma.d.ts +21 -0
- package/dist/server/importers/figma.js +386 -0
- package/dist/server/importers/file.d.ts +6 -0
- package/dist/server/importers/file.js +33 -0
- package/dist/server/importers/pinned-https.d.ts +23 -0
- package/dist/server/importers/pinned-https.js +60 -0
- package/dist/server/importers/registry.d.ts +12 -0
- package/dist/server/importers/registry.js +31 -0
- package/dist/server/importers.d.ts +2 -0
- package/dist/server/importers.js +7 -0
- package/dist/server/library-store.d.ts +19 -1
- package/dist/server/library-store.js +110 -14
- package/dist/server/operations.d.ts +13 -1
- package/dist/server/operations.js +159 -23
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/2.ohi-TClG.css +0 -1
- package/build/client/_app/immutable/assets/2.ohi-TClG.css.br +0 -0
- package/build/client/_app/immutable/assets/2.ohi-TClG.css.gz +0 -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.BYvU4SY7.css.br +0 -0
- package/build/client/_app/immutable/chunks/BAEZPv6c.js +0 -1
- 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/ByVSyIj7.js.br +0 -1
- package/build/client/_app/immutable/chunks/ByVSyIj7.js.gz +0 -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.br +0 -0
- package/build/client/_app/immutable/chunks/CP-bnOxU.js.gz +0 -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/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 +0 -1
- 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 +0 -2
- 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.br +0 -0
- package/build/client/_app/immutable/nodes/1.dMklHTc2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CW4VMcIP.js +0 -3
- 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 +0 -1
- 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.br +0 -0
- package/build/client/_app/immutable/nodes/4.Dgxx52FJ.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-B77ZAVLi.js.map +0 -1
- package/build/server/chunks/chunks/core.js-EA_ysb1J.js.map +0 -1
- package/build/server/chunks/chunks/http.js-DyoR9XRI.js.map +0 -1
- package/build/server/chunks/chunks/library-store.js-DJ-JRE-g.js.map +0 -1
- package/build/server/chunks/manifest.js-GhfNr35x.js.map +0 -1
- package/build/server/chunks/nodes/0.js-DGT86_i-.js +0 -11
- package/build/server/chunks/nodes/0.js-DGT86_i-.js.map +0 -1
- package/build/server/chunks/nodes/1.js-DQgYreU0.js +0 -7
- package/build/server/chunks/nodes/2.js-DItreSrX.js +0 -7
- package/build/server/chunks/nodes/2.js-DItreSrX.js.map +0 -1
- package/build/server/chunks/nodes/3.js-bE1dJ_6v.js +0 -7
- package/build/server/chunks/nodes/3.js-bE1dJ_6v.js.map +0 -1
- package/build/server/chunks/nodes/4.js-BebbMVXy.js +0 -7
|
@@ -8,7 +8,7 @@ import { existsSync } from 'node:fs';
|
|
|
8
8
|
import { mkdir, readFile, rename, rm, unlink, writeFile } from 'node:fs/promises';
|
|
9
9
|
import { dirname, extname, join } from 'node:path';
|
|
10
10
|
import { createHash } from 'node:crypto';
|
|
11
|
-
import { assetIdError, collectAllReferences, createEmptyLibrary, folderNameError, folderNameOf, folderOfRawPath, folderPathError, isFolderOrDescendant, joinFolderPath, manifestColorError, manifestEmojiError, parseLibrary, referenceErrors, normalizeFolderPath, parentFolderPath, portableFolderPathKey, rawFilePathError, rawFileNameOfPath, replaceFolderPrefix, manifestNameError, serializeLibrary } from '../core/index.js';
|
|
11
|
+
import { assetIdError, collectAllReferences, canonicalizeParameters, createEmptyLibrary, folderNameError, folderNameOf, folderOfRawPath, folderPathError, isFolderOrDescendant, joinFolderPath, manifestColorError, manifestEmojiError, parseLibrary, referenceErrors, normalizeFolderPath, parentFolderPath, portableFolderPathKey, rawFilePathError, rawFileNameOfPath, replaceFolderPrefix, manifestNameError, serializeLibrary } from '../core/index.js';
|
|
12
12
|
import { manifestModuleFileName } from './codegen.js';
|
|
13
13
|
import { descriptorsByType, serverPluginForType, serverPluginsByType } from './plugins.js';
|
|
14
14
|
import { isProxyFileNameFor } from './processing/processor.js';
|
|
@@ -114,9 +114,12 @@ export class LibraryStore {
|
|
|
114
114
|
* the owning plugin's default parameters. Returns the updated library.
|
|
115
115
|
*/
|
|
116
116
|
async ingest(options) {
|
|
117
|
-
return this
|
|
117
|
+
return this.createAsset(options);
|
|
118
118
|
}
|
|
119
|
-
async
|
|
119
|
+
async createAsset(options, prepareParameters) {
|
|
120
|
+
return this.#enqueue(() => this.#createAsset(options, prepareParameters));
|
|
121
|
+
}
|
|
122
|
+
async #createAsset(options, prepareParameters) {
|
|
120
123
|
const idProblem = assetIdError(options.id);
|
|
121
124
|
if (idProblem)
|
|
122
125
|
throw new Error(idProblem);
|
|
@@ -131,21 +134,57 @@ export class LibraryStore {
|
|
|
131
134
|
}
|
|
132
135
|
const folder = options.folder === undefined ? '' : normalizeFolderPath(options.folder);
|
|
133
136
|
this.#requireFolder(library, folder);
|
|
137
|
+
const manifests = [...new Set(options.manifests ?? [])].sort();
|
|
138
|
+
for (const manifest of manifests) {
|
|
139
|
+
if (!Object.hasOwn(library.manifests, manifest)) {
|
|
140
|
+
throw new Error(`Unknown manifest "${manifest}".`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
134
143
|
const rawDirectory = join(this.#config.rawDir, folder);
|
|
135
144
|
await mkdir(rawDirectory, { recursive: true });
|
|
136
145
|
const storedName = this.#uniqueRawName(sanitizeFileName(options.fileName), folder);
|
|
137
146
|
const storedPath = folder === '' ? storedName : `${folder}/${storedName}`;
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
parameters
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
const finalPath = join(this.#config.rawDir, storedPath);
|
|
148
|
+
const temporaryPath = join(rawDirectory, `.fundus-create-${crypto.randomUUID()}.tmp`);
|
|
149
|
+
let installed = false;
|
|
150
|
+
try {
|
|
151
|
+
await writeFile(temporaryPath, options.bytes);
|
|
152
|
+
let parameters = plugin.descriptor.validateParameters(plugin.descriptor.defaultParameters(plugin.pluginConfig(this.#config)));
|
|
153
|
+
if (prepareParameters) {
|
|
154
|
+
parameters = plugin.descriptor.validateParameters(await prepareParameters({ rawPath: temporaryPath, rawFileName: storedName, parameters }));
|
|
155
|
+
}
|
|
156
|
+
const record = {
|
|
157
|
+
type: options.type,
|
|
158
|
+
raw: storedPath,
|
|
159
|
+
rawHash: sha256Hex(options.bytes),
|
|
160
|
+
parameters,
|
|
161
|
+
manifests
|
|
162
|
+
};
|
|
163
|
+
if (options.importSource) {
|
|
164
|
+
record.importSource = structuredClone(options.importSource);
|
|
165
|
+
library.version = 2;
|
|
166
|
+
}
|
|
167
|
+
library.assets[options.id] = record;
|
|
168
|
+
// Validate the complete candidate before installing the final raw path.
|
|
169
|
+
parseLibrary(serializeLibrary(library));
|
|
170
|
+
await rename(temporaryPath, finalPath);
|
|
171
|
+
installed = true;
|
|
172
|
+
await this.write(library);
|
|
173
|
+
return library;
|
|
174
|
+
}
|
|
175
|
+
catch (cause) {
|
|
176
|
+
const cleanupErrors = [];
|
|
177
|
+
if (installed)
|
|
178
|
+
await unlink(finalPath).catch((error) => cleanupErrors.push(error));
|
|
179
|
+
await unlink(temporaryPath).catch((error) => {
|
|
180
|
+
if (error.code !== 'ENOENT')
|
|
181
|
+
cleanupErrors.push(error);
|
|
182
|
+
});
|
|
183
|
+
if (cleanupErrors.length > 0) {
|
|
184
|
+
throw new AggregateError([cause, ...cleanupErrors], 'Asset creation failed and cleanup was incomplete.');
|
|
185
|
+
}
|
|
186
|
+
throw cause;
|
|
187
|
+
}
|
|
149
188
|
}
|
|
150
189
|
/**
|
|
151
190
|
* Replace one asset's raw file while preserving its identity and authored
|
|
@@ -166,6 +205,7 @@ export class LibraryStore {
|
|
|
166
205
|
}
|
|
167
206
|
const previousRaw = record.raw;
|
|
168
207
|
const previousHash = record.rawHash;
|
|
208
|
+
const previousSource = record.importSource;
|
|
169
209
|
const folder = folderOfRawPath(previousRaw);
|
|
170
210
|
const previousName = rawFileNameOfPath(previousRaw);
|
|
171
211
|
const storedName = sanitizedName === previousName ? previousName : this.#uniqueRawName(sanitizedName, folder);
|
|
@@ -188,11 +228,14 @@ export class LibraryStore {
|
|
|
188
228
|
replacementInstalled = true;
|
|
189
229
|
record.raw = nextRaw;
|
|
190
230
|
record.rawHash = sha256Hex(options.bytes);
|
|
231
|
+
delete record.importSource;
|
|
191
232
|
await this.write(library);
|
|
192
233
|
}
|
|
193
234
|
catch (cause) {
|
|
194
235
|
record.raw = previousRaw;
|
|
195
236
|
record.rawHash = previousHash;
|
|
237
|
+
if (previousSource)
|
|
238
|
+
record.importSource = previousSource;
|
|
196
239
|
if (replacementInstalled)
|
|
197
240
|
await unlink(nextPath).catch(() => { });
|
|
198
241
|
if (previousStaged)
|
|
@@ -204,6 +247,59 @@ export class LibraryStore {
|
|
|
204
247
|
await unlink(backupPath).catch(() => { });
|
|
205
248
|
return library;
|
|
206
249
|
}
|
|
250
|
+
/** CAS-protected replacement used only by a repeatable import source. */
|
|
251
|
+
async replaceRawFromImportSource(id, bytes, expected, nextSource) {
|
|
252
|
+
return this.#enqueue(async () => {
|
|
253
|
+
const library = await this.read();
|
|
254
|
+
const record = this.#requireAsset(library, id);
|
|
255
|
+
if (record.raw !== expected.raw ||
|
|
256
|
+
record.rawHash !== expected.rawHash ||
|
|
257
|
+
record.type !== expected.type ||
|
|
258
|
+
!record.importSource ||
|
|
259
|
+
canonicalizeParameters(record.importSource) !== expected.canonicalSource) {
|
|
260
|
+
throw new Error('stale-import');
|
|
261
|
+
}
|
|
262
|
+
const absolutePath = join(this.#config.rawDir, record.raw);
|
|
263
|
+
const { verifyStableRawFile } = await import('./raw-reconciliation.js');
|
|
264
|
+
try {
|
|
265
|
+
await verifyStableRawFile(absolutePath, expected.rawHash);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
throw new Error('stale-import');
|
|
269
|
+
}
|
|
270
|
+
const token = crypto.randomUUID();
|
|
271
|
+
const temporaryPath = `${absolutePath}.fundus-reimport-${token}.tmp`;
|
|
272
|
+
const backupPath = `${absolutePath}.fundus-reimport-${token}`;
|
|
273
|
+
const previousHash = record.rawHash;
|
|
274
|
+
const previousSource = structuredClone(record.importSource);
|
|
275
|
+
let staged = false;
|
|
276
|
+
let installed = false;
|
|
277
|
+
try {
|
|
278
|
+
await writeFile(temporaryPath, bytes);
|
|
279
|
+
await rename(absolutePath, backupPath);
|
|
280
|
+
staged = true;
|
|
281
|
+
await rename(temporaryPath, absolutePath);
|
|
282
|
+
installed = true;
|
|
283
|
+
record.rawHash = sha256Hex(bytes);
|
|
284
|
+
if (nextSource)
|
|
285
|
+
record.importSource = structuredClone(nextSource);
|
|
286
|
+
await this.write(library);
|
|
287
|
+
}
|
|
288
|
+
catch (cause) {
|
|
289
|
+
record.rawHash = previousHash;
|
|
290
|
+
record.importSource = previousSource;
|
|
291
|
+
if (installed)
|
|
292
|
+
await unlink(absolutePath).catch(() => { });
|
|
293
|
+
if (staged)
|
|
294
|
+
await rename(backupPath, absolutePath);
|
|
295
|
+
await unlink(temporaryPath).catch(() => { });
|
|
296
|
+
throw cause;
|
|
297
|
+
}
|
|
298
|
+
if (staged)
|
|
299
|
+
await unlink(backupPath).catch(() => { });
|
|
300
|
+
return library;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
207
303
|
/** Replace an asset's parameters (validated by the owning plugin). */
|
|
208
304
|
async updateParameters(id, parameters) {
|
|
209
305
|
return this.#enqueue(() => this.#updateParameters(id, parameters));
|
|
@@ -2,6 +2,7 @@ import { type FundusStateDto, type PatchAssetRequestDto, type PatchManifestReque
|
|
|
2
2
|
import type { ResolvedFundusConfig } from './config-loader.js';
|
|
3
3
|
import { LibraryStore, type IngestOptions, type ReplaceRawFileOptions } from './library-store.js';
|
|
4
4
|
import type { ServerPluginRegistry } from './plugins/contract.js';
|
|
5
|
+
import { SourceImporterRegistry } from './importers/registry.js';
|
|
5
6
|
/**
|
|
6
7
|
* The CLI's `--parameters` merge semantics (M7): a SHALLOW merge at the top
|
|
7
8
|
* level onto the current parameters — a nested object value replaces the whole
|
|
@@ -17,9 +18,16 @@ export interface AssetChangeOptions {
|
|
|
17
18
|
/** Replacement for the explicit manifest membership set (declarative). */
|
|
18
19
|
manifests?: string[];
|
|
19
20
|
}
|
|
21
|
+
export interface ImportAssetOptions extends AssetChangeOptions {
|
|
22
|
+
importer: string;
|
|
23
|
+
input: unknown;
|
|
24
|
+
type: string;
|
|
25
|
+
id: string;
|
|
26
|
+
folder?: string;
|
|
27
|
+
}
|
|
20
28
|
export declare class FundusOperations {
|
|
21
29
|
#private;
|
|
22
|
-
constructor(config: ResolvedFundusConfig, registry?: ServerPluginRegistry);
|
|
30
|
+
constructor(config: ResolvedFundusConfig, registry?: ServerPluginRegistry, importerRegistry?: SourceImporterRegistry);
|
|
23
31
|
get config(): ResolvedFundusConfig;
|
|
24
32
|
get store(): LibraryStore;
|
|
25
33
|
/** Read-only state snapshot, serialized with mutations but never processing or writing. */
|
|
@@ -42,6 +50,10 @@ export declare class FundusOperations {
|
|
|
42
50
|
* rolls the whole ingest back, so a failed ingest leaves nothing behind.
|
|
43
51
|
*/
|
|
44
52
|
ingest(options: IngestOptions & AssetChangeOptions): Promise<FundusStateDto>;
|
|
53
|
+
/** Materialize a source outside the operation queue, then atomically create the asset. */
|
|
54
|
+
importAsset(options: ImportAssetOptions): Promise<FundusStateDto>;
|
|
55
|
+
/** Re-materialize a persisted source with record and on-disk CAS protection. */
|
|
56
|
+
reimportAsset(id: string, input?: unknown): Promise<FundusStateDto>;
|
|
45
57
|
/** Apply a PATCH body: parameters and/or manifests and/or a rename — in that order. */
|
|
46
58
|
patchAsset(id: string, body: PatchAssetRequestDto): Promise<FundusStateDto>;
|
|
47
59
|
moveAsset(id: string, folder: string): Promise<FundusStateDto>;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* operation has exactly one implementation and there is no other save path.
|
|
7
7
|
*/
|
|
8
8
|
import { join } from 'node:path';
|
|
9
|
-
import { assetIdError, allDeliveredAssetIds, collectAllReferences, compareCodeUnits, computeLibraryMembership, folderOfRawPath, parentFolderPath, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, typesForFileName } from '../core/index.js';
|
|
9
|
+
import { assetIdError, allDeliveredAssetIds, canonicalizeParameters, collectAllReferences, compareCodeUnits, computeLibraryMembership, folderOfRawPath, normalizeFolderPath, parentFolderPath, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, typesForFileName } from '../core/index.js';
|
|
10
10
|
import { LibraryStore } from './library-store.js';
|
|
11
11
|
import { generateManifestModules } from './codegen.js';
|
|
12
12
|
import { descriptorsByType, serverPluginForType, serverPluginsByType } from './plugins.js';
|
|
@@ -14,6 +14,8 @@ import { processAssets, readCurrentProxy } from './processing/processor.js';
|
|
|
14
14
|
import { encodeRelativePathForUrl } from './folder-filesystem.js';
|
|
15
15
|
import { classifyRawDirectory, verifyStableRawFile } from './raw-reconciliation.js';
|
|
16
16
|
import { rawSafetyIssues } from './raw-safety.js';
|
|
17
|
+
import { serverImporters } from './importers.js';
|
|
18
|
+
import { SourceImportError } from './importers/contract.js';
|
|
17
19
|
/**
|
|
18
20
|
* The CLI's `--parameters` merge semantics (M7): a SHALLOW merge at the top
|
|
19
21
|
* level onto the current parameters — a nested object value replaces the whole
|
|
@@ -44,12 +46,14 @@ export class FundusOperations {
|
|
|
44
46
|
#config;
|
|
45
47
|
#registry;
|
|
46
48
|
#store;
|
|
49
|
+
#importers;
|
|
47
50
|
#operationQueue = Promise.resolve();
|
|
48
51
|
#pipelineQueue = Promise.resolve();
|
|
49
|
-
constructor(config, registry = serverPluginsByType) {
|
|
52
|
+
constructor(config, registry = serverPluginsByType, importerRegistry = serverImporters) {
|
|
50
53
|
this.#config = config;
|
|
51
54
|
this.#registry = registry;
|
|
52
55
|
this.#store = new LibraryStore(config, registry);
|
|
56
|
+
this.#importers = importerRegistry;
|
|
53
57
|
}
|
|
54
58
|
get config() {
|
|
55
59
|
return this.#config;
|
|
@@ -198,6 +202,7 @@ export class FundusOperations {
|
|
|
198
202
|
record.type = type;
|
|
199
203
|
record.rawHash = edited.hash;
|
|
200
204
|
record.parameters = parameters;
|
|
205
|
+
delete record.importSource;
|
|
201
206
|
return edited.assetId;
|
|
202
207
|
});
|
|
203
208
|
await this.#store.deleteProxiesOf(result.value);
|
|
@@ -217,6 +222,7 @@ export class FundusOperations {
|
|
|
217
222
|
throw new Error(`The moved file "${edited.path}" is not compatible with its current ${record.type} type; choose a compatible type and process it.`);
|
|
218
223
|
}
|
|
219
224
|
candidate.assets[edited.assetId].rawHash = edited.hash;
|
|
225
|
+
delete candidate.assets[edited.assetId].importSource;
|
|
220
226
|
return edited.assetId;
|
|
221
227
|
});
|
|
222
228
|
await this.#store.deleteProxiesOf(result.value);
|
|
@@ -233,36 +239,161 @@ export class FundusOperations {
|
|
|
233
239
|
* rolls the whole ingest back, so a failed ingest leaves nothing behind.
|
|
234
240
|
*/
|
|
235
241
|
ingest(options) {
|
|
236
|
-
return this.#enqueueOperation(() =>
|
|
242
|
+
return this.#enqueueOperation(async () => {
|
|
243
|
+
const importer = this.#importers.require('file');
|
|
244
|
+
const input = importer.validateInput({ fileName: options.fileName, bytes: options.bytes });
|
|
245
|
+
const raw = await importer.importRaw(input, {
|
|
246
|
+
config: this.#config,
|
|
247
|
+
fetch: globalThis.fetch
|
|
248
|
+
});
|
|
249
|
+
return this.#createImportedAsset(raw, options);
|
|
250
|
+
});
|
|
237
251
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
252
|
+
/** Materialize a source outside the operation queue, then atomically create the asset. */
|
|
253
|
+
async importAsset(options) {
|
|
254
|
+
const preflight = await this.#enqueueOperation(async () => {
|
|
255
|
+
const library = await this.#store.read();
|
|
256
|
+
this.#validateImportTarget(options, library);
|
|
257
|
+
if (Object.hasOwn(library.assets, options.id)) {
|
|
258
|
+
throw new SourceImportError('invalid-input', `An asset with id "${options.id}" already exists.`);
|
|
259
|
+
}
|
|
260
|
+
const importer = this.#importers.require(options.importer);
|
|
261
|
+
return { importer, input: importer.validateInput(options.input) };
|
|
262
|
+
});
|
|
263
|
+
const raw = await preflight.importer.importRaw(preflight.input, {
|
|
264
|
+
config: this.#config,
|
|
265
|
+
fetch: globalThis.fetch
|
|
266
|
+
});
|
|
267
|
+
return this.#enqueueOperation(async () => {
|
|
268
|
+
this.#validateImportedRaw(raw, options.importer);
|
|
269
|
+
return this.#createImportedAsset(raw, options);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/** Re-materialize a persisted source with record and on-disk CAS protection. */
|
|
273
|
+
async reimportAsset(id, input) {
|
|
274
|
+
const snapshot = await this.#enqueueOperation(async () => {
|
|
275
|
+
const library = await this.#store.read();
|
|
276
|
+
this.#requireAsset(library, id);
|
|
277
|
+
const record = library.assets[id];
|
|
278
|
+
if (!record.importSource) {
|
|
279
|
+
throw new SourceImportError('invalid-input', `Asset "${id}" has no repeatable import source.`);
|
|
280
|
+
}
|
|
281
|
+
const resolved = this.#importers.requireReimport(record.importSource);
|
|
282
|
+
try {
|
|
283
|
+
await verifyStableRawFile(join(this.#config.rawDir, record.raw), record.rawHash);
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
throw new SourceImportError('stale-import', 'The local raw file changed. Apply or discard that edit before re-importing.');
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
importer: resolved.importer,
|
|
290
|
+
parameters: resolved.parameters,
|
|
291
|
+
input: input === undefined ? undefined : resolved.importer.validateInput(input),
|
|
292
|
+
expected: {
|
|
293
|
+
raw: record.raw,
|
|
294
|
+
rawHash: record.rawHash,
|
|
295
|
+
type: record.type,
|
|
296
|
+
canonicalSource: canonicalizeParameters(record.importSource)
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
const context = { config: this.#config, fetch: globalThis.fetch };
|
|
301
|
+
const raw = snapshot.input === undefined
|
|
302
|
+
? await snapshot.importer.reimportRaw(snapshot.parameters, context)
|
|
303
|
+
: await snapshot.importer.importRaw(snapshot.input, context);
|
|
304
|
+
if (snapshot.input !== undefined && !raw.importSource) {
|
|
305
|
+
throw new SourceImportError('invalid-response', 'The source importer did not return provenance for the updated source.');
|
|
306
|
+
}
|
|
307
|
+
return this.#enqueueOperation(async () => {
|
|
308
|
+
this.#validateImportedRaw(raw, snapshot.importer.kind);
|
|
309
|
+
const plugin = serverPluginForType(snapshot.expected.type, this.#registry);
|
|
310
|
+
if (!plugin.descriptor.accepts.includes(raw.extension)) {
|
|
311
|
+
throw new SourceImportError('invalid-response', `The ${snapshot.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
312
|
+
}
|
|
313
|
+
let library;
|
|
314
|
+
try {
|
|
315
|
+
library = await this.#store.replaceRawFromImportSource(id, raw.bytes, snapshot.expected, raw.importSource);
|
|
316
|
+
}
|
|
317
|
+
catch (cause) {
|
|
318
|
+
if (cause instanceof Error && cause.message === 'stale-import') {
|
|
319
|
+
throw new SourceImportError('stale-import', 'The asset or local raw file changed while Figma was exporting. Nothing was replaced.');
|
|
320
|
+
}
|
|
321
|
+
throw cause;
|
|
322
|
+
}
|
|
323
|
+
return this.#afterMutation(library);
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
async #createImportedAsset(raw, options) {
|
|
327
|
+
this.#validateImportedRaw(raw);
|
|
328
|
+
const fileName = raw.suggestedFileName ?? `${options.id}.${raw.extension}`;
|
|
329
|
+
const plugin = serverPluginForType(options.type, this.#registry);
|
|
330
|
+
const library = await this.#store.createAsset({
|
|
331
|
+
fileName,
|
|
332
|
+
bytes: raw.bytes,
|
|
333
|
+
type: options.type,
|
|
334
|
+
id: options.id,
|
|
335
|
+
folder: options.folder,
|
|
336
|
+
manifests: options.manifests,
|
|
337
|
+
importSource: raw.importSource
|
|
338
|
+
}, async ({ rawPath, rawFileName, parameters }) => {
|
|
339
|
+
let next = parameters;
|
|
242
340
|
if (plugin.seedIngestParameters) {
|
|
243
|
-
const record = library.assets[options.id];
|
|
244
341
|
const seeded = await plugin.seedIngestParameters({
|
|
245
|
-
rawPath
|
|
246
|
-
rawFileName
|
|
247
|
-
parameters:
|
|
342
|
+
rawPath,
|
|
343
|
+
rawFileName,
|
|
344
|
+
parameters: next,
|
|
248
345
|
config: this.#config
|
|
249
346
|
});
|
|
250
|
-
if (seeded !== undefined)
|
|
251
|
-
|
|
252
|
-
}
|
|
347
|
+
if (seeded !== undefined)
|
|
348
|
+
next = seeded;
|
|
253
349
|
}
|
|
254
|
-
if (options.parametersPatch !== undefined
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
350
|
+
if (options.parametersPatch !== undefined) {
|
|
351
|
+
next = mergeParameterPatch(next, options.parametersPatch);
|
|
352
|
+
}
|
|
353
|
+
return plugin.descriptor.validateParameters(next);
|
|
354
|
+
});
|
|
355
|
+
return this.#afterMutation(library);
|
|
356
|
+
}
|
|
357
|
+
#validateImportTarget(options, library) {
|
|
358
|
+
if (typeof options.importer !== 'string' ||
|
|
359
|
+
typeof options.id !== 'string' ||
|
|
360
|
+
typeof options.type !== 'string') {
|
|
361
|
+
throw new SourceImportError('invalid-input', 'Import requires importer, type, and id strings.');
|
|
362
|
+
}
|
|
363
|
+
const problem = assetIdError(options.id);
|
|
364
|
+
if (problem)
|
|
365
|
+
throw new SourceImportError('invalid-input', problem);
|
|
366
|
+
serverPluginForType(options.type, this.#registry);
|
|
367
|
+
if (options.folder !== undefined && typeof options.folder !== 'string') {
|
|
368
|
+
throw new SourceImportError('invalid-input', 'Import folder must be a string.');
|
|
369
|
+
}
|
|
370
|
+
const folder = normalizeFolderPath(options.folder ?? '');
|
|
371
|
+
if (folder !== '' && !library.folders.includes(folder)) {
|
|
372
|
+
throw new SourceImportError('invalid-input', `Unknown folder "${folder}".`);
|
|
373
|
+
}
|
|
374
|
+
if (options.manifests !== undefined &&
|
|
375
|
+
(!Array.isArray(options.manifests) ||
|
|
376
|
+
options.manifests.some((value) => typeof value !== 'string'))) {
|
|
377
|
+
throw new SourceImportError('invalid-input', 'Import manifests must be an array of strings.');
|
|
378
|
+
}
|
|
379
|
+
for (const manifest of new Set(options.manifests ?? [])) {
|
|
380
|
+
if (!Object.hasOwn(library.manifests, manifest)) {
|
|
381
|
+
throw new SourceImportError('invalid-input', `Unknown manifest "${manifest}".`);
|
|
259
382
|
}
|
|
260
383
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
384
|
+
}
|
|
385
|
+
#validateImportedRaw(raw, importerKind) {
|
|
386
|
+
if (!(raw.bytes instanceof Uint8Array) || !/^[a-z0-9]+$/.test(raw.extension)) {
|
|
387
|
+
throw new SourceImportError('invalid-response', 'The source importer returned invalid raw data.');
|
|
388
|
+
}
|
|
389
|
+
if (raw.importSource) {
|
|
390
|
+
if (importerKind && raw.importSource.importer !== importerKind) {
|
|
391
|
+
throw new SourceImportError('invalid-response', 'The source importer returned mismatched provenance.');
|
|
392
|
+
}
|
|
393
|
+
this.#importers
|
|
394
|
+
.require(raw.importSource.importer)
|
|
395
|
+
.validateSourceParameters(raw.importSource.parameters);
|
|
264
396
|
}
|
|
265
|
-
return this.#afterMutation(library);
|
|
266
397
|
}
|
|
267
398
|
/** Apply a PATCH body: parameters and/or manifests and/or a rename — in that order. */
|
|
268
399
|
patchAsset(id, body) {
|
|
@@ -546,6 +677,9 @@ export class FundusOperations {
|
|
|
546
677
|
warnings.push('In no manifest and not referenced by any delivered asset — ' +
|
|
547
678
|
'nothing is processed or generated for it.');
|
|
548
679
|
}
|
|
680
|
+
if (record.importSource && !this.#importers.has(record.importSource.importer)) {
|
|
681
|
+
warnings.push(`Importer "${record.importSource.importer}" is unavailable; the local raw file remains usable.`);
|
|
682
|
+
}
|
|
549
683
|
let proxy = null;
|
|
550
684
|
if (delivered.has(assetId)) {
|
|
551
685
|
try {
|
|
@@ -572,6 +706,7 @@ export class FundusOperations {
|
|
|
572
706
|
folder: folderOfRawPath(record.raw),
|
|
573
707
|
rawUrl: `/files/raw/${encodeRelativePathForUrl(record.raw)}?v=${record.rawHash.slice(0, 12)}`,
|
|
574
708
|
rawHash: record.rawHash,
|
|
709
|
+
importSource: record.importSource,
|
|
575
710
|
parameters: record.parameters,
|
|
576
711
|
manifests: record.manifests,
|
|
577
712
|
passiveManifests: passiveManifestsByAsset.get(assetId) ?? [],
|
|
@@ -614,6 +749,7 @@ export class FundusOperations {
|
|
|
614
749
|
return {
|
|
615
750
|
library,
|
|
616
751
|
assets,
|
|
752
|
+
importDefaults: { figma: { scale: this.#config.import.figma.defaults.scale } },
|
|
617
753
|
issues,
|
|
618
754
|
presetNames,
|
|
619
755
|
manifestMemberships,
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.context-menu.svelte-109nkvw{z-index:200;background:var(--panel-raised);border:1px solid var(--border);border-radius:6px;width:168px;padding:4px;position:fixed;box-shadow:0 8px 24px #00000073}button.svelte-109nkvw{width:100%;color:var(--text);font:inherit;text-align:left;background:0 0;border:0;border-radius:4px;padding:6px 8px}button.svelte-109nkvw:hover,button.svelte-109nkvw:focus-visible{background:var(--accent-soft);outline:none}button.danger.svelte-109nkvw{color:var(--danger)}.manifest-label.svelte-1b4m5oj{align-items:center;gap:4px;min-width:0;display:inline-flex}.emoji.svelte-1b4m5oj{flex:none;line-height:1}.name.svelte-1b4m5oj{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.chip.svelte-1b4m5oj{background:color-mix(in srgb, var(--manifest-color) 20%, transparent);color:var(--manifest-color);border-radius:4px;padding:0 5px;font-size:10px}.chip.passive.svelte-1b4m5oj{border:1px dashed var(--manifest-color);background:0 0}.library-view.svelte-1uha8ag{flex:1;min-height:0;display:flex}.page.svelte-1uha8ag{flex:1;min-height:0;padding:16px;position:relative;overflow-y:auto}.selection-bar.svelte-1uha8ag,.filter-bar.svelte-1uha8ag{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.selection-bar.svelte-1uha8ag{margin-bottom:8px}.filter-bar.svelte-1uha8ag{margin-bottom:16px}.selection-summary.svelte-1uha8ag{color:var(--accent);white-space:nowrap;font-weight:600}.toggle.svelte-1uha8ag{color:var(--text-dim);align-items:center;gap:6px;display:inline-flex}.search.svelte-1uha8ag{align-items:center;gap:5px;width:220px;padding:0 6px;display:flex}.search.svelte-1uha8ag:focus-within{border-color:var(--accent)}.search-icon.svelte-1uha8ag{fill:none;width:14px;height:14px;stroke:var(--text-faint);stroke-width:1.5px;stroke-linecap:round;flex:none}.search-input.svelte-1uha8ag{min-width:0;height:100%;color:var(--text);font:inherit;background:0 0;border:0;outline:none;flex:1;padding:0}.search.svelte-1uha8ag kbd:where(.svelte-1uha8ag){border:1px solid var(--border);color:var(--text-faint);border-radius:3px;flex:none;padding:1px 4px;font:9px/14px system-ui,sans-serif}.import.svelte-1uha8ag{background:var(--accent);color:var(--text);margin-left:auto}.section.svelte-1uha8ag{margin-bottom:24px}.section.svelte-1uha8ag:last-child{margin-bottom:0}.section-emoji.svelte-1uha8ag{margin-right:6px}.grid.svelte-1uha8ag,.folder-grid.svelte-1uha8ag{grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;display:grid}.folder-card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);min-width:0;height:60px;color:var(--text);text-align:left;border-radius:8px;align-items:center;gap:10px;padding:8px 10px;display:flex}.folder-card.svelte-1uha8ag:hover,.folder-card.svelte-1uha8ag:focus-visible{border-color:var(--accent);outline:none}.folder-card.drop-target.svelte-1uha8ag{border-color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent)}.folder-card.dragging-folder.svelte-1uha8ag{opacity:.55}.folder-card-icon.svelte-1uha8ag{color:var(--text-dim);flex:none;align-items:center;display:flex}.folder-card-details.svelte-1uha8ag{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.folder-card-details.svelte-1uha8ag strong:where(.svelte-1uha8ag){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.folder-card-details.svelte-1uha8ag span:where(.svelte-1uha8ag),.folder-card-arrow.svelte-1uha8ag{color:var(--text-faint)}.folder-card-arrow.svelte-1uha8ag{flex:none;font-size:18px}.card.svelte-1uha8ag{background:var(--panel);border:1px solid var(--border-soft);border-radius:8px;flex-direction:column;gap:8px;padding:8px;display:flex;position:relative}.card.selected.svelte-1uha8ag{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}.asset-select.svelte-1uha8ag{z-index:1;width:16px;height:16px;accent-color:var(--accent);position:absolute;top:12px;left:12px}.card.svelte-1uha8ag:hover{border-color:var(--accent)}.thumbnail.svelte-1uha8ag{border-radius:var(--radius);justify-content:center;align-items:center;height:96px;display:flex;overflow:hidden}.meta.svelte-1uha8ag{align-items:center;gap:6px;min-width:0;display:flex}.id.svelte-1uha8ag{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.type-badge.svelte-1uha8ag{color:var(--text-dim);border:1px solid var(--border);border-radius:4px;flex:none;margin-left:auto;padding:0 5px;font-size:10px}.badges.svelte-1uha8ag{flex-wrap:wrap;gap:4px;min-height:16px;display:flex}.badge.svelte-1uha8ag{border-radius:4px;padding:0 5px;font-size:10px}.badge.warning.svelte-1uha8ag{background:var(--warning-soft);color:var(--warning)}.empty.svelte-1uha8ag{color:var(--text-dim);text-align:center;padding:48px}.dialog-row.svelte-1uha8ag{align-items:center;gap:8px;display:flex}.dialog-row.svelte-1uha8ag span:where(.svelte-1uha8ag){width:44px;color:var(--text-dim)}.dialog-row.svelte-1uha8ag input:where(.svelte-1uha8ag){flex:1}.dialog-text.svelte-1uha8ag,.dialog-warning.svelte-1uha8ag{margin:8px 0 0}.dialog-warning.svelte-1uha8ag{color:var(--warning)}.drop-hint.svelte-1uha8ag{border:2px dashed var(--accent);color:var(--accent);pointer-events:none;background:#0d99ff14;border-radius:12px;justify-content:center;align-items:center;font-size:14px;display:flex;position:fixed;inset:48px 8px 8px}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{F as e,X as t,Y as n}from"./D65cSBhe.js";async function r(e){if(!e.ok){let t=`${e.status} ${e.statusText}`;try{let n=await e.json();n.error?.message&&(t=n.error.message)}catch{}throw Error(t)}return await e.json()}async function i(){return r(await fetch(`/api/state`,{cache:`no-store`}))}async function a(){return r(await fetch(`/api/reconcile`,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`},body:JSON.stringify({})}))}async function o(e,t,n,i=[]){return r(await fetch(`/api/raw/adopt`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e,id:t,type:n,manifests:i})}))}async function s(e,t){return r(await fetch(`/api/raw/edited/accept`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e,type:t})}))}async function c(e){return r(await fetch(`/api/raw/edited/dismiss`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e})}))}async function l(e,t,n,i,a=[]){let o=new FormData;o.set(`file`,e),o.set(`type`,t),o.set(`id`,n),o.set(`folder`,i);for(let e of a)o.append(`manifests`,e);return r(await fetch(`/api/assets`,{method:`POST`,body:o}))}async function u(e,t){let n=new FormData;return n.set(`file`,t),r(await fetch(`/api/assets/${encodeURIComponent(e)}/raw`,{method:`PUT`,body:n}))}async function d(e){return r(await fetch(`/api/folders`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e})}))}async function f(e,t){return r(await fetch(`/api/folders/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t})}))}async function p(e,t){return r(await fetch(`/api/folders/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({parent:t})}))}async function m(e){return r(await fetch(`/api/folders/${encodeURIComponent(e)}`,{method:`DELETE`}))}async function h(e,t){return r(await fetch(`/api/assets/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}))}async function g(e,t){return r(await fetch(`/api/assets/move`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({assetIds:e,folder:t})}))}async function _(e){return r(await fetch(`/api/assets/${encodeURIComponent(e)}`,{method:`DELETE`}))}async function v(e){return r(await fetch(`/api/assets/delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({assetIds:e})}))}async function y(e){return r(await fetch(`/api/manifests`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:e})}))}async function b(e){return r(await fetch(`/api/manifests/${encodeURIComponent(e)}`,{method:`DELETE`}))}async function x(e,t){return r(await fetch(`/api/manifests/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(t)}))}var S=class{#e=Promise.resolve();#t=new Map;enqueue(e){let t=this.#e.then(e,e);return this.#e=t.then(()=>{},()=>{}),t}coalesce(e,t){let n=this.#t.get(e);if(n)return n;let r=this.enqueue(t).finally(()=>{this.#t.get(e)===r&&this.#t.delete(e)});return this.#t.set(e,r),r}},C=new class{#e=new S;#t=t(null);get state(){return e(this.#t)}set state(e){n(this.#t,e,!0)}#n=t(!1);get saving(){return e(this.#n)}set saving(e){n(this.#n,e,!0)}#r=t(null);get error(){return e(this.#r)}set error(e){n(this.#r,e,!0)}#i=t(!1);get loaded(){return e(this.#i)}set loaded(e){n(this.#i,e,!0)}async refresh(){return this.#a(i)}reconcile(){return this.#a(a,!0)}#a(e,t=!1){let n=async()=>{try{this.state=await e(),this.error=null}catch(e){this.error=e instanceof Error?e.message:String(e)}finally{this.loaded=!0}};return t?this.#e.coalesce(`reconcile`,n):this.#e.enqueue(n)}mutate(e){return this.#e.enqueue(async()=>{this.saving=!0,this.error=null;try{let t=await e();return this.state=t,t}catch(e){throw this.error=e instanceof Error?e.message:String(e),e}finally{this.saving=!1}})}get manifestNames(){return Object.keys(this.state?.library.manifests??{}).sort()}manifestAppearance(e){return this.state?.library.manifests[e]??{}}get generalIssues(){return this.state?.issues.filter(e=>e.assetId===void 0).map(e=>e.message)??[]}assetById(e){return this.state?.assets.find(t=>t.id===e)??null}},w=`[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}`;RegExp(`^(?:\\.fundus-replace-${w}\\.tmp|\\.fundus-delete(?:-assets)?-${w})$`,`i`),RegExp(`\\.fundus-(?:replace-)?${w}$`,`i`);var T=[`preload`,`release`,`entries`,`constructor`,`prototype`,`hasOwnProperty`,`isPrototypeOf`,`propertyIsEnumerable`,`toLocaleString`,`toString`,`valueOf`],E=/^[a-z][A-Za-z0-9]*$/;function D(e){return E.test(e)?T.includes(e)?`"${e}" is reserved (it collides with a Manifest member name).`:null:`"${e}" is not a valid asset id — use a camelCase identifier starting with a lowercase letter (e.g. "navigationPanel").`}function O(e){return E.test(e)?T.includes(e)?`"${e}" is reserved (it collides with a Manifest member name).`:null:`"${e}" is not a valid manifest name — use a camelCase identifier starting with a lowercase letter (e.g. "mainCatalog").`}var k={type:`audio`,accepts:[`mp3`,`wav`,`m4a`,`ogg`,`flac`],defaultParameters:()=>({preset:`default`}),validateParameters(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Audio parameters must be an object.`);let t=e;if(typeof t.preset!=`string`||t.preset.length===0)throw Error(`Audio parameters need a non-empty string "preset".`);return{preset:t.preset}}};function A(e){return typeof e==`object`&&!!e&&!Array.isArray(e)&&typeof e.$asset==`string`&&e.$asset!==``}var j={keyColor:[0,1,0],colorCutoff:.2,colorFeathering:.33,maskFeathering:1,sharpening:.5,despill:1,despillLuminanceAdd:.2},M=[`colorCutoff`,`colorFeathering`,`maskFeathering`,`sharpening`,`despill`,`despillLuminanceAdd`];function N(e){return Math.min(1,Math.max(0,e))}function P(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`"chromaKey" must be an object.`);let t=e,n=t.keyColor;if(!Array.isArray(n)||n.length!==3||n.some(e=>typeof e!=`number`||!Number.isFinite(e)))throw Error(`"chromaKey.keyColor" must be an array of three numbers (RGB, 0–1 each).`);let r={keyColor:[N(n[0]),N(n[1]),N(n[2])]};for(let e of M){let n=t[e];if(typeof n!=`number`||!Number.isFinite(n))throw Error(`"chromaKey.${e}" must be a number (0–1).`);r[e]=N(n)}return r}var F=[`mp4`,`mov`,`webm`,`m4v`];function I(e,t){if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`${e} parameters must be an object.`);let n=t;if(typeof n.preset!=`string`||n.preset.length===0)throw Error(`${e} parameters need a non-empty string "preset".`);if(n.maxWidth!==void 0&&(typeof n.maxWidth!=`number`||!Number.isInteger(n.maxWidth)||n.maxWidth<=0))throw Error(`${e} "maxWidth" must be a positive integer when set.`);return{preset:n.preset,...n.maxWidth===void 0?{}:{maxWidth:n.maxWidth}}}var L={type:`video`,accepts:[...F],defaultParameters:()=>({preset:`default`}),validateParameters(e){return I(`Video`,e)}};function R(e,t){if(t!==void 0){if(!A(t))throw Error(`"${e}" must be an asset reference ({ "$asset": "<id>" }).`);return{$asset:t.$asset}}}var z={type:`chroma-key-video`,accepts:[...F],defaultParameters:()=>({preset:`default`,chromaKey:{...j,keyColor:[...j.keyColor]}}),validateParameters(e){let t=I(`Chroma-key-video`,e),n=e,r=P(n.chromaKey),i=R(`mask`,n.mask),a=R(`fallback`,n.fallback);return{...t,chromaKey:r,...i===void 0?{}:{mask:i},...a===void 0?{}:{fallback:a}}},collectReferences(e){let t=[];return e.mask&&t.push({field:`mask`,assetId:e.mask.$asset,expectedTypes:[`image`]}),e.fallback&&t.push({field:`fallback`,assetId:e.fallback.$asset,expectedTypes:[`image`]}),t},processingParameters(e){return{preset:e.preset,...e.maxWidth===void 0?{}:{maxWidth:e.maxWidth}}}},B=[`png`,`jpg`,`jpeg`,`webp`,`avif`],V={type:`image`,accepts:[...B],defaultParameters:()=>({preset:`default`}),validateParameters(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Image parameters must be an object.`);let t=e;if(typeof t.preset!=`string`||t.preset.length===0)throw Error(`Image parameters need a non-empty string "preset".`);if(t.targetWidth!==void 0&&(typeof t.targetWidth!=`number`||!Number.isInteger(t.targetWidth)||t.targetWidth<=0))throw Error(`Image "targetWidth" must be a positive integer when set.`);return{preset:t.preset,...t.targetWidth===void 0?{}:{targetWidth:t.targetWidth}}}},H=[`nine`,`three-horizontal`,`three-vertical`,`one`];function U(){return{top:0,right:0,bottom:0,left:0}}function W(e){return{horizontal:e===`nine`||e===`three-horizontal`,vertical:e===`nine`||e===`three-vertical`}}function G(e,t,n,r){return t===`left`?n-e.right:t===`right`?n-e.left:t===`top`?r-e.bottom:r-e.top}function K(e,t,n,r){return G(e,t,n,r)-1}function q(e,t){if(typeof t!=`object`||!t||Array.isArray(t))throw Error(`Slice ${e} must be an object with top/right/bottom/left.`);let n=t,r=[`top`,`right`,`bottom`,`left`],i=U();for(let t of r){let r=n[t];if(typeof r!=`number`||!Number.isInteger(r)||r<0)throw Error(`Slice ${e}.${t} must be a non-negative integer.`);i[t]=r}return i}var J={type:`slice`,accepts:[...B],defaultParameters:()=>({mode:`nine`,insets:U(),pixelRatio:1,preset:`default`}),validateParameters(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`Slice parameters must be an object.`);let t=e;if(typeof t.mode!=`string`||!H.includes(t.mode))throw Error(`Slice "mode" must be one of ${H.map(e=>`'${e}'`).join(` | `)}.`);let n=q(`insets`,t.insets);if(typeof t.pixelRatio!=`number`||!Number.isInteger(t.pixelRatio)||t.pixelRatio<1)throw Error(`Slice "pixelRatio" must be an integer ≥ 1.`);let r=t.overdraw===void 0?void 0:q(`overdraw`,t.overdraw);if(typeof t.preset!=`string`||t.preset.length===0)throw Error(`Slice parameters need a non-empty string "preset".`);return{mode:t.mode,insets:n,pixelRatio:t.pixelRatio,...r===void 0?{}:{overdraw:r},preset:t.preset}}},Y=new class{#e=new Map;register(e){if(this.#e.has(e.type))throw Error(`Plugin type "${e.type}" is already registered.`);this.#e.set(e.type,e)}has(e){return this.#e.has(e)}values(){return[...this.#e.values()]}types(){return[...this.#e.keys()]}project(e,t){let n=Object.create(null);for(let r of this.#e.keys()){if(!Object.hasOwn(e,r))throw Error(`Registered plugin "${r}" has no ${t}.`);n[r]=e[r]}return n}};Y.register(V),Y.register(J),Y.register(L),Y.register(z),Y.register(k);var X=Y.values();function Z(e=X){return[...new Set(e.flatMap(e=>e.accepts))].sort().map(e=>`.${e}`)}function Q(e,t=X){return t.find(t=>t.type===e)?.accepts.map(e=>`.${e}`).sort()??[]}function $(e,t=X){let n=e.slice(e.lastIndexOf(`.`)+1).toLowerCase();return t.filter(e=>e.accepts.includes(n)).map(e=>e.type)}function ee(e){let t=e.replace(/\.[^.]+$/,``).replace(/(?:@|[-_])\dx$/i,``).replace(/([a-z0-9])([A-Z])/g,`$1 $2`).split(/[^a-zA-Z0-9]+/).filter(Boolean);if(t.length===0)return`asset`;let n=t.map((e,t)=>t===0?e.toLowerCase():e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(``).replace(/^[0-9]+/,``);return n?n.charAt(0).toLowerCase()+n.slice(1):`asset`}export{x as A,v as C,g as D,c as E,u as M,l as N,p as O,_ as S,b as T,C as _,Y as a,d as b,G as c,V as d,z as f,O as g,D as h,$ as i,f as j,h as k,K as l,k as m,Q as n,J as o,L as p,ee as r,U as s,Z as t,W as u,s as v,m as w,y as x,o as y};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
I@dj]��\��.2xj�"*��Fu&a��Y�A���Җ���&_r�")_��m+�? ���d����_צ&��r��o��>ߦ:��~��"���1�#"�D�[���2��p�Yv���:L�\�X
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e,s as t}from"../chunks/C8W3KwDq.js";export{t as load_css,e as start};
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{B as e,C as t,D as n,E as r,F as i,G as a,J as o,K as s,M as c,N as l,O as u,S as d,T as f,U as p,V as m,X as h,Y as g,Z as _,at as v,b as y,c as b,et as x,f as S,g as C,it as w,k as T,l as E,n as D,ot as O,q as k,s as A,tt as j,v as M,z as N}from"../chunks/D65cSBhe.js";import{c as P}from"../chunks/C8W3KwDq.js";import"../chunks/xihTtKlq.js";import{t as F}from"../chunks/ByVSyIj7.js";import{E as I,_ as L,h as R,v as z,y as B}from"../chunks/BAEZPv6c.js";import{t as V}from"../chunks/CP-bnOxU.js";var H=O({ssr:()=>!1});function U(e,t){return R(e)??(t.has(e)?`An asset with id "${e}" already exists.`:null)}function W(e,t,n=[]){let r=e;for(let i of t)i.kind===`unsupported`||Object.hasOwn(e,i.token)||(r===e&&(r={...e}),r[i.token]={id:i.kind===`new`?i.proposedId:i.assetId,type:i.kind===`new`?i.compatibleTypes[0]??``:i.compatibleTypes.includes(i.currentType)?i.currentType:``,manifests:i.kind===`new`&&n.length>0?[n.includes(`main`)?`main`:n[0]]:[],error:null,busy:!1});return r}var G=T(`<h2 class="svelte-1rcmmyd"> </h2>`),K=T(`<p class="error blocker-reason svelte-1rcmmyd"> </p>`),q=T(`<option> </option>`),J=T(`<p class="svelte-1rcmmyd">No manifests available — this asset will be unassigned.</p>`),Y=T(`<div class="manifest-list svelte-1rcmmyd"><!></div>`),X=T(`<p class="error svelte-1rcmmyd"> </p>`),Z=T(`<div class="form-controls new-form svelte-1rcmmyd"><label class="svelte-1rcmmyd"><span>Asset id</span> <input spellcheck="false" class="svelte-1rcmmyd"/></label> <label class="svelte-1rcmmyd"><span>Asset type</span> <select class="svelte-1rcmmyd"></select></label> <div class="manifest-row svelte-1rcmmyd"><span class="svelte-1rcmmyd">Manifests</span> <!></div> <div class="actions svelte-1rcmmyd"><button class="svelte-1rcmmyd">Import</button></div></div> <!>`,1),Q=T(`<option>Choose a compatible type</option>`),$=T(`<button class="secondary svelte-1rcmmyd">Apply</button>`),ee=T(`<p class="raw svelte-1rcmmyd"> </p> <div class="form-controls edited-form svelte-1rcmmyd"><label class="svelte-1rcmmyd"><span>Asset type</span> <select class="svelte-1rcmmyd"><!><!></select></label> <div class="actions svelte-1rcmmyd"><button class="svelte-1rcmmyd">Reimport</button> <!></div></div>`,1),te=T(`<!> <!>`,1),ne=T(`<article class="item svelte-1rcmmyd"><div class="identity svelte-1rcmmyd"><span> </span> <!></div> <!> <!></article>`),re=T(`<section class="queue svelte-1rcmmyd" aria-label="Raw file ingestion queue"><div class="heading svelte-1rcmmyd"><strong>External raw files</strong> <span class="svelte-1rcmmyd"> </span></div> <div class="items svelte-1rcmmyd"></div></section>`);function ie(c,p){j(p,!0);let y=h(o({})),w=_(()=>L.state?.rawIngestionQueue??[]),T=_(()=>new Set(L.state?.assets.map(e=>e.id)??[])),D=_(()=>L.manifestNames);m(()=>{g(y,W(i(y),i(w),i(D)),!0)});function O(e,t){e.manifests=e.manifests.includes(t)?e.manifests.filter(e=>e!==t):[...e.manifests,t]}async function M(e){let t=i(y)[e.token];if(t){t.busy=!0,t.error=null;try{e.kind===`new`?await L.mutate(()=>B(e.token,t.id,t.type,t.manifests)):await L.mutate(()=>z(e.token,t.type))}catch(e){t.error=e instanceof Error?e.message:String(e),await L.refresh()}finally{t.busy=!1}}}async function N(e){let t=i(y)[e];if(t){t.busy=!0,t.error=null;try{await L.mutate(()=>I(e))}catch(e){t.error=e instanceof Error?e.message:String(e),await L.refresh()}finally{t.busy=!1}}}var P=u(),F=s(P),R=o=>{var c=re(),u=a(c),p=k(a(u),2),m=a(p);v(p),v(u);var h=k(u,2);d(h,21,()=>i(w),e=>e.token,(o,c)=>{var u=ne(),p=a(u),m=a(p);let h;var g=a(m,!0);v(m);var x=k(m,2),w=t=>{var o=G(),s=a(o,!0);v(o),e(()=>r(s,i(c).path)),n(t,o)},j=t=>{var o=G(),s=a(o,!0);v(o),e(()=>r(s,i(c).assetId)),n(t,o)};f(x,e=>{i(c).kind===`new`||i(c).kind===`unsupported`?e(w):e(j,-1)}),v(p);var P=k(p,2),F=t=>{var o=K(),s=a(o,!0);v(o),e(()=>r(s,i(c).reason)),n(t,o)};f(P,e=>{i(c).kind===`unsupported`&&e(F)});var I=k(P,2),L=o=>{let u=_(()=>i(y)[i(c).token]);var p=te(),m=s(p),h=o=>{var p=Z(),m=s(p),h=a(m),g=k(a(h),2);b(g),v(h);var y=k(h,2),x=k(a(y),2);d(x,21,()=>i(c).compatibleTypes,t,(t,o)=>{var s=q(),c=a(s,!0);v(s);var l={};e(()=>{r(c,i(o)),l!==(l=i(o))&&(s.value=(s.__value=i(o))??``)}),n(t,s)}),v(x),v(y);var C=k(y,2),w=k(a(C),2),j=e=>{n(e,J())},N=e=>{var t=Y();V(a(t),{get manifests(){return i(D)},get selected(){return i(u).manifests},passive:[],onToggle:e=>O(i(u),e),get disabled(){return i(u).busy}}),v(t),n(e,t)};f(w,e=>{i(D).length===0?e(j):e(N,-1)}),v(C);var P=k(C,2),F=a(P);v(P),v(m);var I=k(m,2),L=t=>{var o=X(),s=a(o,!0);v(o),e(e=>r(s,e),[()=>U(i(u).id,i(T))]),n(t,o)},R=_(()=>U(i(u).id,i(T)));f(I,e=>{i(R)&&e(L)}),e((e,t)=>{E(g,`aria-invalid`,e),F.disabled=t},[()=>U(i(u).id,i(T))!==null,()=>i(u).busy||i(u).type===``||U(i(u).id,i(T))!==null]),A(g,()=>i(u).id,e=>i(u).id=e),S(x,()=>i(u).type,e=>i(u).type=e),l(`click`,F,()=>M(i(c))),n(o,p)},g=o=>{var p=ee(),m=s(p),h=a(m,!0);v(m);var g=k(m,2),y=a(g),b=k(a(y),2),x=a(b),C=e=>{var t=Q();t.value=t.__value=``,n(e,t)};f(x,e=>{i(u).type===``&&e(C)}),d(k(x),17,()=>i(c).compatibleTypes,t,(t,o)=>{var s=q(),c=a(s,!0);v(s);var l={};e(()=>{r(c,i(o)),l!==(l=i(o))&&(s.value=(s.__value=i(o))??``)}),n(t,s)}),v(b),v(y);var w=k(y,2),T=a(w),E=k(T,2),D=t=>{var r=$();e(()=>r.disabled=i(u).busy),l(`click`,r,()=>N(i(c).token)),n(t,r)},O=_(()=>i(c).compatibleTypes.includes(i(c).currentType));f(E,e=>{i(O)&&e(D)}),v(w),v(g),e(()=>{r(h,i(c).path),T.disabled=i(u).busy||i(u).type===``}),S(b,()=>i(u).type,e=>i(u).type=e),l(`click`,T,()=>M(i(c))),n(o,p)};f(m,e=>{i(c).kind===`new`?e(h):e(g,-1)});var x=k(m,2),C=t=>{var o=X(),s=a(o,!0);v(o),e(()=>r(s,i(u).error)),n(t,o)};f(x,e=>{i(u).error&&e(C)}),n(o,p)};f(I,e=>{i(c).kind!==`unsupported`&&i(y)[i(c).token]&&e(L)}),v(u),e(()=>{h=C(m,1,`svelte-1rcmmyd`,null,h,{edited:i(c).kind===`edited`,unsupported:i(c).kind===`unsupported`}),r(g,i(c).kind===`new`?`New`:i(c).kind===`edited`?`Edited`:`Unsupported`)}),n(o,u)}),v(h),v(c),e(()=>r(m,`${i(w).length??``} item${i(w).length===1?``:`s`} need${i(w).length===1?`s`:``} attention`)),n(o,c)};f(F,e=>{i(w).length>0&&e(R)}),n(c,P),x()}c([`click`]);var ae=T(`<span class="dot bad svelte-12qhfyh"></span> <span class="status-text error svelte-12qhfyh">Error</span>`,1),oe=T(`<span class="dot saving svelte-12qhfyh"></span> <span class="status-text svelte-12qhfyh">Saving…</span>`,1),se=T(`<span class="dot ok svelte-12qhfyh"></span> <span class="status-text svelte-12qhfyh">Saved ✓</span>`,1),ce=T(`<span class="dot svelte-12qhfyh"></span> <span class="status-text svelte-12qhfyh">Loading…</span>`,1),le=T(`<div class="notice svelte-12qhfyh"> <code class="svelte-12qhfyh">npx fundus start</code> in the host project.</div>`),ue=T(`<span class="svelte-12qhfyh"> </span>`),de=T(`<div class="issue-banner svelte-12qhfyh" role="alert"></div>`),fe=T(`<!> <!> <!>`,1),pe=T(`<div class="shell svelte-12qhfyh"><header class="topbar svelte-12qhfyh"><a class="brand svelte-12qhfyh"><span class="logo svelte-12qhfyh">◆</span> Fundus</a> <nav class="svelte-12qhfyh"><a>Library</a> <a>Manifests</a></nav> <div class="status svelte-12qhfyh"><!></div></header> <!></div>`);function me(t,o){j(o,!0),D(()=>{let e=()=>void L.reconcile();return L.reconcile(),window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)});let c=_(()=>F.url.pathname===`/`||F.url.pathname.startsWith(`/asset`)),l=_(()=>F.url.pathname.startsWith(`/manifests`)),u=_(()=>L.error??(L.generalIssues.length>0?L.generalIssues.join(`
|
|
2
|
-
`):null));var m=pe();M(`12qhfyh`,e=>{N(()=>{p.title=`Fundus`})});var h=a(m),g=a(h),b=k(g,2),S=a(b);let T;var O=k(S,2);let A;v(b);var I=k(b,2),R=a(I),z=t=>{var r=ae(),a=k(s(r),2);e(()=>E(a,`title`,i(u))),n(t,r)},B=e=>{var t=oe();w(2),n(e,t)},V=e=>{var t=se();w(2),n(e,t)},H=e=>{var t=ce();w(2),n(e,t)};f(R,e=>{i(u)?e(z):L.saving?e(B,1):L.loaded?e(V,2):e(H,-1)}),v(I),v(h);var U=k(h,2),W=t=>{var i=le(),o=a(i);w(2),v(i),e(()=>r(o,`Could not reach the Fundus server (${L.error??``}). Start it with `)),n(t,i)},G=t=>{var i=fe(),c=s(i);ie(c,{});var l=k(c,2),u=t=>{var i=de();d(i,20,()=>L.generalIssues,e=>e,(t,i)=>{var o=ue(),s=a(o,!0);v(o),e(()=>r(s,i)),n(t,o)}),v(i),n(t,i)};f(l,e=>{L.generalIssues.length>0&&e(u)}),y(k(l,2),()=>o.children),n(t,i)};f(U,e=>{L.error&&!L.state?e(W):e(G,-1)}),v(m),e((e,t,n)=>{E(g,`href`,e),E(S,`href`,t),T=C(S,1,`svelte-12qhfyh`,null,T,{active:i(c)}),E(O,`href`,n),A=C(O,1,`svelte-12qhfyh`,null,A,{active:i(l)})},[()=>P(`/`),()=>P(`/`),()=>P(`/manifests`)]),n(t,m),x()}export{me as component,H as universal};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|