fundus 0.28.0 → 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/{CRFKGnag.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/{rtFCvv3j.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/{BSzEzOBI.js → wBLhaPea.js} +1 -1
- 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.BiYJKHq5.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.kL9OGUbr.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.DQGC5ZQg.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.BJEXWmrT.js +4 -0
- 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.DkyIyoNd.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.D1JY4Ttk.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-Cncv1qoG.js → exports.js-BsVKSGJk.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-Cncv1qoG.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-C2FKw_9R.js → internal.js-DJGcNryj.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-C2FKw_9R.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-BGsWd7z-.js → shared.js-BtmYg0tL.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-BGsWd7z-.js.map → shared.js-BtmYg0tL.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-C0ADATvf.js → utils.js-CqXk0Ug6.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-C0ADATvf.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-uc4GLvWI.js → handler-DwVfBx6r.js} +5 -5
- package/build/server/chunks/{handler-uc4GLvWI.js.map → handler-DwVfBx6r.js.map} +1 -1
- package/build/server/chunks/{index.js-BTlSiK4q.js → index.js-DgPuPQJn.js} +5 -5
- package/build/server/chunks/{index.js-BTlSiK4q.js.map → index.js-DgPuPQJn.js.map} +1 -1
- package/build/server/chunks/{manifest.js-BB8iIVbZ.js → manifest.js-B054EcAf.js} +31 -31
- package/build/server/chunks/{manifest.js-BB8iIVbZ.js.map → manifest.js-B054EcAf.js.map} +1 -1
- package/build/server/chunks/nodes/{0.js-CccZDEdX.js → 0.js-DoHZTmnT.js} +2 -2
- package/build/server/chunks/nodes/{0.js-CccZDEdX.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-_Ms77u64.js.map → 1.js-BcPlsloO.js.map} +1 -1
- package/build/server/chunks/nodes/{2.js-BpyFsilO.js → 2.js-5qCXkvzl.js} +2 -2
- package/build/server/chunks/nodes/{2.js-BpyFsilO.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-D7RUEviu.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-Cfc3G2Gv.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/BSzEzOBI.js.br +0 -0
- package/build/client/_app/immutable/chunks/BSzEzOBI.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CRFKGnag.js.br +0 -0
- package/build/client/_app/immutable/chunks/CRFKGnag.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/chunks/rtFCvv3j.js.br +0 -0
- package/build/client/_app/immutable/chunks/rtFCvv3j.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.BiYJKHq5.js.br +0 -0
- package/build/client/_app/immutable/entry/app.BiYJKHq5.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BGYYpgAJ.js +0 -1
- package/build/client/_app/immutable/entry/start.BGYYpgAJ.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BGYYpgAJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.kL9OGUbr.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.kL9OGUbr.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DQGC5ZQg.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.DQGC5ZQg.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DXo6NZ8U.js +0 -4
- package/build/client/_app/immutable/nodes/2.DXo6NZ8U.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DXo6NZ8U.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.DkyIyoNd.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DkyIyoNd.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.D1JY4Ttk.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D1JY4Ttk.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-_Ms77u64.js +0 -7
- package/build/server/chunks/nodes/3.js-D7RUEviu.js +0 -7
- package/build/server/chunks/nodes/4.js-Cfc3G2Gv.js +0 -7
- package/dist/core/figma-tag-script.d.ts +0 -154
- package/dist/core/figma-tag-script.js +0 -248
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, J as typesForFileName, k as parentFolderPath, u as portableFolderPathKey } from './core.js-
|
|
2
|
-
import { i as isRecord, s as serverPluginsByType, L as LibraryStore, d as descriptorsByType, m as manifestModuleFileName, l as locateGeneratedAssetDeclaration, a as serializeLibrary, b as serverPluginForType, S as SourceImportError, p as processAssets, g as generateManifestModules, r as readCurrentProxy, e as encodeRelativePathForUrl, c as invalidInput, f as parseLibrary } from './contract.js-
|
|
3
|
-
import { c as collectAllReferences, a as assetIdError, b as computeLibraryMembership, d as allDeliveredAssetIds, i as isValidAssetId } from './manifest-membership.js-
|
|
1
|
+
import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, J as typesForFileName, k as parentFolderPath, u as portableFolderPathKey } from './core.js-AGKlECJ0.js';
|
|
2
|
+
import { i as isRecord, s as serverPluginsByType, L as LibraryStore, d as descriptorsByType, m as manifestModuleFileName, l as locateGeneratedAssetDeclaration, a as serializeLibrary, b as serverPluginForType, S as SourceImportError, p as processAssets, g as generateManifestModules, r as readCurrentProxy, e as encodeRelativePathForUrl, c as invalidInput, f as parseLibrary } from './contract.js-DGZXpcNX.js';
|
|
3
|
+
import { c as collectAllReferences, a as assetIdError, b as computeLibraryMembership, d as allDeliveredAssetIds, i as isValidAssetId } from './manifest-membership.js-DkHaPk2F.js';
|
|
4
4
|
import { v as validateDependencyList, f as formatRequiredBy } from './dependencies.js-pUkjICr5.js';
|
|
5
|
-
import { v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation2.js-
|
|
5
|
+
import { v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation2.js-CMpUvuMd.js';
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
7
|
import { isAbsolute, resolve, basename, dirname, join, extname, relative, sep } from 'node:path';
|
|
8
8
|
import { existsSync, watch, readFileSync } from 'node:fs';
|
|
@@ -16,14 +16,59 @@ import { lookup } from 'node:dns/promises';
|
|
|
16
16
|
import { isIP } from 'node:net';
|
|
17
17
|
import { request } from 'node:https';
|
|
18
18
|
|
|
19
|
-
//#region src/lib/core/figma-tag-script.ts
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* they report its tag without being a separate taggable node.
|
|
20
|
+
* The tag a link URL names, or `null`. An exact string match (no URL parsing)
|
|
21
|
+
* makes any path segment, query, fragment or percent-escape fail the tag grammar.
|
|
24
22
|
*/
|
|
25
|
-
function
|
|
26
|
-
|
|
23
|
+
function parseFundusTagLink(url) {
|
|
24
|
+
if (!url.startsWith("https://fundus.invalid/asset/")) return null;
|
|
25
|
+
const tag = url.slice(29);
|
|
26
|
+
return isValidAssetId(tag) ? tag : null;
|
|
27
|
+
}
|
|
28
|
+
var TAGGABLE_NODE_ID = /^\d+:\d+$/;
|
|
29
|
+
/**
|
|
30
|
+
* The Fundus tags carried by own links on plain scene-node ids; inherited,
|
|
31
|
+
* sublayer, foreign and unparsable links are dropped. One entry per link, so
|
|
32
|
+
* several tags on one node stay several entries. Sorted by tag, then node id.
|
|
33
|
+
*/
|
|
34
|
+
function figmaTagEntries(links) {
|
|
35
|
+
const entries = [];
|
|
36
|
+
for (const link of links) {
|
|
37
|
+
if (link.inherited || !TAGGABLE_NODE_ID.test(link.nodeId)) continue;
|
|
38
|
+
const tag = parseFundusTagLink(link.url);
|
|
39
|
+
if (tag === null) continue;
|
|
40
|
+
entries.push(link.linkId === void 0 ? {
|
|
41
|
+
tag,
|
|
42
|
+
nodeId: link.nodeId
|
|
43
|
+
} : {
|
|
44
|
+
tag,
|
|
45
|
+
nodeId: link.nodeId,
|
|
46
|
+
linkId: link.linkId
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return entries.sort((left, right) => compareCodeUnits(left.tag, right.tag) || compareCodeUnits(left.nodeId, right.nodeId));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The links in a REST `GET /v1/files/:key/dev_resources` body, or `null` when
|
|
53
|
+
* `dev_resources` is not an array. Entries without string `id`/`url`/`node_id`
|
|
54
|
+
* are skipped.
|
|
55
|
+
*/
|
|
56
|
+
function figmaLinksFromRest(body) {
|
|
57
|
+
const resources = typeof body === "object" && body !== null ? body.dev_resources : void 0;
|
|
58
|
+
if (!Array.isArray(resources)) return null;
|
|
59
|
+
const links = [];
|
|
60
|
+
for (const resource of resources) {
|
|
61
|
+
if (typeof resource !== "object" || resource === null) continue;
|
|
62
|
+
const { id, url, node_id: nodeId } = resource;
|
|
63
|
+
if (typeof id !== "string" || typeof url !== "string" || typeof nodeId !== "string") continue;
|
|
64
|
+
links.push({
|
|
65
|
+
nodeId,
|
|
66
|
+
url,
|
|
67
|
+
inherited: false,
|
|
68
|
+
linkId: id
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return links;
|
|
27
72
|
}
|
|
28
73
|
//#endregion
|
|
29
74
|
//#region src/lib/core/propose-asset-id.ts
|
|
@@ -427,6 +472,9 @@ var PNG_SIGNATURE = Uint8Array.from([
|
|
|
427
472
|
26,
|
|
428
473
|
10
|
|
429
474
|
]);
|
|
475
|
+
/** Worst case per API call: 3 attempts × 30 s timeout + 2 waits × 10 s = 110 s. */
|
|
476
|
+
var FIGMA_RATE_LIMIT_ATTEMPTS = 3;
|
|
477
|
+
var FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS = 10;
|
|
430
478
|
function record(value) {
|
|
431
479
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
432
480
|
}
|
|
@@ -506,12 +554,12 @@ function retryAfter(response) {
|
|
|
506
554
|
const seconds = Number(raw);
|
|
507
555
|
return Number.isSafeInteger(seconds) ? seconds : void 0;
|
|
508
556
|
}
|
|
509
|
-
function upstreamStatusError(response) {
|
|
557
|
+
function upstreamStatusError(response, scope) {
|
|
510
558
|
if (response.status === 401) return new SourceImportError("unauthorized", "Figma authentication failed.");
|
|
511
|
-
if (response.status === 403) return new SourceImportError("forbidden", "Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.");
|
|
559
|
+
if (response.status === 403) return new SourceImportError("forbidden", scope ? `Figma authentication or access failed. The token may be invalid or expired, may lack the ${scope} scope, or may not have access to this file.` : "Figma authentication or access failed. The token may be invalid or expired, or it may not have access to this file.");
|
|
512
560
|
if (response.status === 404) return new SourceImportError("not-found", "The Figma file or node was not found.");
|
|
513
561
|
if (response.status === 429) return new SourceImportError("rate-limited", "Figma rate-limited this request.", retryAfter(response));
|
|
514
|
-
return new SourceImportError("upstream-failed", `Figma
|
|
562
|
+
return new SourceImportError("upstream-failed", `Figma request failed with status ${response.status}.`);
|
|
515
563
|
}
|
|
516
564
|
function isForbiddenIpv4(address) {
|
|
517
565
|
const parts = address.split(".").map(Number);
|
|
@@ -570,7 +618,7 @@ async function resolveSafeDownloadTarget(value) {
|
|
|
570
618
|
addresses
|
|
571
619
|
};
|
|
572
620
|
}
|
|
573
|
-
async function fetchWithDeadline(fetcher, url, init,
|
|
621
|
+
async function fetchWithDeadline(fetcher, url, init, scope) {
|
|
574
622
|
const controller = new AbortController();
|
|
575
623
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
576
624
|
try {
|
|
@@ -578,12 +626,12 @@ async function fetchWithDeadline(fetcher, url, init, consume) {
|
|
|
578
626
|
...init,
|
|
579
627
|
signal: controller.signal
|
|
580
628
|
});
|
|
581
|
-
if (!response.ok) throw upstreamStatusError(response);
|
|
582
|
-
return await
|
|
629
|
+
if (!response.ok) throw upstreamStatusError(response, scope);
|
|
630
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
583
631
|
} catch (cause) {
|
|
584
|
-
if (controller.signal.aborted || cause instanceof Error && cause.name === "AbortError") throw new SourceImportError("download-timeout", "Figma
|
|
632
|
+
if (controller.signal.aborted || cause instanceof Error && cause.name === "AbortError") throw new SourceImportError("download-timeout", "Figma request timed out.");
|
|
585
633
|
if (cause instanceof SourceImportError) throw cause;
|
|
586
|
-
throw new SourceImportError("upstream-failed", "Figma
|
|
634
|
+
throw new SourceImportError("upstream-failed", "Figma request failed.");
|
|
587
635
|
} finally {
|
|
588
636
|
clearTimeout(timeout);
|
|
589
637
|
}
|
|
@@ -684,44 +732,28 @@ async function validatePng(bytes) {
|
|
|
684
732
|
if (!metadata.width || !metadata.height) throw new SourceImportError("invalid-response", "Figma export has invalid dimensions.");
|
|
685
733
|
if (metadata.width * metadata.height > MAX_PIXELS) throw new SourceImportError("image-too-large", "Figma export exceeds the 32 megapixel limit.");
|
|
686
734
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const current = record(value);
|
|
696
|
-
if (!current) return;
|
|
697
|
-
const name = typeof current.name === "string" ? current.name : "";
|
|
698
|
-
const pageName = current.type === "CANVAS" ? name : page;
|
|
699
|
-
if (typeof current.id === "string" && current.type !== "DOCUMENT" && current.type !== "CANVAS" && !isInstanceSublayerId(current.id)) {
|
|
700
|
-
const shared = record(current.sharedPluginData);
|
|
701
|
-
const fundus = shared ? record(shared.fundus) : null;
|
|
702
|
-
const tag = fundus && typeof fundus.assetId === "string" ? fundus.assetId : "";
|
|
703
|
-
nodes.push({
|
|
704
|
-
nodeId: current.id,
|
|
705
|
-
nodeName: name,
|
|
706
|
-
page: pageName,
|
|
707
|
-
tag: tag === "" ? null : tag
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
if (Array.isArray(current.children)) for (const child of current.children) visit(child, pageName);
|
|
711
|
-
};
|
|
712
|
-
visit(record(document), "");
|
|
713
|
-
return nodes;
|
|
735
|
+
async function fetchFigmaApiBytes(endpoint, init, scope, context) {
|
|
736
|
+
for (let attempt = 1;; attempt++) try {
|
|
737
|
+
return await fetchWithDeadline(context.fetch, endpoint, init, scope);
|
|
738
|
+
} catch (cause) {
|
|
739
|
+
const wait = cause instanceof SourceImportError && cause.code === "rate-limited" ? cause.retryAfterSeconds : void 0;
|
|
740
|
+
if (wait === void 0 || wait > FIGMA_RATE_LIMIT_MAX_WAIT_SECONDS || attempt >= FIGMA_RATE_LIMIT_ATTEMPTS) throw cause;
|
|
741
|
+
await new Promise((resolve) => setTimeout(resolve, wait * 1e3));
|
|
742
|
+
}
|
|
714
743
|
}
|
|
715
|
-
|
|
716
|
-
async function fetchFigmaDocument(fileKey, context) {
|
|
744
|
+
async function requestFigmaApi(endpoint, context, request) {
|
|
717
745
|
const token = context.config.import.figma.token;
|
|
718
746
|
if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
|
|
719
|
-
const
|
|
720
|
-
|
|
721
|
-
const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, {
|
|
747
|
+
const jsonBytes = await fetchFigmaApiBytes(endpoint, {
|
|
748
|
+
method: request.method ?? "GET",
|
|
722
749
|
redirect: "error",
|
|
723
|
-
headers: {
|
|
724
|
-
|
|
750
|
+
headers: {
|
|
751
|
+
"X-Figma-Token": token,
|
|
752
|
+
...request.body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
753
|
+
},
|
|
754
|
+
...request.body !== void 0 ? { body: JSON.stringify(request.body) } : {}
|
|
755
|
+
}, request.scope, context);
|
|
756
|
+
if (jsonBytes.byteLength === 0) return {};
|
|
725
757
|
let payload;
|
|
726
758
|
try {
|
|
727
759
|
payload = JSON.parse(new TextDecoder().decode(jsonBytes));
|
|
@@ -729,38 +761,64 @@ async function fetchFigmaDocument(fileKey, context) {
|
|
|
729
761
|
throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
|
|
730
762
|
}
|
|
731
763
|
const body = record(payload);
|
|
732
|
-
if (!body || body.err || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response",
|
|
733
|
-
|
|
764
|
+
if (!body || body.err || body.error === true || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", request.errorMessage);
|
|
765
|
+
if (Array.isArray(body.errors) && body.errors.length > 0) throw new SourceImportError("upstream-failed", `Figma rejected the request: ${body.errors.map((entry) => {
|
|
766
|
+
const reason = record(entry)?.error;
|
|
767
|
+
return typeof reason === "string" ? reason : "unknown error";
|
|
768
|
+
}).join("; ")}`);
|
|
769
|
+
return body;
|
|
770
|
+
}
|
|
771
|
+
function figmaFileEndpoint(fileKey, path) {
|
|
772
|
+
return new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}${path}`);
|
|
773
|
+
}
|
|
774
|
+
/** Every Fundus tag link in the file (orphaned ones included); each entry has its `linkId`. */
|
|
775
|
+
async function listFigmaTagEntries(fileKey, context) {
|
|
776
|
+
const links = figmaLinksFromRest(await requestFigmaApi(figmaFileEndpoint(fileKey, "/dev_resources"), context, {
|
|
777
|
+
scope: "file_dev_resources:read",
|
|
778
|
+
errorMessage: "Figma returned an invalid response."
|
|
779
|
+
}));
|
|
780
|
+
if (!links) throw new SourceImportError("invalid-response", "Figma returned an invalid Dev Resources list.");
|
|
781
|
+
return figmaTagEntries(links).filter((entry) => entry.linkId !== void 0);
|
|
782
|
+
}
|
|
783
|
+
/** Export URLs for the nodes in one `/images` call; `null` for a node Figma cannot render. */
|
|
784
|
+
async function exportImageUrls(fileKey, nodeIds, scale, context) {
|
|
785
|
+
const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(fileKey)}`);
|
|
786
|
+
endpoint.searchParams.set("ids", nodeIds.join(","));
|
|
787
|
+
endpoint.searchParams.set("format", "png");
|
|
788
|
+
endpoint.searchParams.set("scale", String(scale));
|
|
789
|
+
const images = record((await requestFigmaApi(endpoint, context, {
|
|
790
|
+
scope: "file_content:read",
|
|
791
|
+
errorMessage: "Figma could not render this node."
|
|
792
|
+
})).images);
|
|
793
|
+
const urls = {};
|
|
794
|
+
for (const nodeId of nodeIds) {
|
|
795
|
+
if (!images || !Object.hasOwn(images, nodeId)) throw new SourceImportError("invalid-response", "Figma did not return the requested node.");
|
|
796
|
+
const imageUrl = images[nodeId];
|
|
797
|
+
urls[nodeId] = typeof imageUrl === "string" && imageUrl.length > 0 ? imageUrl : null;
|
|
798
|
+
}
|
|
799
|
+
return urls;
|
|
734
800
|
}
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
801
|
+
/**
|
|
802
|
+
* The one renderable node carrying `tag`. All candidates go into a single
|
|
803
|
+
* `/images` call, which answers deleted nodes with `null`; a live but
|
|
804
|
+
* unrenderable second candidate therefore goes unnoticed.
|
|
805
|
+
*/
|
|
806
|
+
async function resolveTaggedNode(fileKey, tag, scale, context) {
|
|
807
|
+
const candidates = [...new Set((await listFigmaTagEntries(fileKey, context)).filter((entry) => entry.tag === tag).map((entry) => entry.nodeId))];
|
|
808
|
+
if (candidates.length === 0) throw new SourceImportError("not-found", `No Figma node is tagged "${tag}" in this file.`);
|
|
809
|
+
const urls = await exportImageUrls(fileKey, candidates, scale, context);
|
|
810
|
+
const live = candidates.flatMap((nodeId) => {
|
|
811
|
+
const imageUrl = urls[nodeId];
|
|
812
|
+
return imageUrl ? [{
|
|
813
|
+
nodeId,
|
|
814
|
+
imageUrl
|
|
815
|
+
}] : [];
|
|
816
|
+
});
|
|
817
|
+
if (live.length === 0) throw new SourceImportError("not-found", `Every Figma node tagged "${tag}" (${candidates.join(", ")}) is deleted or cannot be rendered.`);
|
|
818
|
+
if (live.length > 1) throw new SourceImportError("ambiguous-tag", `More than one Figma node is tagged "${tag}" in this file (${live.map((node) => node.nodeId).join(", ")}).`);
|
|
819
|
+
return live[0];
|
|
740
820
|
}
|
|
741
|
-
async function
|
|
742
|
-
const token = context.config.import.figma.token;
|
|
743
|
-
if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
|
|
744
|
-
const endpoint = new URL(`https://api.figma.com/v1/images/${encodeURIComponent(source.fileKey)}`);
|
|
745
|
-
endpoint.searchParams.set("ids", source.nodeId);
|
|
746
|
-
endpoint.searchParams.set("format", source.format);
|
|
747
|
-
endpoint.searchParams.set("scale", String(source.scale));
|
|
748
|
-
const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, {
|
|
749
|
-
redirect: "error",
|
|
750
|
-
headers: { "X-Figma-Token": token }
|
|
751
|
-
}, async (response) => new Uint8Array(await response.arrayBuffer()));
|
|
752
|
-
let payload;
|
|
753
|
-
try {
|
|
754
|
-
payload = JSON.parse(new TextDecoder().decode(jsonBytes));
|
|
755
|
-
} catch {
|
|
756
|
-
throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
|
|
757
|
-
}
|
|
758
|
-
const body = record(payload);
|
|
759
|
-
if (!body || body.err || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", "Figma could not render this node.");
|
|
760
|
-
const images = record(body.images);
|
|
761
|
-
if (!images || !Object.hasOwn(images, source.nodeId)) throw new SourceImportError("invalid-response", "Figma did not return the requested node.");
|
|
762
|
-
const imageUrl = images[source.nodeId];
|
|
763
|
-
if (typeof imageUrl !== "string" || imageUrl.length === 0) throw new SourceImportError("invalid-response", "Figma could not render the requested node.");
|
|
821
|
+
async function downloadRaw(source, imageUrl, context) {
|
|
764
822
|
const bytes = await downloadExport(context.httpsTransport ?? requestPinnedHttps, imageUrl);
|
|
765
823
|
await validatePng(bytes);
|
|
766
824
|
return {
|
|
@@ -772,6 +830,18 @@ async function materialize(source, context) {
|
|
|
772
830
|
}
|
|
773
831
|
};
|
|
774
832
|
}
|
|
833
|
+
async function importNode(source, context) {
|
|
834
|
+
const imageUrl = (await exportImageUrls(source.fileKey, [source.nodeId], source.scale, context))[source.nodeId];
|
|
835
|
+
if (!imageUrl) throw new SourceImportError("invalid-response", "Figma could not render the requested node.");
|
|
836
|
+
return downloadRaw(source, imageUrl, context);
|
|
837
|
+
}
|
|
838
|
+
async function importTag(source, context) {
|
|
839
|
+
const { nodeId, imageUrl } = await resolveTaggedNode(source.fileKey, source.fundusTag, source.scale, context);
|
|
840
|
+
return downloadRaw({
|
|
841
|
+
...source,
|
|
842
|
+
nodeId
|
|
843
|
+
}, imageUrl, context);
|
|
844
|
+
}
|
|
775
845
|
var figmaSourceImporter = {
|
|
776
846
|
kind: "figma",
|
|
777
847
|
label: "Figma",
|
|
@@ -780,18 +850,16 @@ var figmaSourceImporter = {
|
|
|
780
850
|
if (input.mode === "tag") {
|
|
781
851
|
const fileKey = input.fileKey ?? context.config.import.figma.defaultFileKey;
|
|
782
852
|
if (!fileKey) throw new SourceImportError("not-configured", "Figma tag import needs a fileKey or import.figma.defaultFileKey in fundus.config.");
|
|
783
|
-
|
|
784
|
-
return materialize({
|
|
853
|
+
return importTag({
|
|
785
854
|
mode: "tag",
|
|
786
855
|
fileKey,
|
|
787
856
|
fundusTag: input.tag,
|
|
788
|
-
nodeId,
|
|
789
857
|
format: "png",
|
|
790
858
|
scale: input.scale ?? context.config.import.figma.defaults.scale
|
|
791
859
|
}, context);
|
|
792
860
|
}
|
|
793
861
|
const parsed = parseFigmaSelectionUrl(input.url);
|
|
794
|
-
return
|
|
862
|
+
return importNode({
|
|
795
863
|
fileKey: parsed.fileKey,
|
|
796
864
|
nodeId: parsed.nodeId,
|
|
797
865
|
format: "png",
|
|
@@ -800,14 +868,8 @@ var figmaSourceImporter = {
|
|
|
800
868
|
},
|
|
801
869
|
validateSourceParameters: validateFigmaSourceParameters,
|
|
802
870
|
async reimportRaw(source, context) {
|
|
803
|
-
if (source.mode === "tag")
|
|
804
|
-
|
|
805
|
-
return materialize({
|
|
806
|
-
...source,
|
|
807
|
-
nodeId
|
|
808
|
-
}, context);
|
|
809
|
-
}
|
|
810
|
-
return materialize(source, context);
|
|
871
|
+
if (source.mode === "tag") return importTag(source, context);
|
|
872
|
+
return importNode(source, context);
|
|
811
873
|
}
|
|
812
874
|
};
|
|
813
875
|
//#endregion
|
|
@@ -2514,4 +2576,4 @@ async function createFundusContext() {
|
|
|
2514
2576
|
}
|
|
2515
2577
|
|
|
2516
2578
|
export { getFundusContext as g, initializeFundusContext as i };
|
|
2517
|
-
//# sourceMappingURL=context.js-
|
|
2579
|
+
//# sourceMappingURL=context.js-DFZgDxCD.js.map
|