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
|
@@ -14,6 +14,7 @@ import { runBuild } from './build.js';
|
|
|
14
14
|
import { formatCheckFinding, runCheck } from './check.js';
|
|
15
15
|
import { loadConfig } from './config-loader.js';
|
|
16
16
|
import { FundusOperations } from './operations.js';
|
|
17
|
+
import { validateFigmaSourceParameters } from './importers/figma.js';
|
|
17
18
|
import { pluginsByType, serverPluginForType } from './plugins.js';
|
|
18
19
|
import { CliUsageError, formatBytes, parseArguments, parseJsonFlag, parseManifestList, printJsonDocument, requirePositionals } from './cli-io.js';
|
|
19
20
|
const COMMON_FLAGS = {
|
|
@@ -111,6 +112,10 @@ function printHumanAssetDetail(asset) {
|
|
|
111
112
|
console.log(` raw: ${asset.raw}`);
|
|
112
113
|
console.log(` folder: ${asset.folder || 'root'}`);
|
|
113
114
|
console.log(` rawHash: ${asset.rawHash}`);
|
|
115
|
+
if (asset.importSource?.importer === 'figma') {
|
|
116
|
+
const source = validateFigmaSourceParameters(asset.importSource.parameters);
|
|
117
|
+
console.log(` source: Figma node ${source.nodeId} at ${source.scale}x`);
|
|
118
|
+
}
|
|
114
119
|
console.log(` manifests: ${asset.manifests.length > 0 ? asset.manifests.join(', ') : '(none)'}`);
|
|
115
120
|
for (const membership of asset.passiveManifests) {
|
|
116
121
|
console.log(` passive: ${membership.manifest} (via ${membership.via.join(', ')})`);
|
|
@@ -201,7 +206,8 @@ document on stdout) and --help.
|
|
|
201
206
|
Subcommands:
|
|
202
207
|
list list assets (--manifest, --type, --warnings-only)
|
|
203
208
|
show one asset in detail
|
|
204
|
-
ingest
|
|
209
|
+
ingest acquire a file or Figma selection as a typed asset
|
|
210
|
+
reimport refresh an asset from its saved source
|
|
205
211
|
replace replace an asset's raw file while preserving its metadata
|
|
206
212
|
set merge parameters and/or replace manifest membership
|
|
207
213
|
rename rename an asset id
|
|
@@ -248,43 +254,65 @@ Read-only: nothing is processed or written.
|
|
|
248
254
|
Example:
|
|
249
255
|
fundus asset show navigationPanel --json
|
|
250
256
|
`;
|
|
251
|
-
export const ASSET_INGEST_HELP = `fundus asset ingest —
|
|
257
|
+
export const ASSET_INGEST_HELP = `fundus asset ingest — acquire a file or Figma selection as a typed asset
|
|
252
258
|
|
|
253
259
|
Usage: fundus asset ingest <file> [--type <type>] [--id <id>] [--folder <path|root>]
|
|
260
|
+
[--manifests <a,b>] [--parameters <json>] [--from file] [--json]
|
|
261
|
+
fundus asset ingest <figma-selection-link> --from figma --type <image|slice> --id <id>
|
|
262
|
+
[--scale <1|2|3|4>] [--folder <path|root>]
|
|
254
263
|
[--manifests <a,b>] [--parameters <json>] [--json]
|
|
255
264
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
additionally seeds insets from the image dimensions and a pixel ratio
|
|
260
|
-
from a @2x-style file-name suffix. Runs the full autosave chain
|
|
261
|
-
(write library → process → regenerate manifest modules).
|
|
265
|
+
File ingest remains the default and behaves like an editor upload. Figma
|
|
266
|
+
ingest materializes one selection as PNG through the same importer-neutral
|
|
267
|
+
operations pipeline. Both run the full autosave chain.
|
|
262
268
|
|
|
263
269
|
Flags:
|
|
264
|
-
--
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
270
|
+
--from <file|figma> acquisition source; default: file. URLs are never
|
|
271
|
+
detected heuristically
|
|
272
|
+
--type <type> required for Figma (image or slice) and when a file
|
|
273
|
+
extension is ambiguous; known types:
|
|
268
274
|
${Object.keys(pluginsByType).sort().join(', ')}
|
|
269
|
-
--id <id>
|
|
270
|
-
|
|
271
|
-
(panel_button@2x.png → sidebarPanel)
|
|
275
|
+
--id <id> required for Figma; for files defaults to a proposal
|
|
276
|
+
from the file name
|
|
272
277
|
--folder <path|root> destination folder; default: root
|
|
273
|
-
--manifests <a,b> explicit manifest membership
|
|
274
|
-
|
|
275
|
-
must exist)
|
|
276
|
-
--parameters <json> parameter patch merged onto the plugin defaults
|
|
277
|
-
— same shallow-merge semantics as \`asset set\`
|
|
278
|
+
--manifests <a,b> explicit manifest membership (every name must exist)
|
|
279
|
+
--parameters <json> shallow parameter patch merged after ingest seeding
|
|
278
280
|
(see \`fundus asset set --help\`)
|
|
281
|
+
--scale <1|2|3|4> Figma export scale; default:
|
|
282
|
+
import.figma.defaults.scale from fundus.config.ts
|
|
283
|
+
(invalid for file ingest)
|
|
279
284
|
--json print {"ok": true, "asset": <AssetStateDto>, "issues": […]}
|
|
280
285
|
--help this help
|
|
281
286
|
|
|
282
|
-
A failed ingest
|
|
283
|
-
behind: the raw file and record are rolled back.
|
|
287
|
+
A failed ingest leaves neither a raw file nor a record behind.
|
|
284
288
|
|
|
285
289
|
Example:
|
|
286
|
-
fundus asset ingest ./exports/navigation_panel@2x.png --type slice
|
|
287
|
-
|
|
290
|
+
fundus asset ingest ./exports/navigation_panel@2x.png --type slice --json
|
|
291
|
+
fundus asset ingest 'https://www.figma.com/design/abc/UI?node-id=12-34' \\
|
|
292
|
+
--from figma --type slice --id navigationPanel --scale 3 --json
|
|
293
|
+
`;
|
|
294
|
+
export const ASSET_REIMPORT_HELP = `fundus asset reimport — refresh an asset from its saved source
|
|
295
|
+
|
|
296
|
+
Usage: fundus asset reimport <id> [--json]
|
|
297
|
+
fundus asset reimport <id> --figma-link <selection-link> [--scale <1|2|3|4>] [--json]
|
|
298
|
+
fundus asset reimport <id> --scale <1|2|3|4> [--json]
|
|
299
|
+
|
|
300
|
+
Without overrides, re-materializes the persisted importer source. Figma
|
|
301
|
+
overrides may update the link, scale, or both; omitted values are preserved.
|
|
302
|
+
Asset type, parameters, folder, manifests, and id remain unchanged. Raw-file
|
|
303
|
+
drift or concurrent changes abort without overwriting local edits.
|
|
304
|
+
|
|
305
|
+
Flags:
|
|
306
|
+
--figma-link <link> replace the persisted Figma file/node selection
|
|
307
|
+
--scale <1|2|3|4> replace the persisted Figma export scale
|
|
308
|
+
--json print {"ok": true, "asset": <AssetStateDto>, "issues": […]}
|
|
309
|
+
--help this help
|
|
310
|
+
|
|
311
|
+
Example:
|
|
312
|
+
fundus asset reimport navigationPanel
|
|
313
|
+
fundus asset reimport navigationPanel --figma-link '<new-selection-link>'
|
|
314
|
+
fundus asset reimport navigationPanel --scale 4
|
|
315
|
+
fundus asset reimport navigationPanel --figma-link '<new-selection-link>' --scale 4 --json
|
|
288
316
|
`;
|
|
289
317
|
export const ASSET_REPLACE_HELP = `fundus asset replace — replace an asset's raw file
|
|
290
318
|
|
|
@@ -385,6 +413,7 @@ const ASSET_SUBCOMMAND_HELP = {
|
|
|
385
413
|
list: ASSET_LIST_HELP,
|
|
386
414
|
show: ASSET_SHOW_HELP,
|
|
387
415
|
ingest: ASSET_INGEST_HELP,
|
|
416
|
+
reimport: ASSET_REIMPORT_HELP,
|
|
388
417
|
replace: ASSET_REPLACE_HELP,
|
|
389
418
|
set: ASSET_SET_HELP,
|
|
390
419
|
rename: ASSET_RENAME_HELP,
|
|
@@ -470,9 +499,57 @@ async function runAssetIngest(argumentList) {
|
|
|
470
499
|
id: { takesValue: true },
|
|
471
500
|
manifests: { takesValue: true },
|
|
472
501
|
parameters: { takesValue: true },
|
|
473
|
-
folder: { takesValue: true }
|
|
502
|
+
folder: { takesValue: true },
|
|
503
|
+
from: { takesValue: true },
|
|
504
|
+
scale: { takesValue: true }
|
|
474
505
|
}, 'fundus asset ingest');
|
|
475
|
-
const [
|
|
506
|
+
const [source] = requirePositionals(parsed, ['<file|figma-selection-link>'], 'fundus asset ingest');
|
|
507
|
+
const from = parsed.flags.from === undefined ? 'file' : parsed.flags.from;
|
|
508
|
+
if (from !== 'file' && from !== 'figma') {
|
|
509
|
+
throw new CliUsageError('Flag "--from" must be "file" or "figma" — run `fundus asset ingest --help`.');
|
|
510
|
+
}
|
|
511
|
+
const scale = typeof parsed.flags.scale === 'string'
|
|
512
|
+
? parseFigmaScale(parsed.flags.scale, 'fundus asset ingest')
|
|
513
|
+
: undefined;
|
|
514
|
+
if (from === 'file' && scale !== undefined) {
|
|
515
|
+
throw new CliUsageError('Flag "--scale" is only valid with `--from figma` — run `fundus asset ingest --help`.');
|
|
516
|
+
}
|
|
517
|
+
const parametersPatch = typeof parsed.flags.parameters === 'string'
|
|
518
|
+
? parseJsonFlag('parameters', parsed.flags.parameters)
|
|
519
|
+
: undefined;
|
|
520
|
+
const manifests = typeof parsed.flags.manifests === 'string'
|
|
521
|
+
? parseManifestList(parsed.flags.manifests)
|
|
522
|
+
: undefined;
|
|
523
|
+
const folder = typeof parsed.flags.folder === 'string' ? parseFolderToken(parsed.flags.folder) : '';
|
|
524
|
+
if (from === 'figma') {
|
|
525
|
+
if (typeof parsed.flags.id !== 'string') {
|
|
526
|
+
throw new CliUsageError('Figma ingest requires --id <id> — run `fundus asset ingest --help`.');
|
|
527
|
+
}
|
|
528
|
+
if (typeof parsed.flags.type !== 'string' ||
|
|
529
|
+
(parsed.flags.type !== 'image' && parsed.flags.type !== 'slice')) {
|
|
530
|
+
throw new CliUsageError('Figma ingest requires --type <image|slice> — run `fundus asset ingest --help`.');
|
|
531
|
+
}
|
|
532
|
+
const id = parsed.flags.id;
|
|
533
|
+
const type = parsed.flags.type;
|
|
534
|
+
const operations = await createOperations();
|
|
535
|
+
const state = await operations.importAsset({
|
|
536
|
+
importer: 'figma',
|
|
537
|
+
input: { url: source, format: 'png', ...(scale !== undefined ? { scale } : {}) },
|
|
538
|
+
type,
|
|
539
|
+
id,
|
|
540
|
+
folder,
|
|
541
|
+
parametersPatch,
|
|
542
|
+
manifests
|
|
543
|
+
});
|
|
544
|
+
const asset = assetById(state, id);
|
|
545
|
+
if (parsed.flags.json) {
|
|
546
|
+
printJsonDocument({ ok: true, asset, issues: state.issues });
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
printMutationResult(`Imported asset "${id}" from Figma as ${type}.`, asset, state);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
const filePath = source;
|
|
476
553
|
const absolutePath = resolve(process.cwd(), filePath);
|
|
477
554
|
let bytes;
|
|
478
555
|
try {
|
|
@@ -484,13 +561,6 @@ async function runAssetIngest(argumentList) {
|
|
|
484
561
|
const fileName = basename(absolutePath);
|
|
485
562
|
const type = typeof parsed.flags.type === 'string' ? parsed.flags.type : inferTypeForFileName(fileName);
|
|
486
563
|
const id = typeof parsed.flags.id === 'string' ? parsed.flags.id : proposeAssetId(fileName);
|
|
487
|
-
const parametersPatch = typeof parsed.flags.parameters === 'string'
|
|
488
|
-
? parseJsonFlag('parameters', parsed.flags.parameters)
|
|
489
|
-
: undefined;
|
|
490
|
-
const manifests = typeof parsed.flags.manifests === 'string'
|
|
491
|
-
? parseManifestList(parsed.flags.manifests)
|
|
492
|
-
: undefined;
|
|
493
|
-
const folder = typeof parsed.flags.folder === 'string' ? parseFolderToken(parsed.flags.folder) : '';
|
|
494
564
|
const operations = await createOperations();
|
|
495
565
|
const state = await operations.ingest({
|
|
496
566
|
fileName,
|
|
@@ -508,6 +578,55 @@ async function runAssetIngest(argumentList) {
|
|
|
508
578
|
}
|
|
509
579
|
printMutationResult(`Ingested "${fileName}" as ${type} asset "${id}".`, asset, state);
|
|
510
580
|
}
|
|
581
|
+
function parseFigmaScale(value, commandPath) {
|
|
582
|
+
if (value === '1' || value === '2' || value === '3' || value === '4') {
|
|
583
|
+
return Number(value);
|
|
584
|
+
}
|
|
585
|
+
throw new CliUsageError(`Flag "--scale" must be 1, 2, 3, or 4 — run \`${commandPath} --help\`.`);
|
|
586
|
+
}
|
|
587
|
+
function canonicalFigmaSelectionLink(source) {
|
|
588
|
+
const url = new URL(`https://www.figma.com/design/${encodeURIComponent(source.fileKey)}/fundus`);
|
|
589
|
+
url.searchParams.set('node-id', source.nodeId.replace(':', '-'));
|
|
590
|
+
return url.toString();
|
|
591
|
+
}
|
|
592
|
+
async function runAssetReimport(argumentList) {
|
|
593
|
+
const parsed = parseArguments(argumentList, {
|
|
594
|
+
...COMMON_FLAGS,
|
|
595
|
+
'figma-link': { takesValue: true },
|
|
596
|
+
scale: { takesValue: true }
|
|
597
|
+
}, 'fundus asset reimport');
|
|
598
|
+
const [id] = requirePositionals(parsed, ['<id>'], 'fundus asset reimport');
|
|
599
|
+
const scale = typeof parsed.flags.scale === 'string'
|
|
600
|
+
? parseFigmaScale(parsed.flags.scale, 'fundus asset reimport')
|
|
601
|
+
: undefined;
|
|
602
|
+
const figmaLink = typeof parsed.flags['figma-link'] === 'string' ? parsed.flags['figma-link'] : undefined;
|
|
603
|
+
const operations = await createOperations();
|
|
604
|
+
let state;
|
|
605
|
+
if (figmaLink === undefined && scale === undefined) {
|
|
606
|
+
state = await operations.reimportAsset(id);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
const current = await operations.state();
|
|
610
|
+
const currentAsset = assetById(current, id);
|
|
611
|
+
if (currentAsset.importSource?.importer !== 'figma') {
|
|
612
|
+
throw new Error(`Asset "${id}" does not have a Figma source.`);
|
|
613
|
+
}
|
|
614
|
+
const source = validateFigmaSourceParameters(currentAsset.importSource.parameters);
|
|
615
|
+
state = await operations.reimportAsset(id, {
|
|
616
|
+
url: figmaLink ?? canonicalFigmaSelectionLink(source),
|
|
617
|
+
format: 'png',
|
|
618
|
+
scale: scale ?? source.scale
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
const asset = assetById(state, id);
|
|
622
|
+
if (parsed.flags.json) {
|
|
623
|
+
printJsonDocument({ ok: true, asset, issues: state.issues });
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
printMutationResult(figmaLink === undefined && scale === undefined
|
|
627
|
+
? `Refreshed asset "${id}" from its saved source.`
|
|
628
|
+
: `Reimported asset "${id}" with updated Figma source.`, asset, state);
|
|
629
|
+
}
|
|
511
630
|
async function runAssetReplace(argumentList) {
|
|
512
631
|
const parsed = parseArguments(argumentList, COMMON_FLAGS, 'fundus asset replace');
|
|
513
632
|
const [id, filePath] = requirePositionals(parsed, ['<id>', '<file>'], 'fundus asset replace');
|
|
@@ -593,7 +712,7 @@ export async function runAssetCommand(argumentList) {
|
|
|
593
712
|
if (subcommand === undefined || subcommand === '--help') {
|
|
594
713
|
console.log(ASSET_HELP);
|
|
595
714
|
if (subcommand === undefined) {
|
|
596
|
-
throw new CliUsageError('`fundus asset` needs a subcommand: list, show, ingest, replace, set, rename, move, delete.');
|
|
715
|
+
throw new CliUsageError('`fundus asset` needs a subcommand: list, show, ingest, reimport, replace, set, rename, move, delete.');
|
|
597
716
|
}
|
|
598
717
|
return;
|
|
599
718
|
}
|
|
@@ -609,6 +728,8 @@ export async function runAssetCommand(argumentList) {
|
|
|
609
728
|
return runAssetShow(rest);
|
|
610
729
|
case 'ingest':
|
|
611
730
|
return runAssetIngest(rest);
|
|
731
|
+
case 'reimport':
|
|
732
|
+
return runAssetReimport(rest);
|
|
612
733
|
case 'replace':
|
|
613
734
|
return runAssetReplace(rest);
|
|
614
735
|
case 'set':
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioPreset, ImagePreset, VideoPreset } from '../core/index.js';
|
|
1
|
+
import type { AudioPreset, FigmaImportScale, ImagePreset, VideoPreset } from '../core/index.js';
|
|
2
2
|
import type { ServerPluginRegistry } from './plugins/contract.js';
|
|
3
3
|
export interface ResolvedPresetPluginConfig {
|
|
4
4
|
presets: Record<string, ImagePreset>;
|
|
@@ -28,6 +28,14 @@ export interface ResolvedFundusConfig {
|
|
|
28
28
|
video: ResolvedVideoPluginConfig;
|
|
29
29
|
audio: ResolvedAudioPluginConfig;
|
|
30
30
|
};
|
|
31
|
+
import: {
|
|
32
|
+
figma: {
|
|
33
|
+
token?: string;
|
|
34
|
+
defaults: {
|
|
35
|
+
scale: FigmaImportScale;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
31
39
|
}
|
|
32
40
|
/** Pure resolution step (testable without a config file on disk). */
|
|
33
41
|
export declare function resolveConfig(projectRoot: string, value: unknown, registry?: ServerPluginRegistry): ResolvedFundusConfig;
|
|
@@ -51,13 +51,38 @@ export function resolveConfig(projectRoot, value, registry = serverPluginsByType
|
|
|
51
51
|
value: plugins[definition.namespace]
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
+
const importConfig = value.import === undefined ? {} : value.import;
|
|
55
|
+
if (!isRecord(importConfig)) {
|
|
56
|
+
throw new Error('fundus.config: "import" must be an object.');
|
|
57
|
+
}
|
|
58
|
+
const figma = importConfig.figma === undefined ? {} : importConfig.figma;
|
|
59
|
+
if (!isRecord(figma)) {
|
|
60
|
+
throw new Error('fundus.config: "import.figma" must be an object.');
|
|
61
|
+
}
|
|
62
|
+
if (figma.token !== undefined && (typeof figma.token !== 'string' || figma.token.length === 0)) {
|
|
63
|
+
throw new Error('fundus.config: "import.figma.token" must be a non-empty string.');
|
|
64
|
+
}
|
|
65
|
+
const defaults = figma.defaults === undefined ? {} : figma.defaults;
|
|
66
|
+
if (!isRecord(defaults)) {
|
|
67
|
+
throw new Error('fundus.config: "import.figma.defaults" must be an object.');
|
|
68
|
+
}
|
|
69
|
+
const scale = defaults.scale === undefined ? 2 : defaults.scale;
|
|
70
|
+
if (scale !== 1 && scale !== 2 && scale !== 3 && scale !== 4) {
|
|
71
|
+
throw new Error('fundus.config: "import.figma.defaults.scale" must be 1, 2, 3, or 4.');
|
|
72
|
+
}
|
|
54
73
|
return {
|
|
55
74
|
rawDir: resolvePath(projectRoot, requiredString(value, 'rawDir')),
|
|
56
75
|
proxyDir: resolvePath(projectRoot, requiredString(value, 'proxyDir')),
|
|
57
76
|
library: resolvePath(projectRoot, requiredString(value, 'library')),
|
|
58
77
|
manifestsDir: resolvePath(projectRoot, requiredString(value, 'manifestsDir')),
|
|
59
78
|
proxyBasePath,
|
|
60
|
-
plugins: resolvedPlugins
|
|
79
|
+
plugins: resolvedPlugins,
|
|
80
|
+
import: {
|
|
81
|
+
figma: {
|
|
82
|
+
...(figma.token !== undefined ? { token: figma.token } : {}),
|
|
83
|
+
defaults: { scale }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
61
86
|
};
|
|
62
87
|
}
|
|
63
88
|
/** Load `fundus.config.ts` from the host project root. */
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import open from 'open';
|
|
5
|
+
const execute = promisify(execFile);
|
|
6
|
+
/** Reveal a file, or open a directory, in the host platform's file manager. */
|
|
7
|
+
export async function openInFileManager(target, kind) {
|
|
8
|
+
if (kind === 'file' && process.platform === 'darwin') {
|
|
9
|
+
await execute('open', ['-R', target]);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (kind === 'file' && process.platform === 'win32') {
|
|
13
|
+
await execute('explorer.exe', [`/select,${target}`], { windowsHide: true });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
await open(kind === 'file' ? dirname(target) : target);
|
|
17
|
+
}
|
package/dist/server/http.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare function routeNotFound(event: {
|
|
|
5
5
|
url: URL;
|
|
6
6
|
}): Response;
|
|
7
7
|
export declare function apiResponse(run: () => Promise<unknown>): Promise<Response>;
|
|
8
|
+
export declare function sourceImportResponse(run: () => Promise<unknown>): Promise<Response>;
|
|
8
9
|
export declare function parseByteRange(rangeHeader: string | null, size: number): {
|
|
9
10
|
start: number;
|
|
10
11
|
end: number;
|
package/dist/server/http.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import { lstat, readFile } from 'node:fs/promises';
|
|
3
3
|
import { extname, join } from 'node:path';
|
|
4
4
|
import { assertSafeRelativeFilePath } from './library-store.js';
|
|
5
|
+
import { SourceImportError } from './importers/contract.js';
|
|
5
6
|
const CONTENT_TYPES = {
|
|
6
7
|
'.png': 'image/png',
|
|
7
8
|
'.jpg': 'image/jpeg',
|
|
@@ -37,6 +38,42 @@ export async function apiResponse(run) {
|
|
|
37
38
|
return errorResponse(cause, 400);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
41
|
+
const SOURCE_ERROR_STATUS = {
|
|
42
|
+
'invalid-input': 400,
|
|
43
|
+
'not-configured': 401,
|
|
44
|
+
unauthorized: 401,
|
|
45
|
+
forbidden: 403,
|
|
46
|
+
'not-found': 404,
|
|
47
|
+
'rate-limited': 429,
|
|
48
|
+
'upstream-failed': 502,
|
|
49
|
+
'invalid-response': 502,
|
|
50
|
+
'unsafe-download-url': 502,
|
|
51
|
+
'download-timeout': 504,
|
|
52
|
+
'download-too-large': 502,
|
|
53
|
+
'image-too-large': 502,
|
|
54
|
+
'stale-import': 409
|
|
55
|
+
};
|
|
56
|
+
export async function sourceImportResponse(run) {
|
|
57
|
+
try {
|
|
58
|
+
return Response.json(await run());
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
const error = cause instanceof SourceImportError
|
|
62
|
+
? cause
|
|
63
|
+
: new SourceImportError('invalid-input', cause instanceof Error ? cause.message : String(cause));
|
|
64
|
+
const body = {
|
|
65
|
+
error: {
|
|
66
|
+
message: error.message,
|
|
67
|
+
code: error.code,
|
|
68
|
+
retryAfterSeconds: error.retryAfterSeconds
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const headers = error.code === 'rate-limited' && error.retryAfterSeconds !== undefined
|
|
72
|
+
? { 'Retry-After': String(error.retryAfterSeconds) }
|
|
73
|
+
: undefined;
|
|
74
|
+
return Response.json(body, { status: SOURCE_ERROR_STATUS[error.code], headers });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
40
77
|
export function parseByteRange(rangeHeader, size) {
|
|
41
78
|
if (!rangeHeader)
|
|
42
79
|
return null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ImportSourceRecord, SourceImportErrorCode } from '../../core/index.js';
|
|
2
|
+
import type { ResolvedFundusConfig } from '../config-loader.js';
|
|
3
|
+
import type { PinnedHttpsTransport } from './pinned-https.js';
|
|
4
|
+
export interface ImportedRaw {
|
|
5
|
+
bytes: Uint8Array;
|
|
6
|
+
/** Lowercase extension without a leading dot. */
|
|
7
|
+
extension: string;
|
|
8
|
+
suggestedFileName?: string;
|
|
9
|
+
importSource?: ImportSourceRecord;
|
|
10
|
+
}
|
|
11
|
+
export interface ImporterContext {
|
|
12
|
+
config: ResolvedFundusConfig;
|
|
13
|
+
fetch: typeof globalThis.fetch;
|
|
14
|
+
httpsTransport?: PinnedHttpsTransport;
|
|
15
|
+
}
|
|
16
|
+
export interface ServerSourceImporter<TInput = unknown, TSource = unknown> {
|
|
17
|
+
kind: string;
|
|
18
|
+
label: string;
|
|
19
|
+
validateInput(value: unknown): TInput;
|
|
20
|
+
importRaw(input: TInput, context: ImporterContext): Promise<ImportedRaw>;
|
|
21
|
+
validateSourceParameters(value: unknown): TSource;
|
|
22
|
+
reimportRaw?(source: TSource, context: ImporterContext): Promise<ImportedRaw>;
|
|
23
|
+
}
|
|
24
|
+
export declare class SourceImportError extends Error {
|
|
25
|
+
readonly code: SourceImportErrorCode;
|
|
26
|
+
readonly retryAfterSeconds?: number;
|
|
27
|
+
constructor(code: SourceImportErrorCode, message: string, retryAfterSeconds?: number);
|
|
28
|
+
}
|
|
29
|
+
export declare function invalidInput(message: string): never;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class SourceImportError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
retryAfterSeconds;
|
|
4
|
+
constructor(code, message, retryAfterSeconds) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'SourceImportError';
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function invalidInput(message) {
|
|
12
|
+
throw new SourceImportError('invalid-input', message);
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ServerSourceImporter } from './contract.js';
|
|
2
|
+
import { type PinnedHttpsTarget } from './pinned-https.js';
|
|
3
|
+
export interface FigmaSourceParameters {
|
|
4
|
+
fileKey: string;
|
|
5
|
+
nodeId: string;
|
|
6
|
+
format: 'png';
|
|
7
|
+
scale: 1 | 2 | 3 | 4;
|
|
8
|
+
}
|
|
9
|
+
export interface FigmaImportInput {
|
|
10
|
+
url: string;
|
|
11
|
+
format?: 'png';
|
|
12
|
+
scale?: 1 | 2 | 3 | 4;
|
|
13
|
+
}
|
|
14
|
+
export declare function parseFigmaSelectionUrl(value: string): {
|
|
15
|
+
fileKey: string;
|
|
16
|
+
nodeId: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function validateFigmaSourceParameters(value: unknown): FigmaSourceParameters;
|
|
19
|
+
export declare function resolveSafeDownloadTarget(value: string | URL): Promise<PinnedHttpsTarget>;
|
|
20
|
+
export declare function assertSafeDownloadUrl(value: string | URL): Promise<URL>;
|
|
21
|
+
export declare const figmaSourceImporter: ServerSourceImporter<FigmaImportInput, FigmaSourceParameters>;
|