@figma-vars/hooks 1.3.3 → 1.4.4

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.
Files changed (53) hide show
  1. package/README.md +85 -19
  2. package/dist/figma-vars-hooks.js +314 -296
  3. package/dist/figma-vars-hooks.umd.cjs +3 -3
  4. package/dist/src/api/fetcher.d.ts +28 -0
  5. package/dist/src/api/index.d.ts +25 -0
  6. package/dist/src/api/mutator.d.ts +33 -0
  7. package/dist/src/api/mutator.test.d.ts +1 -0
  8. package/dist/src/constants/index.d.ts +89 -0
  9. package/dist/src/contexts/FigmaVarsProvider.d.ts +56 -0
  10. package/dist/src/contexts/index.d.ts +21 -0
  11. package/dist/src/hooks/index.d.ts +143 -0
  12. package/dist/src/hooks/useBulkUpdateVariables.d.ts +46 -0
  13. package/dist/src/hooks/useCreateVariable.d.ts +45 -0
  14. package/dist/src/hooks/useDeleteVariable.d.ts +33 -0
  15. package/dist/src/hooks/useFigmaToken.d.ts +21 -0
  16. package/dist/src/hooks/useMutation.d.ts +53 -0
  17. package/dist/src/hooks/useUpdateVariable.d.ts +40 -0
  18. package/dist/src/hooks/useVariableCollections.d.ts +35 -0
  19. package/dist/src/hooks/useVariableModes.d.ts +32 -0
  20. package/dist/src/hooks/useVariables.d.ts +32 -0
  21. package/dist/src/index.d.ts +80 -0
  22. package/dist/src/types/contexts.d.ts +77 -0
  23. package/dist/src/types/figma.d.ts +244 -0
  24. package/dist/src/types/hooks.d.ts +67 -0
  25. package/dist/src/types/index.d.ts +30 -0
  26. package/dist/src/types/mutations.d.ts +314 -0
  27. package/dist/src/utils/filterVariables.d.ts +31 -0
  28. package/dist/src/utils/index.d.ts +21 -0
  29. package/dist/tests/FigmaVarsProvider.test.d.ts +1 -0
  30. package/dist/tests/api/fetcher.test.d.ts +1 -0
  31. package/dist/tests/api/mutator.test.d.ts +1 -0
  32. package/dist/tests/constants/index.test.d.ts +1 -0
  33. package/dist/tests/contexts/index.test.d.ts +1 -0
  34. package/dist/tests/hooks/index.test.d.ts +1 -0
  35. package/dist/tests/hooks/useBulkUpdateVariables.test.d.ts +1 -0
  36. package/dist/tests/hooks/useCreateVariable.test.d.ts +1 -0
  37. package/dist/tests/hooks/useDeleteVariable.test.d.ts +1 -0
  38. package/dist/tests/hooks/useFigmaToken.test.d.ts +1 -0
  39. package/dist/tests/hooks/useMutation.test.d.ts +1 -0
  40. package/dist/tests/hooks/useUpdateVariable.test.d.ts +1 -0
  41. package/dist/tests/hooks/useVariableCollections.test.d.ts +1 -0
  42. package/dist/tests/hooks/useVariableModes.test.d.ts +1 -0
  43. package/dist/tests/hooks/useVariables.test.d.ts +1 -0
  44. package/dist/tests/index.test.d.ts +1 -0
  45. package/dist/tests/mocks/variables.d.ts +2 -0
  46. package/dist/tests/setup.d.ts +0 -0
  47. package/dist/tests/test-utils.d.ts +10 -0
  48. package/dist/tests/test-utils.test.d.ts +1 -0
  49. package/dist/tests/types.test.d.ts +1 -0
  50. package/dist/tests/utils/filterVariables.test.d.ts +1 -0
  51. package/dist/tests/utils/index.test.d.ts +1 -0
  52. package/package.json +4 -2
  53. package/dist/index.d.ts +0 -1221
