fundus 0.28.1 → 0.29.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 +41 -33
- package/build/client/_app/immutable/chunks/{OL1Dh1oP.js → BCmR1_e0.js} +1 -1
- package/build/client/_app/immutable/chunks/BCmR1_e0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BCmR1_e0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{apKHI4vq.js → C0uU_Rhe.js} +2 -2
- package/build/client/_app/immutable/chunks/C0uU_Rhe.js.br +0 -0
- package/build/client/_app/immutable/chunks/C0uU_Rhe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{g2rma9Ym.js → CMJ10zbJ.js} +1 -1
- package/build/client/_app/immutable/chunks/CMJ10zbJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/CMJ10zbJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{QlQ-jeIO.js → kkVEh3_1.js} +1 -1
- package/build/client/_app/immutable/chunks/kkVEh3_1.js.br +2 -0
- package/build/client/_app/immutable/chunks/kkVEh3_1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/wBLhaPea.js +1 -0
- package/build/client/_app/immutable/chunks/wBLhaPea.js.br +0 -0
- package/build/client/_app/immutable/chunks/wBLhaPea.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.DpZM49_s.js → app.DCXSqiQ1.js} +2 -2
- package/build/client/_app/immutable/entry/app.DCXSqiQ1.js.br +0 -0
- package/build/client/_app/immutable/entry/app.DCXSqiQ1.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BOUpxuMU.js +1 -0
- package/build/client/_app/immutable/entry/start.BOUpxuMU.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BOUpxuMU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.Wqvn8XD-.js → 0.CsqkK05g.js} +1 -1
- package/build/client/_app/immutable/nodes/0.CsqkK05g.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.CsqkK05g.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.Z-UvvLkP.js → 1.BVSXvtU9.js} +1 -1
- package/build/client/_app/immutable/nodes/1.BVSXvtU9.js.br +2 -0
- package/build/client/_app/immutable/nodes/1.BVSXvtU9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.lu89W_qJ.js → 2.BJEXWmrT.js} +1 -1
- package/build/client/_app/immutable/nodes/2.BJEXWmrT.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BJEXWmrT.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.Dt32EAoq.js → 3.BDMmDyL1.js} +1 -1
- package/build/client/_app/immutable/nodes/3.BDMmDyL1.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.BDMmDyL1.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.WipzcX8_.js → 4.dd49_qQE.js} +1 -1
- package/build/client/_app/immutable/nodes/4.dd49_qQE.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.dd49_qQE.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/{context.js-BZSZNuAd.js → context.js-DFZgDxCD.js} +157 -95
- package/build/server/chunks/chunks/context.js-DFZgDxCD.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js → contract.js-DGZXpcNX.js} +7 -7
- package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js.map → contract.js-DGZXpcNX.js.map} +1 -1
- package/build/server/chunks/chunks/{core.js-BHxa3VBo.js → core.js-AGKlECJ0.js} +32 -32
- package/build/server/chunks/chunks/core.js-AGKlECJ0.js.map +1 -0
- package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js → exports.js-BsVKSGJk.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js.map → exports.js-BsVKSGJk.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-DYYKvppy.js → http.js-BQhjMaW9.js} +2 -2
- package/build/server/chunks/chunks/{http.js-DYYKvppy.js.map → http.js-BQhjMaW9.js.map} +1 -1
- package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js → internal.js-DJGcNryj.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js.map → internal.js-DJGcNryj.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js → manifest-membership.js-DkHaPk2F.js} +2 -2
- package/build/server/chunks/chunks/{manifest-membership.js-BkrPsM_r.js.map → manifest-membership.js-DkHaPk2F.js.map} +1 -1
- package/build/server/chunks/chunks/{raw-reconciliation.js-DPnNXe0b.js → raw-reconciliation.js-D2sI2C-t.js} +3 -3
- package/build/server/chunks/chunks/raw-reconciliation.js-D2sI2C-t.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation2.js-DKOpJ8if.js → raw-reconciliation2.js-CMpUvuMd.js} +2 -2
- package/build/server/chunks/chunks/{raw-reconciliation2.js-DKOpJ8if.js.map → raw-reconciliation2.js-CMpUvuMd.js.map} +1 -1
- package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js → shared.js-BtmYg0tL.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js.map → shared.js-BtmYg0tL.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js → utils.js-CqXk0Ug6.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js.map → utils.js-CqXk0Ug6.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js → _server.ts.js-DKGD9Jk2.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js.map → _server.ts.js-DKGD9Jk2.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js → _server.ts.js-C1UfF0EO.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js.map → _server.ts.js-C1UfF0EO.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js → _server.ts.js-DpASkk00.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js.map → _server.ts.js-DpASkk00.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js → _server.ts.js-C3jU2vC8.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js.map → _server.ts.js-C3jU2vC8.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js → _server.ts.js-B7OwufF3.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js.map → _server.ts.js-B7OwufF3.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js → _server.ts.js-COhg1nYk.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js.map → _server.ts.js-COhg1nYk.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js → _server.ts.js-DAEE17eM.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js.map → _server.ts.js-DAEE17eM.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js → _server.ts.js-BrZSS4gm.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js.map → _server.ts.js-BrZSS4gm.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js → _server.ts.js-Cfst-Brd.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js.map → _server.ts.js-Cfst-Brd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js → _server.ts.js-aN_h2Ifo.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js.map → _server.ts.js-aN_h2Ifo.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js → _server.ts.js-CX2A66ij.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js.map → _server.ts.js-CX2A66ij.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js → _server.ts.js-CwTiaheP.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js.map → _server.ts.js-CwTiaheP.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js → _server.ts.js-fIbsr_2e.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js.map → _server.ts.js-fIbsr_2e.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js → _server.ts.js-Dvo1bsLi.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js.map → _server.ts.js-Dvo1bsLi.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js → _server.ts.js-VLg1G3mN.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js.map → _server.ts.js-VLg1G3mN.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js → _server.ts.js-DqctsOop.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js.map → _server.ts.js-DqctsOop.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js → _server.ts.js-CoxSU5iO.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js.map → _server.ts.js-CoxSU5iO.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js → _server.ts.js-wUxsLZdr.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js.map → _server.ts.js-wUxsLZdr.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js → _server.ts.js-BKsF0Oit.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js.map → _server.ts.js-BKsF0Oit.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js → _server.ts.js-Dk9oOZwM.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js.map → _server.ts.js-Dk9oOZwM.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js → _server.ts.js-DxjNmmtL.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js.map → _server.ts.js-DxjNmmtL.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js → _server.ts.js-DD0b38VV.js} +6 -6
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js.map → _server.ts.js-DD0b38VV.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js → _server.ts.js-DId6F2i_.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js.map → _server.ts.js-DId6F2i_.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js → _server.ts.js-DKKkGoK2.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js.map → _server.ts.js-DKKkGoK2.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js → hooks.server.js-B5Ctvorj.js} +6 -6
- package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js.map → hooks.server.js-B5Ctvorj.js.map} +1 -1
- package/build/server/chunks/{handler-BAe0c9yw.js → handler-DwVfBx6r.js} +5 -5
- package/build/server/chunks/{handler-BAe0c9yw.js.map → handler-DwVfBx6r.js.map} +1 -1
- package/build/server/chunks/{index.js-DUYD4JB0.js → index.js-DgPuPQJn.js} +5 -5
- package/build/server/chunks/{index.js-DUYD4JB0.js.map → index.js-DgPuPQJn.js.map} +1 -1
- package/build/server/chunks/{manifest.js-zwun-T7O.js → manifest.js-B054EcAf.js} +31 -31
- package/build/server/chunks/{manifest.js-zwun-T7O.js.map → manifest.js-B054EcAf.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-BmkXwDRY.js → 0.js-DoHZTmnT.js} +2 -2
- package/build/server/chunks/nodes/{0.js-BmkXwDRY.js.map → 0.js-DoHZTmnT.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-BcPlsloO.js +7 -0
- package/build/server/chunks/nodes/{1.js-xbOwEHCW.js.map → 1.js-BcPlsloO.js.map} +1 -1
- package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js → 2.js-5qCXkvzl.js} +2 -2
- package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js.map → 2.js-5qCXkvzl.js.map} +1 -1
- package/build/server/chunks/nodes/3.js-D6fAMX1w.js +7 -0
- package/build/server/chunks/nodes/{3.js-Dpr_DvNU.js.map → 3.js-D6fAMX1w.js.map} +1 -1
- package/build/server/chunks/nodes/4.js-CGkeT0SQ.js +7 -0
- package/build/server/chunks/nodes/{4.js-14Lypd4o.js.map → 4.js-CGkeT0SQ.js.map} +1 -1
- package/dist/cli.js +3 -4
- package/dist/core/figma-tag-links.d.ts +66 -0
- package/dist/core/figma-tag-links.js +97 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/server/cli-commands.d.ts +1 -1
- package/dist/server/cli-commands.js +1 -1
- package/dist/server/cli-figma-tags.d.ts +1 -1
- package/dist/server/cli-figma-tags.js +149 -88
- package/dist/server/figma-tags.d.ts +72 -24
- package/dist/server/figma-tags.js +130 -79
- package/dist/server/importers/figma.d.ts +20 -15
- package/dist/server/importers/figma.js +172 -92
- package/package.json +1 -1
- package/build/client/_app/immutable/chunks/Bsj1ssvc.js +0 -1
- package/build/client/_app/immutable/chunks/Bsj1ssvc.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bsj1ssvc.js.gz +0 -0
- package/build/client/_app/immutable/chunks/OL1Dh1oP.js.br +0 -0
- package/build/client/_app/immutable/chunks/OL1Dh1oP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/QlQ-jeIO.js.br +0 -2
- package/build/client/_app/immutable/chunks/QlQ-jeIO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/apKHI4vq.js.br +0 -0
- package/build/client/_app/immutable/chunks/apKHI4vq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/g2rma9Ym.js.br +0 -0
- package/build/client/_app/immutable/chunks/g2rma9Ym.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.DpZM49_s.js.br +0 -0
- package/build/client/_app/immutable/entry/app.DpZM49_s.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.B3EMVPEN.js +0 -1
- package/build/client/_app/immutable/entry/start.B3EMVPEN.js.br +0 -0
- package/build/client/_app/immutable/entry/start.B3EMVPEN.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.Wqvn8XD-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Z-UvvLkP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.lu89W_qJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.Dt32EAoq.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.WipzcX8_.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.WipzcX8_.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-BZSZNuAd.js.map +0 -1
- package/build/server/chunks/chunks/core.js-BHxa3VBo.js.map +0 -1
- package/build/server/chunks/chunks/raw-reconciliation.js-DPnNXe0b.js.map +0 -1
- package/build/server/chunks/nodes/1.js-xbOwEHCW.js +0 -7
- package/build/server/chunks/nodes/3.js-Dpr_DvNU.js +0 -7
- package/build/server/chunks/nodes/4.js-14Lypd4o.js +0 -7
- package/dist/core/figma-tag-script.d.ts +0 -154
- package/dist/core/figma-tag-script.js +0 -248
|
@@ -6,7 +6,7 @@ export declare const ASSET_HELP = "fundus asset \u2014 inspect and mutate assets
|
|
|
6
6
|
export declare const ASSET_LIST_HELP: string;
|
|
7
7
|
export declare const ASSET_SHOW_HELP = "fundus asset show \u2014 one asset in detail\n\nUsage: fundus asset show <id> [--json]\n\nPrints the asset's raw file, content hash, parameters, explicit +\npassive manifest memberships, proxy status, reference edges (outgoing\nand incoming), and warnings.\n\nFlags:\n --json print {\"ok\": true, \"asset\": <AssetStateDto>}\n --help this help\n\nRead-only: nothing is processed or written.\n\nExample:\n fundus asset show navigationPanel --json\n";
|
|
8
8
|
export declare const ASSET_INGEST_HELP: string;
|
|
9
|
-
export declare const ASSET_REIMPORT_HELP = "fundus asset reimport \u2014 refresh an asset from its saved source\n\nUsage: fundus asset reimport <id> [--json]\n fundus asset reimport <id> --figma-link <selection-link> [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --figma-tag <newTag> [--figma-file <key|link>] [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --figma-file <key|link> [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --scale <1|2|3|4> [--json]\n\nWithout overrides, re-materializes the persisted importer source (a Figma tag\nasset
|
|
9
|
+
export declare const ASSET_REIMPORT_HELP = "fundus asset reimport \u2014 refresh an asset from its saved source\n\nUsage: fundus asset reimport <id> [--json]\n fundus asset reimport <id> --figma-link <selection-link> [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --figma-tag <newTag> [--figma-file <key|link>] [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --figma-file <key|link> [--scale <1|2|3|4>] [--json]\n fundus asset reimport <id> --scale <1|2|3|4> [--json]\n\nWithout overrides, re-materializes the persisted importer source (a Figma tag\nasset looks up the node carrying the tag again, self-healing after node moves).\nA Figma override may update the source or scale; omitted values are preserved.\nAsset type, parameters, folder, and manifests remain unchanged. Raw-file drift\nor concurrent changes abort without overwriting local edits.\n\nNode vs tag assets accept different overrides. A node asset takes --figma-link\n(and --scale); --figma-tag and --figma-file are rejected. A tag asset takes\n--figma-tag to change its tag, --figma-file to re-point in place to another\ndocument, and --scale; --figma-link is rejected. Because the tag IS the asset\nid, changing it with --figma-tag renames the asset to the new tag (the new id\nmust be valid and unused).\n\nFlags:\n --figma-link <link> node asset only: replace the persisted file/node selection\n --figma-tag <newTag> tag asset only: change the tag, renaming the asset to the\n new tag (the tag is the asset id)\n --figma-file <key|link>\n tag asset only: re-point in place to another file (raw\n key or a Figma link)\n --scale <1|2|3|4> replace the persisted Figma export scale\n --json print {\"ok\": true, \"asset\": <AssetStateDto>, \"issues\": [\u2026]}\n --help this help\n\nExample:\n fundus asset reimport navigationPanel\n fundus asset reimport navigationPanel --figma-link '<new-selection-link>'\n fundus asset reimport navigationPanel --figma-tag mainNavigationPanel\n fundus asset reimport navigationPanel --figma-file def456\n fundus asset reimport navigationPanel --scale 4\n fundus asset reimport navigationPanel --figma-link '<new-selection-link>' --scale 4 --json\n";
|
|
10
10
|
export declare const ASSET_REPLACE_HELP = "fundus asset replace \u2014 replace an asset's raw file\n\nUsage: fundus asset replace <id> <file|figma-selection-link>\n [--from <file|figma>] [--scale <1|2|3|4>] [--json]\n fundus asset replace <id> --from figma --figma-tag <tag>\n [--figma-file <key|link>] [--scale <1|2|3|4>] [--json]\n\nReplaces the stored raw file and content hash while preserving the asset's\nid, type, folder, parameters, references, and manifest memberships. The new\nsource must be accepted by the existing asset type. File replacement remains\nthe default and disconnects any saved source. Figma replacement stores the new\nselection (node mode) or tag (tag mode) as a repeatable source. A tag\nreplacement must resolve to the asset's own id, so it can only re-point the\nsame asset's own tag. Runs the full autosave chain, so delivered assets are\nreprocessed and manifests regenerated.\n\nFlags:\n --from <file|figma> replacement source; default: file\n --figma-tag <tag> Figma tag mode: replace from the node tagged with this\n Fundus asset id (takes no positional link)\n --figma-file <key|link>\n fileKey for tag mode as a raw key or a Figma link;\n defaults to import.figma.defaultFileKey from\n fundus.config.ts\n --scale <1|2|3|4> Figma export scale; default:\n import.figma.defaults.scale from fundus.config.ts\n --json print {\"ok\": true, \"asset\": <AssetStateDto>, \"issues\": [\u2026]}\n --help this help\n\nExample:\n fundus asset replace navigationPanel ./exports/navigation_panel_v2.png --json\n fundus asset replace navigationPanel \\\n 'https://www.figma.com/design/abc/UI?node-id=12-34' --from figma --scale 3 --json\n fundus asset replace navigationPanel --from figma \\\n --figma-tag navigationPanel --figma-file abc --scale 3 --json\n";
|
|
11
11
|
export declare const ASSET_SET_HELP = "fundus asset set \u2014 update an asset's parameters and/or memberships\n\nUsage: fundus asset set <id> [--parameters <json>] [--manifests <a,b>]\n [--compression-x <0-100>] [--compression-y <0-100>] [--json]\n\nAt least one change flag is required. Runs the full autosave chain\n(write library \u2192 process \u2192 regenerate manifest modules).\n\nFlags:\n --parameters <json> SHALLOW MERGE at the top level onto the current\n parameters, then plugin validation:\n {\"preset\": \"webp-hq\"} sets one field,\n keeps the others\n {\"chromaKey\": {\u2026}} replaces the whole\n chromaKey object\n {\"mask\": null} clears an optional\n field\n {\"mask\": {\"$asset\": \"someImage\"}}\n sets an asset\n reference\n --manifests <a,b> REPLACES the explicit membership set (declarative,\n idempotent); --manifests \"\" clears it\n --compression-x <0-100>\n --compression-y <0-100>\n set one Slice stretch-compression axis while preserving\n the omitted axis; setting both axes to 0 removes\n compression. These values override compression supplied\n through --parameters in the same invocation\n --json print {\"ok\": true, \"asset\": <AssetStateDto>, \"issues\": [\u2026]}\n --help this help\n\nThe mutation is validated first and rejected (exit 1, nothing written)\nif it would leave the library invalid \u2014 e.g. a reference to a missing\nasset, a reference cycle, or an unknown manifest name. Ingest reference\ntargets before pointing at them.\n\nExample:\n fundus asset set navigationPanel --compression-x 75 --compression-y 25 --json\n fundus asset set characterIdle \\\n --parameters '{\"mask\": {\"$asset\": \"characterIdleMask\"}}' --json\n";
|
|
12
12
|
export declare const ASSET_RENAME_HELP = "fundus asset rename \u2014 rename an asset id\n\nUsage: fundus asset rename <id> <newId> [--json]\n\nRenames the asset's id (the raw file keeps its name \u2014 ids are the\nstable key) and re-hashes its proxy under the new id via the autosave\nchain. Fails if another asset references <id> \u2014 update the referrers\nfirst \u2014 or if <newId> is taken or invalid.\n\nFlags:\n --json print {\"ok\": true, \"asset\": <AssetStateDto>, \"issues\": [\u2026]}\n --help this help\n\nExample:\n fundus asset rename sidebarPanel navigationPanel --json\n";
|
|
@@ -437,7 +437,7 @@ Usage: fundus asset reimport <id> [--json]
|
|
|
437
437
|
fundus asset reimport <id> --scale <1|2|3|4> [--json]
|
|
438
438
|
|
|
439
439
|
Without overrides, re-materializes the persisted importer source (a Figma tag
|
|
440
|
-
asset
|
|
440
|
+
asset looks up the node carrying the tag again, self-healing after node moves).
|
|
441
441
|
A Figma override may update the source or scale; omitted values are preserved.
|
|
442
442
|
Asset type, parameters, folder, and manifests remain unchanged. Raw-file drift
|
|
443
443
|
or concurrent changes abort without overwriting local edits.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const FIGMA_HELP = "fundus figma \u2014
|
|
1
|
+
export declare const FIGMA_HELP = "fundus figma \u2014 write Fundus tag links in Figma\n\nUsage: fundus figma <subcommand> \u2026 [--json]\n\nA Fundus tag is a Dev Resources link on the node:\nhttps://fundus.invalid/asset/<tag>, named \"Fundus: <tag>\". These commands\nread the file's links and the tagged nodes over the REST API, check the\nrequest against them and the library, then write the links directly. The\nDev Mode annotation follows once the Fundus Figma plugin opens the node's page.\n\nSubcommands:\n set-tag tag a node (--node-id, --tag)\n delete-tag remove a node's tag (--tag or --node-id)\n\nRequires import.figma.token in fundus.config.ts: a personal access token with\nthe file_content:read and file_dev_resources:read scopes, plus\nfile_dev_resources:write for these commands.\n";
|
|
2
2
|
export declare function runFigmaCommand(argumentList: string[]): Promise<void>;
|
|
@@ -1,98 +1,110 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `fundus figma` command group:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* caller runs with Figma's MCP `use_figma` tool.
|
|
2
|
+
* The `fundus figma` command group: set and delete Fundus tag links on Figma
|
|
3
|
+
* nodes over the REST API. The tag commands validate against a confirmed
|
|
4
|
+
* snapshot of the file (see figma-tags.ts) and the library before writing.
|
|
6
5
|
*/
|
|
7
6
|
import { assetIdError } from '../core/index.js';
|
|
8
7
|
import { loadConfig } from './config-loader.js';
|
|
9
|
-
import { FigmaTagConflictError,
|
|
8
|
+
import { FigmaTagConflictError, applyFigmaTagWrites, loadFigmaTagSnapshot, parseFigmaNodeId, planDeleteFigmaTag, planSetFigmaTag } from './figma-tags.js';
|
|
9
|
+
import { LibraryStore } from './library-store.js';
|
|
10
10
|
import { resolveFigmaFileKeyFlag } from './cli-commands.js';
|
|
11
11
|
import { CliUsageError, parseArguments, printJsonDocument, requirePositionals } from './cli-io.js';
|
|
12
|
-
|
|
12
|
+
const NEXT_STEP = "The Fundus Figma plugin updates the node's annotation once it opens the node's page.";
|
|
13
|
+
export const FIGMA_HELP = `fundus figma — write Fundus tag links in Figma
|
|
13
14
|
|
|
14
15
|
Usage: fundus figma <subcommand> … [--json]
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
the tag and its Dev Mode annotation exactly like the Fundus Figma plugin, and
|
|
22
|
-
returns the result. It throws without writing when the document changed.
|
|
17
|
+
A Fundus tag is a Dev Resources link on the node:
|
|
18
|
+
https://fundus.invalid/asset/<tag>, named "Fundus: <tag>". These commands
|
|
19
|
+
read the file's links and the tagged nodes over the REST API, check the
|
|
20
|
+
request against them and the library, then write the links directly. The
|
|
21
|
+
Dev Mode annotation follows once the Fundus Figma plugin opens the node's page.
|
|
23
22
|
|
|
24
23
|
Subcommands:
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
set-tag tag a node (--node-id, --tag)
|
|
25
|
+
delete-tag remove a node's tag (--tag or --node-id)
|
|
27
26
|
|
|
28
|
-
Requires import.figma.token in fundus.config.ts
|
|
27
|
+
Requires import.figma.token in fundus.config.ts: a personal access token with
|
|
28
|
+
the file_content:read and file_dev_resources:read scopes, plus
|
|
29
|
+
file_dev_resources:write for these commands.
|
|
29
30
|
`;
|
|
30
|
-
const
|
|
31
|
+
const SET_TAG_HELP = `fundus figma set-tag — tag a Figma node with a Fundus asset id
|
|
31
32
|
|
|
32
|
-
Usage: fundus figma
|
|
33
|
-
|
|
33
|
+
Usage: fundus figma set-tag --node-id <id> --tag <tag>
|
|
34
|
+
[--file <key|link>] [--force] [--json]
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
Adds the tag link to the node. A node that already carries the tag is left as
|
|
37
|
+
is. Refuses unless --force, listing the file's existing tags, when another node
|
|
38
|
+
carries the tag, when the node carries another tag, or when a Fundus asset
|
|
39
|
+
with that id exists from another source. An asset imported from this very
|
|
40
|
+
node by node id is not a conflict: afterwards
|
|
41
|
+
\`fundus asset replace <tag> --from figma --figma-tag <tag>\` moves it to the
|
|
42
|
+
tag and keeps its id, parameters, and manifests.
|
|
43
|
+
|
|
44
|
+
The new link is written first, then --force deletes the node's other tag
|
|
45
|
+
links and the tag's links on other nodes. A failed step stops the rest, so an
|
|
46
|
+
interruption at worst leaves the tag on two nodes (\`ambiguous-tag\` on
|
|
47
|
+
import), never loses it. Links on deleted nodes and non-Fundus links are
|
|
48
|
+
never touched.
|
|
43
49
|
|
|
44
50
|
Flags:
|
|
45
51
|
--node-id <id> the node to tag: 12:34 or 12-34
|
|
46
|
-
--tag <tag> the Fundus asset id to
|
|
52
|
+
--tag <tag> the Fundus asset id to link to the node (camelCase)
|
|
47
53
|
--file <key|link> Figma file key or link; default:
|
|
48
54
|
import.figma.defaultFileKey from fundus.config.ts
|
|
49
|
-
--force
|
|
50
|
-
|
|
51
|
-
despite a Fundus asset from another source
|
|
55
|
+
--force replace the node's other tags, move the tag away from
|
|
56
|
+
other nodes (this also resolves \`ambiguous-tag\`), or
|
|
57
|
+
tag despite a Fundus asset from another source
|
|
52
58
|
--json print {"ok": true, "fileKey", "nodeId", "tag",
|
|
53
|
-
"previousTag", "
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
"previousTag", "movedFrom": [{"nodeId", "nodeName"}],
|
|
60
|
+
"warnings", "next"}; a refusal prints {"ok": false,
|
|
61
|
+
"error": {"message"}, "existingTags": [{"tag", "nodeId",
|
|
62
|
+
"nodeName"}]}; a failed write prints {"ok": false,
|
|
63
|
+
"error": {"message"}, "written": [{"action":
|
|
64
|
+
"create"|"delete", "nodeId", "nodeName", "tag"}],
|
|
65
|
+
"notWritten": [same]} and exits 1
|
|
56
66
|
--help this help
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
The
|
|
60
|
-
|
|
68
|
+
Needs a token with file_content:read, file_dev_resources:read, and
|
|
69
|
+
file_dev_resources:write. The Dev Mode annotation appears once the Fundus
|
|
70
|
+
Figma plugin opens the node's page. Afterwards:
|
|
71
|
+
\`fundus asset ingest --from figma --figma-tag <tag>\`.
|
|
61
72
|
|
|
62
73
|
Example:
|
|
63
|
-
fundus figma
|
|
74
|
+
fundus figma set-tag --file 'https://www.figma.com/design/abc/UI' \\
|
|
64
75
|
--node-id 12-34 --tag navigationPanel --json
|
|
65
76
|
`;
|
|
66
|
-
const
|
|
77
|
+
const DELETE_TAG_HELP = `fundus figma delete-tag — remove a Fundus tag from a Figma node
|
|
67
78
|
|
|
68
|
-
Usage: fundus figma
|
|
69
|
-
|
|
79
|
+
Usage: fundus figma delete-tag (--tag <tag> | --node-id <id>)
|
|
80
|
+
[--file <key|link>] [--force] [--json]
|
|
70
81
|
|
|
71
|
-
|
|
72
|
-
unless --force when a Fundus asset is
|
|
73
|
-
would fail afterwards).
|
|
82
|
+
Deletes the node's tag link. The node must exist: a link left on a deleted
|
|
83
|
+
node is ignored, not cleaned up. Refuses unless --force when a Fundus asset is
|
|
84
|
+
imported from the tag (its reimport would fail afterwards).
|
|
74
85
|
|
|
75
86
|
Flags:
|
|
76
87
|
--tag <tag> the tag to remove (must be on exactly one node)
|
|
77
88
|
--node-id <id> the node whose tag to remove: 12:34 or 12-34; with --tag,
|
|
78
|
-
both must match
|
|
89
|
+
both must match; a node with several tags needs --tag
|
|
79
90
|
--file <key|link> Figma file key or link; default:
|
|
80
91
|
import.figma.defaultFileKey from fundus.config.ts
|
|
81
92
|
--force delete even when a Fundus asset is imported from the tag
|
|
82
93
|
--json print {"ok": true, "fileKey", "nodeId", "tag",
|
|
83
|
-
"warnings", "next"
|
|
84
|
-
|
|
94
|
+
"warnings", "next"}; refusals and failed writes as for
|
|
95
|
+
set-tag
|
|
85
96
|
--help this help
|
|
86
97
|
|
|
87
|
-
|
|
88
|
-
|
|
98
|
+
Needs a token with file_content:read, file_dev_resources:read, and
|
|
99
|
+
file_dev_resources:write. The Fundus Figma plugin removes the node's
|
|
100
|
+
annotation once it opens the node's page.
|
|
89
101
|
|
|
90
102
|
Example:
|
|
91
|
-
fundus figma
|
|
103
|
+
fundus figma delete-tag --tag navigationPanel --json
|
|
92
104
|
`;
|
|
93
105
|
const FIGMA_SUBCOMMAND_HELP = {
|
|
94
|
-
'
|
|
95
|
-
'
|
|
106
|
+
'set-tag': SET_TAG_HELP,
|
|
107
|
+
'delete-tag': DELETE_TAG_HELP
|
|
96
108
|
};
|
|
97
109
|
const TAG_FLAGS = {
|
|
98
110
|
json: { takesValue: false },
|
|
@@ -112,17 +124,17 @@ function stringFlag(parsed, name) {
|
|
|
112
124
|
const value = parsed.flags[name];
|
|
113
125
|
return typeof value === 'string' ? value : undefined;
|
|
114
126
|
}
|
|
115
|
-
async function resolvePlanInputs(parsed, commandPath) {
|
|
127
|
+
async function resolvePlanInputs(parsed, commandPath, targetNodeId) {
|
|
116
128
|
const config = await loadConfig(process.cwd());
|
|
117
129
|
const fileFlag = stringFlag(parsed, 'file');
|
|
118
130
|
const fileKey = fileFlag !== undefined ? resolveFigmaFileKeyFlag(fileFlag) : config.import.figma.defaultFileKey;
|
|
119
131
|
if (!fileKey) {
|
|
120
132
|
throw new CliUsageError(`\`${commandPath}\` needs --file <key|link> or import.figma.defaultFileKey in fundus.config.ts.`);
|
|
121
133
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return
|
|
134
|
+
const context = { config, fetch: globalThis.fetch };
|
|
135
|
+
const library = await new LibraryStore(config).read();
|
|
136
|
+
const snapshot = await loadFigmaTagSnapshot(context, fileKey, targetNodeId);
|
|
137
|
+
return { fileKey, context, plan: { library, snapshot } };
|
|
126
138
|
}
|
|
127
139
|
/** Refusals that list the file's tags get their own document; others take the standard error path. */
|
|
128
140
|
function reportConflict(cause, json) {
|
|
@@ -139,24 +151,63 @@ function reportConflict(cause, json) {
|
|
|
139
151
|
console.error(`fundus: ${cause.message}`);
|
|
140
152
|
console.error(cause.existingTags.length === 0 ? 'No tags in this file yet.' : 'Existing tags in this file:');
|
|
141
153
|
for (const entry of cause.existingTags) {
|
|
142
|
-
console.error(` ${entry.tag} ${entry.nodeId} "${entry.nodeName}"
|
|
154
|
+
console.error(` ${entry.tag} ${entry.nodeId} "${entry.nodeName}"`);
|
|
143
155
|
}
|
|
144
156
|
}
|
|
145
157
|
process.exitCode = 1;
|
|
146
158
|
return true;
|
|
147
159
|
}
|
|
148
|
-
|
|
160
|
+
/** The printed form of a write: the link id is internal. */
|
|
161
|
+
function publicWrite({ action, nodeId, nodeName, tag }) {
|
|
162
|
+
return { action, nodeId, nodeName, tag };
|
|
163
|
+
}
|
|
164
|
+
function describeWrite(write) {
|
|
165
|
+
return `${write.action === 'create' ? 'add' : 'remove'} tag "${write.tag}" on "${write.nodeName}" (${write.nodeId})`;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Applies the plan's writes and prints the outcome. Returns false after
|
|
169
|
+
* reporting a failed write, which leaves exit code 1.
|
|
170
|
+
*/
|
|
171
|
+
async function writeAndReport(fileKey, writes, warnings, context, json) {
|
|
172
|
+
const { written, failure, notWritten } = await applyFigmaTagWrites(fileKey, writes, context);
|
|
173
|
+
if (!failure)
|
|
174
|
+
return true;
|
|
175
|
+
// Rerunning plans only the steps still missing, and prints the plan's hints again.
|
|
176
|
+
const message = `Could not ${describeWrite(failure.write)}: ${failure.message}${written.length > 0 ? ' Rerun the same command to finish the remaining steps.' : ''}`;
|
|
149
177
|
if (json) {
|
|
150
|
-
printJsonDocument({
|
|
178
|
+
printJsonDocument({
|
|
179
|
+
ok: false,
|
|
180
|
+
error: { message },
|
|
181
|
+
written: written.map(publicWrite),
|
|
182
|
+
notWritten: notWritten.map(publicWrite)
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
for (const warning of warnings)
|
|
187
|
+
console.error(`⚠ ${warning}`);
|
|
188
|
+
console.error(`fundus: ${message}`);
|
|
189
|
+
console.error(written.length === 0 ? 'Nothing was written.' : 'Written:');
|
|
190
|
+
for (const write of written)
|
|
191
|
+
console.error(` ${describeWrite(write)}`);
|
|
192
|
+
console.error('Not written:');
|
|
193
|
+
for (const write of notWritten)
|
|
194
|
+
console.error(` ${describeWrite(write)}`);
|
|
195
|
+
}
|
|
196
|
+
process.exitCode = 1;
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
function printSuccess(summary, warnings, document, json) {
|
|
200
|
+
if (json) {
|
|
201
|
+
printJsonDocument({ ok: true, ...document, warnings, next: NEXT_STEP });
|
|
151
202
|
return;
|
|
152
203
|
}
|
|
153
|
-
for (const warning of
|
|
204
|
+
for (const warning of warnings)
|
|
154
205
|
console.error(`⚠ ${warning}`);
|
|
155
|
-
console.
|
|
156
|
-
|
|
206
|
+
console.log(summary);
|
|
207
|
+
console.log(NEXT_STEP);
|
|
157
208
|
}
|
|
158
|
-
async function
|
|
159
|
-
const commandPath = 'fundus figma
|
|
209
|
+
async function runSetTag(argumentList) {
|
|
210
|
+
const commandPath = 'fundus figma set-tag';
|
|
160
211
|
const parsed = parseArguments(argumentList, TAG_FLAGS, commandPath);
|
|
161
212
|
requirePositionals(parsed, [], commandPath);
|
|
162
213
|
const nodeIdFlag = stringFlag(parsed, 'node-id');
|
|
@@ -167,24 +218,30 @@ async function runPrepareSetTag(argumentList) {
|
|
|
167
218
|
const nodeId = parseFigmaNodeId(nodeIdFlag);
|
|
168
219
|
assertTag(tag);
|
|
169
220
|
const json = parsed.flags.json === true;
|
|
170
|
-
const { fileKey, context } = await resolvePlanInputs(parsed, commandPath);
|
|
221
|
+
const { fileKey, context, plan: planContext } = await resolvePlanInputs(parsed, commandPath, nodeId);
|
|
222
|
+
let plan;
|
|
171
223
|
try {
|
|
172
|
-
|
|
173
|
-
printPlan(plan, {
|
|
174
|
-
fileKey,
|
|
175
|
-
nodeId: plan.nodeId,
|
|
176
|
-
tag: plan.tag,
|
|
177
|
-
previousTag: plan.previousTag,
|
|
178
|
-
warnings: plan.warnings
|
|
179
|
-
}, json);
|
|
224
|
+
plan = planSetFigmaTag({ fileKey, nodeId, tag, force: parsed.flags.force === true }, planContext);
|
|
180
225
|
}
|
|
181
226
|
catch (cause) {
|
|
182
|
-
if (
|
|
183
|
-
|
|
227
|
+
if (reportConflict(cause, json))
|
|
228
|
+
return;
|
|
229
|
+
throw cause;
|
|
184
230
|
}
|
|
231
|
+
if (!(await writeAndReport(fileKey, plan.writes, plan.warnings, context, json)))
|
|
232
|
+
return;
|
|
233
|
+
printSuccess(plan.writes.length === 0
|
|
234
|
+
? `Node "${plan.nodeName}" (${nodeId}) already carries tag "${tag}"; nothing to write.`
|
|
235
|
+
: `Tagged "${plan.nodeName}" (${nodeId}) with "${tag}".`, plan.warnings, {
|
|
236
|
+
fileKey,
|
|
237
|
+
nodeId,
|
|
238
|
+
tag,
|
|
239
|
+
previousTag: plan.previousTag,
|
|
240
|
+
movedFrom: plan.movedFrom
|
|
241
|
+
}, json);
|
|
185
242
|
}
|
|
186
|
-
async function
|
|
187
|
-
const commandPath = 'fundus figma
|
|
243
|
+
async function runDeleteTag(argumentList) {
|
|
244
|
+
const commandPath = 'fundus figma delete-tag';
|
|
188
245
|
const parsed = parseArguments(argumentList, TAG_FLAGS, commandPath);
|
|
189
246
|
requirePositionals(parsed, [], commandPath);
|
|
190
247
|
const nodeIdFlag = stringFlag(parsed, 'node-id');
|
|
@@ -195,22 +252,26 @@ async function runPrepareDeleteTag(argumentList) {
|
|
|
195
252
|
const nodeId = nodeIdFlag === undefined ? undefined : parseFigmaNodeId(nodeIdFlag);
|
|
196
253
|
assertTag(tag);
|
|
197
254
|
const json = parsed.flags.json === true;
|
|
198
|
-
const { fileKey, context } = await resolvePlanInputs(parsed, commandPath);
|
|
255
|
+
const { fileKey, context, plan: planContext } = await resolvePlanInputs(parsed, commandPath, nodeId);
|
|
256
|
+
let plan;
|
|
199
257
|
try {
|
|
200
|
-
|
|
201
|
-
printPlan(plan, { fileKey, nodeId: plan.nodeId, tag: plan.tag, warnings: plan.warnings }, json);
|
|
258
|
+
plan = planDeleteFigmaTag({ fileKey, nodeId, tag, force: parsed.flags.force === true }, planContext);
|
|
202
259
|
}
|
|
203
260
|
catch (cause) {
|
|
204
|
-
if (
|
|
205
|
-
|
|
261
|
+
if (reportConflict(cause, json))
|
|
262
|
+
return;
|
|
263
|
+
throw cause;
|
|
206
264
|
}
|
|
265
|
+
if (!(await writeAndReport(fileKey, plan.writes, plan.warnings, context, json)))
|
|
266
|
+
return;
|
|
267
|
+
printSuccess(`Removed tag "${plan.tag}" from "${plan.nodeName}" (${plan.nodeId}).`, plan.warnings, { fileKey, nodeId: plan.nodeId, tag: plan.tag }, json);
|
|
207
268
|
}
|
|
208
269
|
export async function runFigmaCommand(argumentList) {
|
|
209
270
|
const [subcommand, ...rest] = argumentList;
|
|
210
271
|
if (subcommand === undefined || subcommand === '--help') {
|
|
211
272
|
console.log(FIGMA_HELP);
|
|
212
273
|
if (subcommand === undefined) {
|
|
213
|
-
throw new CliUsageError('`fundus figma` needs a subcommand:
|
|
274
|
+
throw new CliUsageError('`fundus figma` needs a subcommand: set-tag, delete-tag.');
|
|
214
275
|
}
|
|
215
276
|
return;
|
|
216
277
|
}
|
|
@@ -219,10 +280,10 @@ export async function runFigmaCommand(argumentList) {
|
|
|
219
280
|
return;
|
|
220
281
|
}
|
|
221
282
|
switch (subcommand) {
|
|
222
|
-
case '
|
|
223
|
-
return
|
|
224
|
-
case '
|
|
225
|
-
return
|
|
283
|
+
case 'set-tag':
|
|
284
|
+
return runSetTag(rest);
|
|
285
|
+
case 'delete-tag':
|
|
286
|
+
return runDeleteTag(rest);
|
|
226
287
|
default:
|
|
227
288
|
throw new CliUsageError(`Unknown subcommand "figma ${subcommand}" — run \`fundus figma --help\`.`);
|
|
228
289
|
}
|
|
@@ -1,46 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Planning for
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* Planning and REST writes for `fundus figma set-tag` / `delete-tag`. Fundus
|
|
3
|
+
* confirms the file's tag links against the nodes that still exist (one link
|
|
4
|
+
* list plus one `/nodes` call), plans purely on that snapshot and the library,
|
|
5
|
+
* then writes the links in an order where an interruption can at worst leave
|
|
6
|
+
* a tag on two nodes (`ambiguous-tag`), never lose it.
|
|
7
7
|
*/
|
|
8
8
|
import { type Library } from '../core/index.js';
|
|
9
|
-
import type {
|
|
9
|
+
import type { ImporterContext } from './importers/contract.js';
|
|
10
|
+
import { type FigmaNodeSummary } from './importers/figma.js';
|
|
11
|
+
/** A tag link on a node that exists. */
|
|
12
|
+
export interface ConfirmedFigmaTag {
|
|
13
|
+
tag: string;
|
|
14
|
+
nodeId: string;
|
|
15
|
+
nodeName: string;
|
|
16
|
+
nodeType: string;
|
|
17
|
+
linkId: string;
|
|
18
|
+
}
|
|
19
|
+
export interface FigmaTagSnapshot {
|
|
20
|
+
/** Tag links on nodes that exist (orphaned links dropped). */
|
|
21
|
+
tags: ConfirmedFigmaTag[];
|
|
22
|
+
/** The requested node when it exists, tagged or not. */
|
|
23
|
+
target: FigmaNodeSummary | null;
|
|
24
|
+
}
|
|
10
25
|
/** A tagged node in the file, as reported alongside conflicts. */
|
|
11
26
|
export interface FigmaTagListing {
|
|
12
27
|
tag: string;
|
|
13
28
|
nodeId: string;
|
|
14
29
|
nodeName: string;
|
|
15
|
-
page: string;
|
|
16
30
|
}
|
|
17
31
|
/** An expected refusal that carries the file's current tags so the caller can pick another. */
|
|
18
32
|
export declare class FigmaTagConflictError extends Error {
|
|
19
33
|
readonly existingTags: FigmaTagListing[];
|
|
20
34
|
constructor(message: string, existingTags: FigmaTagListing[]);
|
|
21
35
|
}
|
|
22
|
-
|
|
23
|
-
fileKey: string;
|
|
36
|
+
interface FigmaTagWriteBase {
|
|
24
37
|
nodeId: string;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/** The `use_figma` script body. */
|
|
28
|
-
code: string;
|
|
38
|
+
nodeName: string;
|
|
39
|
+
tag: string;
|
|
29
40
|
}
|
|
30
|
-
|
|
41
|
+
/** One REST write; a delete names the link it removes. */
|
|
42
|
+
export type FigmaTagWrite = (FigmaTagWriteBase & {
|
|
43
|
+
action: 'create';
|
|
44
|
+
}) | (FigmaTagWriteBase & {
|
|
45
|
+
action: 'delete';
|
|
46
|
+
linkId: string;
|
|
47
|
+
});
|
|
48
|
+
export interface SetFigmaTagPlan {
|
|
49
|
+
fileKey: string;
|
|
50
|
+
nodeId: string;
|
|
51
|
+
nodeName: string;
|
|
31
52
|
tag: string;
|
|
32
|
-
/**
|
|
53
|
+
/** Another tag the node carried, else `tag` when it already carried it, else null. */
|
|
33
54
|
previousTag: string | null;
|
|
55
|
+
/** Other nodes the tag is removed from. */
|
|
56
|
+
movedFrom: Array<{
|
|
57
|
+
nodeId: string;
|
|
58
|
+
nodeName: string;
|
|
59
|
+
}>;
|
|
60
|
+
/** Ordered: the create (if any) first, then deletes. */
|
|
61
|
+
writes: FigmaTagWrite[];
|
|
62
|
+
/** Non-fatal findings the caller should relay (e.g. a Fundus asset to reimport). */
|
|
63
|
+
warnings: string[];
|
|
34
64
|
}
|
|
35
|
-
export interface DeleteFigmaTagPlan
|
|
65
|
+
export interface DeleteFigmaTagPlan {
|
|
66
|
+
fileKey: string;
|
|
67
|
+
nodeId: string;
|
|
68
|
+
nodeName: string;
|
|
36
69
|
tag: string;
|
|
70
|
+
writes: FigmaTagWrite[];
|
|
71
|
+
warnings: string[];
|
|
37
72
|
}
|
|
38
|
-
/** Normalize a `12:34` / `12-34` node id; Fundus
|
|
73
|
+
/** Normalize a `12:34` / `12-34` node id; Fundus tags only this id form. */
|
|
39
74
|
export declare function parseFigmaNodeId(value: string): string;
|
|
40
75
|
export interface FigmaTagPlanContext {
|
|
41
76
|
library: Library;
|
|
42
|
-
|
|
43
|
-
document: unknown;
|
|
77
|
+
snapshot: FigmaTagSnapshot;
|
|
44
78
|
}
|
|
45
79
|
export interface SetFigmaTagRequest {
|
|
46
80
|
fileKey: string;
|
|
@@ -48,14 +82,28 @@ export interface SetFigmaTagRequest {
|
|
|
48
82
|
tag: string;
|
|
49
83
|
force: boolean;
|
|
50
84
|
}
|
|
51
|
-
export declare function planSetFigmaTag(request: SetFigmaTagRequest, { library,
|
|
85
|
+
export declare function planSetFigmaTag(request: SetFigmaTagRequest, { library, snapshot }: FigmaTagPlanContext): SetFigmaTagPlan;
|
|
52
86
|
export interface DeleteFigmaTagRequest {
|
|
53
87
|
fileKey: string;
|
|
54
|
-
/**
|
|
88
|
+
/** At least one of nodeId / tag identifies the node; both must agree when given. */
|
|
55
89
|
nodeId?: string;
|
|
56
90
|
tag?: string;
|
|
57
91
|
force: boolean;
|
|
58
92
|
}
|
|
59
|
-
export declare function planDeleteFigmaTag(request: DeleteFigmaTagRequest, { library,
|
|
60
|
-
/**
|
|
61
|
-
|
|
93
|
+
export declare function planDeleteFigmaTag(request: DeleteFigmaTagRequest, { library, snapshot }: FigmaTagPlanContext): DeleteFigmaTagPlan;
|
|
94
|
+
/**
|
|
95
|
+
* The file's tag links confirmed against the nodes that exist: one link list,
|
|
96
|
+
* then one `/nodes` call over every tagged node plus the target. Links on
|
|
97
|
+
* missing nodes are orphaned and dropped, so nothing ever touches them.
|
|
98
|
+
*/
|
|
99
|
+
export declare function loadFigmaTagSnapshot(context: ImporterContext, fileKey: string, targetNodeId?: string): Promise<FigmaTagSnapshot>;
|
|
100
|
+
/** Runs the writes in order and stops at the first failure; retries live in the REST client. */
|
|
101
|
+
export declare function applyFigmaTagWrites(fileKey: string, writes: readonly FigmaTagWrite[], context: ImporterContext): Promise<{
|
|
102
|
+
written: FigmaTagWrite[];
|
|
103
|
+
failure: {
|
|
104
|
+
write: FigmaTagWrite;
|
|
105
|
+
message: string;
|
|
106
|
+
} | null;
|
|
107
|
+
notWritten: FigmaTagWrite[];
|
|
108
|
+
}>;
|
|
109
|
+
export {};
|