fundus 0.16.0 → 0.17.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 +37 -1
- package/build/client/_app/immutable/assets/{AssetSourceMenu.B5fzYfym.css → AssetSourceMenu.Buj2UxUg.css} +1 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.Buj2UxUg.css.br +0 -0
- package/build/client/_app/immutable/assets/{AssetSourceMenu.B5fzYfym.css.gz → AssetSourceMenu.Buj2UxUg.css.gz} +0 -0
- package/build/client/_app/immutable/chunks/{D6c2mfMB.js → 5fq8ySvR.js} +1 -1
- package/build/client/_app/immutable/chunks/5fq8ySvR.js.br +0 -0
- package/build/client/_app/immutable/chunks/5fq8ySvR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js +1 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcVZHIBD.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js +2 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js.br +0 -0
- package/build/client/_app/immutable/chunks/DXiUbZ9S.js.gz +0 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js +108 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/H5KnxQLQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{B97y-eFA.js → jEVVu5G9.js} +1 -1
- package/build/client/_app/immutable/chunks/jEVVu5G9.js.br +0 -0
- package/build/client/_app/immutable/chunks/jEVVu5G9.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.V1MmmICK.js → app.Z9n2k33I.js} +2 -2
- package/build/client/_app/immutable/entry/app.Z9n2k33I.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Z9n2k33I.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js +1 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DGo1uhI2.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js +1 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DiZpkhxP.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.BqoPRvUU.js → 1.rgoSlmPu.js} +1 -1
- package/build/client/_app/immutable/nodes/1.rgoSlmPu.js.br +2 -0
- package/build/client/_app/immutable/nodes/1.rgoSlmPu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js +3 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Dzp3a3be.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js +1 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.mSsa2TDI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.js +2 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.4oRGPYr4.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-BXaBgcZT.js → context.js-Dh0ibRIF.js} +196 -7
- package/build/server/chunks/chunks/context.js-Dh0ibRIF.js.map +1 -0
- package/build/server/chunks/chunks/{contract.js-IY1F-HE_.js → contract.js-_LTMZBo2.js} +68 -6
- package/build/server/chunks/chunks/contract.js-_LTMZBo2.js.map +1 -0
- package/build/server/chunks/chunks/{core.js-D1sYC_78.js → core.js-CTyKR4bu.js} +2 -14
- package/build/server/chunks/chunks/{core.js-D1sYC_78.js.map → core.js-CTyKR4bu.js.map} +1 -1
- package/build/server/chunks/chunks/{exports.js-B5DLeNXr.js → exports.js-gz2aNXzz.js} +2 -2
- package/build/server/chunks/chunks/{exports.js-B5DLeNXr.js.map → exports.js-gz2aNXzz.js.map} +1 -1
- package/build/server/chunks/chunks/{http.js-CzB9Igb0.js → http.js-BiqUcAuu.js} +3 -2
- package/build/server/chunks/chunks/http.js-BiqUcAuu.js.map +1 -0
- package/build/server/chunks/chunks/{internal.js-HE35Pm1C.js → internal.js-DoH0cN5N.js} +3 -3
- package/build/server/chunks/chunks/{internal.js-HE35Pm1C.js.map → internal.js-DoH0cN5N.js.map} +1 -1
- package/build/server/chunks/chunks/internal2.js-BlXt2rfE.js.map +1 -1
- package/build/server/chunks/chunks/{manifest-membership.js-Cm_2fU-Z.js → manifest-membership.js-at1ixQdW.js} +10 -3
- package/build/server/chunks/chunks/manifest-membership.js-at1ixQdW.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation.js-1_IwPhKb.js → raw-reconciliation.js-CUH8IIJx.js} +3 -3
- package/build/server/chunks/chunks/raw-reconciliation.js-CUH8IIJx.js.map +1 -0
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CcO9li5n.js → raw-reconciliation2.js-z4xl5zw2.js} +2 -2
- package/build/server/chunks/chunks/{raw-reconciliation2.js-CcO9li5n.js.map → raw-reconciliation2.js-z4xl5zw2.js.map} +1 -1
- package/build/server/chunks/chunks/{shared.js-MR8sPPTu.js → shared.js-CI-ZkPQn.js} +2 -2
- package/build/server/chunks/chunks/{shared.js-MR8sPPTu.js.map → shared.js-CI-ZkPQn.js.map} +1 -1
- package/build/server/chunks/chunks/{utils.js-C2UFBITa.js → utils.js-gXYLxRG9.js} +3 -3
- package/build/server/chunks/chunks/{utils.js-C2UFBITa.js.map → utils.js-gXYLxRG9.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-BnRJ5Qnd.js → _server.ts.js-CdDjuW0r.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/_...path_/{_server.ts.js-BnRJ5Qnd.js.map → _server.ts.js-CdDjuW0r.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-BZPR6n5n.js → _server.ts.js-OWM1eORG.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/{_server.ts.js-BZPR6n5n.js.map → _server.ts.js-OWM1eORG.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-DiBS3A0C.js → _server.ts.js-DoG-7ZpZ.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/raw/{_server.ts.js-DiBS3A0C.js.map → _server.ts.js-DoG-7ZpZ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-LOO6qm2-.js → _server.ts.js-CAWjVeGd.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/_id_/reimport/{_server.ts.js-LOO6qm2-.js.map → _server.ts.js-CAWjVeGd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/_server.ts.js-CqS4aALY.js +38 -0
- package/build/server/chunks/entries/endpoints/api/assets/_id_/retag/_server.ts.js-CqS4aALY.js.map +1 -0
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CRtJJoSs.js → _server.ts.js-Bo_EsYXJ.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/{_server.ts.js-CRtJJoSs.js.map → _server.ts.js-Bo_EsYXJ.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-Ds4zCZ9H.js → _server.ts.js-DW4w0XAr.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/delete/{_server.ts.js-Ds4zCZ9H.js.map → _server.ts.js-DW4w0XAr.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DD4N8pcj.js → _server.ts.js-_MiNPnSy.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/assets/move/{_server.ts.js-DD4N8pcj.js.map → _server.ts.js-_MiNPnSy.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CZev9aYz.js → _server.ts.js-DwbrQnBc.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/_path_/{_server.ts.js-CZev9aYz.js.map → _server.ts.js-DwbrQnBc.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-MBDVW0q1.js → _server.ts.js-CEnHQf3b.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/folders/{_server.ts.js-MBDVW0q1.js.map → _server.ts.js-CEnHQf3b.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-C7naXnsR.js → _server.ts.js-BZDuJZtF.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/imports/{_server.ts.js-C7naXnsR.js.map → _server.ts.js-BZDuJZtF.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DuGyRdf3.js → _server.ts.js-DRgdpKKd.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/_name_/{_server.ts.js-DuGyRdf3.js.map → _server.ts.js-DRgdpKKd.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-0-ZCt0qH.js → _server.ts.js-CP5QyIhz.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/manifests/{_server.ts.js-0-ZCt0qH.js.map → _server.ts.js-CP5QyIhz.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-DFYU_sZL.js → _server.ts.js-BKEvt065.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/adopt/{_server.ts.js-DFYU_sZL.js.map → _server.ts.js-BKEvt065.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-BqJpK0sJ.js → _server.ts.js-C_zihkDS.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/accept/{_server.ts.js-BqJpK0sJ.js.map → _server.ts.js-C_zihkDS.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js--LSqADJp.js → _server.ts.js-watkBmy6.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/raw/edited/dismiss/{_server.ts.js--LSqADJp.js.map → _server.ts.js-watkBmy6.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DcL8nYDM.js → _server.ts.js-YtumLIou.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reconcile/{_server.ts.js-DcL8nYDM.js.map → _server.ts.js-YtumLIou.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-72OcyLfP.js → _server.ts.js-Dkouuu-M.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/reveal/{_server.ts.js-72OcyLfP.js.map → _server.ts.js-Dkouuu-M.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-D0bOxmG0.js → _server.ts.js-DwsEQeuf.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/state/{_server.ts.js-D0bOxmG0.js.map → _server.ts.js-DwsEQeuf.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BjDVCRNV.js → _server.ts.js-CdQxfhV3.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/usage/{_server.ts.js-BjDVCRNV.js.map → _server.ts.js-CdQxfhV3.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-CndfoXXd.js → _server.ts.js-DDdMocWj.js} +6 -6
- package/build/server/chunks/entries/endpoints/files/_...path_/{_server.ts.js-CndfoXXd.js.map → _server.ts.js-DDdMocWj.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-Ck1mgbk5.js → _server.ts.js-DbzjbH32.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/proxy/_...path_/{_server.ts.js-Ck1mgbk5.js.map → _server.ts.js-DbzjbH32.js.map} +1 -1
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-lZ9oP8tz.js → _server.ts.js-K_JbXZsU.js} +7 -7
- package/build/server/chunks/entries/endpoints/files/raw/_...path_/{_server.ts.js-lZ9oP8tz.js.map → _server.ts.js-K_JbXZsU.js.map} +1 -1
- package/build/server/chunks/entries/{hooks.server.js-DQ6l2RSK.js → hooks.server.js-DgZAVFbQ.js} +6 -6
- package/build/server/chunks/entries/{hooks.server.js-DQ6l2RSK.js.map → hooks.server.js-DgZAVFbQ.js.map} +1 -1
- package/build/server/chunks/{handler-Dfk_4a-r.js → handler-CFkKak8t.js} +5 -5
- package/build/server/chunks/{handler-Dfk_4a-r.js.map → handler-CFkKak8t.js.map} +1 -1
- package/build/server/chunks/{index.js-O3Wl1zok.js → index.js-B1IroJH5.js} +5 -5
- package/build/server/chunks/{index.js-O3Wl1zok.js.map → index.js-B1IroJH5.js.map} +1 -1
- package/build/server/chunks/{manifest.js-51nEZnKQ.js → manifest.js-DNDBsrEU.js} +36 -29
- package/build/server/chunks/manifest.js-DNDBsrEU.js.map +1 -0
- package/build/server/chunks/nodes/{0.js-DjqMfDtB.js → 0.js-CZ3mZUZl.js} +2 -2
- package/build/server/chunks/nodes/{0.js-DjqMfDtB.js.map → 0.js-CZ3mZUZl.js.map} +1 -1
- package/build/server/chunks/nodes/1.js-BmDzLKxV.js +7 -0
- package/build/server/chunks/nodes/{1.js-BwfSLYJH.js.map → 1.js-BmDzLKxV.js.map} +1 -1
- package/build/server/chunks/nodes/2.js-Dirm-bY-.js +7 -0
- package/build/server/chunks/nodes/2.js-Dirm-bY-.js.map +1 -0
- package/build/server/chunks/nodes/3.js-DOqHmSWt.js +7 -0
- package/build/server/chunks/nodes/{3.js-D7_hF0qp.js.map → 3.js-DOqHmSWt.js.map} +1 -1
- package/build/server/chunks/nodes/4.js-C8pmF8IP.js +7 -0
- package/build/server/chunks/nodes/{4.js-D58M2chZ.js.map → 4.js-C8pmF8IP.js.map} +1 -1
- package/dist/core/api-types.d.ts +2 -1
- package/dist/core/config.d.ts +2 -0
- package/dist/core/ingest.d.ts +1 -6
- package/dist/core/ingest.js +4 -21
- package/dist/core/propose-asset-id.d.ts +10 -0
- package/dist/core/propose-asset-id.js +25 -0
- package/dist/server/cli-commands.d.ts +2 -2
- package/dist/server/cli-commands.js +213 -29
- package/dist/server/config-loader.d.ts +1 -0
- package/dist/server/config-loader.js +5 -0
- package/dist/server/http.js +1 -0
- package/dist/server/importers/figma.d.ts +26 -3
- package/dist/server/importers/figma.js +114 -1
- package/dist/server/library-store.d.ts +9 -0
- package/dist/server/library-store.js +79 -0
- package/dist/server/operations.d.ts +12 -0
- package/dist/server/operations.js +121 -1
- package/package.json +1 -1
- package/build/client/_app/immutable/assets/AssetSourceMenu.B5fzYfym.css.br +0 -0
- package/build/client/_app/immutable/chunks/B06eqbax.js +0 -108
- package/build/client/_app/immutable/chunks/B06eqbax.js.br +0 -0
- package/build/client/_app/immutable/chunks/B06eqbax.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B97y-eFA.js.br +0 -0
- package/build/client/_app/immutable/chunks/B97y-eFA.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C9MzfQz6.js +0 -2
- package/build/client/_app/immutable/chunks/C9MzfQz6.js.br +0 -0
- package/build/client/_app/immutable/chunks/C9MzfQz6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CcuyGBqj.js +0 -1
- package/build/client/_app/immutable/chunks/CcuyGBqj.js.br +0 -0
- package/build/client/_app/immutable/chunks/CcuyGBqj.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D6c2mfMB.js.br +0 -2
- package/build/client/_app/immutable/chunks/D6c2mfMB.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.V1MmmICK.js.br +0 -0
- package/build/client/_app/immutable/entry/app.V1MmmICK.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BbyflZUw.js +0 -1
- package/build/client/_app/immutable/entry/start.BbyflZUw.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BbyflZUw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js +0 -1
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BJOUVkow.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BqoPRvUU.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BqoPRvUU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js +0 -3
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BSUVFDfW.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js +0 -1
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.B6beFiTQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js +0 -2
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.Dt96q8V4.js.gz +0 -0
- package/build/server/chunks/chunks/context.js-BXaBgcZT.js.map +0 -1
- package/build/server/chunks/chunks/contract.js-IY1F-HE_.js.map +0 -1
- package/build/server/chunks/chunks/http.js-CzB9Igb0.js.map +0 -1
- package/build/server/chunks/chunks/manifest-membership.js-Cm_2fU-Z.js.map +0 -1
- package/build/server/chunks/chunks/raw-reconciliation.js-1_IwPhKb.js.map +0 -1
- package/build/server/chunks/manifest.js-51nEZnKQ.js.map +0 -1
- package/build/server/chunks/nodes/1.js-BwfSLYJH.js +0 -7
- package/build/server/chunks/nodes/2.js-buHbEytf.js +0 -7
- package/build/server/chunks/nodes/2.js-buHbEytf.js.map +0 -1
- package/build/server/chunks/nodes/3.js-D7_hF0qp.js +0 -7
- package/build/server/chunks/nodes/4.js-D58M2chZ.js +0 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, H as typesForFileName,
|
|
2
|
-
import { s as serverPluginsByType, i as isRecord, 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, f as flatLibraryIssues, c as manifestModuleCollisionIssues, h as invalidInput, j as parseLibrary, k as isRecord$1, n as assertSafeKey, o as parseManifestRecord, q as parseImportSource } from './contract.js-
|
|
3
|
-
import { c as collectAllReferences, a as assetIdError, b as computeLibraryMembership, d as allDeliveredAssetIds } from './manifest-membership.js-
|
|
4
|
-
import { v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation2.js-
|
|
1
|
+
import { c as compareCodeUnits, h as folderOfRawPath, j as rawFileNameOfPath, g as canonicalizeParameters, n as normalizeFolderPath, H as typesForFileName, k as parentFolderPath, u as portableFolderPathKey, B as isAssetReference } from './core.js-CTyKR4bu.js';
|
|
2
|
+
import { s as serverPluginsByType, i as isRecord, 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, f as flatLibraryIssues, c as manifestModuleCollisionIssues, h as invalidInput, j as parseLibrary, k as isRecord$1, n as assertSafeKey, o as parseManifestRecord, q as parseImportSource } from './contract.js-_LTMZBo2.js';
|
|
3
|
+
import { c as collectAllReferences, a as assetIdError, b as computeLibraryMembership, d as allDeliveredAssetIds, i as isValidAssetId } from './manifest-membership.js-at1ixQdW.js';
|
|
4
|
+
import { v as verifyStableRawFile, c as classifyRawDirectory } from './raw-reconciliation2.js-z4xl5zw2.js';
|
|
5
5
|
import { createRequire } from 'node:module';
|
|
6
6
|
import { isAbsolute, resolve, join, dirname, extname, relative, sep } from 'node:path';
|
|
7
7
|
import { existsSync, readFileSync } from 'node:fs';
|
|
@@ -234,6 +234,24 @@ function materializeLibrary(effective) {
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
//#endregion
|
|
237
|
+
//#region src/lib/core/propose-asset-id.ts
|
|
238
|
+
/**
|
|
239
|
+
* Propose a camelCase asset id from a file (or node) name: split on
|
|
240
|
+
* non-alphanumeric runs and case boundaries, drop a `@2x`-style scale suffix,
|
|
241
|
+
* lowercase the first word, capitalize the rest, strip leading digits.
|
|
242
|
+
*
|
|
243
|
+
* Pure and dependency-free so it can be shared everywhere — including the Figma
|
|
244
|
+
* plugin bundle, which must not pull in the plugin registry that `ingest.ts`
|
|
245
|
+
* imports.
|
|
246
|
+
*/
|
|
247
|
+
function proposeAssetId(fileName) {
|
|
248
|
+
const words = fileName.replace(/\.[^.]+$/, "").replace(/(?:@|[-_])\dx$/i, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/).filter(Boolean);
|
|
249
|
+
if (words.length === 0) return "asset";
|
|
250
|
+
const withoutLeadingDigits = words.map((word, index) => index === 0 ? word.toLowerCase() : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("").replace(/^[0-9]+/, "");
|
|
251
|
+
if (!withoutLeadingDigits) return "asset";
|
|
252
|
+
return withoutLeadingDigits.charAt(0).toLowerCase() + withoutLeadingDigits.slice(1);
|
|
253
|
+
}
|
|
254
|
+
//#endregion
|
|
237
255
|
//#region src/lib/server/config-loader.ts
|
|
238
256
|
/**
|
|
239
257
|
* Loads and resolves the host's `fundus.config.ts` through jiti, validates
|
|
@@ -338,6 +356,7 @@ function resolveConfig(projectRoot, value, registry = serverPluginsByType) {
|
|
|
338
356
|
const figma = importConfig.figma === void 0 ? {} : importConfig.figma;
|
|
339
357
|
if (!isRecord(figma)) throw new Error("fundus.config: \"import.figma\" must be an object.");
|
|
340
358
|
if (figma.token !== void 0 && (typeof figma.token !== "string" || figma.token.length === 0)) throw new Error("fundus.config: \"import.figma.token\" must be a non-empty string.");
|
|
359
|
+
if (figma.defaultFileKey !== void 0 && (typeof figma.defaultFileKey !== "string" || figma.defaultFileKey.length === 0)) throw new Error("fundus.config: \"import.figma.defaultFileKey\" must be a non-empty string.");
|
|
341
360
|
const defaults = figma.defaults === void 0 ? {} : figma.defaults;
|
|
342
361
|
if (!isRecord(defaults)) throw new Error("fundus.config: \"import.figma.defaults\" must be an object.");
|
|
343
362
|
const scale = defaults.scale === void 0 ? 2 : defaults.scale;
|
|
@@ -356,6 +375,7 @@ function resolveConfig(projectRoot, value, registry = serverPluginsByType) {
|
|
|
356
375
|
plugins: resolvedPlugins,
|
|
357
376
|
import: { figma: {
|
|
358
377
|
...figma.token !== void 0 ? { token: figma.token } : {},
|
|
378
|
+
...figma.defaultFileKey !== void 0 ? { defaultFileKey: figma.defaultFileKey } : {},
|
|
359
379
|
defaults: { scale }
|
|
360
380
|
} },
|
|
361
381
|
usage: usage === void 0 ? null : usage,
|
|
@@ -761,9 +781,22 @@ function validateScale(value) {
|
|
|
761
781
|
}
|
|
762
782
|
function validateInput(value) {
|
|
763
783
|
const input = record(value);
|
|
764
|
-
if (!input
|
|
784
|
+
if (!input) return invalidInput("Figma import requires a URL.");
|
|
765
785
|
if (input.format !== void 0 && input.format !== "png") return invalidInput("Figma import currently supports PNG only.");
|
|
786
|
+
if (input.mode === "tag") {
|
|
787
|
+
if (typeof input.tag !== "string" || !isValidAssetId(input.tag)) return invalidInput("Figma tag import requires a valid Fundus asset id as the tag.");
|
|
788
|
+
if (input.fileKey !== void 0 && (typeof input.fileKey !== "string" || input.fileKey.length === 0)) return invalidInput("Figma tag import fileKey must be a non-empty string.");
|
|
789
|
+
return {
|
|
790
|
+
mode: "tag",
|
|
791
|
+
tag: input.tag,
|
|
792
|
+
format: "png",
|
|
793
|
+
...input.fileKey !== void 0 ? { fileKey: input.fileKey } : {},
|
|
794
|
+
...input.scale !== void 0 ? { scale: validateScale(input.scale) } : {}
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
if (typeof input.url !== "string") return invalidInput("Figma import requires a URL.");
|
|
766
798
|
return {
|
|
799
|
+
mode: "node",
|
|
767
800
|
url: input.url,
|
|
768
801
|
format: "png",
|
|
769
802
|
...input.scale !== void 0 ? { scale: validateScale(input.scale) } : {}
|
|
@@ -772,6 +805,17 @@ function validateInput(value) {
|
|
|
772
805
|
function validateFigmaSourceParameters(value) {
|
|
773
806
|
const source = record(value);
|
|
774
807
|
if (!source || typeof source.fileKey !== "string" || source.fileKey.length === 0 || typeof source.nodeId !== "string" || !/^\d+:\d+$/.test(source.nodeId) || source.format !== "png") return invalidInput("Stored Figma source parameters are invalid.");
|
|
808
|
+
if (source.mode === "tag") {
|
|
809
|
+
if (typeof source.fundusTag !== "string" || !isValidAssetId(source.fundusTag)) return invalidInput("Stored Figma source parameters are invalid.");
|
|
810
|
+
return {
|
|
811
|
+
mode: "tag",
|
|
812
|
+
fileKey: source.fileKey,
|
|
813
|
+
fundusTag: source.fundusTag,
|
|
814
|
+
nodeId: source.nodeId,
|
|
815
|
+
format: "png",
|
|
816
|
+
scale: validateScale(source.scale)
|
|
817
|
+
};
|
|
818
|
+
}
|
|
775
819
|
return {
|
|
776
820
|
fileKey: source.fileKey,
|
|
777
821
|
nodeId: source.nodeId,
|
|
@@ -963,6 +1007,37 @@ async function validatePng(bytes) {
|
|
|
963
1007
|
if (!metadata.width || !metadata.height) throw new SourceImportError("invalid-response", "Figma export has invalid dimensions.");
|
|
964
1008
|
if (metadata.width * metadata.height > MAX_PIXELS) throw new SourceImportError("image-too-large", "Figma export exceeds the 32 megapixel limit.");
|
|
965
1009
|
}
|
|
1010
|
+
function collectTaggedNodeIds(node, tag, matches) {
|
|
1011
|
+
const current = record(node);
|
|
1012
|
+
if (!current) return;
|
|
1013
|
+
const shared = record(current.sharedPluginData);
|
|
1014
|
+
const fundus = shared ? record(shared.fundus) : null;
|
|
1015
|
+
if (fundus && fundus.assetId === tag && typeof current.id === "string") matches.push(current.id);
|
|
1016
|
+
if (Array.isArray(current.children)) for (const child of current.children) collectTaggedNodeIds(child, tag, matches);
|
|
1017
|
+
}
|
|
1018
|
+
async function resolveTagToNode(fileKey, tag, context) {
|
|
1019
|
+
const token = context.config.import.figma.token;
|
|
1020
|
+
if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
|
|
1021
|
+
const endpoint = new URL(`https://api.figma.com/v1/files/${encodeURIComponent(fileKey)}`);
|
|
1022
|
+
endpoint.searchParams.set("plugin_data", "shared");
|
|
1023
|
+
const jsonBytes = await fetchWithDeadline(context.fetch, endpoint, {
|
|
1024
|
+
redirect: "error",
|
|
1025
|
+
headers: { "X-Figma-Token": token }
|
|
1026
|
+
}, async (response) => new Uint8Array(await response.arrayBuffer()));
|
|
1027
|
+
let payload;
|
|
1028
|
+
try {
|
|
1029
|
+
payload = JSON.parse(new TextDecoder().decode(jsonBytes));
|
|
1030
|
+
} catch {
|
|
1031
|
+
throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
|
|
1032
|
+
}
|
|
1033
|
+
const body = record(payload);
|
|
1034
|
+
if (!body || body.err || typeof body.status === "number" && body.status >= 400) throw new SourceImportError("invalid-response", "Figma returned an invalid response.");
|
|
1035
|
+
const matches = [];
|
|
1036
|
+
collectTaggedNodeIds(body.document, tag, matches);
|
|
1037
|
+
if (matches.length === 0) throw new SourceImportError("not-found", `No Figma node is tagged "${tag}" in this file.`);
|
|
1038
|
+
if (matches.length > 1) throw new SourceImportError("ambiguous-tag", `More than one Figma node is tagged "${tag}" in this file.`);
|
|
1039
|
+
return matches[0];
|
|
1040
|
+
}
|
|
966
1041
|
async function materialize(source, context) {
|
|
967
1042
|
const token = context.config.import.figma.token;
|
|
968
1043
|
if (!token) throw new SourceImportError("not-configured", "Figma access is not configured.");
|
|
@@ -1002,6 +1077,19 @@ var figmaSourceImporter = {
|
|
|
1002
1077
|
label: "Figma",
|
|
1003
1078
|
validateInput,
|
|
1004
1079
|
async importRaw(input, context) {
|
|
1080
|
+
if (input.mode === "tag") {
|
|
1081
|
+
const fileKey = input.fileKey ?? context.config.import.figma.defaultFileKey;
|
|
1082
|
+
if (!fileKey) throw new SourceImportError("not-configured", "Figma tag import needs a fileKey or import.figma.defaultFileKey in fundus.config.");
|
|
1083
|
+
const nodeId = await resolveTagToNode(fileKey, input.tag, context);
|
|
1084
|
+
return materialize({
|
|
1085
|
+
mode: "tag",
|
|
1086
|
+
fileKey,
|
|
1087
|
+
fundusTag: input.tag,
|
|
1088
|
+
nodeId,
|
|
1089
|
+
format: "png",
|
|
1090
|
+
scale: input.scale ?? context.config.import.figma.defaults.scale
|
|
1091
|
+
}, context);
|
|
1092
|
+
}
|
|
1005
1093
|
const parsed = parseFigmaSelectionUrl(input.url);
|
|
1006
1094
|
return materialize({
|
|
1007
1095
|
fileKey: parsed.fileKey,
|
|
@@ -1012,6 +1100,13 @@ var figmaSourceImporter = {
|
|
|
1012
1100
|
},
|
|
1013
1101
|
validateSourceParameters: validateFigmaSourceParameters,
|
|
1014
1102
|
async reimportRaw(source, context) {
|
|
1103
|
+
if (source.mode === "tag") {
|
|
1104
|
+
const nodeId = await resolveTagToNode(source.fileKey, source.fundusTag, context);
|
|
1105
|
+
return materialize({
|
|
1106
|
+
...source,
|
|
1107
|
+
nodeId
|
|
1108
|
+
}, context);
|
|
1109
|
+
}
|
|
1015
1110
|
return materialize(source, context);
|
|
1016
1111
|
}
|
|
1017
1112
|
};
|
|
@@ -1610,6 +1705,17 @@ function figmaSlicePixelRatio(raw, type) {
|
|
|
1610
1705
|
if (type !== "slice" || raw.importSource?.importer !== "figma") return void 0;
|
|
1611
1706
|
return validateFigmaSourceParameters(raw.importSource.parameters).scale;
|
|
1612
1707
|
}
|
|
1708
|
+
/**
|
|
1709
|
+
* The Fundus tag of a Figma tag-mode import source, else null. In tag mode the
|
|
1710
|
+
* tag IS the asset id, so this is the single seam that ties provenance to
|
|
1711
|
+
* identity — used to assert id equality on import/reimport and to forbid
|
|
1712
|
+
* renaming a tag-referenced asset. Only Figma sources are inspected.
|
|
1713
|
+
*/
|
|
1714
|
+
function figmaTagOf(importSource) {
|
|
1715
|
+
if (importSource?.importer !== "figma") return null;
|
|
1716
|
+
const params = validateFigmaSourceParameters(importSource.parameters);
|
|
1717
|
+
return params.mode === "tag" ? params.fundusTag : null;
|
|
1718
|
+
}
|
|
1613
1719
|
var FundusOperations = class {
|
|
1614
1720
|
#config;
|
|
1615
1721
|
#registry;
|
|
@@ -1881,6 +1987,8 @@ var FundusOperations = class {
|
|
|
1881
1987
|
});
|
|
1882
1988
|
return this.#enqueueOperation(async () => {
|
|
1883
1989
|
this.#validateImportedRaw(raw, options.importer);
|
|
1990
|
+
const tag = figmaTagOf(raw.importSource);
|
|
1991
|
+
if (tag !== null && tag !== options.id) throw new SourceImportError("invalid-input", `A Figma tag import must use its tag as the asset id: the tag is "${tag}", not "${options.id}".`);
|
|
1884
1992
|
return this.#createImportedAsset(raw, options);
|
|
1885
1993
|
});
|
|
1886
1994
|
}
|
|
@@ -1917,6 +2025,8 @@ var FundusOperations = class {
|
|
|
1917
2025
|
if (snapshot.input !== void 0 && !raw.importSource) throw new SourceImportError("invalid-response", "The source importer did not return provenance for the updated source.");
|
|
1918
2026
|
return this.#enqueueOperation(async () => {
|
|
1919
2027
|
this.#validateImportedRaw(raw, snapshot.importer.kind);
|
|
2028
|
+
const tag = figmaTagOf(raw.importSource);
|
|
2029
|
+
if (tag !== null && tag !== id) throw new SourceImportError("invalid-input", `A Figma tag reimport may not retarget asset "${id}" to a different tag "${tag}".`);
|
|
1920
2030
|
const plugin = serverPluginForType(snapshot.expected.type, this.#registry);
|
|
1921
2031
|
if (!plugin.descriptor.accepts.includes(raw.extension)) throw new SourceImportError("invalid-response", `The ${snapshot.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
1922
2032
|
const pixelRatio = snapshot.input === void 0 ? void 0 : figmaSlicePixelRatio(raw, snapshot.expected.type);
|
|
@@ -1963,6 +2073,8 @@ var FundusOperations = class {
|
|
|
1963
2073
|
const importSource = raw.importSource;
|
|
1964
2074
|
return this.#enqueueOperation(async () => {
|
|
1965
2075
|
this.#validateImportedRaw(raw, preflight.importer.kind);
|
|
2076
|
+
const tag = figmaTagOf(importSource);
|
|
2077
|
+
if (tag !== null && tag !== id) throw new SourceImportError("invalid-input", `A Figma tag replacement must use its own tag as the asset id: the tag is "${tag}", not "${id}".`);
|
|
1966
2078
|
const plugin = serverPluginForType(preflight.expected.type, this.#registry);
|
|
1967
2079
|
if (!plugin.descriptor.accepts.includes(raw.extension)) throw new SourceImportError("invalid-response", `The ${preflight.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
1968
2080
|
const previousName = rawFileNameOfPath(preflight.expected.raw);
|
|
@@ -1984,6 +2096,79 @@ var FundusOperations = class {
|
|
|
1984
2096
|
}
|
|
1985
2097
|
});
|
|
1986
2098
|
}
|
|
2099
|
+
/**
|
|
2100
|
+
* Edit a Figma tag asset's tag, fileKey, and/or scale in place. Because in tag
|
|
2101
|
+
* mode the tag IS the asset id, changing the tag renames the asset (moves the
|
|
2102
|
+
* library key); changing only fileKey/scale is an in-place re-point. Mirrors
|
|
2103
|
+
* `reimportAsset`'s three phases: preflight in the queue, materialize outside
|
|
2104
|
+
* it, then commit atomically through `store.repointTagAsset`.
|
|
2105
|
+
*/
|
|
2106
|
+
async retagFigmaAsset(id, input) {
|
|
2107
|
+
const snapshot = await this.#enqueueOperation(async () => {
|
|
2108
|
+
const library = await this.#store.read();
|
|
2109
|
+
this.#requireAsset(library, id);
|
|
2110
|
+
const record = library.assets[id];
|
|
2111
|
+
const currentTag = figmaTagOf(record.importSource);
|
|
2112
|
+
if (currentTag === null || !record.importSource) throw new SourceImportError("invalid-input", `Asset "${id}" is not a Figma tag import.`);
|
|
2113
|
+
const current = validateFigmaSourceParameters(record.importSource.parameters);
|
|
2114
|
+
const newTag = input.tag ?? currentTag;
|
|
2115
|
+
const fileKey = input.fileKey ?? current.fileKey;
|
|
2116
|
+
const scale = input.scale ?? current.scale;
|
|
2117
|
+
if (newTag !== id) {
|
|
2118
|
+
const problem = assetIdError(newTag);
|
|
2119
|
+
if (problem) throw new SourceImportError("invalid-input", problem);
|
|
2120
|
+
if (Object.hasOwn(library.assets, newTag)) throw new SourceImportError("invalid-input", `An asset with id "${newTag}" already exists.`);
|
|
2121
|
+
const candidate = structuredClone(library);
|
|
2122
|
+
candidate.assets[newTag] = candidate.assets[id];
|
|
2123
|
+
delete candidate.assets[id];
|
|
2124
|
+
await this.#assertNoIntroducedIssues(library, candidate);
|
|
2125
|
+
}
|
|
2126
|
+
try {
|
|
2127
|
+
await verifyStableRawFile(join(this.#config.rawDir, record.raw), record.rawHash);
|
|
2128
|
+
} catch {
|
|
2129
|
+
throw new SourceImportError("stale-import", "The local raw file changed. Apply or discard that edit before retagging.");
|
|
2130
|
+
}
|
|
2131
|
+
const importer = this.#importers.require("figma");
|
|
2132
|
+
return {
|
|
2133
|
+
importer,
|
|
2134
|
+
input: importer.validateInput({
|
|
2135
|
+
mode: "tag",
|
|
2136
|
+
tag: newTag,
|
|
2137
|
+
fileKey,
|
|
2138
|
+
scale,
|
|
2139
|
+
format: "png"
|
|
2140
|
+
}),
|
|
2141
|
+
newTag,
|
|
2142
|
+
expected: {
|
|
2143
|
+
raw: record.raw,
|
|
2144
|
+
rawHash: record.rawHash,
|
|
2145
|
+
type: record.type,
|
|
2146
|
+
canonicalSource: canonicalizeParameters(record.importSource)
|
|
2147
|
+
}
|
|
2148
|
+
};
|
|
2149
|
+
});
|
|
2150
|
+
const raw = await snapshot.importer.importRaw(snapshot.input, {
|
|
2151
|
+
config: this.#config,
|
|
2152
|
+
fetch: globalThis.fetch
|
|
2153
|
+
});
|
|
2154
|
+
if (!raw.importSource) throw new SourceImportError("invalid-response", "The Figma importer did not return provenance for the retagged source.");
|
|
2155
|
+
const importSource = raw.importSource;
|
|
2156
|
+
return this.#enqueueOperation(async () => {
|
|
2157
|
+
this.#validateImportedRaw(raw, snapshot.importer.kind);
|
|
2158
|
+
if (figmaTagOf(importSource) !== snapshot.newTag) throw new SourceImportError("invalid-response", `The Figma importer resolved a different tag than "${snapshot.newTag}".`);
|
|
2159
|
+
const plugin = serverPluginForType(snapshot.expected.type, this.#registry);
|
|
2160
|
+
if (!plugin.descriptor.accepts.includes(raw.extension)) throw new SourceImportError("invalid-response", `The ${snapshot.expected.type} type does not accept ".${raw.extension}" files.`);
|
|
2161
|
+
const pixelRatio = figmaSlicePixelRatio(raw, snapshot.expected.type);
|
|
2162
|
+
let library;
|
|
2163
|
+
try {
|
|
2164
|
+
library = await this.#store.repointTagAsset(id, snapshot.newTag, raw.bytes, snapshot.expected, importSource, pixelRatio === void 0 ? void 0 : (parameters) => plugin.descriptor.validateParameters(mergeParameterPatch(parameters, { pixelRatio })));
|
|
2165
|
+
} catch (cause) {
|
|
2166
|
+
if (cause instanceof Error && cause.message === "stale-import") throw new SourceImportError("stale-import", "The asset or local raw file changed while Figma was exporting. Nothing was changed.");
|
|
2167
|
+
throw cause;
|
|
2168
|
+
}
|
|
2169
|
+
return this.#afterMutation(library);
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
1987
2172
|
async #createImportedAsset(raw, options) {
|
|
1988
2173
|
this.#validateImportedRaw(raw);
|
|
1989
2174
|
const fileName = raw.suggestedFileName ?? `${options.id}.${raw.extension}`;
|
|
@@ -2164,6 +2349,7 @@ var FundusOperations = class {
|
|
|
2164
2349
|
async #renameAsset(id, newId) {
|
|
2165
2350
|
const library = await this.#store.read();
|
|
2166
2351
|
this.#requireAsset(library, id);
|
|
2352
|
+
if (figmaTagOf(library.assets[id].importSource) !== null) throw new SourceImportError("invalid-input", "This asset is referenced by a Figma tag and cannot be renamed; re-import with a new tag instead.");
|
|
2167
2353
|
if (newId !== id && !Object.hasOwn(library.assets, newId)) {
|
|
2168
2354
|
const candidate = structuredClone(library);
|
|
2169
2355
|
candidate.assets[newId] = candidate.assets[id];
|
|
@@ -2381,7 +2567,10 @@ var FundusOperations = class {
|
|
|
2381
2567
|
gitBranch,
|
|
2382
2568
|
library,
|
|
2383
2569
|
assets,
|
|
2384
|
-
importDefaults: { figma: {
|
|
2570
|
+
importDefaults: { figma: {
|
|
2571
|
+
scale: this.#config.import.figma.defaults.scale,
|
|
2572
|
+
...this.#config.import.figma.defaultFileKey !== void 0 ? { defaultFileKey: this.#config.import.figma.defaultFileKey } : {}
|
|
2573
|
+
} },
|
|
2385
2574
|
issues,
|
|
2386
2575
|
presetNames,
|
|
2387
2576
|
presetCapabilities,
|
|
@@ -2605,4 +2794,4 @@ async function createFundusContext() {
|
|
|
2605
2794
|
}
|
|
2606
2795
|
|
|
2607
2796
|
export { getFundusContext as g, initializeFundusContext as i };
|
|
2608
|
-
//# sourceMappingURL=context.js-
|
|
2797
|
+
//# sourceMappingURL=context.js-Dh0ibRIF.js.map
|