@@ -1,4 +1,4 @@
1
- (function(g,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],Z):(g=typeof globalThis<"u"?globalThis:g||self,Z(g["@figma-vars/hooks"]={},g["react/jsx-runtime"],g.React))})(this,function(g,Z,m){"use strict";const Me=m.createContext(void 0),mt=({children:e,token:t,fileKey:n})=>Z.jsx(Me.Provider,{value:{token:t,fileKey:n},children:e}),H=()=>{const e=m.useContext(Me);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e};var se={exports:{}},Ee={};/**
1
+ (function(y,Z){typeof exports=="object"&&typeof module<"u"?Z(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],Z):(y=typeof globalThis<"u"?globalThis:y||self,Z(y["@figma-vars/hooks"]={},y["react/jsx-runtime"],y.React))})(this,function(y,Z,p){"use strict";const Pe=p.createContext(void 0),dt=({children:e,token:t,fileKey:n})=>Z.jsx(Pe.Provider,{value:{token:t,fileKey:n},children:e}),ee=()=>{const e=p.useContext(Pe);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e};var se={exports:{}},Ee={};/**
2
2
  * @license React
3
3
  * use-sync-external-store-shim.production.js
4
4
  *
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * This source code is licensed under the MIT license found in the
8
8
  * LICENSE file in the root directory of this source tree.
9
- */var Pe;function pt(){if(Pe)return Ee;Pe=1;var e=m;function t(c,d){return c===d&&(c!==0||1/c===1/d)||c!==c&&d!==d}var n=typeof Object.is=="function"?Object.is:t,r=e.useState,o=e.useEffect,s=e.useLayoutEffect,a=e.useDebugValue;function h(c,d){var u=d(),E=r({inst:{value:u,getSnapshot:d}}),l=E[0].inst,C=E[1];return s(function(){l.value=u,l.getSnapshot=d,S(l)&&C({inst:l})},[c,u,d]),o(function(){return S(l)&&C({inst:l}),c(function(){S(l)&&C({inst:l})})},[c]),a(u),u}function S(c){var d=c.getSnapshot;c=c.value;try{var u=d();return!n(c,u)}catch{return!0}}function D(c,d){return d()}var O=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?D:h;return Ee.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:O,Ee}var me={};/**
9
+ */var je;function Et(){if(je)return Ee;je=1;var e=p;function t(c,d){return c===d&&(c!==0||1/c===1/d)||c!==c&&d!==d}var n=typeof Object.is=="function"?Object.is:t,r=e.useState,o=e.useEffect,s=e.useLayoutEffect,i=e.useDebugValue;function E(c,d){var u=d(),m=r({inst:{value:u,getSnapshot:d}}),l=m[0].inst,I=m[1];return s(function(){l.value=u,l.getSnapshot=d,S(l)&&I({inst:l})},[c,u,d]),o(function(){return S(l)&&I({inst:l}),c(function(){S(l)&&I({inst:l})})},[c]),i(u),u}function S(c){var d=c.getSnapshot;c=c.value;try{var u=d();return!n(c,u)}catch{return!0}}function D(c,d){return d()}var O=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?D:E;return Ee.useSyncExternalStore=e.useSyncExternalStore!==void 0?e.useSyncExternalStore:O,Ee}var me={};/**
10
10
  * @license React
11
11
  * use-sync-external-store-shim.development.js
12
12
  *
@@ -14,4 +14,4 @@
14
14
  *
15
15
  * This source code is licensed under the MIT license found in the
16
16
  * LICENSE file in the root directory of this source tree.
17
- */var je;function ht(){return je||(je=1,process.env.NODE_ENV!=="production"&&function(){function e(u,E){return u===E&&(u!==0||1/u===1/E)||u!==u&&E!==E}function t(u,E){O||o.startTransition===void 0||(O=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var l=E();if(!c){var C=E();s(l,C)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}C=a({inst:{value:l,getSnapshot:E}});var i=C[0].inst,q=C[1];return S(function(){i.value=l,i.getSnapshot=E,n(i)&&q({inst:i})},[u,l,E]),h(function(){return n(i)&&q({inst:i}),u(function(){n(i)&&q({inst:i})})},[u]),D(l),l}function n(u){var E=u.getSnapshot;u=u.value;try{var l=E();return!s(u,l)}catch{return!0}}function r(u,E){return E()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var o=m,s=typeof Object.is=="function"?Object.is:e,a=o.useState,h=o.useEffect,S=o.useLayoutEffect,D=o.useDebugValue,O=!1,c=!1,d=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?r:t;me.useSyncExternalStore=o.useSyncExternalStore!==void 0?o.useSyncExternalStore:d,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),me}var xe;function St(){return xe||(xe=1,process.env.NODE_ENV==="production"?se.exports=pt():se.exports=ht()),se.exports}var _t=St();const Ue=0,ke=1,qe=2,Ge=3;var We=Object.prototype.hasOwnProperty;function pe(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&pe(e[r],t[r]););return r===-1}if(!n||typeof e=="object"){r=0;for(n in e)if(We.call(e,n)&&++r&&!We.call(t,n)||!(n in t)||!pe(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}const P=new WeakMap,U=()=>{},R=U(),he=Object,f=e=>e===R,N=e=>typeof e=="function",k=(e,t)=>({...e,...t}),Be=e=>N(e.then),Se={},ie={},_e="undefined",ee=typeof window!=_e,ve=typeof document!=_e,vt=ee&&"Deno"in window,Ot=()=>ee&&typeof window.requestAnimationFrame!=_e,He=(e,t)=>{const n=P.get(e);return[()=>!f(t)&&e.get(t)||Se,r=>{if(!f(t)){const o=e.get(t);t in ie||(ie[t]=o),n[5](t,k(o,r),o||Se)}},n[6],()=>!f(t)&&t in ie?ie[t]:!f(t)&&e.get(t)||Se]};let Oe=!0;const wt=()=>Oe,[we,ge]=ee&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[U,U],gt=()=>{const e=ve&&document.visibilityState;return f(e)||e!=="hidden"},yt=e=>(ve&&document.addEventListener("visibilitychange",e),we("focus",e),()=>{ve&&document.removeEventListener("visibilitychange",e),ge("focus",e)}),Tt=e=>{const t=()=>{Oe=!0,e()},n=()=>{Oe=!1};return we("online",t),we("offline",n),()=>{ge("online",t),ge("offline",n)}},At={isOnline:wt,isVisible:gt},Rt={initFocus:yt,initReconnect:Tt},$e=!m.useId,te=!ee||vt,Dt=e=>Ot()?window.requestAnimationFrame(e):setTimeout(e,1),ye=te?m.useEffect:m.useLayoutEffect,Te=typeof navigator<"u"&&navigator.connection,Ke=!te&&Te&&(["slow-2g","2g"].includes(Te.effectiveType)||Te.saveData),ae=new WeakMap,Ae=(e,t)=>he.prototype.toString.call(e)===`[object ${t}]`;let It=0;const Re=e=>{const t=typeof e,n=Ae(e,"Date"),r=Ae(e,"RegExp"),o=Ae(e,"Object");let s,a;if(he(e)===e&&!n&&!r){if(s=ae.get(e),s)return s;if(s=++It+"~",ae.set(e,s),Array.isArray(e)){for(s="@",a=0;a<e.length;a++)s+=Re(e[a])+",";ae.set(e,s)}if(o){s="#";const h=he.keys(e).sort();for(;!f(a=h.pop());)f(e[a])||(s+=a+":"+Re(e[a])+",");ae.set(e,s)}}else s=n?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return s},De=e=>{if(N(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?Re(e):"",[e,t]};let Ct=0;const Ie=()=>++Ct;async function Je(...e){const[t,n,r,o]=e,s=k({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let a=s.populateCache;const h=s.rollbackOnError;let S=s.optimisticData;const D=d=>typeof h=="function"?h(d):h!==!1,O=s.throwOnError;if(N(n)){const d=n,u=[],E=t.keys();for(const l of E)!/^\$(inf|sub)\$/.test(l)&&d(t.get(l)._k)&&u.push(l);return Promise.all(u.map(c))}return c(n);async function c(d){const[u]=De(d);if(!u)return;const[E,l]=He(t,u),[C,i,q,re]=P.get(t),G=()=>{const V=C[u];return(N(s.revalidate)?s.revalidate(E().data,d):s.revalidate!==!1)&&(delete q[u],delete re[u],V&&V[0])?V[0](qe).then(()=>E().data):E().data};if(e.length<3)return G();let T=r,b;const $=Ie();i[u]=[$,0];const v=!f(S),K=E(),M=K.data,J=K._c,W=f(J)?M:J;if(v&&(S=N(S)?S(W,M):S,l({data:S,_c:W})),N(T))try{T=T(W)}catch(V){b=V}if(T&&Be(T))if(T=await T.catch(V=>{b=V}),$!==i[u][0]){if(b)throw b;return T}else b&&v&&D(b)&&(a=!0,l({data:W,_c:R}));if(a&&!b)if(N(a)){const V=a(T,W);l({data:V,error:R,_c:R})}else l({data:T,error:R,_c:R});if(i[u][1]=Ie(),Promise.resolve(G()).then(()=>{l({_c:R})}),b){if(O)throw b;return}return T}}const Ye=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},bt=(e,t)=>{if(!P.has(e)){const n=k(Rt,t),r=Object.create(null),o=Je.bind(R,e);let s=U;const a=Object.create(null),h=(O,c)=>{const d=a[O]||[];return a[O]=d,d.push(c),()=>d.splice(d.indexOf(c),1)},S=(O,c,d)=>{e.set(O,c);const u=a[O];if(u)for(const E of u)E(c,d)},D=()=>{if(!P.has(e)&&(P.set(e,[r,Object.create(null),Object.create(null),Object.create(null),o,S,h]),!te)){const O=n.initFocus(setTimeout.bind(R,Ye.bind(R,r,Ue))),c=n.initReconnect(setTimeout.bind(R,Ye.bind(R,r,ke)));s=()=>{O&&O(),c&&c(),P.delete(e)}}};return D(),[e,o,D,s]}return[e,P.get(e)[4]]},Lt=(e,t,n,r,o)=>{const s=n.errorRetryCount,a=o.retryCount,h=~~((Math.random()+.5)*(1<<(a<8?a:8)))*n.errorRetryInterval;!f(s)&&a>s||setTimeout(r,h,o)},Vt=pe,[ze,Ft]=bt(new Map),Nt=k({onLoadingSlow:U,onSuccess:U,onError:U,onErrorRetry:Lt,onDiscarded:U,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Ke?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Ke?5e3:3e3,compare:Vt,isPaused:()=>!1,cache:ze,mutate:Ft,fallback:{}},At),Mt=(e,t)=>{const n=k(e,t);if(t){const{use:r,fallback:o}=e,{use:s,fallback:a}=t;r&&s&&(n.use=r.concat(s)),o&&a&&(n.fallback=k(o,a))}return n},Pt=m.createContext({}),jt="$inf$",Xe=ee&&window.__SWR_DEVTOOLS_USE__,xt=Xe?window.__SWR_DEVTOOLS_USE__:[],Ut=()=>{Xe&&(window.__SWR_DEVTOOLS_REACT__=m)},kt=e=>N(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],qt=()=>k(Nt,m.useContext(Pt)),Gt=e=>(t,n,r)=>e(t,n&&((...s)=>{const[a]=De(t),[,,,h]=P.get(ze);if(a.startsWith(jt))return n(...s);const S=h[a];return f(S)?n(...s):(delete h[a],S)}),r),Wt=xt.concat(Gt),Bt=e=>function(...n){const r=qt(),[o,s,a]=kt(n),h=Mt(r,a);let S=e;const{use:D}=h,O=(D||[]).concat(Wt);for(let c=O.length;c--;)S=O[c](S);return S(o,s||h.fetcher||null,h)},Ht=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const o=r.indexOf(n);o>=0&&(r[o]=r[r.length-1],r.pop())}};Ut();const Ce=m.use||(e=>{switch(e.status){case"pending":throw e;case"fulfilled":return e.value;case"rejected":throw e.reason;default:throw e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e}}),be={dedupe:!0},$t=Bt((e,t,n)=>{const{cache:r,compare:o,suspense:s,fallbackData:a,revalidateOnMount:h,revalidateIfStale:S,refreshInterval:D,refreshWhenHidden:O,refreshWhenOffline:c,keepPreviousData:d}=n,[u,E,l,C]=P.get(r),[i,q]=De(e),re=m.useRef(!1),G=m.useRef(!1),T=m.useRef(i),b=m.useRef(t),$=m.useRef(n),v=()=>$.current,K=()=>v().isVisible()&&v().isOnline(),[M,J,W,V]=He(r,i),Y=m.useRef({}).current,le=f(a)?f(n.fallback)?R:n.fallback[i]:a,st=(_,p)=>{for(const A in Y){const w=A;if(w==="data"){if(!o(_[w],p[w])&&(!f(_[w])||!o(de,p[w])))return!1}else if(p[w]!==_[w])return!1}return!0},it=m.useMemo(()=>{const _=!i||!t?!1:f(h)?v().isPaused()||s?!1:S!==!1:h,p=I=>{const j=k(I);return delete j._k,_?{isValidating:!0,isLoading:!0,...j}:j},A=M(),w=V(),F=p(A),Q=A===w?F:p(w);let y=F;return[()=>{const I=p(M());return st(I,y)?(y.data=I.data,y.isLoading=I.isLoading,y.isValidating=I.isValidating,y.error=I.error,y):(y=I,I)},()=>Q]},[r,i]),z=_t.useSyncExternalStore(m.useCallback(_=>W(i,(p,A)=>{st(A,p)||_()}),[r,i]),it[0],it[1]),at=!re.current,sn=u[i]&&u[i].length>0,X=z.data,B=f(X)?le&&Be(le)?Ce(le):le:X,fe=z.error,Ve=m.useRef(B),de=d?f(X)?f(Ve.current)?B:Ve.current:X:B,ut=sn&&!f(fe)?!1:at&&!f(h)?h:v().isPaused()?!1:s?f(B)?!1:S:f(B)||S,ct=!!(i&&t&&at&&ut),an=f(z.isValidating)?ct:z.isValidating,un=f(z.isLoading)?ct:z.isLoading,oe=m.useCallback(async _=>{const p=b.current;if(!i||!p||G.current||v().isPaused())return!1;let A,w,F=!0;const Q=_||{},y=!l[i]||!Q.dedupe,I=()=>$e?!G.current&&i===T.current&&re.current:i===T.current,j={isValidating:!1,isLoading:!1},ft=()=>{J(j)},dt=()=>{const L=l[i];L&&L[1]===w&&delete l[i]},Et={isValidating:!0};f(M().data)&&(Et.isLoading=!0);try{if(y&&(J(Et),n.loadingTimeout&&f(M().data)&&setTimeout(()=>{F&&I()&&v().onLoadingSlow(i,n)},n.loadingTimeout),l[i]=[p(q),Ie()]),[A,w]=l[i],A=await A,y&&setTimeout(dt,n.dedupingInterval),!l[i]||l[i][1]!==w)return y&&I()&&v().onDiscarded(i),!1;j.error=R;const L=E[i];if(!f(L)&&(w<=L[0]||w<=L[1]||L[1]===0))return ft(),y&&I()&&v().onDiscarded(i),!1;const x=M().data;j.data=o(x,A)?x:A,y&&I()&&v().onSuccess(A,i,n)}catch(L){dt();const x=v(),{shouldRetryOnError:Fe}=x;x.isPaused()||(j.error=L,y&&I()&&(x.onError(L,i,x),(Fe===!0||N(Fe)&&Fe(L))&&(!v().revalidateOnFocus||!v().revalidateOnReconnect||K())&&x.onErrorRetry(L,i,x,cn=>{const Ne=u[i];Ne&&Ne[0]&&Ne[0](Ge,cn)},{retryCount:(Q.retryCount||0)+1,dedupe:!0})))}return F=!1,ft(),!0},[i,r]),lt=m.useCallback((..._)=>Je(r,T.current,..._),[]);if(ye(()=>{b.current=t,$.current=n,f(X)||(Ve.current=X)}),ye(()=>{if(!i)return;const _=oe.bind(R,be);let p=0;v().revalidateOnFocus&&(p=Date.now()+v().focusThrottleInterval);const w=Ht(i,u,(F,Q={})=>{if(F==Ue){const y=Date.now();v().revalidateOnFocus&&y>p&&K()&&(p=y+v().focusThrottleInterval,_())}else if(F==ke)v().revalidateOnReconnect&&K()&&_();else{if(F==qe)return oe();if(F==Ge)return oe(Q)}});return G.current=!1,T.current=i,re.current=!0,J({_k:q}),ut&&(f(B)||te?_():Dt(_)),()=>{G.current=!0,w()}},[i]),ye(()=>{let _;function p(){const w=N(D)?D(M().data):D;w&&_!==-1&&(_=setTimeout(A,w))}function A(){!M().error&&(O||v().isVisible())&&(c||v().isOnline())?oe(be).then(p):p()}return p(),()=>{_&&(clearTimeout(_),_=-1)}},[D,O,c,i]),m.useDebugValue(de),s&&f(B)&&i){if(!$e&&te)throw new Error("Fallback data is required when using Suspense in SSR.");b.current=t,$.current=n,G.current=!1;const _=C[i];if(!f(_)){const p=lt(_);Ce(p)}if(f(fe)){const p=oe(be);f(de)||(p.status="fulfilled",p.value=!0),Ce(p)}else throw fe}return{mutate:lt,get data(){return Y.data=!0,de},get error(){return Y.error=!0,fe},get isValidating(){return Y.isValidating=!0,an},get isLoading(){return Y.isLoading=!0,un}}}),Qe="https://api.figma.com",Kt=`${Qe}/v1/files`,Ze=`${Qe}/v1/variables`,et=Ze,tt=e=>`${Ze}/${e}`,Jt=e=>`${Kt}/${e}/variables/local`,nt="application/json",rt="X-FIGMA-TOKEN",ne="A Figma API token is required.",ot="An error occurred while fetching data from the Figma API.",Yt=async(e,t)=>{if(!t)throw new Error(ne);const n=await fetch(e,{headers:{[rt]:t,"Content-Type":nt}});if(!n.ok){const r=await n.json();throw new Error(r.message||ot)}return n.json()},Le=()=>{const{token:e,fileKey:t}=H(),n=t?Jt(t):null,{data:r,error:o,isLoading:s,isValidating:a}=$t(e&&n?[n,e]:null,Yt);return{data:r,isLoading:s,isValidating:a,error:o}},zt=()=>{const{data:e}=Le(),t=m.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),n=m.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:t,collectionsById:n}},Xt=()=>{const{data:e}=Le();return m.useMemo(()=>{const t=[],n={},r={};if(e!=null&&e.meta)for(const o of Object.values(e.meta.variableCollections)){t.push(...o.modes),n[o.id]=o.modes;for(const s of o.modes)r[s.modeId]=s}return{modes:t,modesByCollectionId:n,modesById:r}},[e])},Qt=()=>{const{token:e}=H();return e};function Zt(e,t){switch(t.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:t.payload};case"error":return{...e,status:"error",error:t.payload};default:return e}}const ue=e=>{const t={status:"idle",data:null,error:null},[n,r]=m.useReducer(Zt,t);return{mutate:m.useCallback(async s=>{r({type:"loading"});try{const a=await e(s);return r({type:"success",payload:a}),a}catch(a){r({type:"error",payload:a});return}},[e]),...n,isLoading:n.status==="loading",isSuccess:n.status==="success",isError:n.status==="error"}},ce=async(e,t,n,r)=>{if(!t)throw new Error(ne);const o=await fetch(e,{method:n,headers:{[rt]:t,"Content-Type":nt},...r&&{body:JSON.stringify(r)}});if(!o.ok){const s=await o.json();throw new Error(s.message||ot)}return o.status===204?Promise.resolve(void 0):o.json()},en=()=>{const{token:e}=H();if(!e)throw new Error(ne);return ue(async n=>await ce(et,e,"POST",n))},tn=()=>{const{token:e}=H();if(!e)throw new Error(ne);return ue(async n=>await ce(tt(n),e,"DELETE"))},nn=()=>{const{token:e}=H();return ue(async({variableId:n,payload:r})=>{if(!e)throw new Error("A Figma API token is required.");const o=tt(n);return await ce(o,e,"PUT",r)})},rn=()=>{const{token:e}=H();return ue(async n=>{if(!e)throw new Error(ne);return await ce(et,e,"PUT",n)})};function on(e,t){return e.filter(n=>{let r=!0;return t.resolvedType&&(r=r&&n.resolvedType===t.resolvedType),t.name&&(r=r&&n.name.includes(t.name)),r})}g.FigmaVarsProvider=mt,g.filterVariables=on,g.useBulkUpdateVariables=rn,g.useCreateVariable=en,g.useDeleteVariable=tn,g.useFigmaToken=Qt,g.useUpdateVariable=nn,g.useVariableCollections=zt,g.useVariableModes=Xt,g.useVariables=Le,Object.defineProperty(g,Symbol.toStringTag,{value:"Module"})});
17
+ */var xe;function mt(){return xe||(xe=1,process.env.NODE_ENV!=="production"&&function(){function e(u,m){return u===m&&(u!==0||1/u===1/m)||u!==u&&m!==m}function t(u,m){O||o.startTransition===void 0||(O=!0,console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));var l=m();if(!c){var I=m();s(l,I)||(console.error("The result of getSnapshot should be cached to avoid an infinite loop"),c=!0)}I=i({inst:{value:l,getSnapshot:m}});var a=I[0].inst,W=I[1];return S(function(){a.value=l,a.getSnapshot=m,n(a)&&W({inst:a})},[u,l,m]),E(function(){return n(a)&&W({inst:a}),u(function(){n(a)&&W({inst:a})})},[u]),D(l),l}function n(u){var m=u.getSnapshot;u=u.value;try{var l=m();return!s(u,l)}catch{return!0}}function r(u,m){return m()}typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());var o=p,s=typeof Object.is=="function"?Object.is:e,i=o.useState,E=o.useEffect,S=o.useLayoutEffect,D=o.useDebugValue,O=!1,c=!1,d=typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u"?r:t;me.useSyncExternalStore=o.useSyncExternalStore!==void 0?o.useSyncExternalStore:d,typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop=="function"&&__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error())}()),me}var Ue;function pt(){return Ue||(Ue=1,process.env.NODE_ENV==="production"?se.exports=Et():se.exports=mt()),se.exports}var ht=pt();const Ge=0,We=1,ke=2,qe=3;var Be=Object.prototype.hasOwnProperty;function pe(e,t){var n,r;if(e===t)return!0;if(e&&t&&(n=e.constructor)===t.constructor){if(n===Date)return e.getTime()===t.getTime();if(n===RegExp)return e.toString()===t.toString();if(n===Array){if((r=e.length)===t.length)for(;r--&&pe(e[r],t[r]););return r===-1}if(!n||typeof e=="object"){r=0;for(n in e)if(Be.call(e,n)&&++r&&!Be.call(t,n)||!(n in t)||!pe(e[n],t[n]))return!1;return Object.keys(t).length===r}}return e!==e&&t!==t}const P=new WeakMap,U=()=>{},R=U(),he=Object,f=e=>e===R,F=e=>typeof e=="function",G=(e,t)=>({...e,...t}),$e=e=>F(e.then),Se={},ie={},_e="undefined",te=typeof window!=_e,ve=typeof document!=_e,St=te&&"Deno"in window,_t=()=>te&&typeof window.requestAnimationFrame!=_e,He=(e,t)=>{const n=P.get(e);return[()=>!f(t)&&e.get(t)||Se,r=>{if(!f(t)){const o=e.get(t);t in ie||(ie[t]=o),n[5](t,G(o,r),o||Se)}},n[6],()=>!f(t)&&t in ie?ie[t]:!f(t)&&e.get(t)||Se]};let Oe=!0;const vt=()=>Oe,[we,Te]=te&&window.addEventListener?[window.addEventListener.bind(window),window.removeEventListener.bind(window)]:[U,U],Ot=()=>{const e=ve&&document.visibilityState;return f(e)||e!=="hidden"},wt=e=>(ve&&document.addEventListener("visibilitychange",e),we("focus",e),()=>{ve&&document.removeEventListener("visibilitychange",e),Te("focus",e)}),Tt=e=>{const t=()=>{Oe=!0,e()},n=()=>{Oe=!1};return we("online",t),we("offline",n),()=>{Te("online",t),Te("offline",n)}},yt={isOnline:vt,isVisible:Ot},gt={initFocus:wt,initReconnect:Tt},Ke=!p.useId,ne=!te||St,At=e=>_t()?window.requestAnimationFrame(e):setTimeout(e,1),ye=ne?p.useEffect:p.useLayoutEffect,ge=typeof navigator<"u"&&navigator.connection,Je=!ne&&ge&&(["slow-2g","2g"].includes(ge.effectiveType)||ge.saveData),ae=new WeakMap,Ae=(e,t)=>he.prototype.toString.call(e)===`[object ${t}]`;let Rt=0;const Re=e=>{const t=typeof e,n=Ae(e,"Date"),r=Ae(e,"RegExp"),o=Ae(e,"Object");let s,i;if(he(e)===e&&!n&&!r){if(s=ae.get(e),s)return s;if(s=++Rt+"~",ae.set(e,s),Array.isArray(e)){for(s="@",i=0;i<e.length;i++)s+=Re(e[i])+",";ae.set(e,s)}if(o){s="#";const E=he.keys(e).sort();for(;!f(i=E.pop());)f(e[i])||(s+=i+":"+Re(e[i])+",");ae.set(e,s)}}else s=n?e.toJSON():t=="symbol"?e.toString():t=="string"?JSON.stringify(e):""+e;return s},De=e=>{if(F(e))try{e=e()}catch{e=""}const t=e;return e=typeof e=="string"?e:(Array.isArray(e)?e.length:e)?Re(e):"",[e,t]};let Dt=0;const Ce=()=>++Dt;async function Ye(...e){const[t,n,r,o]=e,s=G({populateCache:!0,throwOnError:!0},typeof o=="boolean"?{revalidate:o}:o||{});let i=s.populateCache;const E=s.rollbackOnError;let S=s.optimisticData;const D=d=>typeof E=="function"?E(d):E!==!1,O=s.throwOnError;if(F(n)){const d=n,u=[],m=t.keys();for(const l of m)!/^\$(inf|sub)\$/.test(l)&&d(t.get(l)._k)&&u.push(l);return Promise.all(u.map(c))}return c(n);async function c(d){const[u]=De(d);if(!u)return;const[m,l]=He(t,u),[I,a,W,re]=P.get(t),k=()=>{const V=I[u];return(F(s.revalidate)?s.revalidate(m().data,d):s.revalidate!==!1)&&(delete W[u],delete re[u],V&&V[0])?V[0](ke).then(()=>m().data):m().data};if(e.length<3)return k();let g=r,b;const H=Ce();a[u]=[H,0];const v=!f(S),K=m(),M=K.data,J=K._c,q=f(J)?M:J;if(v&&(S=F(S)?S(q,M):S,l({data:S,_c:q})),F(g))try{g=g(q)}catch(V){b=V}if(g&&$e(g))if(g=await g.catch(V=>{b=V}),H!==a[u][0]){if(b)throw b;return g}else b&&v&&D(b)&&(i=!0,l({data:q,_c:R}));if(i&&!b)if(F(i)){const V=i(g,q);l({data:V,error:R,_c:R})}else l({data:g,error:R,_c:R});if(a[u][1]=Ce(),Promise.resolve(k()).then(()=>{l({_c:R})}),b){if(O)throw b;return}return g}}const ze=(e,t)=>{for(const n in e)e[n][0]&&e[n][0](t)},Ct=(e,t)=>{if(!P.has(e)){const n=G(gt,t),r=Object.create(null),o=Ye.bind(R,e);let s=U;const i=Object.create(null),E=(O,c)=>{const d=i[O]||[];return i[O]=d,d.push(c),()=>d.splice(d.indexOf(c),1)},S=(O,c,d)=>{e.set(O,c);const u=i[O];if(u)for(const m of u)m(c,d)},D=()=>{if(!P.has(e)&&(P.set(e,[r,Object.create(null),Object.create(null),Object.create(null),o,S,E]),!ne)){const O=n.initFocus(setTimeout.bind(R,ze.bind(R,r,Ge))),c=n.initReconnect(setTimeout.bind(R,ze.bind(R,r,We)));s=()=>{O&&O(),c&&c(),P.delete(e)}}};return D(),[e,o,D,s]}return[e,P.get(e)[4]]},It=(e,t,n,r,o)=>{const s=n.errorRetryCount,i=o.retryCount,E=~~((Math.random()+.5)*(1<<(i<8?i:8)))*n.errorRetryInterval;!f(s)&&i>s||setTimeout(r,E,o)},bt=pe,[Xe,Lt]=Ct(new Map),Vt=G({onLoadingSlow:U,onSuccess:U,onError:U,onErrorRetry:It,onDiscarded:U,revalidateOnFocus:!0,revalidateOnReconnect:!0,revalidateIfStale:!0,shouldRetryOnError:!0,errorRetryInterval:Je?1e4:5e3,focusThrottleInterval:5*1e3,dedupingInterval:2*1e3,loadingTimeout:Je?5e3:3e3,compare:bt,isPaused:()=>!1,cache:Xe,mutate:Lt,fallback:{}},yt),Nt=(e,t)=>{const n=G(e,t);if(t){const{use:r,fallback:o}=e,{use:s,fallback:i}=t;r&&s&&(n.use=r.concat(s)),o&&i&&(n.fallback=G(o,i))}return n},Ft=p.createContext({}),Mt="$inf$",Qe=te&&window.__SWR_DEVTOOLS_USE__,Pt=Qe?window.__SWR_DEVTOOLS_USE__:[],jt=()=>{Qe&&(window.__SWR_DEVTOOLS_REACT__=p)},xt=e=>F(e[1])?[e[0],e[1],e[2]||{}]:[e[0],null,(e[1]===null?e[2]:e[1])||{}],Ut=()=>G(Vt,p.useContext(Ft)),Gt=e=>(t,n,r)=>e(t,n&&((...s)=>{const[i]=De(t),[,,,E]=P.get(Xe);if(i.startsWith(Mt))return n(...s);const S=E[i];return f(S)?n(...s):(delete E[i],S)}),r),Wt=Pt.concat(Gt),kt=e=>function(...n){const r=Ut(),[o,s,i]=xt(n),E=Nt(r,i);let S=e;const{use:D}=E,O=(D||[]).concat(Wt);for(let c=O.length;c--;)S=O[c](S);return S(o,s||E.fetcher||null,E)},qt=(e,t,n)=>{const r=t[e]||(t[e]=[]);return r.push(n),()=>{const o=r.indexOf(n);o>=0&&(r[o]=r[r.length-1],r.pop())}};jt();const Ie=p.use||(e=>{switch(e.status){case"pending":throw e;case"fulfilled":return e.value;case"rejected":throw e.reason;default:throw e.status="pending",e.then(t=>{e.status="fulfilled",e.value=t},t=>{e.status="rejected",e.reason=t}),e}}),be={dedupe:!0},Bt=kt((e,t,n)=>{const{cache:r,compare:o,suspense:s,fallbackData:i,revalidateOnMount:E,revalidateIfStale:S,refreshInterval:D,refreshWhenHidden:O,refreshWhenOffline:c,keepPreviousData:d}=n,[u,m,l,I]=P.get(r),[a,W]=De(e),re=p.useRef(!1),k=p.useRef(!1),g=p.useRef(a),b=p.useRef(t),H=p.useRef(n),v=()=>H.current,K=()=>v().isVisible()&&v().isOnline(),[M,J,q,V]=He(r,a),Y=p.useRef({}).current,le=f(i)?f(n.fallback)?R:n.fallback[a]:i,rt=(_,h)=>{for(const A in Y){const w=A;if(w==="data"){if(!o(_[w],h[w])&&(!f(_[w])||!o(de,h[w])))return!1}else if(h[w]!==_[w])return!1}return!0},ot=p.useMemo(()=>{const _=!a||!t?!1:f(E)?v().isPaused()||s?!1:S!==!1:E,h=C=>{const j=G(C);return delete j._k,_?{isValidating:!0,isLoading:!0,...j}:j},A=M(),w=V(),N=h(A),Q=A===w?N:h(w);let T=N;return[()=>{const C=h(M());return rt(C,T)?(T.data=C.data,T.isLoading=C.isLoading,T.isValidating=C.isValidating,T.error=C.error,T):(T=C,C)},()=>Q]},[r,a]),z=ht.useSyncExternalStore(p.useCallback(_=>q(a,(h,A)=>{rt(A,h)||_()}),[r,a]),ot[0],ot[1]),st=!re.current,on=u[a]&&u[a].length>0,X=z.data,B=f(X)?le&&$e(le)?Ie(le):le:X,fe=z.error,Ne=p.useRef(B),de=d?f(X)?f(Ne.current)?B:Ne.current:X:B,it=on&&!f(fe)?!1:st&&!f(E)?E:v().isPaused()?!1:s?f(B)?!1:S:f(B)||S,at=!!(a&&t&&st&&it),sn=f(z.isValidating)?at:z.isValidating,an=f(z.isLoading)?at:z.isLoading,oe=p.useCallback(async _=>{const h=b.current;if(!a||!h||k.current||v().isPaused())return!1;let A,w,N=!0;const Q=_||{},T=!l[a]||!Q.dedupe,C=()=>Ke?!k.current&&a===g.current&&re.current:a===g.current,j={isValidating:!1,isLoading:!1},ct=()=>{J(j)},lt=()=>{const L=l[a];L&&L[1]===w&&delete l[a]},ft={isValidating:!0};f(M().data)&&(ft.isLoading=!0);try{if(T&&(J(ft),n.loadingTimeout&&f(M().data)&&setTimeout(()=>{N&&C()&&v().onLoadingSlow(a,n)},n.loadingTimeout),l[a]=[h(W),Ce()]),[A,w]=l[a],A=await A,T&&setTimeout(lt,n.dedupingInterval),!l[a]||l[a][1]!==w)return T&&C()&&v().onDiscarded(a),!1;j.error=R;const L=m[a];if(!f(L)&&(w<=L[0]||w<=L[1]||L[1]===0))return ct(),T&&C()&&v().onDiscarded(a),!1;const x=M().data;j.data=o(x,A)?x:A,T&&C()&&v().onSuccess(A,a,n)}catch(L){lt();const x=v(),{shouldRetryOnError:Fe}=x;x.isPaused()||(j.error=L,T&&C()&&(x.onError(L,a,x),(Fe===!0||F(Fe)&&Fe(L))&&(!v().revalidateOnFocus||!v().revalidateOnReconnect||K())&&x.onErrorRetry(L,a,x,un=>{const Me=u[a];Me&&Me[0]&&Me[0](qe,un)},{retryCount:(Q.retryCount||0)+1,dedupe:!0})))}return N=!1,ct(),!0},[a,r]),ut=p.useCallback((..._)=>Ye(r,g.current,..._),[]);if(ye(()=>{b.current=t,H.current=n,f(X)||(Ne.current=X)}),ye(()=>{if(!a)return;const _=oe.bind(R,be);let h=0;v().revalidateOnFocus&&(h=Date.now()+v().focusThrottleInterval);const w=qt(a,u,(N,Q={})=>{if(N==Ge){const T=Date.now();v().revalidateOnFocus&&T>h&&K()&&(h=T+v().focusThrottleInterval,_())}else if(N==We)v().revalidateOnReconnect&&K()&&_();else{if(N==ke)return oe();if(N==qe)return oe(Q)}});return k.current=!1,g.current=a,re.current=!0,J({_k:W}),it&&(f(B)||ne?_():At(_)),()=>{k.current=!0,w()}},[a]),ye(()=>{let _;function h(){const w=F(D)?D(M().data):D;w&&_!==-1&&(_=setTimeout(A,w))}function A(){!M().error&&(O||v().isVisible())&&(c||v().isOnline())?oe(be).then(h):h()}return h(),()=>{_&&(clearTimeout(_),_=-1)}},[D,O,c,a]),p.useDebugValue(de),s&&f(B)&&a){if(!Ke&&ne)throw new Error("Fallback data is required when using Suspense in SSR.");b.current=t,H.current=n,k.current=!1;const _=I[a];if(!f(_)){const h=ut(_);Ie(h)}if(f(fe)){const h=oe(be);f(de)||(h.status="fulfilled",h.value=!0),Ie(h)}else throw fe}return{mutate:ut,get data(){return Y.data=!0,de},get error(){return Y.error=!0,fe},get isValidating(){return Y.isValidating=!0,sn},get isLoading(){return Y.isLoading=!0,an}}}),Le="https://api.figma.com",$t=`${Le}/v1/files`,Ze=`${Le}/v1/variables`,et=Ze,tt=e=>`${Ze}/${e}`,Ht=e=>`${$t}/${e}/variables/local`,Kt="application/json",nt="X-FIGMA-TOKEN",$="A Figma API token is required.",Jt="An error occurred while fetching data from the Figma API.";async function Yt(e,t){if(!t)throw new Error($);const n=await fetch(e,{method:"GET",headers:{[nt]:t,"Content-Type":Kt}});if(!n.ok){let r=Jt;try{const o=await n.json();o!=null&&o.message&&(r=o.message)}catch{}throw new Error(r)}return n.json()}const Ve=()=>{const{token:e,fileKey:t}=ee(),n=t?Ht(t):null,{data:r,error:o,isLoading:s,isValidating:i,mutate:E}=Bt(e&&n?[n,e]:null,Yt);return{data:r,isLoading:s,isValidating:i,error:o,mutate:E}},zt=()=>{const{data:e}=Ve(),t=p.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),n=p.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:t,collectionsById:n}},Xt=()=>{const{data:e}=Ve();return p.useMemo(()=>{const t=[],n={},r={};if(e!=null&&e.meta)for(const o of Object.values(e.meta.variableCollections)){t.push(...o.modes),n[o.id]=o.modes;for(const s of o.modes)r[s.modeId]=s}return{modes:t,modesByCollectionId:n,modesById:r}},[e])};function Qt(e,t){switch(t.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:t.payload};case"error":return{...e,status:"error",error:t.payload};default:return e}}const ue=e=>{const t={status:"idle",data:null,error:null},[n,r]=p.useReducer(Qt,t);return{mutate:p.useCallback(async s=>{r({type:"loading"});try{const i=await e(s);return r({type:"success",payload:i}),i}catch(i){r({type:"error",payload:i});return}},[e]),...n,isLoading:n.status==="loading",isSuccess:n.status==="success",isError:n.status==="error"}};async function ce(e,t,n,r){if(!t)throw new Error($);const s={CREATE:"POST",UPDATE:"PUT",DELETE:"DELETE"}[n],i=await fetch(`${Le}${e}`,{method:s,headers:{"Content-Type":"application/json",[nt]:t},body:r?JSON.stringify(r):void 0});if(!i.ok){const E=await i.json().catch(()=>({}));throw new Error(E.err||E.message||"An API error occurred")}return i.status===204||!i.body?{}:i.json()}const Zt=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(et,e,"CREATE",n)})},en=()=>{const{token:e}=ee();return ue(async({variableId:n,payload:r})=>{if(!e)throw new Error($);const o=tt(n);return await ce(o,e,"UPDATE",r)})},tn=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(tt(n),e,"DELETE",void 0)})},nn=()=>{const{token:e}=ee();return ue(async n=>{if(!e)throw new Error($);return await ce(et,e,"CREATE",n)})};function rn(e,t){return e.filter(n=>{let r=!0;return t.resolvedType&&(r=r&&n.resolvedType===t.resolvedType),t.name&&(r=r&&n.name.includes(t.name)),r})}y.FigmaVarsProvider=dt,y.filterVariables=rn,y.useBulkUpdateVariables=nn,y.useCreateVariable=Zt,y.useDeleteVariable=tn,y.useUpdateVariable=en,y.useVariableCollections=zt,y.useVariableModes=Xt,y.useVariables=Ve,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Low-level utility to fetch data from the Figma Variables REST API with authentication.
3
+ *
4
+ * @remarks
5
+ * Sends an authenticated HTTP GET request to the given Figma API endpoint using the provided Personal Access Token (PAT).
6
+ * Parses JSON responses and throws detailed errors for failed requests.
7
+ * Intended for internal use by hooks but can be used directly for custom API interactions.
8
+ *
9
+ * @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
10
+ * @param token - Figma Personal Access Token (PAT) for authentication.
11
+ *
12
+ * @returns A Promise resolving to the parsed JSON response from the Figma API.
13
+ *
14
+ * @throws Throws an Error if the token is not provided.
15
+ * @throws Throws an Error if the HTTP response is not ok, including the message returned by the Figma API or a default error message.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { fetcher } from '@figma-vars/hooks/api';
20
+ *
21
+ * async function loadVariables(fileKey: string, token: string) {
22
+ * const url = `https://api.figma.com/v1/files/${fileKey}/variables`;
23
+ * const data = await fetcher(url, token);
24
+ * return data;
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function fetcher(url: string, token: string): Promise<any>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Barrel file for API utilities and mutators in @figma-vars/hooks.
4
+ *
5
+ * @summary
6
+ * Central entry point for all API-related utilities used to interact with the Figma Variables REST API.
7
+ *
8
+ * @remarks
9
+ * This module re-exports the core fetch and mutation functions that provide network communication and RESTful operations for Figma Variables.
10
+ * Import from here to access low-level API functions supporting hooks and other utilities.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { fetcher, mutator } from '@figma-vars/hooks/api';
15
+ *
16
+ * async function loadVariables() {
17
+ * const variables = await fetcher('/variables', 'YOUR_FIGMA_TOKEN');
18
+ * // process variables
19
+ * }
20
+ * ```
21
+ *
22
+ * @public
23
+ */
24
+ export { fetcher } from './fetcher';
25
+ export { mutator } from './mutator';
@@ -0,0 +1,33 @@
1
+ import { VariableAction } from '../types/mutations';
2
+ /**
3
+ * Low-level utility to send authenticated POST, PUT, or DELETE requests to the Figma Variables REST API.
4
+ *
5
+ * @remarks
6
+ * This function performs authenticated HTTP mutations (POST, PUT, DELETE) against the specified Figma API endpoint.
7
+ * It handles JSON serialization of the request body, parses JSON responses, and propagates detailed errors.
8
+ * Intended primarily for internal use by mutation hooks, but also suitable for direct custom API mutations.
9
+ *
10
+ * @typeParam T - The expected response type returned from the Figma API.
11
+ * @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
12
+ * @param token - Figma Personal Access Token (PAT) used for authentication.
13
+ * @param action - The action for the mutation: 'CREATE', 'UPDATE', or 'DELETE'.
14
+ * @param body - Optional request payload sent as a JSON string.
15
+ *
16
+ * @returns A Promise resolving to the parsed JSON response from the Figma API.
17
+ *
18
+ * @throws Throws an Error if the token is not provided.
19
+ * @throws Throws an Error if the HTTP response is unsuccessful, including the error message from the API or a default message.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { mutator } from '@figma-vars/hooks/api';
24
+ *
25
+ * async function updateVariable(fileKey: string, token: string, variableId: string) {
26
+ * const url = `https://api.figma.com/v1/files/${fileKey}/variables/${variableId}`;
27
+ * const payload = { name: 'Updated Name' };
28
+ * const result = await mutator(url, token, 'PUT', payload);
29
+ * return result;
30
+ * }
31
+ * ```
32
+ */
33
+ export declare function mutator(url: string, token: string, action: VariableAction, body?: any): Promise<any>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Constants and error messages used across the @figma-vars/hooks library.
4
+ *
5
+ * @remarks
6
+ * Includes base URLs for the Figma API, endpoint builders, HTTP content types, header keys, and consistent error message strings for various failure scenarios.
7
+ *
8
+ * Use these constants to ensure consistent API interaction and error handling throughout the library.
9
+ *
10
+ * @public
11
+ */
12
+ export declare const FIGMA_API_BASE_URL = "https://api.figma.com";
13
+ export declare const FIGMA_FILES_ENDPOINT = "https://api.figma.com/v1/files";
14
+ /**
15
+ * Builds the Figma Variables endpoint URL for a given file key.
16
+ *
17
+ * @param fileKey - The unique key of the Figma file.
18
+ * @returns The URL string to access variables in the specified file.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const url = FIGMA_VARIABLES_ENDPOINT('your-file-key')
23
+ * ```
24
+ */
25
+ export declare const FIGMA_VARIABLES_ENDPOINT: (fileKey: string) => string;
26
+ /**
27
+ * The base endpoint for creating new variables via POST requests.
28
+ */
29
+ export declare const FIGMA_POST_VARIABLES_ENDPOINT = "https://api.figma.com/v1/variables";
30
+ /**
31
+ * Builds the URL to access a specific Figma variable by its ID.
32
+ *
33
+ * @param variableId - The unique ID of the Figma variable.
34
+ * @returns The URL string to access the variable.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * const url = FIGMA_VARIABLE_BY_ID_ENDPOINT('variable-id')
39
+ * ```
40
+ */
41
+ export declare const FIGMA_VARIABLE_BY_ID_ENDPOINT: (variableId: string) => string;
42
+ /**
43
+ * Builds the URL to fetch local variables for a given Figma file.
44
+ *
45
+ * @param fileKey - The unique key of the Figma file.
46
+ * @returns The URL string to access local variables.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * const url = FIGMA_LOCAL_VARIABLES_ENDPOINT('your-file-key')
51
+ * ```
52
+ */
53
+ export declare const FIGMA_LOCAL_VARIABLES_ENDPOINT: (fileKey: string) => string;
54
+ /**
55
+ * The HTTP Content-Type header value for JSON requests.
56
+ */
57
+ export declare const CONTENT_TYPE_JSON = "application/json";
58
+ /**
59
+ * The HTTP header key used to pass the Figma Personal Access Token.
60
+ */
61
+ export declare const FIGMA_TOKEN_HEADER = "X-FIGMA-TOKEN";
62
+ /**
63
+ * Error message when no Figma API token is provided.
64
+ */
65
+ export declare const ERROR_MSG_TOKEN_REQUIRED = "A Figma API token is required.";
66
+ /**
67
+ * Error message when both the Figma API token and file key are missing.
68
+ */
69
+ export declare const ERROR_MSG_TOKEN_FILE_KEY_REQUIRED = "A Figma API token is required. and file key are required.";
70
+ /**
71
+ * Error message when a bulk update operation fails.
72
+ */
73
+ export declare const ERROR_MSG_BULK_UPDATE_FAILED = "Failed to perform bulk update.";
74
+ /**
75
+ * Error message when creating a Figma variable fails.
76
+ */
77
+ export declare const ERROR_MSG_CREATE_VARIABLE_FAILED = "Failed to create Figma variable.";
78
+ /**
79
+ * Error message when deleting a Figma variable fails.
80
+ */
81
+ export declare const ERROR_MSG_DELETE_VARIABLE_FAILED = "Failed to delete Figma variable.";
82
+ /**
83
+ * Error message when updating a Figma variable fails.
84
+ */
85
+ export declare const ERROR_MSG_UPDATE_VARIABLE_FAILED = "Failed to update Figma variable.";
86
+ /**
87
+ * Error message when fetching data from the Figma API fails.
88
+ */
89
+ export declare const ERROR_MSG_FETCH_FIGMA_DATA_FAILED = "An error occurred while fetching data from the Figma API.";
@@ -0,0 +1,56 @@
1
+ import { FigmaTokenContextType, FigmaVarsProviderProps } from '../types/contexts';
2
+ /**
3
+ * React context provider that supplies the Figma Personal Access Token and file key to all descendant components.
4
+ *
5
+ * @remarks
6
+ * Wrap your application or feature subtree with this provider to securely and type-safely provide the Figma Personal Access Token (PAT) and target Figma file key. This enables all child hooks and utilities to access the Figma Variables REST API with consistent authentication and scoping.
7
+ *
8
+ * This is the central source of truth for Figma authentication and file context within the app.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { FigmaVarsProvider } from '@figma-vars/hooks/contexts';
13
+ *
14
+ * function App() {
15
+ * return (
16
+ * <FigmaVarsProvider token={process.env.FIGMA_PAT!} fileKey="AbC123">
17
+ * <MyDashboard />
18
+ * </FigmaVarsProvider>
19
+ * );
20
+ * }
21
+ * ```
22
+ *
23
+ * @public
24
+ */
25
+ export declare const FigmaVarsProvider: ({ children, token, fileKey, }: FigmaVarsProviderProps) => import("react/jsx-runtime").JSX.Element;
26
+ /**
27
+ * React hook to access the current Figma Personal Access Token and file key from context.
28
+ *
29
+ * @remarks
30
+ * Retrieves the token and file key provided by the nearest `FigmaVarsProvider`.
31
+ * Throws a descriptive error if used outside of the provider to prevent silent failures.
32
+ *
33
+ * Use this hook in any component or hook that requires authenticated access to the Figma Variables API scoped to a file.
34
+ *
35
+ * @returns The current FigmaTokenContextType containing `{ token, fileKey }`.
36
+ *
37
+ * @throws Throws if called outside of a `FigmaVarsProvider` context.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * import { useFigmaTokenContext } from '@figma-vars/hooks/contexts';
42
+ *
43
+ * function DebugToken() {
44
+ * const { token, fileKey } = useFigmaTokenContext();
45
+ * return (
46
+ * <div>
47
+ * <p>Token: {token?.slice(0, 6)}... (hidden for security)</p>
48
+ * <p>File Key: {fileKey}</p>
49
+ * </div>
50
+ * );
51
+ * }
52
+ * ```
53
+ *
54
+ * @public
55
+ */
56
+ export declare const useFigmaTokenContext: () => FigmaTokenContextType;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Barrel file for React context providers and related hooks in @figma-vars/hooks.
4
+ *
5
+ * @remarks
6
+ * Re-exports the `FigmaVarsProvider` React context provider and the `useFigmaTokenContext` hook. Use this module to provide and access Figma API authentication and file scoping context throughout your app.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { FigmaVarsProvider, useFigmaTokenContext } from '@figma-vars/hooks';
11
+ *
12
+ * function App() {
13
+ * return (
14
+ * <FigmaVarsProvider token={process.env.FIGMA_PAT!} fileKey="your-file-key">
15
+ * <App />
16
+ * </FigmaVarsProvider>
17
+ * );
18
+ * }
19
+ * ```
20
+ */
21
+ export { FigmaVarsProvider, useFigmaTokenContext, } from './FigmaVarsProvider';
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @module hooks
3
+ * Barrel file for all Figma Variables React hooks.
4
+ *
5
+ * @remarks
6
+ * Re-exports all hooks for convenient importing.
7
+ *
8
+ * @public
9
+ */
10
+ /**
11
+ * React hook to fetch all local variables, collections, and modes for the current Figma file.
12
+ *
13
+ * @remarks
14
+ * Uses SWR for efficient data fetching and caching.
15
+ *
16
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { useVariables } from '@figma-vars/hooks';
21
+ * const { data, isLoading } = useVariables();
22
+ * ```
23
+ *
24
+ * @public
25
+ */
26
+ export { useVariables } from './useVariables';
27
+ /**
28
+ * React hook to select and memoize variable collections from the loaded Figma variables data.
29
+ *
30
+ * @remarks
31
+ * Returns collections in both array and lookup formats for convenience.
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * import { useVariableCollections } from '@figma-vars/hooks';
36
+ * const { collections } = useVariableCollections();
37
+ * ```
38
+ *
39
+ * @public
40
+ */
41
+ export { useVariableCollections } from './useVariableCollections';
42
+ /**
43
+ * React hook to select and memoize variable modes from the loaded Figma variables data.
44
+ *
45
+ * @remarks
46
+ * Returns all modes, modes by collection, and modes by ID for efficient access.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * import { useVariableModes } from '@figma-vars/hooks';
51
+ * const { modes, modesById } = useVariableModes();
52
+ * ```
53
+ *
54
+ * @public
55
+ */
56
+ export { useVariableModes } from './useVariableModes';
57
+ /**
58
+ * React hook to access the Figma Personal Access Token from context.
59
+ *
60
+ * @remarks
61
+ * Returns the token provided to the FigmaVarsProvider, or null if not available.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * import { useFigmaToken } from '@figma-vars/hooks';
66
+ * const token = useFigmaToken();
67
+ * ```
68
+ *
69
+ * @public
70
+ */
71
+ export { default as useFigmaToken } from './useFigmaToken';
72
+ /**
73
+ * React hook to create a new Figma variable in the current file.
74
+ *
75
+ * @remarks
76
+ * Returns a mutation object with state, error, and a trigger function.
77
+ *
78
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
79
+ *
80
+ * @example
81
+ * ```tsx
82
+ * import { useCreateVariable } from '@figma-vars/hooks';
83
+ * const { mutate, isLoading } = useCreateVariable();
84
+ * // mutate({ name: 'Primary Color', ... })
85
+ * ```
86
+ *
87
+ * @public
88
+ */
89
+ export { useCreateVariable } from './useCreateVariable';
90
+ /**
91
+ * React hook to update an existing Figma variable by ID.
92
+ *
93
+ * @remarks
94
+ * Returns a mutation object for updating variable properties.
95
+ *
96
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
97
+ *
98
+ * @example
99
+ * ```tsx
100
+ * import { useUpdateVariable } from '@figma-vars/hooks';
101
+ * const { mutate } = useUpdateVariable();
102
+ * // mutate({ variableId: 'id', payload: { name: 'Updated' } })
103
+ * ```
104
+ *
105
+ * @public
106
+ */
107
+ export { useUpdateVariable } from './useUpdateVariable';
108
+ /**
109
+ * React hook to delete a Figma variable by ID.
110
+ *
111
+ * @remarks
112
+ * Returns a mutation object for deleting variables.
113
+ *
114
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * import { useDeleteVariable } from '@figma-vars/hooks';
119
+ * const { mutate } = useDeleteVariable();
120
+ * // mutate('variable-id')
121
+ * ```
122
+ *
123
+ * @public
124
+ */
125
+ export { useDeleteVariable } from './useDeleteVariable';
126
+ /**
127
+ * React hook to perform a bulk update of multiple Figma variables in a single request.
128
+ *
129
+ * @remarks
130
+ * Returns a mutation object for bulk updates.
131
+ *
132
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
133
+ *
134
+ * @example
135
+ * ```tsx
136
+ * import { useBulkUpdateVariables } from '@figma-vars/hooks';
137
+ * const { mutate } = useBulkUpdateVariables();
138
+ * // mutate({ variableIds: [...], updates: {...} })
139
+ * ```
140
+ *
141
+ * @public
142
+ */
143
+ export { useBulkUpdateVariables } from './useBulkUpdateVariables';
@@ -0,0 +1,46 @@
1
+ import { BulkUpdatePayload } from '../types/mutations';
2
+ /**
3
+ * React hook that performs a bulk update of multiple Figma variables in a single request via the Figma Variables API.
4
+ *
5
+ * @remarks
6
+ * Returns a mutation object with status flags and error info.
7
+ * Call `mutate(payload)` with a `BulkUpdatePayload` object to trigger the update—`payload` must include:
8
+ * - `variableIds`: array of Figma variable IDs to update
9
+ * - `variableCollectionId`: the collection context for the update
10
+ * - `updates`: an object mapping variable IDs to their updated values or properties
11
+ *
12
+ * The hook throws if the Figma Personal Access Token (PAT) is missing from context.
13
+ * Use for advanced workflows requiring atomic, multi-variable updates.
14
+ *
15
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { useBulkUpdateVariables } from '@figma-vars/hooks';
20
+ *
21
+ * function BulkUpdateComponent() {
22
+ * const { mutate, isLoading, isSuccess, error } = useBulkUpdateVariables();
23
+ *
24
+ * const handleBulkUpdate = () => {
25
+ * mutate({
26
+ * variableIds: ['VariableID:123:456', 'VariableID:123:457'],
27
+ * variableCollectionId: 'VariableCollectionId:123:456',
28
+ * updates: {
29
+ * 'VariableID:123:456': { name: 'Primary Color Updated' },
30
+ * 'VariableID:123:457': { name: 'Secondary Color Updated' }
31
+ * }
32
+ * });
33
+ * };
34
+ *
35
+ * if (!mutate) return <div>Not authorized. Figma token missing.</div>;
36
+ * if (isLoading) return <div>Updating variables…</div>;
37
+ * if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
38
+ * if (isSuccess) return <div>Variables updated successfully!</div>;
39
+ *
40
+ * return <button onClick={handleBulkUpdate}>Update All Variables</button>;
41
+ * }
42
+ * ```
43
+ *
44
+ * @public
45
+ */
46
+ export declare const useBulkUpdateVariables: () => import('../types/mutations').MutationResult<any, BulkUpdatePayload>;
@@ -0,0 +1,45 @@
1
+ import { CreateVariablePayload } from '../types/mutations';
2
+ /**
3
+ * React hook that creates a new Figma variable in the current file using the Figma Variables API.
4
+ *
5
+ * @remarks
6
+ * Returns a mutation object with status flags and error info. To trigger creation, call `mutate(payload)` with a `CreateVariablePayload` object containing:
7
+ * - `name`: the variable name
8
+ * - `variableCollectionId`: target collection ID
9
+ * - `resolvedType`: variable type
10
+ * - `valuesByMode`: values for one or more modes
11
+ *
12
+ * Throws if the Figma Personal Access Token (PAT) is missing from context.
13
+ * Use for advanced workflows, automated variable management, or custom UI tooling.
14
+ *
15
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { useCreateVariable } from '@figma-vars/hooks';
20
+ *
21
+ * function CreateVariableComponent() {
22
+ * const { mutate, isLoading, isSuccess, error } = useCreateVariable();
23
+ *
24
+ * const handleCreate = () => {
25
+ * mutate({
26
+ * name: 'Primary Color',
27
+ * variableCollectionId: 'VariableCollectionId:123:456',
28
+ * resolvedType: 'COLOR',
29
+ * valuesByMode: {
30
+ * '42:0': { r: 0.2, g: 0.4, b: 0.8, a: 1 }
31
+ * }
32
+ * });
33
+ * };
34
+ *
35
+ * if (isLoading) return <div>Creating variable…</div>;
36
+ * if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
37
+ * if (isSuccess) return <div>Variable created successfully!</div>;
38
+ *
39
+ * return <button onClick={handleCreate}>Create Variable</button>;
40
+ * }
41
+ * ```
42
+ *
43
+ * @public
44
+ */
45
+ export declare const useCreateVariable: () => import('../types/mutations').MutationResult<any, CreateVariablePayload>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * React hook that deletes a Figma variable by ID using the Figma Variables API.
3
+ *
4
+ * @remarks
5
+ * Returns a mutation object with status flags and error info. To trigger deletion, call `mutate(variableId)` with the variable's ID as a string.
6
+ * Throws if the Figma Personal Access Token (PAT) is missing from context.
7
+ * Use this for advanced workflows, admin tooling, or custom variable management UIs.
8
+ *
9
+ * @see {@link https://www.figma.com/developers/api#variables | Figma Variables API}
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { useDeleteVariable } from '@figma-vars/hooks';
14
+ *
15
+ * function DeleteVariableButton({ variableId }: { variableId: string }) {
16
+ * const { mutate, isLoading, isSuccess, error } = useDeleteVariable();
17
+ *
18
+ * const handleDelete = () => {
19
+ * mutate(variableId); // variableId must be a string
20
+ * };
21
+ *
22
+ * if (!mutate) return <div>Not authorized. Figma token missing.</div>;
23
+ * if (isLoading) return <div>Deleting variable…</div>;
24
+ * if (error) return <div style={{ color: 'red' }}>Error: {error.message}</div>;
25
+ * if (isSuccess) return <div>Variable deleted successfully!</div>;
26
+ *
27
+ * return <button onClick={handleDelete}>Delete Variable</button>;
28
+ * }
29
+ * ```
30
+ *
31
+ * @public
32
+ */
33
+ export declare const useDeleteVariable: () => import('..').MutationResult<any, string>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * React hook that provides access to the Figma Personal Access Token (PAT) from context.
3
+ *
4
+ * @remarks
5
+ * Returns the PAT provided to the FigmaVarsProvider, or `null` if no token is available. Use this hook to authenticate API requests, secure routes, or prompt users to enter their token if missing. Centralizes Figma authentication for all hooks and utilities.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { useFigmaToken } from '@figma-vars/hooks';
10
+ *
11
+ * function AuthStatus() {
12
+ * const token = useFigmaToken();
13
+ * if (!token) return <div>Please provide a Figma API token.</div>;
14
+ * return <div>Token available.</div>;
15
+ * }
16
+ * ```
17
+ *
18
+ * @public
19
+ */
20
+ declare const useFigmaToken: () => string | null;
21
+ export default useFigmaToken;