@figma-vars/hooks 3.0.0 → 3.1.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 +50 -0
- package/dist/api/fetcher.d.ts +32 -1
- package/dist/api/fetcher.d.ts.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/mutator.d.ts +27 -1
- package/dist/api/mutator.d.ts.map +1 -1
- package/dist/contexts/FigmaVarsProvider.d.ts +2 -0
- package/dist/contexts/FigmaVarsProvider.d.ts.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.mjs +1 -1
- package/dist/hooks/index.d.ts +45 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useCollectionById.d.ts +31 -0
- package/dist/hooks/useCollectionById.d.ts.map +1 -0
- package/dist/hooks/useInvalidateVariables.d.ts +3 -0
- package/dist/hooks/useInvalidateVariables.d.ts.map +1 -1
- package/dist/hooks/useModesByCollection.d.ts +34 -0
- package/dist/hooks/useModesByCollection.d.ts.map +1 -0
- package/dist/hooks/usePublishedVariables.d.ts.map +1 -1
- package/dist/hooks/useVariableById.d.ts +31 -0
- package/dist/hooks/useVariableById.d.ts.map +1 -0
- package/dist/hooks/useVariables.d.ts.map +1 -1
- package/dist/index-5ZyKWuYv.cjs +1 -0
- package/dist/index-ClHLYVvu.js +142 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +250 -167
- package/dist/types/contexts.d.ts +1 -0
- package/dist/types/contexts.d.ts.map +1 -1
- package/dist/types/figma.d.ts +9 -1
- package/dist/types/figma.d.ts.map +1 -1
- package/dist/types/mutations.d.ts +14 -0
- package/dist/types/mutations.d.ts.map +1 -1
- package/dist/utils/errorHelpers.d.ts +46 -0
- package/dist/utils/errorHelpers.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/swrKeys.d.ts +24 -0
- package/dist/utils/swrKeys.d.ts.map +1 -0
- package/dist/utils/typeGuards.d.ts +50 -0
- package/dist/utils/typeGuards.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/index-BIUpDTdr.cjs +0 -1
- package/dist/index-Cd4HQQHO.js +0 -94
package/README.md
CHANGED
|
@@ -254,6 +254,53 @@ function VariableEditor() {
|
|
|
254
254
|
|
|
255
255
|
## 🛡️ Error Handling
|
|
256
256
|
|
|
257
|
+
### Error Boundaries (Recommended)
|
|
258
|
+
|
|
259
|
+
Wrap your Figma-connected components with an error boundary to gracefully handle errors:
|
|
260
|
+
|
|
261
|
+
```tsx
|
|
262
|
+
import { ErrorBoundary } from 'react-error-boundary'
|
|
263
|
+
import { FigmaVarsProvider } from '@figma-vars/hooks'
|
|
264
|
+
|
|
265
|
+
function FigmaErrorFallback({ error }: { error: Error }) {
|
|
266
|
+
return (
|
|
267
|
+
<div role='alert'>
|
|
268
|
+
<h2>Failed to load Figma data</h2>
|
|
269
|
+
<pre>{error.message}</pre>
|
|
270
|
+
</div>
|
|
271
|
+
)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function App() {
|
|
275
|
+
return (
|
|
276
|
+
<ErrorBoundary FallbackComponent={FigmaErrorFallback}>
|
|
277
|
+
<FigmaVarsProvider
|
|
278
|
+
token={FIGMA_TOKEN}
|
|
279
|
+
fileKey={FIGMA_FILE_KEY}>
|
|
280
|
+
<YourApp />
|
|
281
|
+
</FigmaVarsProvider>
|
|
282
|
+
</ErrorBoundary>
|
|
283
|
+
)
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
> **Note:** The provider validates fallback file structure at runtime and logs warnings in development. Invalid fallback data won't crash the app but will result in `undefined` data.
|
|
288
|
+
|
|
289
|
+
### Runtime Validation
|
|
290
|
+
|
|
291
|
+
Use type guards to validate data at runtime:
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
import { isLocalVariablesResponse, isPublishedVariablesResponse } from '@figma-vars/hooks'
|
|
295
|
+
|
|
296
|
+
// Validate before using
|
|
297
|
+
if (isLocalVariablesResponse(data)) {
|
|
298
|
+
// Safe to access data.meta.variables
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Error Utilities
|
|
303
|
+
|
|
257
304
|
3.0.0 introduces powerful error handling utilities for type-safe error checking:
|
|
258
305
|
|
|
259
306
|
```tsx
|
|
@@ -371,6 +418,7 @@ Customize SWR behavior globally through the provider:
|
|
|
371
418
|
### Hooks
|
|
372
419
|
|
|
373
420
|
- **Queries**: `useVariables` (local), `usePublishedVariables` (library/published), `useVariableCollections`, `useVariableModes`, `useFigmaToken`
|
|
421
|
+
- **Granular Selectors**: `useCollectionById`, `useModesByCollection`, `useVariableById` (optimized selectors for specific entities)
|
|
374
422
|
- **Mutations**: `useCreateVariable`, `useUpdateVariable`, `useDeleteVariable`, `useBulkUpdateVariables`
|
|
375
423
|
- **Cache**: `useInvalidateVariables` (invalidate/revalidate cache)
|
|
376
424
|
|
|
@@ -378,6 +426,8 @@ Customize SWR behavior globally through the provider:
|
|
|
378
426
|
|
|
379
427
|
- **Filtering**: `filterVariables` (filter by type, name, etc.)
|
|
380
428
|
- **Error Handling**: `isFigmaApiError`, `getErrorStatus`, `getErrorMessage`, `hasErrorStatus`
|
|
429
|
+
- **Type Guards**: `isLocalVariablesResponse`, `isPublishedVariablesResponse`, `validateFallbackData` (runtime validation)
|
|
430
|
+
- **SWR Keys**: `getVariablesKey`, `getPublishedVariablesKey`, `getInvalidationKeys` (centralized cache key construction)
|
|
381
431
|
- **Core helpers**: `fetcher`, `mutator`, constants for endpoints and headers
|
|
382
432
|
|
|
383
433
|
### Types
|
package/dist/api/fetcher.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring fetcher behavior.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface FetcherOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Optional AbortSignal to cancel the request.
|
|
9
|
+
*/
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
/**
|
|
12
|
+
* Optional timeout in milliseconds. Creates an AbortSignal internally if provided.
|
|
13
|
+
*/
|
|
14
|
+
timeout?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Optional fetch implementation override (useful for testing or custom fetch implementations).
|
|
17
|
+
*/
|
|
18
|
+
fetch?: typeof fetch;
|
|
19
|
+
}
|
|
1
20
|
/**
|
|
2
21
|
* Low-level utility to fetch data from the Figma Variables REST API with authentication.
|
|
3
22
|
*
|
|
@@ -6,13 +25,17 @@
|
|
|
6
25
|
* Parses JSON responses and throws detailed errors for failed requests.
|
|
7
26
|
* Intended for internal use by hooks but can be used directly for custom API interactions.
|
|
8
27
|
*
|
|
28
|
+
* Supports request cancellation via AbortSignal and timeout handling.
|
|
29
|
+
*
|
|
9
30
|
* @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
|
|
10
31
|
* @param token - Figma Personal Access Token (PAT) for authentication.
|
|
32
|
+
* @param options - Optional configuration for abort signal, timeout, or custom fetch implementation.
|
|
11
33
|
*
|
|
12
34
|
* @returns A Promise resolving to the parsed JSON response from the Figma API.
|
|
13
35
|
*
|
|
14
36
|
* @throws Throws an Error if the token is not provided.
|
|
15
37
|
* @throws Throws an Error if the HTTP response is not ok, including the message returned by the Figma API or a default error message.
|
|
38
|
+
* @throws Throws an AbortError if the request is aborted or times out.
|
|
16
39
|
*
|
|
17
40
|
* @example
|
|
18
41
|
* ```ts
|
|
@@ -23,7 +46,15 @@
|
|
|
23
46
|
* const data = await fetcher(url, token);
|
|
24
47
|
* return data;
|
|
25
48
|
* }
|
|
49
|
+
*
|
|
50
|
+
* // With timeout:
|
|
51
|
+
* const data = await fetcher(url, token, { timeout: 5000 });
|
|
52
|
+
*
|
|
53
|
+
* // With abort signal:
|
|
54
|
+
* const controller = new AbortController();
|
|
55
|
+
* const data = await fetcher(url, token, { signal: controller.signal });
|
|
56
|
+
* controller.abort(); // Cancel the request
|
|
26
57
|
* ```
|
|
27
58
|
*/
|
|
28
|
-
export declare function fetcher<TResponse = unknown>(url: string, token: string): Promise<TResponse>;
|
|
59
|
+
export declare function fetcher<TResponse = unknown>(url: string, token: string, options?: FetcherOptions): Promise<TResponse>;
|
|
29
60
|
//# sourceMappingURL=fetcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/api/fetcher.ts"],"names":[],"mappings":"AAWA
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/api/fetcher.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAsB,OAAO,CAAC,SAAS,GAAG,OAAO,EAC/C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,SAAS,CAAC,CA0FpB"}
|
package/dist/api/index.d.ts
CHANGED
package/dist/api/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/api/mutator.d.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { VariableAction, BulkUpdatePayload } from '../types/mutations.js';
|
|
2
|
+
/**
|
|
3
|
+
* Options for configuring mutator behavior.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export interface MutatorOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Optional AbortSignal to cancel the request.
|
|
10
|
+
*/
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
/**
|
|
13
|
+
* Optional timeout in milliseconds. Creates an AbortSignal internally if provided.
|
|
14
|
+
*/
|
|
15
|
+
timeout?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Optional fetch implementation override (useful for testing or custom fetch implementations).
|
|
18
|
+
*/
|
|
19
|
+
fetch?: typeof fetch;
|
|
20
|
+
}
|
|
2
21
|
/**
|
|
3
22
|
* Low-level utility to send authenticated POST, PUT, or DELETE requests to the Figma Variables REST API.
|
|
4
23
|
*
|
|
@@ -7,15 +26,19 @@ import { VariableAction, BulkUpdatePayload } from '../types/mutations.js';
|
|
|
7
26
|
* It handles JSON serialization of the request body, parses JSON responses, and propagates detailed errors.
|
|
8
27
|
* Intended primarily for internal use by mutation hooks, but also suitable for direct custom API mutations.
|
|
9
28
|
*
|
|
29
|
+
* Supports request cancellation via AbortSignal and timeout handling.
|
|
30
|
+
*
|
|
10
31
|
* @typeParam TResponse - The expected response type returned from the Figma API.
|
|
11
32
|
* @param url - The full Figma REST API endpoint URL (e.g., 'https://api.figma.com/v1/files/{file_key}/variables').
|
|
12
33
|
* @param token - Figma Personal Access Token (PAT) used for authentication.
|
|
13
34
|
* @param action - The action for the mutation: 'CREATE', 'UPDATE', or 'DELETE'.
|
|
14
35
|
* @param body - Optional request payload. For bulk operations, use BulkUpdatePayload. For individual operations, use objects with `variables` array.
|
|
36
|
+
* @param options - Optional configuration for abort signal, timeout, or custom fetch implementation.
|
|
15
37
|
*
|
|
16
38
|
* @returns A Promise resolving to the parsed JSON response from the Figma API.
|
|
17
39
|
*
|
|
18
40
|
* @throws Throws a FigmaApiError if the token is not provided or if the HTTP response is unsuccessful.
|
|
41
|
+
* @throws Throws an AbortError if the request is aborted or times out.
|
|
19
42
|
*
|
|
20
43
|
* @example
|
|
21
44
|
* ```ts
|
|
@@ -27,9 +50,12 @@ import { VariableAction, BulkUpdatePayload } from '../types/mutations.js';
|
|
|
27
50
|
* const result = await mutator(url, token, 'UPDATE', payload);
|
|
28
51
|
* return result;
|
|
29
52
|
* }
|
|
53
|
+
*
|
|
54
|
+
* // With timeout:
|
|
55
|
+
* const result = await mutator(url, token, 'UPDATE', payload, { timeout: 5000 });
|
|
30
56
|
* ```
|
|
31
57
|
*/
|
|
32
58
|
export declare function mutator<TResponse = unknown>(url: string, token: string, action: VariableAction, body?: BulkUpdatePayload | {
|
|
33
59
|
variables?: Array<Record<string, unknown>>;
|
|
34
|
-
} | Record<string, unknown
|
|
60
|
+
} | Record<string, unknown>, options?: MutatorOptions): Promise<TResponse>;
|
|
35
61
|
//# sourceMappingURL=mutator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutator.d.ts","sourceRoot":"","sources":["../../src/api/mutator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3E
|
|
1
|
+
{"version":3,"file":"mutator.d.ts","sourceRoot":"","sources":["../../src/api/mutator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3E;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,OAAO,CAAC,SAAS,GAAG,OAAO,EAC/C,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,EACtB,IAAI,CAAC,EACD,iBAAiB,GACjB;IAAE,SAAS,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE,GAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,SAAS,CAAC,CAyGpB"}
|
|
@@ -7,6 +7,8 @@ import { FigmaVarsProviderProps } from '../types/contexts';
|
|
|
7
7
|
*
|
|
8
8
|
* This is the central source of truth for Figma authentication and file context within the app.
|
|
9
9
|
*
|
|
10
|
+
* Fallback JSON files are parsed once during provider initialization to avoid repeated parsing and provide early validation.
|
|
11
|
+
*
|
|
10
12
|
* @example
|
|
11
13
|
* ```tsx
|
|
12
14
|
* import { FigmaVarsProvider } from '@figma-vars/hooks/contexts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FigmaVarsProvider.d.ts","sourceRoot":"","sources":["../../src/contexts/FigmaVarsProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"FigmaVarsProvider.d.ts","sourceRoot":"","sources":["../../src/contexts/FigmaVarsProvider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,gBAAgB,CAAA;AAIvB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,iBAAiB,GAAI,wDAM/B,sBAAsB,4CAqFxB,CAAA"}
|
package/dist/core.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./index-5ZyKWuYv.cjs");exports.CONTENT_TYPE_JSON=_.CONTENT_TYPE_JSON;exports.ERROR_MSG_BULK_UPDATE_FAILED=_.ERROR_MSG_BULK_UPDATE_FAILED;exports.ERROR_MSG_CREATE_VARIABLE_FAILED=_.ERROR_MSG_CREATE_VARIABLE_FAILED;exports.ERROR_MSG_DELETE_VARIABLE_FAILED=_.ERROR_MSG_DELETE_VARIABLE_FAILED;exports.ERROR_MSG_FETCH_FIGMA_DATA_FAILED=_.ERROR_MSG_FETCH_FIGMA_DATA_FAILED;exports.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED=_.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED;exports.ERROR_MSG_TOKEN_REQUIRED=_.ERROR_MSG_TOKEN_REQUIRED;exports.ERROR_MSG_UPDATE_VARIABLE_FAILED=_.ERROR_MSG_UPDATE_VARIABLE_FAILED;exports.FIGMA_API_BASE_URL=_.FIGMA_API_BASE_URL;exports.FIGMA_FILES_ENDPOINT=_.FIGMA_FILES_ENDPOINT;exports.FIGMA_FILE_VARIABLES_PATH=_.FIGMA_FILE_VARIABLES_PATH;exports.FIGMA_LOCAL_VARIABLES_ENDPOINT=_.FIGMA_LOCAL_VARIABLES_ENDPOINT;exports.FIGMA_PUBLISHED_VARIABLES_PATH=_.FIGMA_PUBLISHED_VARIABLES_PATH;exports.FIGMA_TOKEN_HEADER=_.FIGMA_TOKEN_HEADER;exports.fetcher=_.fetcher;exports.filterVariables=_.filterVariables;exports.mutator=_.mutator;
|
package/dist/core.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as A, j as R, k as I, l as a, o as L, a as s, E as F, n as T,
|
|
1
|
+
import { C as A, j as R, k as I, l as a, o as L, a as s, E as F, n as T, d as D, e as O, F as G, h as M, g as S, i as N, f as B, c as P, m as U } from "./index-ClHLYVvu.js";
|
|
2
2
|
export {
|
|
3
3
|
A as CONTENT_TYPE_JSON,
|
|
4
4
|
R as ERROR_MSG_BULK_UPDATE_FAILED,
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -160,4 +160,49 @@ export { useInvalidateVariables } from './useInvalidateVariables';
|
|
|
160
160
|
* @public
|
|
161
161
|
*/
|
|
162
162
|
export { usePublishedVariables } from './usePublishedVariables';
|
|
163
|
+
/**
|
|
164
|
+
* React hook to select a single variable by ID from loaded Figma variables data.
|
|
165
|
+
*
|
|
166
|
+
* @remarks
|
|
167
|
+
* Returns the variable with the specified ID, or undefined if not found.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```tsx
|
|
171
|
+
* import { useVariableById } from '@figma-vars/hooks';
|
|
172
|
+
* const variable = useVariableById('VariableID:123:456');
|
|
173
|
+
* ```
|
|
174
|
+
*
|
|
175
|
+
* @public
|
|
176
|
+
*/
|
|
177
|
+
export { useVariableById } from './useVariableById';
|
|
178
|
+
/**
|
|
179
|
+
* React hook to select a single variable collection by ID from loaded Figma variables data.
|
|
180
|
+
*
|
|
181
|
+
* @remarks
|
|
182
|
+
* Returns the collection with the specified ID, or undefined if not found.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```tsx
|
|
186
|
+
* import { useCollectionById } from '@figma-vars/hooks';
|
|
187
|
+
* const collection = useCollectionById('VariableCollectionId:123:456');
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @public
|
|
191
|
+
*/
|
|
192
|
+
export { useCollectionById } from './useCollectionById';
|
|
193
|
+
/**
|
|
194
|
+
* React hook to select modes for a specific variable collection.
|
|
195
|
+
*
|
|
196
|
+
* @remarks
|
|
197
|
+
* Returns an array of modes belonging to the specified collection.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```tsx
|
|
201
|
+
* import { useModesByCollection } from '@figma-vars/hooks';
|
|
202
|
+
* const modes = useModesByCollection('VariableCollectionId:123:456');
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* @public
|
|
206
|
+
*/
|
|
207
|
+
export { useModesByCollection } from './useModesByCollection';
|
|
163
208
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC9D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC9D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACrE;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FigmaCollection } from 'types';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that selects a single variable collection by ID from loaded Figma variables data.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Returns the collection with the specified ID, or `undefined` if not found.
|
|
7
|
+
* Useful for accessing a specific collection without manually mapping through all collections.
|
|
8
|
+
*
|
|
9
|
+
* @param collectionId - The ID of the collection to retrieve.
|
|
10
|
+
* @returns The collection object, or `undefined` if not found.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { useCollectionById } from '@figma-vars/hooks';
|
|
15
|
+
*
|
|
16
|
+
* function CollectionDetails({ collectionId }: { collectionId: string }) {
|
|
17
|
+
* const collection = useCollectionById(collectionId);
|
|
18
|
+
*
|
|
19
|
+
* if (!collection) return <div>Collection not found</div>;
|
|
20
|
+
*
|
|
21
|
+
* return <div>
|
|
22
|
+
* <h2>{collection.name}</h2>
|
|
23
|
+
* <p>Variables: {collection.variableIds.length}</p>
|
|
24
|
+
* </div>;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare const useCollectionById: (collectionId: string) => FigmaCollection | undefined;
|
|
31
|
+
//# sourceMappingURL=useCollectionById.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCollectionById.d.ts","sourceRoot":"","sources":["../../src/hooks/useCollectionById.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,iBAAiB,GAC5B,cAAc,MAAM,KACnB,eAAe,GAAG,SAMpB,CAAA"}
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* Returns functions to invalidate and revalidate SWR cache for variables hooks.
|
|
6
6
|
* Use this after mutations to ensure fresh data is fetched.
|
|
7
7
|
*
|
|
8
|
+
* Supports both live API usage (with token and fileKey) and fallback-only usage
|
|
9
|
+
* (with fallbackFile but no fileKey).
|
|
10
|
+
*
|
|
8
11
|
* @returns Object with `invalidate` and `revalidate` functions.
|
|
9
12
|
*
|
|
10
13
|
* @example
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInvalidateVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useInvalidateVariables.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"useInvalidateVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useInvalidateVariables.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,sBAAsB;;;CAoDlC,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { VariableMode } from 'types';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that selects modes for a specific variable collection.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Returns an array of modes belonging to the specified collection, or an empty array if not found.
|
|
7
|
+
* Useful for filtering modes by collection without manually accessing modesByCollectionId.
|
|
8
|
+
*
|
|
9
|
+
* @param collectionId - The ID of the collection to get modes for.
|
|
10
|
+
* @returns An array of VariableMode objects for the collection, or an empty array if not found.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { useModesByCollection } from '@figma-vars/hooks';
|
|
15
|
+
*
|
|
16
|
+
* function CollectionModes({ collectionId }: { collectionId: string }) {
|
|
17
|
+
* const modes = useModesByCollection(collectionId);
|
|
18
|
+
*
|
|
19
|
+
* if (!modes.length) return <div>No modes found</div>;
|
|
20
|
+
*
|
|
21
|
+
* return (
|
|
22
|
+
* <ul>
|
|
23
|
+
* {modes.map(mode => (
|
|
24
|
+
* <li key={mode.modeId}>{mode.name}</li>
|
|
25
|
+
* ))}
|
|
26
|
+
* </ul>
|
|
27
|
+
* );
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export declare const useModesByCollection: (collectionId: string) => VariableMode[];
|
|
34
|
+
//# sourceMappingURL=useModesByCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useModesByCollection.d.ts","sourceRoot":"","sources":["../../src/hooks/useModesByCollection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,YAAY,EAMvE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePublishedVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/usePublishedVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"usePublishedVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/usePublishedVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,qBAAqB,sMA+CjC,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FigmaVariable } from 'types';
|
|
2
|
+
/**
|
|
3
|
+
* React hook that selects a single variable by ID from loaded Figma variables data.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Returns the variable with the specified ID, or `undefined` if not found.
|
|
7
|
+
* Useful for accessing a specific variable without manually mapping through all variables.
|
|
8
|
+
*
|
|
9
|
+
* @param variableId - The ID of the variable to retrieve.
|
|
10
|
+
* @returns The variable object, or `undefined` if not found.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* import { useVariableById } from '@figma-vars/hooks';
|
|
15
|
+
*
|
|
16
|
+
* function VariableDetails({ variableId }: { variableId: string }) {
|
|
17
|
+
* const variable = useVariableById(variableId);
|
|
18
|
+
*
|
|
19
|
+
* if (!variable) return <div>Variable not found</div>;
|
|
20
|
+
*
|
|
21
|
+
* return <div>
|
|
22
|
+
* <h2>{variable.name}</h2>
|
|
23
|
+
* <p>Type: {variable.resolvedType}</p>
|
|
24
|
+
* </div>;
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare const useVariableById: (variableId: string) => FigmaVariable | undefined;
|
|
31
|
+
//# sourceMappingURL=useVariableById.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVariableById.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariableById.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,eAAe,GAC1B,YAAY,MAAM,KACjB,aAAa,GAAG,SASlB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"useVariables.d.ts","sourceRoot":"","sources":["../../src/hooks/useVariables.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAIzD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,0LAgDxB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var N=Object.defineProperty;var g=(t,s,r)=>s in t?N(t,s,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[s]=r;var m=(t,s,r)=>g(t,typeof s!="symbol"?s+"":s,r);const T="https://api.figma.com",O=`${T}/v1/files`,v=t=>`/v1/files/${t}/variables/published`,P=t=>`/v1/files/${t}/variables`,y=t=>`${O}/${t}/variables/local`,D="application/json",p="X-FIGMA-TOKEN",h="A Figma API token is required.",B=`${h} and file key are required.`,U="Failed to perform bulk update.",w="Failed to create Figma variable.",b="Failed to delete Figma variable.",C="Failed to update Figma variable.",G="An error occurred while fetching data from the Figma API.";class l extends Error{constructor(r,o,c){super(r);m(this,"statusCode");m(this,"retryAfter");this.name="FigmaApiError",this.statusCode=o,this.retryAfter=c??void 0,Error.captureStackTrace&&Error.captureStackTrace(this,l)}}async function V(t,s,r){if(!s)throw new Error(h);const{signal:o,timeout:c,fetch:F=fetch}=r??{};let i,A;const a=o||(c?(A=new AbortController,i=setTimeout(()=>{A==null||A.abort()},c),A.signal):void 0);try{const E=t.startsWith("http://")||t.startsWith("https://")?t:`${T}${t.startsWith("/")?"":"/"}${t}`,n=await F(E,{method:"GET",headers:{[p]:s,"Content-Type":D},...a!==void 0&&{signal:a}});if(i!==void 0&&(clearTimeout(i),i=void 0),!n.ok){let R=G;const L=n.status;let d;if(L===429){const _=n.headers.get("Retry-After");if(_){const e=parseInt(_,10);Number.isNaN(e)||(d=e)}}try{const _=n.headers.get("content-type");if(_!=null&&_.includes("application/json")){const e=await n.json();e!=null&&e.message?R=e.message:e!=null&&e.err&&(R=e.err)}}catch{}throw new l(R,L,d)}return n.json()}catch(E){throw i!==void 0&&(clearTimeout(i),i=void 0),E}}async function H(t,s,r,o,c){if(!s)throw new Error(h);const{signal:F,timeout:i,fetch:A=fetch}=c??{};let a,E;const n=F||(i?(E=new AbortController,a=setTimeout(()=>{E==null||E.abort()},i),E.signal):void 0);try{const d={method:{CREATE:"POST",UPDATE:"PUT",DELETE:"DELETE"}[r],headers:{"Content-Type":"application/json",[p]:s},...n!==void 0&&{signal:n}};o&&(d.body=JSON.stringify(o));const _=t.startsWith("http://")||t.startsWith("https://")?t:`${T}${t.startsWith("/")?"":"/"}${t}`,e=await A(_,d);if(a!==void 0&&(clearTimeout(a),a=void 0),!e.ok){const S=e.status;let u="An API error occurred",M;if(S===429){const I=e.headers.get("Retry-After");if(I){const f=parseInt(I,10);Number.isNaN(f)||(M=f)}}try{const I=e.headers.get("content-type");if(I!=null&&I.includes("application/json")){const f=await e.json();u=f.err||f.message||u}}catch{}throw new l(u,S,M)}return e.status===204||!e.body?{}:e.json()}catch(R){throw a!==void 0&&(clearTimeout(a),a=void 0),R}}function $(t,s){return t.filter(r=>{let o=!0;return s.resolvedType&&(o=o&&r.resolvedType===s.resolvedType),s.name&&(o=o&&r.name.includes(s.name)),o})}exports.CONTENT_TYPE_JSON=D;exports.ERROR_MSG_BULK_UPDATE_FAILED=U;exports.ERROR_MSG_CREATE_VARIABLE_FAILED=w;exports.ERROR_MSG_DELETE_VARIABLE_FAILED=b;exports.ERROR_MSG_FETCH_FIGMA_DATA_FAILED=G;exports.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED=B;exports.ERROR_MSG_TOKEN_REQUIRED=h;exports.ERROR_MSG_UPDATE_VARIABLE_FAILED=C;exports.FIGMA_API_BASE_URL=T;exports.FIGMA_FILES_ENDPOINT=O;exports.FIGMA_FILE_VARIABLES_PATH=P;exports.FIGMA_LOCAL_VARIABLES_ENDPOINT=y;exports.FIGMA_PUBLISHED_VARIABLES_PATH=v;exports.FIGMA_TOKEN_HEADER=p;exports.FigmaApiError=l;exports.fetcher=V;exports.filterVariables=$;exports.mutator=H;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
var L = Object.defineProperty;
|
|
2
|
+
var S = (t, s, r) => s in t ? L(t, s, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[s] = r;
|
|
3
|
+
var I = (t, s, r) => S(t, typeof s != "symbol" ? s + "" : s, r);
|
|
4
|
+
const T = "https://api.figma.com", M = `${T}/v1/files`, D = (t) => `/v1/files/${t}/variables/published`, G = (t) => `/v1/files/${t}/variables`, b = (t) => `${M}/${t}/variables/local`, N = "application/json", y = "X-FIGMA-TOKEN", F = "A Figma API token is required.", P = `${F} and file key are required.`, C = "Failed to perform bulk update.", $ = "Failed to create Figma variable.", U = "Failed to delete Figma variable.", j = "Failed to update Figma variable.", O = "An error occurred while fetching data from the Figma API.";
|
|
5
|
+
class p extends Error {
|
|
6
|
+
constructor(r, a, A) {
|
|
7
|
+
super(r);
|
|
8
|
+
/** HTTP status code from the API response. */
|
|
9
|
+
I(this, "statusCode");
|
|
10
|
+
/**
|
|
11
|
+
* Retry-After header value in seconds (for 429 rate limit errors).
|
|
12
|
+
* Undefined if not a rate limit error or header not present.
|
|
13
|
+
*/
|
|
14
|
+
I(this, "retryAfter");
|
|
15
|
+
this.name = "FigmaApiError", this.statusCode = a, this.retryAfter = A ?? void 0, Error.captureStackTrace && Error.captureStackTrace(this, p);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function B(t, s, r) {
|
|
19
|
+
if (!s)
|
|
20
|
+
throw new Error(F);
|
|
21
|
+
const {
|
|
22
|
+
signal: a,
|
|
23
|
+
timeout: A,
|
|
24
|
+
fetch: u = fetch
|
|
25
|
+
} = r ?? {};
|
|
26
|
+
let o, d;
|
|
27
|
+
const i = a || (A ? (d = new AbortController(), o = setTimeout(() => {
|
|
28
|
+
d == null || d.abort();
|
|
29
|
+
}, A), d.signal) : void 0);
|
|
30
|
+
try {
|
|
31
|
+
const n = t.startsWith("http://") || t.startsWith("https://") ? t : `${T}${t.startsWith("/") ? "" : "/"}${t}`, c = await u(n, {
|
|
32
|
+
method: "GET",
|
|
33
|
+
headers: {
|
|
34
|
+
[y]: s,
|
|
35
|
+
"Content-Type": N
|
|
36
|
+
},
|
|
37
|
+
...i !== void 0 && { signal: i }
|
|
38
|
+
});
|
|
39
|
+
if (o !== void 0 && (clearTimeout(o), o = void 0), !c.ok) {
|
|
40
|
+
let f = O;
|
|
41
|
+
const m = c.status;
|
|
42
|
+
let h;
|
|
43
|
+
if (m === 429) {
|
|
44
|
+
const E = c.headers.get("Retry-After");
|
|
45
|
+
if (E) {
|
|
46
|
+
const e = parseInt(E, 10);
|
|
47
|
+
Number.isNaN(e) || (h = e);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const E = c.headers.get("content-type");
|
|
52
|
+
if (E != null && E.includes("application/json")) {
|
|
53
|
+
const e = await c.json();
|
|
54
|
+
e != null && e.message ? f = e.message : e != null && e.err && (f = e.err);
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
throw new p(f, m, h);
|
|
59
|
+
}
|
|
60
|
+
return c.json();
|
|
61
|
+
} catch (n) {
|
|
62
|
+
throw o !== void 0 && (clearTimeout(o), o = void 0), n;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function H(t, s, r, a, A) {
|
|
66
|
+
if (!s)
|
|
67
|
+
throw new Error(F);
|
|
68
|
+
const {
|
|
69
|
+
signal: u,
|
|
70
|
+
timeout: o,
|
|
71
|
+
fetch: d = fetch
|
|
72
|
+
} = A ?? {};
|
|
73
|
+
let i, n;
|
|
74
|
+
const c = u || (o ? (n = new AbortController(), i = setTimeout(() => {
|
|
75
|
+
n == null || n.abort();
|
|
76
|
+
}, o), n.signal) : void 0);
|
|
77
|
+
try {
|
|
78
|
+
const h = {
|
|
79
|
+
method: {
|
|
80
|
+
CREATE: "POST",
|
|
81
|
+
UPDATE: "PUT",
|
|
82
|
+
DELETE: "DELETE"
|
|
83
|
+
}[r],
|
|
84
|
+
headers: {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
[y]: s
|
|
87
|
+
},
|
|
88
|
+
...c !== void 0 && { signal: c }
|
|
89
|
+
};
|
|
90
|
+
a && (h.body = JSON.stringify(a));
|
|
91
|
+
const E = t.startsWith("http://") || t.startsWith("https://") ? t : `${T}${t.startsWith("/") ? "" : "/"}${t}`, e = await d(E, h);
|
|
92
|
+
if (i !== void 0 && (clearTimeout(i), i = void 0), !e.ok) {
|
|
93
|
+
const g = e.status;
|
|
94
|
+
let R = "An API error occurred", v;
|
|
95
|
+
if (g === 429) {
|
|
96
|
+
const l = e.headers.get("Retry-After");
|
|
97
|
+
if (l) {
|
|
98
|
+
const _ = parseInt(l, 10);
|
|
99
|
+
Number.isNaN(_) || (v = _);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const l = e.headers.get("content-type");
|
|
104
|
+
if (l != null && l.includes("application/json")) {
|
|
105
|
+
const _ = await e.json();
|
|
106
|
+
R = _.err || _.message || R;
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
throw new p(R, g, v);
|
|
111
|
+
}
|
|
112
|
+
return e.status === 204 || !e.body ? {} : e.json();
|
|
113
|
+
} catch (f) {
|
|
114
|
+
throw i !== void 0 && (clearTimeout(i), i = void 0), f;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function V(t, s) {
|
|
118
|
+
return t.filter((r) => {
|
|
119
|
+
let a = !0;
|
|
120
|
+
return s.resolvedType && (a = a && r.resolvedType === s.resolvedType), s.name && (a = a && r.name.includes(s.name)), a;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
export {
|
|
124
|
+
N as C,
|
|
125
|
+
F as E,
|
|
126
|
+
G as F,
|
|
127
|
+
P as a,
|
|
128
|
+
p as b,
|
|
129
|
+
V as c,
|
|
130
|
+
T as d,
|
|
131
|
+
M as e,
|
|
132
|
+
B as f,
|
|
133
|
+
D as g,
|
|
134
|
+
b as h,
|
|
135
|
+
y as i,
|
|
136
|
+
C as j,
|
|
137
|
+
$ as k,
|
|
138
|
+
U as l,
|
|
139
|
+
H as m,
|
|
140
|
+
j as n,
|
|
141
|
+
O as o
|
|
142
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("react/jsx-runtime"),u=require("react"),m=require("swr"),i=require("./index-5ZyKWuYv.cjs"),k=u.createContext(void 0);function A(e){if(typeof e!="object"||e===null)return!1;const r=e;if(typeof r.meta!="object"||r.meta===null)return!1;const t=r.meta;return!(typeof t.variableCollections!="object"||t.variableCollections===null||typeof t.variables!="object"||t.variables===null)}function _(e){if(A(e))return e}const V=({children:e,token:r,fileKey:t,fallbackFile:o,swrConfig:s})=>{const a=u.useId(),l=u.useMemo(()=>`figma-vars-provider-${a}`,[a]),f=u.useMemo(()=>{if(o){if(typeof o=="object"){const n=_(o);if(n)return n;process.env.NODE_ENV!=="production"&&console.warn("[figma-vars-hooks] fallbackFile object does not match expected Figma Variables API response structure. Expected { meta: { variableCollections: {...}, variables: {...} } }");return}if(typeof o=="string")try{const n=JSON.parse(o),d=_(n);if(d)return d;process.env.NODE_ENV!=="production"&&console.warn("[figma-vars-hooks] Parsed fallbackFile JSON does not match expected Figma Variables API response structure. Expected { meta: { variableCollections: {...}, variables: {...} } }");return}catch(n){process.env.NODE_ENV!=="production"&&console.error(`[figma-vars-hooks] Failed to parse fallbackFile JSON: ${n instanceof Error?n.message:"Unknown error"}`);return}}},[o]),c=u.useMemo(()=>{const n={token:r,fileKey:t,providerId:l,...s!==void 0&&{swrConfig:s}};return o===void 0?n:{...n,fallbackFile:o,parsedFallbackFile:f}},[r,t,o,f,l,s]);return g.jsx(k.Provider,{value:c,children:e})},b=()=>{const e=u.useContext(k);if(e===void 0)throw new Error("useFigmaTokenContext must be used within a FigmaVarsProvider");return e};function M(e){const{fileKey:r,token:t,providerId:o,hasFallback:s}=e;return!!(t&&r)&&t&&r?[`https://api.figma.com/v1/files/${r}/variables/local`,t]:s?[`fallback-${o??"default"}`,"fallback"]:null}function O(e){const{fileKey:r,token:t,providerId:o,hasFallback:s}=e;return!!(t&&r)&&t&&r?[`https://api.figma.com/v1/files/${r}/variables/published`,t]:s?[`fallback-${o??"default"}`,"fallback"]:null}function I(e){const{fileKey:r,token:t,providerId:o,hasFallback:s}=e,a=[];return t&&r&&(a.push([`https://api.figma.com/v1/files/${r}/variables/local`,t]),a.push([`https://api.figma.com/v1/files/${r}/variables/published`,t])),s&&o&&a.push([`fallback-${o}`,"fallback"]),a}const R=()=>{const{token:e,fileKey:r,fallbackFile:t,parsedFallbackFile:o,providerId:s,swrConfig:a}=b(),f=M({fileKey:r,token:e,providerId:s,hasFallback:!!(t||o)});return m(f,async(...n)=>{if(o)return o;if(t&&typeof t=="object")return t;const[d,E]=Array.isArray(n[0])?n[0]:[n[0],n[1]];if(!d||!E)throw new Error("Missing URL or token for live API request");return i.fetcher(d,E)},a)},S=()=>{const{data:e}=R(),r=u.useMemo(()=>e!=null&&e.meta?Object.values(e.meta.variableCollections):[],[e]),t=u.useMemo(()=>e!=null&&e.meta?e.meta.variableCollections:{},[e]);return{collections:r,collectionsById:t}},K=()=>{const{data:e}=R();return u.useMemo(()=>{const r=[],t={},o={};if(e!=null&&e.meta)for(const s of Object.values(e.meta.variableCollections)){r.push(...s.modes),t[s.id]=s.modes;for(const a of s.modes)o[a.modeId]=a}return{modes:r,modesByCollectionId:t,modesById:o}},[e])};function T(e,r){switch(r.type){case"loading":return{...e,status:"loading",error:null};case"success":return{...e,status:"success",data:r.payload};case"error":return{...e,status:"error",error:r.payload};default:return e}}const v=(e,r)=>{const{throwOnError:t=!1}={},o={status:"idle",data:null,error:null},[s,a]=u.useReducer(T,o),l=u.useRef(e),f=u.useRef({throwOnError:t}),c=u.useRef(!0),n=u.useRef(0);return u.useEffect(()=>{l.current=e,f.current={throwOnError:t}},[e,t]),u.useEffect(()=>(c.current=!0,()=>{c.current=!1}),[]),{mutate:u.useCallback(async E=>{if(!c.current)return;const y=++n.current;a({type:"loading"});try{const p=await l.current(E);return c.current&&y===n.current&&a({type:"success",payload:p}),p}catch(p){const h=p;if(c.current&&y===n.current&&a({type:"error",payload:h}),f.current.throwOnError)throw h;return}},[]),...s,isLoading:s.status==="loading",isSuccess:s.status==="success",isError:s.status==="error"}},C=()=>{const{token:e,fileKey:r}=b();return v(async o=>{if(!e)throw new Error(i.ERROR_MSG_TOKEN_REQUIRED);if(!r)throw new Error(i.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED);return await i.mutator(i.FIGMA_FILE_VARIABLES_PATH(r),e,"CREATE",{variables:[{action:"CREATE",...o}]})})},L=()=>{const{token:e,fileKey:r}=b();return v(async({variableId:o,payload:s})=>{if(!e)throw new Error(i.ERROR_MSG_TOKEN_REQUIRED);if(!r)throw new Error(i.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED);return await i.mutator(i.FIGMA_FILE_VARIABLES_PATH(r),e,"UPDATE",{variables:[{action:"UPDATE",id:o,...s}]})})},P=()=>{const{token:e,fileKey:r}=b();return v(async o=>{if(!e)throw new Error(i.ERROR_MSG_TOKEN_REQUIRED);if(!r)throw new Error(i.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED);return await i.mutator(i.FIGMA_FILE_VARIABLES_PATH(r),e,"DELETE",{variables:[{action:"DELETE",id:o}]})})},D=()=>{const{token:e,fileKey:r}=b();return v(async o=>{if(!e)throw new Error(i.ERROR_MSG_TOKEN_REQUIRED);if(!r)throw new Error(i.ERROR_MSG_TOKEN_FILE_KEY_REQUIRED);return await i.mutator(i.FIGMA_FILE_VARIABLES_PATH(r),e,"UPDATE",o)})},U=()=>{const{mutate:e}=m.useSWRConfig(),{token:r,fileKey:t,fallbackFile:o,providerId:s}=b(),a=!!o;return{invalidate:()=>{const c=I({fileKey:t,token:r,providerId:s,hasFallback:a});for(const n of c)e(n)},revalidate:()=>{const c=I({fileKey:t,token:r,providerId:s,hasFallback:a});for(const n of c)e(n,void 0,{revalidate:!0})}}},N=()=>{const{token:e,fileKey:r,fallbackFile:t,parsedFallbackFile:o,providerId:s,swrConfig:a}=b(),f=O({fileKey:r,token:e,providerId:s,hasFallback:!!(t||o)});return m(f,async(...n)=>{if(o)return o;if(t&&typeof t=="object")return t;const[d,E]=Array.isArray(n[0])?n[0]:[n[0],n[1]];if(!d||!E)throw new Error("Missing URL or token for live API request");return i.fetcher(d,E)},a)};function w(e){return e instanceof i.FigmaApiError}function F(e){return w(e)?e.statusCode:null}function j(e,r="An error occurred"){return e instanceof Error?e.message||r:typeof e=="string"?e:r}function B(e,r){return F(e)===r}exports.FigmaApiError=i.FigmaApiError;exports.filterVariables=i.filterVariables;exports.FigmaVarsProvider=V;exports.getErrorMessage=j;exports.getErrorStatus=F;exports.hasErrorStatus=B;exports.isFigmaApiError=w;exports.useBulkUpdateVariables=D;exports.useCreateVariable=C;exports.useDeleteVariable=P;exports.useInvalidateVariables=U;exports.usePublishedVariables=N;exports.useUpdateVariable=L;exports.useVariableCollections=S;exports.useVariableModes=K;exports.useVariables=R;
|