fundus 0.28.1 → 0.29.1
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/{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/{Bsj1ssvc.js → CE3cWlK6.js} +1 -1
- package/build/client/_app/immutable/chunks/CE3cWlK6.js.br +0 -0
- package/build/client/_app/immutable/chunks/CE3cWlK6.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 → Cq3PJxJG.js} +1 -1
- package/build/client/_app/immutable/chunks/Cq3PJxJG.js.br +2 -0
- package/build/client/_app/immutable/chunks/Cq3PJxJG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{OL1Dh1oP.js → Wk7WcyQU.js} +1 -1
- package/build/client/_app/immutable/chunks/Wk7WcyQU.js.br +0 -0
- package/build/client/_app/immutable/chunks/Wk7WcyQU.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.DpZM49_s.js → app.Dit62aNJ.js} +2 -2
- package/build/client/_app/immutable/entry/app.Dit62aNJ.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Dit62aNJ.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.CCBu6ABN.js +1 -0
- package/build/client/_app/immutable/entry/start.CCBu6ABN.js.br +0 -0
- package/build/client/_app/immutable/entry/start.CCBu6ABN.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.Wqvn8XD-.js → 0.DnyKXqLr.js} +1 -1
- package/build/client/_app/immutable/nodes/0.DnyKXqLr.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DnyKXqLr.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.Z-UvvLkP.js → 1.Cz-4S6LF.js} +1 -1
- package/build/client/_app/immutable/nodes/1.Cz-4S6LF.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Cz-4S6LF.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.lu89W_qJ.js → 2.C75-hsCY.js} +1 -1
- package/build/client/_app/immutable/nodes/2.C75-hsCY.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.C75-hsCY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.Dt32EAoq.js → 3.4pSddugU.js} +1 -1
- package/build/client/_app/immutable/nodes/3.4pSddugU.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.4pSddugU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.WipzcX8_.js → 4.KoQxJEWQ.js} +1 -1
- package/build/client/_app/immutable/nodes/4.KoQxJEWQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.KoQxJEWQ.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-BR2IRl9z.js} +205 -115
- package/build/server/chunks/chunks/context.js-BR2IRl9z.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-B4JdXFgm.js → contract.js-DHeIVVv8.js} +46 -12
- package/build/server/chunks/chunks/contract.js-DHeIVVv8.js.map +1 -0
- 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-CNZgoxR0.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-D0dALD2Q.js.map → exports.js-CNZgoxR0.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-DYYKvppy.js → http.js-dk5jbOFm.js} +2 -2
- package/build/server/chunks/chunks/{http.js-DYYKvppy.js.map → http.js-dk5jbOFm.js.map} +1 -1
- package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js → internal.js-DlRiYJji.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-CJkB_gzV.js.map → internal.js-DlRiYJji.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-reconciliation2.js-DKOpJ8if.js → raw-reconciliation.js-Cco4r8lr.js} +52 -18
- package/build/server/chunks/chunks/raw-reconciliation.js-Cco4r8lr.js.map +1 -0
- package/build/server/chunks/chunks/raw-reconciliation2.js-CuYSsYTP.js +11 -0
- package/build/server/chunks/chunks/raw-reconciliation2.js-CuYSsYTP.js.map +1 -0
- package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js → shared.js-C6qC0jnA.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-D3ZDVUlh.js.map → shared.js-C6qC0jnA.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js → utils.js-BZ32hXFI.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-CqWW_v-5.js.map → utils.js-BZ32hXFI.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js → _server.ts.js-8jGLP2Aj.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-Dw2MW5Tm.js.map → _server.ts.js-8jGLP2Aj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js → _server.ts.js-BOW9Ejim.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-GQDuJGug.js.map → _server.ts.js-BOW9Ejim.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js → _server.ts.js-Clac8atJ.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-JbLSv7Xx.js.map → _server.ts.js-Clac8atJ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js → _server.ts.js-EdHTA-SO.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-BPae-BYF.js.map → _server.ts.js-EdHTA-SO.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js → _server.ts.js-ZBCRgRYi.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/{_server.ts.js-BafrrUxu.js.map → _server.ts.js-ZBCRgRYi.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js → _server.ts.js-DY_e5K6d.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-UOlSNEi9.js.map → _server.ts.js-DY_e5K6d.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js → _server.ts.js-Cl2jxJNi.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-QE1vUuAx.js.map → _server.ts.js-Cl2jxJNi.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js → _server.ts.js-DrrZWUbd.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DIVfppGt.js.map → _server.ts.js-DrrZWUbd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js → _server.ts.js-Bnw0HbEk.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/events/{_server.ts.js-B6R_kqP8.js.map → _server.ts.js-Bnw0HbEk.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js → _server.ts.js-NeVn2ap9.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CertbDsH.js.map → _server.ts.js-NeVn2ap9.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js → _server.ts.js-ENGDgoLy.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-DEIF3Hu2.js.map → _server.ts.js-ENGDgoLy.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js → _server.ts.js-BQVGCzBR.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-DNFsNGr4.js.map → _server.ts.js-BQVGCzBR.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js → _server.ts.js-Pxver0Y-.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DDW8XRPe.js.map → _server.ts.js-Pxver0Y-.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js → _server.ts.js-DYtiqzJq.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-C222-xli.js.map → _server.ts.js-DYtiqzJq.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js → _server.ts.js-lBgmEZHV.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-CI1P1uyd.js.map → _server.ts.js-lBgmEZHV.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js → _server.ts.js-BJHyONFH.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-DpiUwaSh.js.map → _server.ts.js-BJHyONFH.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js → _server.ts.js-Bm5XO80W.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js-DT0VPqPT.js.map → _server.ts.js-Bm5XO80W.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js → _server.ts.js-B7Z20kYf.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DBpHM42g.js.map → _server.ts.js-B7Z20kYf.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js → _server.ts.js-Cg-f37jc.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-Cxu5b6Au.js.map → _server.ts.js-Cg-f37jc.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js → _server.ts.js-dIXZiq5l.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-W4dhMo8Y.js.map → _server.ts.js-dIXZiq5l.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js → _server.ts.js-CnTrS5pT.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-DJ_adxbT.js.map → _server.ts.js-CnTrS5pT.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js → _server.ts.js-B7TcFRuL.js} +6 -6
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-BisoHihD.js.map → _server.ts.js-B7TcFRuL.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js → _server.ts.js-BkUQInqW.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-D4jLLuko.js.map → _server.ts.js-BkUQInqW.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js → _server.ts.js-CshyvqOq.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-Dfv2ItjT.js.map → _server.ts.js-CshyvqOq.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-oHJX5INm.js → hooks.server.js-D4DECjz_.js} +8 -7
- package/build/server/chunks/entries/hooks.server.js-D4DECjz_.js.map +1 -0
- package/build/server/chunks/{handler-BAe0c9yw.js → handler-Cna54zf6.js} +5 -5
- package/build/server/chunks/{handler-BAe0c9yw.js.map → handler-Cna54zf6.js.map} +1 -1
- package/build/server/chunks/{index.js-DUYD4JB0.js → index.js-BnpHWDec.js} +5 -5
- package/build/server/chunks/{index.js-DUYD4JB0.js.map → index.js-BnpHWDec.js.map} +1 -1
- package/build/server/chunks/{manifest.js-zwun-T7O.js → manifest.js-9WMEOpxH.js} +31 -31
- package/build/server/chunks/{manifest.js-zwun-T7O.js.map → manifest.js-9WMEOpxH.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-BmkXwDRY.js → 0.js-C2b1a672.js} +2 -2
- package/build/server/chunks/nodes/{0.js-BmkXwDRY.js.map → 0.js-C2b1a672.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-P3Ai28oj.js +7 -0
- package/build/server/chunks/nodes/{1.js-xbOwEHCW.js.map → 1.js-P3Ai28oj.js.map} +1 -1
- package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js → 2.js-sM3j5BqB.js} +2 -2
- package/build/server/chunks/nodes/{2.js-BuNw1vTZ.js.map → 2.js-sM3j5BqB.js.map} +1 -1
- package/build/server/chunks/nodes/3.js-G0jV-ymM.js +7 -0
- package/build/server/chunks/nodes/{3.js-Dpr_DvNU.js.map → 3.js-G0jV-ymM.js.map} +1 -1
- package/build/server/chunks/nodes/4.js-BUTPrI45.js +7 -0
- package/build/server/chunks/nodes/{4.js-14Lypd4o.js.map → 4.js-BUTPrI45.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/concurrency.d.ts +12 -0
- package/dist/server/concurrency.js +23 -0
- package/dist/server/figma-tags.d.ts +72 -24
- package/dist/server/figma-tags.js +130 -79
- package/dist/server/image-duplicates.js +6 -4
- package/dist/server/importers/figma.d.ts +20 -15
- package/dist/server/importers/figma.js +172 -92
- package/dist/server/operations.d.ts +7 -0
- package/dist/server/operations.js +53 -26
- package/dist/server/processing/processor.d.ts +29 -1
- package/dist/server/processing/processor.js +42 -5
- package/dist/server/raw-reconciliation.js +26 -10
- package/package.json +1 -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/contract.js-B4JdXFgm.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 +0 -11
- package/build/server/chunks/chunks/raw-reconciliation.js-DPnNXe0b.js.map +0 -1
- package/build/server/chunks/chunks/raw-reconciliation2.js-DKOpJ8if.js.map +0 -1
- package/build/server/chunks/entries/hooks.server.js-oHJX5INm.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
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"raw-reconciliation2.js-DKOpJ8if.js","sources":["../../../../.svelte-kit/output/server/chunks/raw-reconciliation2.js"],"sourcesContent":["import { A as isFundusTransactionName, L as folderPathError, M as rawFilePathError, j as portableRawPathKey, n as compareCodeUnits } from \"./core.js\";\nimport { join } from \"node:path\";\nimport { constants } from \"node:fs\";\nimport { lstat, open, readdir } from \"node:fs/promises\";\nimport { createHash } from \"node:crypto\";\n//#region src/lib/server/raw-reconciliation.ts\nfunction objectIdentity(value) {\n\treturn `${value.dev}:${value.ino}:${value.mode}`;\n}\nfunction fileIdentity(value) {\n\treturn `${objectIdentity(value)}:${value.size}:${value.mtimeNs}:${value.ctimeNs}`;\n}\nfunction pathMatchesHandle(pathStat, handleStat) {\n\treturn pathStat.isFile() && objectIdentity(pathStat) === objectIdentity(handleStat);\n}\n/** Hash one regular file without following its final path component. */\nasync function stableRawFileHash(path) {\n\tlet lastProblem;\n\tfor (let attempt = 0; attempt < 3; attempt++) try {\n\t\tconst handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);\n\t\ttry {\n\t\t\tconst before = await handle.stat({ bigint: true });\n\t\t\tconst pathBefore = await lstat(path, { bigint: true });\n\t\t\tif (!before.isFile() || !pathMatchesHandle(pathBefore, before)) throw new Error(\"path is not the opened regular file\");\n\t\t\tconst hash = createHash(\"sha256\");\n\t\t\tfor await (const chunk of handle.createReadStream({ autoClose: false })) hash.update(chunk);\n\t\t\tconst after = await handle.stat({ bigint: true });\n\t\t\tconst pathAfter = await lstat(path, { bigint: true });\n\t\t\tif (fileIdentity(before) === fileIdentity(after) && pathMatchesHandle(pathAfter, after)) return hash.digest(\"hex\");\n\t\t\tlastProblem = /* @__PURE__ */ new Error(\"changed while it was being hashed\");\n\t\t} finally {\n\t\t\tawait handle.close().catch(() => {});\n\t\t}\n\t} catch (cause) {\n\t\tlastProblem = cause;\n\t}\n\tthrow lastProblem instanceof Error ? lastProblem : new Error(String(lastProblem));\n}\nasync function verifyStableRawFile(path, expectedHash) {\n\tconst actualHash = await stableRawFileHash(path);\n\tif (actualHash !== expectedHash) throw new Error(`Raw source changed (expected ${expectedHash}, found ${actualHash}).`);\n}\n/** Enumerate without following symlinks and retain structural scan completeness. */\nasync function scanRawDirectory(rawDir, includeFile = () => true) {\n\tconst files = [];\n\tconst blockers = [];\n\tconst diagnostics = [];\n\tconst occupiedPaths = /* @__PURE__ */ new Set();\n\tconst entryKinds = /* @__PURE__ */ new Map();\n\tconst ignoredRegularPaths = [];\n\tlet complete = true;\n\tfunction markIncomplete(path, reason) {\n\t\tcomplete = false;\n\t\tdiagnostics.push({\n\t\t\tpath,\n\t\t\treason\n\t\t});\n\t}\n\tasync function visit(folder) {\n\t\tconst absolutePath = join(rawDir, folder);\n\t\tlet before;\n\t\ttry {\n\t\t\tbefore = await lstat(absolutePath, { bigint: true });\n\t\t} catch (cause) {\n\t\t\tmarkIncomplete(folder, `${folder === \"\" ? \"Raw directory\" : `Directory \"${folder}\"`} cannot be read: ${cause instanceof Error ? cause.message : String(cause)}`);\n\t\t\treturn;\n\t\t}\n\t\tif (!before.isDirectory() || before.isSymbolicLink()) {\n\t\t\tmarkIncomplete(folder, `${folder === \"\" ? \"Raw directory\" : `Directory \"${folder}\"`} is not a regular directory.`);\n\t\t\treturn;\n\t\t}\n\t\tlet entries;\n\t\ttry {\n\t\t\tentries = await readdir(absolutePath, { withFileTypes: true });\n\t\t} catch (cause) {\n\t\t\tmarkIncomplete(folder, `${folder === \"\" ? \"Raw directory\" : `Directory \"${folder}\"`} cannot be traversed: ${cause instanceof Error ? cause.message : String(cause)}`);\n\t\t\treturn;\n\t\t}\n\t\tfor (const entry of entries.sort((a, b) => compareCodeUnits(a.name, b.name))) {\n\t\t\tconst path = folder === \"\" ? entry.name : `${folder}/${entry.name}`;\n\t\t\tif (entry.name === \".gitkeep\" || isFundusTransactionName(entry.name)) continue;\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\toccupiedPaths.add(path);\n\t\t\t\tentryKinds.set(path, \"directory\");\n\t\t\t\tconst problem = folderPathError(path);\n\t\t\t\tif (problem) blockers.push({\n\t\t\t\t\tpath,\n\t\t\t\t\treason: problem\n\t\t\t\t});\n\t\t\t\telse await visit(path);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (entry.isFile()) {\n\t\t\t\tif (!includeFile(path)) {\n\t\t\t\t\tignoredRegularPaths.push(path);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\toccupiedPaths.add(path);\n\t\t\t\tentryKinds.set(path, \"file\");\n\t\t\t\tconst problem = rawFilePathError(path);\n\t\t\t\tif (problem) {\n\t\t\t\t\tblockers.push({\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\treason: problem\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tfiles.push({\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\thash: await stableRawFileHash(join(rawDir, path))\n\t\t\t\t\t});\n\t\t\t\t} catch (cause) {\n\t\t\t\t\tblockers.push({\n\t\t\t\t\t\tpath,\n\t\t\t\t\t\treason: `Could not obtain a stable file hash: ${cause instanceof Error ? cause.message : String(cause)}`\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst kind = entry.isSymbolicLink() ? \"symlink\" : \"special\";\n\t\t\toccupiedPaths.add(path);\n\t\t\tentryKinds.set(path, kind);\n\t\t\tblockers.push({\n\t\t\t\tpath,\n\t\t\t\treason: \"Symlinks and special files are not supported.\"\n\t\t\t});\n\t\t}\n\t\ttry {\n\t\t\tconst after = await lstat(absolutePath, { bigint: true });\n\t\t\tif (!after.isDirectory() || objectIdentity(before) !== objectIdentity(after)) markIncomplete(folder, `${folder === \"\" ? \"Raw directory\" : `Directory \"${folder}\"`} changed during traversal.`);\n\t\t} catch (cause) {\n\t\t\tmarkIncomplete(folder, `${folder === \"\" ? \"Raw directory\" : `Directory \"${folder}\"`} changed during traversal: ${cause instanceof Error ? cause.message : String(cause)}`);\n\t\t}\n\t}\n\tawait visit(\"\");\n\tconst collisions = /* @__PURE__ */ new Map();\n\tfor (const path of [...occupiedPaths].sort(compareCodeUnits)) {\n\t\tconst key = portableRawPathKey(path);\n\t\tconst previous = collisions.get(key);\n\t\tif (previous !== void 0 && previous !== path) {\n\t\t\tconst reason = `Raw paths \"${previous}\" and \"${path}\" collide portably.`;\n\t\t\tblockers.push({\n\t\t\t\tpath: previous,\n\t\t\t\treason\n\t\t\t});\n\t\t\tblockers.push({\n\t\t\t\tpath,\n\t\t\t\treason\n\t\t\t});\n\t\t} else collisions.set(key, path);\n\t}\n\tconst blockersByPath = /* @__PURE__ */ new Map();\n\tfor (const blocker of blockers) if (!blockersByPath.has(blocker.path)) blockersByPath.set(blocker.path, blocker);\n\tconst sortedBlockers = [...blockersByPath.values()].sort((a, b) => compareCodeUnits(a.path, b.path));\n\tconst blocked = new Set(sortedBlockers.map((entry) => entry.path));\n\treturn {\n\t\tcomplete,\n\t\tdiagnostics: diagnostics.sort((a, b) => compareCodeUnits(a.path, b.path)),\n\t\tfiles: files.filter((entry) => !blocked.has(entry.path)).sort((a, b) => compareCodeUnits(a.path, b.path)),\n\t\tblockers: sortedBlockers,\n\t\toccupiedPaths,\n\t\tentryKinds,\n\t\tignoredRegularPaths: ignoredRegularPaths.sort(compareCodeUnits)\n\t};\n}\n/** Pure deterministic matching: exact path first, then only 1:1 hash groups. */\nfunction classifyRawFiles(library, scan) {\n\tconst filesByPath = new Map(scan.files.map((file) => [file.path, file]));\n\tconst remainingFiles = new Map(filesByPath);\n\tconst remainingRecords = /* @__PURE__ */ new Map();\n\tconst unchangedAssetIds = [];\n\tconst edited = [];\n\tconst blockers = [...scan.blockers];\n\tconst excludedPrefixes = [];\n\tfor (const assetId of Object.keys(library.assets).sort(compareCodeUnits)) {\n\t\tconst record = library.assets[assetId];\n\t\tconst kind = scan.entryKinds.get(record.raw);\n\t\tif (kind !== void 0 && kind !== \"file\") {\n\t\t\tconst existing = blockers.find((blocker) => blocker.path === record.raw);\n\t\t\tif (existing) existing.assetId = assetId;\n\t\t\telse blockers.push({\n\t\t\t\tassetId,\n\t\t\t\tpath: record.raw,\n\t\t\t\treason: `Managed raw path is occupied by a ${kind}.`\n\t\t\t});\n\t\t\texcludedPrefixes.push(record.raw);\n\t\t\tcontinue;\n\t\t}\n\t\tconst exact = filesByPath.get(record.raw);\n\t\tif (exact) {\n\t\t\tremainingFiles.delete(record.raw);\n\t\t\tif (exact.hash === record.rawHash) unchangedAssetIds.push(assetId);\n\t\t\telse edited.push({\n\t\t\t\tassetId,\n\t\t\t\t...exact\n\t\t\t});\n\t\t} else if (scan.complete && !scan.occupiedPaths.has(record.raw) && !scan.blockers.some((blocker) => record.raw === blocker.path || record.raw.startsWith(`${blocker.path}/`))) remainingRecords.set(assetId, {\n\t\t\tpath: record.raw,\n\t\t\thash: record.rawHash\n\t\t});\n\t}\n\tfor (const path of remainingFiles.keys()) if (excludedPrefixes.some((prefix) => path.startsWith(`${prefix}/`))) remainingFiles.delete(path);\n\tconst recordsByHash = /* @__PURE__ */ new Map();\n\tfor (const [assetId, record] of remainingRecords) recordsByHash.set(record.hash, [...recordsByHash.get(record.hash) ?? [], assetId]);\n\tconst filesByHash = /* @__PURE__ */ new Map();\n\tfor (const file of remainingFiles.values()) filesByHash.set(file.hash, [...filesByHash.get(file.hash) ?? [], file]);\n\tconst moves = [];\n\tif (scan.complete) for (const [hash, assetIds] of recordsByHash) {\n\t\tconst candidates = filesByHash.get(hash) ?? [];\n\t\tif (assetIds.length !== 1 || candidates.length !== 1) continue;\n\t\tconst assetId = assetIds[0];\n\t\tconst file = candidates[0];\n\t\tmoves.push({\n\t\t\tassetId,\n\t\t\tfrom: remainingRecords.get(assetId)?.path ?? \"\",\n\t\t\t...file\n\t\t});\n\t\tremainingRecords.delete(assetId);\n\t\tremainingFiles.delete(file.path);\n\t}\n\tconst blockerKeys = /* @__PURE__ */ new Set();\n\tconst uniqueBlockers = blockers.filter((blocker) => {\n\t\tconst key = `${blocker.assetId ?? \"\"}|${blocker.path}`;\n\t\tif (blockerKeys.has(key)) return false;\n\t\tblockerKeys.add(key);\n\t\treturn true;\n\t});\n\treturn {\n\t\tcomplete: scan.complete,\n\t\tdiagnostics: scan.diagnostics,\n\t\tunchangedAssetIds,\n\t\tedited: edited.sort((a, b) => compareCodeUnits(a.path, b.path)),\n\t\tmoves: scan.complete ? moves.sort((a, b) => compareCodeUnits(a.path, b.path)) : [],\n\t\tdeletions: scan.complete ? [...remainingRecords].map(([assetId, record]) => ({\n\t\t\tassetId,\n\t\t\tpath: record.path\n\t\t})) : [],\n\t\tunmanaged: [...remainingFiles.values()].sort((a, b) => compareCodeUnits(a.path, b.path)),\n\t\tblockers: uniqueBlockers.sort((a, b) => compareCodeUnits(a.path, b.path))\n\t};\n}\nasync function classifyRawDirectory(rawDir, library, includeExternalFile = () => true) {\n\tconst managedPaths = new Set(Object.values(library.assets).map((record) => record.raw));\n\tconst scan = await scanRawDirectory(rawDir, (path) => managedPaths.has(path) || includeExternalFile(path));\n\tconst classification = classifyRawFiles(library, scan);\n\tif (!classification.complete || classification.deletions.length === 0) return classification;\n\tconst ignoredByHash = /* @__PURE__ */ new Map();\n\tfor (const path of scan.ignoredRegularPaths) try {\n\t\tconst hash = await stableRawFileHash(join(rawDir, path));\n\t\tignoredByHash.set(hash, [...ignoredByHash.get(hash) ?? [], path]);\n\t} catch (cause) {\n\t\treturn {\n\t\t\t...classification,\n\t\t\tcomplete: false,\n\t\t\tdiagnostics: [...classification.diagnostics, {\n\t\t\t\tpath,\n\t\t\t\treason: `Could not safely check ignored raw file \"${path}\" while managed files were missing: ${cause instanceof Error ? cause.message : String(cause)}`\n\t\t\t}].sort((a, b) => compareCodeUnits(a.path, b.path)),\n\t\t\tmoves: [],\n\t\t\tdeletions: []\n\t\t};\n\t}\n\tconst missingByHash = /* @__PURE__ */ new Map();\n\tfor (const deletion of classification.deletions) {\n\t\tconst hash = library.assets[deletion.assetId].rawHash;\n\t\tmissingByHash.set(hash, [...missingByHash.get(hash) ?? [], deletion]);\n\t}\n\tconst supportedByHash = /* @__PURE__ */ new Map();\n\tfor (const file of classification.unmanaged) supportedByHash.set(file.hash, [...supportedByHash.get(file.hash) ?? [], file.path]);\n\tconst protectedAssetIds = /* @__PURE__ */ new Set();\n\tconst unsupportedBlockers = [];\n\tconst ambiguityDiagnostics = [];\n\tfor (const [hash, ignoredPaths] of ignoredByHash) {\n\t\tconst missing = missingByHash.get(hash) ?? [];\n\t\tif (missing.length === 0) continue;\n\t\tconst candidatePaths = [...supportedByHash.get(hash) ?? [], ...ignoredPaths].sort(compareCodeUnits);\n\t\tconst sortedMissing = [...missing].sort((a, b) => compareCodeUnits(a.assetId, b.assetId));\n\t\tif (sortedMissing.length === 1 && ignoredPaths.length === 1 && candidatePaths.length === 1) {\n\t\t\tconst [{ assetId, path: oldPath }] = sortedMissing;\n\t\t\tconst [destination] = ignoredPaths;\n\t\t\tprotectedAssetIds.add(assetId);\n\t\t\tunsupportedBlockers.push({\n\t\t\t\tassetId,\n\t\t\t\tpath: destination,\n\t\t\t\treason: `Asset \"${assetId}\" was moved from \"${oldPath}\" to unsupported path \"${destination}\". Rename it externally to a supported extension.`\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\t\tambiguityDiagnostics.push({\n\t\t\tpath: candidatePaths[0] ?? \"\",\n\t\t\treason: `Ignored raw files ambiguously match missing assets [${sortedMissing.map((entry) => entry.assetId).join(\", \")}] and candidate paths [${candidatePaths.join(\", \")}]. Restore or reduce the external files until the match is unique.`\n\t\t});\n\t}\n\tif (ambiguityDiagnostics.length > 0) return {\n\t\t...classification,\n\t\tcomplete: false,\n\t\tdiagnostics: [...classification.diagnostics, ...ambiguityDiagnostics].sort((a, b) => compareCodeUnits(`${a.path}|${a.reason}`, `${b.path}|${b.reason}`)),\n\t\tmoves: [],\n\t\tdeletions: [],\n\t\tblockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))\n\t};\n\treturn {\n\t\t...classification,\n\t\tdeletions: classification.deletions.filter((deletion) => !protectedAssetIds.has(deletion.assetId)),\n\t\tblockers: [...classification.blockers, ...unsupportedBlockers].sort((a, b) => compareCodeUnits(a.path, b.path))\n\t};\n}\n//#endregion\nexport { verifyStableRawFile as a, stableRawFileHash as i, classifyRawFiles as n, scanRawDirectory as r, classifyRawDirectory as t };\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.server.js-oHJX5INm.js","sources":["../../../../.svelte-kit/output/server/entries/hooks.server.js"],"sourcesContent":["import { n as initializeFundusContext } from \"../chunks/context.js\";\n//#region src/hooks.server.ts\nasync function init() {\n\tawait initializeFundusContext();\n}\n//#endregion\nexport { init };\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AACA;AACA,eAAe,IAAI,GAAG;AACtB,CAAC,MAAM,uBAAuB,EAAE;AAChC;;;;"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const index = 1;
|
|
2
|
-
const imports = ["_app/immutable/nodes/1.Z-UvvLkP.js","_app/immutable/chunks/DLEDBLL1.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/QlQ-jeIO.js","_app/immutable/chunks/Bsj1ssvc.js"];
|
|
3
|
-
const stylesheets = [];
|
|
4
|
-
const fonts = [];
|
|
5
|
-
|
|
6
|
-
export { fonts, imports, index, stylesheets };
|
|
7
|
-
//# sourceMappingURL=1.js-xbOwEHCW.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const index = 3;
|
|
2
|
-
const imports = ["_app/immutable/nodes/3.Dt32EAoq.js","_app/immutable/chunks/DLEDBLL1.js","_app/immutable/chunks/Bsj1ssvc.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/QlQ-jeIO.js","_app/immutable/chunks/apKHI4vq.js","_app/immutable/chunks/OL1Dh1oP.js","_app/immutable/chunks/g2rma9Ym.js","_app/immutable/chunks/CzxolZCO.js"];
|
|
3
|
-
const stylesheets = ["_app/immutable/assets/ManifestSelector.Cue3sCA1.css","_app/immutable/assets/Popover.CCTioPJZ.css","_app/immutable/assets/AssetSourceMenu.DWPxyX6L.css","_app/immutable/assets/3.Dfl33dj0.css"];
|
|
4
|
-
const fonts = [];
|
|
5
|
-
|
|
6
|
-
export { fonts, imports, index, stylesheets };
|
|
7
|
-
//# sourceMappingURL=3.js-Dpr_DvNU.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const index = 4;
|
|
2
|
-
const imports = ["_app/immutable/nodes/4.WipzcX8_.js","_app/immutable/chunks/DLEDBLL1.js","_app/immutable/chunks/Bsj1ssvc.js","_app/immutable/chunks/xihTtKlq.js","_app/immutable/chunks/apKHI4vq.js","_app/immutable/chunks/CzxolZCO.js"];
|
|
3
|
-
const stylesheets = ["_app/immutable/assets/Popover.CCTioPJZ.css","_app/immutable/assets/4.C0QkCMQ4.css"];
|
|
4
|
-
const fonts = [];
|
|
5
|
-
|
|
6
|
-
export { fonts, imports, index, stylesheets };
|
|
7
|
-
//# sourceMappingURL=4.js-14Lypd4o.js.map
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin-API code that reads and writes Fundus tags inside a Figma document.
|
|
3
|
-
* Two runtimes execute it: the Fundus Figma plugin imports these functions
|
|
4
|
-
* directly, and the CLI serializes them (via `Function.prototype.toString`)
|
|
5
|
-
* into a script an agent runs through Figma's MCP `use_figma` tool. The Figma
|
|
6
|
-
* REST API cannot write plugin data, so a script is the only headless write
|
|
7
|
-
* path.
|
|
8
|
-
*
|
|
9
|
-
* Serialization constrains every function listed in `SCRIPT_FUNCTIONS`: it
|
|
10
|
-
* may reference only its parameters, the other listed functions, and the
|
|
11
|
-
* constants in `SCRIPT_CONSTANTS` — never imports or other module scope. The
|
|
12
|
-
* `figma` global is passed in as a parameter so tests can drive the same code
|
|
13
|
-
* against a fake document.
|
|
14
|
-
*/
|
|
15
|
-
/** Shared-plugin-data namespace; the REST API returns it under `sharedPluginData`. */
|
|
16
|
-
export declare const FIGMA_TAG_NAMESPACE = "fundus";
|
|
17
|
-
/** Key holding the node's Fundus asset id (the tag). */
|
|
18
|
-
export declare const FIGMA_TAG_KEY = "assetId";
|
|
19
|
-
/**
|
|
20
|
-
* Key holding the exact label of the annotation Fundus owns on the node; empty
|
|
21
|
-
* when it owns none. Tracking ownership out-of-band keeps the visible label
|
|
22
|
-
* exactly equal to the tag and leaves the user's own annotations untouched.
|
|
23
|
-
*/
|
|
24
|
-
export declare const FIGMA_ANNOTATION_LABEL_KEY = "annotationLabel";
|
|
25
|
-
/**
|
|
26
|
-
* Visible prefix earlier plugin builds used as the ownership marker. Still
|
|
27
|
-
* recognized so those annotations are migrated or stripped instead of
|
|
28
|
-
* duplicated.
|
|
29
|
-
*/
|
|
30
|
-
export declare const LEGACY_ANNOTATION_PREFIX = "Fundus asset: ";
|
|
31
|
-
/** The annotation fields Fundus reads and writes (a subset of Figma's `Annotation`). */
|
|
32
|
-
export interface FigmaAnnotation {
|
|
33
|
-
readonly label?: string;
|
|
34
|
-
readonly labelMarkdown?: string;
|
|
35
|
-
readonly properties?: ReadonlyArray<{
|
|
36
|
-
readonly type: string;
|
|
37
|
-
}>;
|
|
38
|
-
readonly categoryId?: string;
|
|
39
|
-
}
|
|
40
|
-
/** The node surface Fundus uses (a structural subset of Figma's `BaseNode`). */
|
|
41
|
-
export interface FigmaTagNode {
|
|
42
|
-
readonly id: string;
|
|
43
|
-
readonly name: string;
|
|
44
|
-
readonly type: string;
|
|
45
|
-
readonly parent: FigmaTagNode | null;
|
|
46
|
-
getSharedPluginData(namespace: string, key: string): string;
|
|
47
|
-
setSharedPluginData(namespace: string, key: string, value: string): void;
|
|
48
|
-
}
|
|
49
|
-
export interface FigmaAnnotatableNode extends FigmaTagNode {
|
|
50
|
-
annotations: ReadonlyArray<FigmaAnnotation>;
|
|
51
|
-
}
|
|
52
|
-
export interface FigmaTagPage extends FigmaTagNode {
|
|
53
|
-
loadAsync(): Promise<void>;
|
|
54
|
-
findAll(predicate: (node: FigmaTagNode) => boolean): FigmaTagNode[];
|
|
55
|
-
}
|
|
56
|
-
/** The `figma` global surface the tag scripts use. */
|
|
57
|
-
export interface FigmaTagApi {
|
|
58
|
-
readonly root: {
|
|
59
|
-
readonly children: ReadonlyArray<FigmaTagPage>;
|
|
60
|
-
};
|
|
61
|
-
getNodeByIdAsync(id: string): Promise<FigmaTagNode | null>;
|
|
62
|
-
}
|
|
63
|
-
export interface SetFigmaTagInput {
|
|
64
|
-
nodeId: string;
|
|
65
|
-
tag: string;
|
|
66
|
-
/**
|
|
67
|
-
* Replace a different tag on the node, rewrite the same one, or move the tag
|
|
68
|
-
* here from the other nodes carrying it.
|
|
69
|
-
*/
|
|
70
|
-
force: boolean;
|
|
71
|
-
}
|
|
72
|
-
/** A node the tag was moved away from. */
|
|
73
|
-
export interface FigmaTagHolder {
|
|
74
|
-
nodeId: string;
|
|
75
|
-
nodeName: string;
|
|
76
|
-
page: string;
|
|
77
|
-
}
|
|
78
|
-
export interface SetFigmaTagResult {
|
|
79
|
-
ok: true;
|
|
80
|
-
nodeId: string;
|
|
81
|
-
nodeName: string;
|
|
82
|
-
tag: string;
|
|
83
|
-
previousTag: string | null;
|
|
84
|
-
/** False for node types without annotation support (e.g. Group, Section). */
|
|
85
|
-
annotated: boolean;
|
|
86
|
-
/** Other nodes that carried the tag; forced sets clear it there. */
|
|
87
|
-
movedFrom: FigmaTagHolder[];
|
|
88
|
-
}
|
|
89
|
-
export interface DeleteFigmaTagInput {
|
|
90
|
-
nodeId: string;
|
|
91
|
-
/** The tag the node is expected to carry; guards against a stale plan. */
|
|
92
|
-
tag: string;
|
|
93
|
-
}
|
|
94
|
-
export interface DeleteFigmaTagResult {
|
|
95
|
-
ok: true;
|
|
96
|
-
nodeId: string;
|
|
97
|
-
nodeName: string;
|
|
98
|
-
removedTag: string;
|
|
99
|
-
annotationRemoved: boolean;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Whether the id names a node inside an instance (`I<instance>;<source>`).
|
|
103
|
-
* Such nodes inherit the shared plugin data of the main component's node, so
|
|
104
|
-
* they report its tag without being a separate taggable node.
|
|
105
|
-
*/
|
|
106
|
-
export declare function isInstanceSublayerId(id: string): boolean;
|
|
107
|
-
export declare function supportsAnnotations(node: FigmaTagNode): node is FigmaAnnotatableNode;
|
|
108
|
-
/**
|
|
109
|
-
* The annotation's shown text. Figma reports a plain-label annotation with
|
|
110
|
-
* `labelMarkdown: ""`, so an empty markdown field falls back to `label`.
|
|
111
|
-
*/
|
|
112
|
-
export declare function annotationText(annotation: FigmaAnnotation): string;
|
|
113
|
-
/**
|
|
114
|
-
* Figma returns BOTH `label` and `labelMarkdown` when reading annotations, but
|
|
115
|
-
* the setter rejects an annotation that carries both. Re-emit a single-field
|
|
116
|
-
* copy (non-empty markdown first), preserving `properties`/`categoryId`, so
|
|
117
|
-
* preserved annotations can be written back without failing validation.
|
|
118
|
-
*/
|
|
119
|
-
export declare function writableAnnotation(annotation: FigmaAnnotation): FigmaAnnotation;
|
|
120
|
-
/** Whether this annotation is one Fundus owns — by the stored label or the legacy prefix. */
|
|
121
|
-
export declare function isFundusAnnotation(annotation: FigmaAnnotation, ownedLabel: string): boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Ensure the node carries exactly one Fundus annotation whose label is the tag,
|
|
124
|
-
* preserving all others. Writes only when not already in sync, so a steady
|
|
125
|
-
* state neither dirties the file nor adds undo steps.
|
|
126
|
-
*/
|
|
127
|
-
export declare function writeFundusAnnotation(node: FigmaAnnotatableNode, tag: string): void;
|
|
128
|
-
/** Remove the Fundus annotation (incl. legacy), preserving all others. */
|
|
129
|
-
export declare function stripFundusAnnotation(node: FigmaAnnotatableNode): void;
|
|
130
|
-
export declare function pageOfNode(node: FigmaTagNode): FigmaTagPage | null;
|
|
131
|
-
/**
|
|
132
|
-
* Resolve a scene node and load its page. `loadAsync` loads without
|
|
133
|
-
* navigating, so running a script never moves anyone's canvas.
|
|
134
|
-
*/
|
|
135
|
-
export declare function loadTaggableNode(figma: FigmaTagApi, nodeId: string): Promise<FigmaTagNode>;
|
|
136
|
-
/**
|
|
137
|
-
* Every other node carrying `tag`, across every page. Scripts start with only
|
|
138
|
-
* the first page loaded, and `findAll` on an unloaded page silently misses
|
|
139
|
-
* content, so each page is loaded first.
|
|
140
|
-
*/
|
|
141
|
-
export declare function findTagHolders(figma: FigmaTagApi, tag: string, exceptNodeId: string): Promise<Array<{
|
|
142
|
-
node: FigmaTagNode;
|
|
143
|
-
page: FigmaTagPage;
|
|
144
|
-
}>>;
|
|
145
|
-
/** Clear the node's tag and its Fundus annotation; returns whether an annotation was removed. */
|
|
146
|
-
export declare function clearFundusTag(node: FigmaTagNode): boolean;
|
|
147
|
-
/**
|
|
148
|
-
* Tag a node, re-checking the live document right before writing: the CLI's
|
|
149
|
-
* REST snapshot can lag behind edits made since it ran.
|
|
150
|
-
*/
|
|
151
|
-
export declare function setFundusTag(figma: FigmaTagApi, input: SetFigmaTagInput): Promise<SetFigmaTagResult>;
|
|
152
|
-
export declare function deleteFundusTag(figma: FigmaTagApi, input: DeleteFigmaTagInput): Promise<DeleteFigmaTagResult>;
|
|
153
|
-
export declare function buildSetTagScript(input: SetFigmaTagInput): string;
|
|
154
|
-
export declare function buildDeleteTagScript(input: DeleteFigmaTagInput): string;
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin-API code that reads and writes Fundus tags inside a Figma document.
|
|
3
|
-
* Two runtimes execute it: the Fundus Figma plugin imports these functions
|
|
4
|
-
* directly, and the CLI serializes them (via `Function.prototype.toString`)
|
|
5
|
-
* into a script an agent runs through Figma's MCP `use_figma` tool. The Figma
|
|
6
|
-
* REST API cannot write plugin data, so a script is the only headless write
|
|
7
|
-
* path.
|
|
8
|
-
*
|
|
9
|
-
* Serialization constrains every function listed in `SCRIPT_FUNCTIONS`: it
|
|
10
|
-
* may reference only its parameters, the other listed functions, and the
|
|
11
|
-
* constants in `SCRIPT_CONSTANTS` — never imports or other module scope. The
|
|
12
|
-
* `figma` global is passed in as a parameter so tests can drive the same code
|
|
13
|
-
* against a fake document.
|
|
14
|
-
*/
|
|
15
|
-
/** Shared-plugin-data namespace; the REST API returns it under `sharedPluginData`. */
|
|
16
|
-
export const FIGMA_TAG_NAMESPACE = 'fundus';
|
|
17
|
-
/** Key holding the node's Fundus asset id (the tag). */
|
|
18
|
-
export const FIGMA_TAG_KEY = 'assetId';
|
|
19
|
-
/**
|
|
20
|
-
* Key holding the exact label of the annotation Fundus owns on the node; empty
|
|
21
|
-
* when it owns none. Tracking ownership out-of-band keeps the visible label
|
|
22
|
-
* exactly equal to the tag and leaves the user's own annotations untouched.
|
|
23
|
-
*/
|
|
24
|
-
export const FIGMA_ANNOTATION_LABEL_KEY = 'annotationLabel';
|
|
25
|
-
/**
|
|
26
|
-
* Visible prefix earlier plugin builds used as the ownership marker. Still
|
|
27
|
-
* recognized so those annotations are migrated or stripped instead of
|
|
28
|
-
* duplicated.
|
|
29
|
-
*/
|
|
30
|
-
export const LEGACY_ANNOTATION_PREFIX = 'Fundus asset: ';
|
|
31
|
-
/**
|
|
32
|
-
* Whether the id names a node inside an instance (`I<instance>;<source>`).
|
|
33
|
-
* Such nodes inherit the shared plugin data of the main component's node, so
|
|
34
|
-
* they report its tag without being a separate taggable node.
|
|
35
|
-
*/
|
|
36
|
-
export function isInstanceSublayerId(id) {
|
|
37
|
-
return id.startsWith('I');
|
|
38
|
-
}
|
|
39
|
-
export function supportsAnnotations(node) {
|
|
40
|
-
return 'annotations' in node;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* The annotation's shown text. Figma reports a plain-label annotation with
|
|
44
|
-
* `labelMarkdown: ""`, so an empty markdown field falls back to `label`.
|
|
45
|
-
*/
|
|
46
|
-
export function annotationText(annotation) {
|
|
47
|
-
return annotation.labelMarkdown || annotation.label || '';
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Figma returns BOTH `label` and `labelMarkdown` when reading annotations, but
|
|
51
|
-
* the setter rejects an annotation that carries both. Re-emit a single-field
|
|
52
|
-
* copy (non-empty markdown first), preserving `properties`/`categoryId`, so
|
|
53
|
-
* preserved annotations can be written back without failing validation.
|
|
54
|
-
*/
|
|
55
|
-
export function writableAnnotation(annotation) {
|
|
56
|
-
const copy = {};
|
|
57
|
-
if (annotation.labelMarkdown)
|
|
58
|
-
copy.labelMarkdown = annotation.labelMarkdown;
|
|
59
|
-
else if (annotation.label !== undefined)
|
|
60
|
-
copy.label = annotation.label;
|
|
61
|
-
if (annotation.properties)
|
|
62
|
-
copy.properties = annotation.properties;
|
|
63
|
-
if (annotation.categoryId)
|
|
64
|
-
copy.categoryId = annotation.categoryId;
|
|
65
|
-
return copy;
|
|
66
|
-
}
|
|
67
|
-
/** Whether this annotation is one Fundus owns — by the stored label or the legacy prefix. */
|
|
68
|
-
export function isFundusAnnotation(annotation, ownedLabel) {
|
|
69
|
-
const text = annotationText(annotation);
|
|
70
|
-
return (ownedLabel !== '' && text === ownedLabel) || text.startsWith(LEGACY_ANNOTATION_PREFIX);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Ensure the node carries exactly one Fundus annotation whose label is the tag,
|
|
74
|
-
* preserving all others. Writes only when not already in sync, so a steady
|
|
75
|
-
* state neither dirties the file nor adds undo steps.
|
|
76
|
-
*/
|
|
77
|
-
export function writeFundusAnnotation(node, tag) {
|
|
78
|
-
const owned = node.getSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_ANNOTATION_LABEL_KEY);
|
|
79
|
-
const current = node.annotations;
|
|
80
|
-
const ours = current.filter((annotation) => isFundusAnnotation(annotation, owned));
|
|
81
|
-
const inSync = owned === tag && ours.length === 1 && annotationText(ours[0]) === tag;
|
|
82
|
-
if (inSync)
|
|
83
|
-
return;
|
|
84
|
-
const kept = current
|
|
85
|
-
.filter((annotation) => !isFundusAnnotation(annotation, owned) && annotationText(annotation) !== tag)
|
|
86
|
-
.map(writableAnnotation);
|
|
87
|
-
node.annotations = [...kept, { label: tag }];
|
|
88
|
-
if (owned !== tag) {
|
|
89
|
-
node.setSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_ANNOTATION_LABEL_KEY, tag);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/** Remove the Fundus annotation (incl. legacy), preserving all others. */
|
|
93
|
-
export function stripFundusAnnotation(node) {
|
|
94
|
-
const owned = node.getSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_ANNOTATION_LABEL_KEY);
|
|
95
|
-
const current = node.annotations;
|
|
96
|
-
const kept = current
|
|
97
|
-
.filter((annotation) => !isFundusAnnotation(annotation, owned))
|
|
98
|
-
.map(writableAnnotation);
|
|
99
|
-
if (kept.length !== current.length)
|
|
100
|
-
node.annotations = kept;
|
|
101
|
-
if (owned !== '')
|
|
102
|
-
node.setSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_ANNOTATION_LABEL_KEY, '');
|
|
103
|
-
}
|
|
104
|
-
export function pageOfNode(node) {
|
|
105
|
-
let current = node;
|
|
106
|
-
while (current && current.type !== 'PAGE')
|
|
107
|
-
current = current.parent;
|
|
108
|
-
return current ? current : null;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Resolve a scene node and load its page. `loadAsync` loads without
|
|
112
|
-
* navigating, so running a script never moves anyone's canvas.
|
|
113
|
-
*/
|
|
114
|
-
export async function loadTaggableNode(figma, nodeId) {
|
|
115
|
-
const node = await figma.getNodeByIdAsync(nodeId);
|
|
116
|
-
const page = node ? pageOfNode(node) : null;
|
|
117
|
-
if (!node || !page || node.type === 'PAGE') {
|
|
118
|
-
throw new Error(`Figma node "${nodeId}" does not exist in this file.`);
|
|
119
|
-
}
|
|
120
|
-
await page.loadAsync();
|
|
121
|
-
return node;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Every other node carrying `tag`, across every page. Scripts start with only
|
|
125
|
-
* the first page loaded, and `findAll` on an unloaded page silently misses
|
|
126
|
-
* content, so each page is loaded first.
|
|
127
|
-
*/
|
|
128
|
-
export async function findTagHolders(figma, tag, exceptNodeId) {
|
|
129
|
-
const holders = [];
|
|
130
|
-
for (const page of figma.root.children) {
|
|
131
|
-
await page.loadAsync();
|
|
132
|
-
const found = page.findAll((candidate) => candidate.id !== exceptNodeId &&
|
|
133
|
-
!isInstanceSublayerId(candidate.id) &&
|
|
134
|
-
candidate.getSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_TAG_KEY) === tag);
|
|
135
|
-
for (const node of found)
|
|
136
|
-
holders.push({ node, page });
|
|
137
|
-
}
|
|
138
|
-
return holders;
|
|
139
|
-
}
|
|
140
|
-
/** Clear the node's tag and its Fundus annotation; returns whether an annotation was removed. */
|
|
141
|
-
export function clearFundusTag(node) {
|
|
142
|
-
node.setSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_TAG_KEY, '');
|
|
143
|
-
if (!supportsAnnotations(node)) {
|
|
144
|
-
node.setSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_ANNOTATION_LABEL_KEY, '');
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
const before = node.annotations.length;
|
|
148
|
-
stripFundusAnnotation(node);
|
|
149
|
-
return node.annotations.length < before;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Tag a node, re-checking the live document right before writing: the CLI's
|
|
153
|
-
* REST snapshot can lag behind edits made since it ran.
|
|
154
|
-
*/
|
|
155
|
-
export async function setFundusTag(figma, input) {
|
|
156
|
-
const node = await loadTaggableNode(figma, input.nodeId);
|
|
157
|
-
const previous = node.getSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_TAG_KEY);
|
|
158
|
-
if (!input.force && previous === input.tag) {
|
|
159
|
-
throw new Error(`Node "${node.name}" (${node.id}) already carries tag "${input.tag}"; rerun prepare-set-tag with --force to rewrite it.`);
|
|
160
|
-
}
|
|
161
|
-
if (!input.force && previous !== '') {
|
|
162
|
-
throw new Error(`Node "${node.name}" (${node.id}) already carries tag "${previous}"; rerun prepare-set-tag with --force to replace it.`);
|
|
163
|
-
}
|
|
164
|
-
const holders = await findTagHolders(figma, input.tag, node.id);
|
|
165
|
-
if (!input.force && holders.length > 0) {
|
|
166
|
-
const [holder] = holders;
|
|
167
|
-
throw new Error(`Tag "${input.tag}" is already used by "${holder.node.name}" (${holder.node.id}) on page "${holder.page.name}"; choose another tag, or rerun prepare-set-tag with --force to move it here.`);
|
|
168
|
-
}
|
|
169
|
-
for (const holder of holders)
|
|
170
|
-
clearFundusTag(holder.node);
|
|
171
|
-
node.setSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_TAG_KEY, input.tag);
|
|
172
|
-
const annotated = supportsAnnotations(node);
|
|
173
|
-
if (annotated)
|
|
174
|
-
writeFundusAnnotation(node, input.tag);
|
|
175
|
-
return {
|
|
176
|
-
ok: true,
|
|
177
|
-
nodeId: node.id,
|
|
178
|
-
nodeName: node.name,
|
|
179
|
-
tag: input.tag,
|
|
180
|
-
previousTag: previous === '' ? null : previous,
|
|
181
|
-
annotated,
|
|
182
|
-
movedFrom: holders.map((holder) => ({
|
|
183
|
-
nodeId: holder.node.id,
|
|
184
|
-
nodeName: holder.node.name,
|
|
185
|
-
page: holder.page.name
|
|
186
|
-
}))
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
export async function deleteFundusTag(figma, input) {
|
|
190
|
-
const node = await loadTaggableNode(figma, input.nodeId);
|
|
191
|
-
const current = node.getSharedPluginData(FIGMA_TAG_NAMESPACE, FIGMA_TAG_KEY);
|
|
192
|
-
if (current !== input.tag) {
|
|
193
|
-
throw new Error(current === ''
|
|
194
|
-
? `Node "${node.name}" (${node.id}) carries no Fundus tag.`
|
|
195
|
-
: `Node "${node.name}" (${node.id}) carries tag "${current}", not "${input.tag}"; rerun prepare-delete-tag.`);
|
|
196
|
-
}
|
|
197
|
-
const annotationRemoved = clearFundusTag(node);
|
|
198
|
-
return {
|
|
199
|
-
ok: true,
|
|
200
|
-
nodeId: node.id,
|
|
201
|
-
nodeName: node.name,
|
|
202
|
-
removedTag: input.tag,
|
|
203
|
-
annotationRemoved
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
const SCRIPT_CONSTANTS = {
|
|
207
|
-
FIGMA_TAG_NAMESPACE,
|
|
208
|
-
FIGMA_TAG_KEY,
|
|
209
|
-
FIGMA_ANNOTATION_LABEL_KEY,
|
|
210
|
-
LEGACY_ANNOTATION_PREFIX
|
|
211
|
-
};
|
|
212
|
-
const SCRIPT_FUNCTIONS = [
|
|
213
|
-
isInstanceSublayerId,
|
|
214
|
-
supportsAnnotations,
|
|
215
|
-
annotationText,
|
|
216
|
-
writableAnnotation,
|
|
217
|
-
isFundusAnnotation,
|
|
218
|
-
writeFundusAnnotation,
|
|
219
|
-
stripFundusAnnotation,
|
|
220
|
-
pageOfNode,
|
|
221
|
-
loadTaggableNode,
|
|
222
|
-
findTagHolders,
|
|
223
|
-
clearFundusTag,
|
|
224
|
-
setFundusTag,
|
|
225
|
-
deleteFundusTag
|
|
226
|
-
];
|
|
227
|
-
/**
|
|
228
|
-
* A self-contained `use_figma` script body: top-level `await` and `return`,
|
|
229
|
-
* with the `figma` global in scope. It returns the operation's JSON result
|
|
230
|
-
* and throws, before mutating anything, when the live document disagrees.
|
|
231
|
-
*/
|
|
232
|
-
function buildScript(summary, call) {
|
|
233
|
-
const constants = Object.entries(SCRIPT_CONSTANTS).map(([name, value]) => `const ${name} = ${JSON.stringify(value)};`);
|
|
234
|
-
return [
|
|
235
|
-
`// ${summary}`,
|
|
236
|
-
'// Generated by the fundus CLI — run it unchanged with the Figma MCP `use_figma` tool.',
|
|
237
|
-
...constants,
|
|
238
|
-
...SCRIPT_FUNCTIONS.map(String),
|
|
239
|
-
`return await ${call};`,
|
|
240
|
-
''
|
|
241
|
-
].join('\n\n');
|
|
242
|
-
}
|
|
243
|
-
export function buildSetTagScript(input) {
|
|
244
|
-
return buildScript(`Set Fundus tag ${JSON.stringify(input.tag)} on Figma node ${JSON.stringify(input.nodeId)}.`, `setFundusTag(figma, ${JSON.stringify(input)})`);
|
|
245
|
-
}
|
|
246
|
-
export function buildDeleteTagScript(input) {
|
|
247
|
-
return buildScript(`Delete Fundus tag ${JSON.stringify(input.tag)} from Figma node ${JSON.stringify(input.nodeId)}.`, `deleteFundusTag(figma, ${JSON.stringify(input)})`);
|
|
248
|
-
}
|