figma-metadata-extractor 1.0.7 → 1.0.8
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 +111 -3
- package/dist/index.cjs +17 -8
- package/dist/index.js +17 -8
- package/dist/lib.d.ts +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,6 +8,15 @@ A TypeScript library for extracting metadata and downloading images from Figma f
|
|
|
8
8
|
npm install figma-metadata-extractor
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- 🎨 Extract comprehensive metadata from Figma files
|
|
14
|
+
- 📦 Auto-download image assets (to disk or as buffers)
|
|
15
|
+
- 🔄 Support for both file-based and buffer-based workflows
|
|
16
|
+
- 🎯 Enrich metadata with image paths and markup
|
|
17
|
+
- 🔐 Support for both API keys and OAuth tokens
|
|
18
|
+
- 📝 Multiple output formats (JSON, YAML, object)
|
|
19
|
+
|
|
11
20
|
## Quick Start
|
|
12
21
|
|
|
13
22
|
### Get Metadata with Auto-Downloaded Images (LLM-Ready!)
|
|
@@ -15,7 +24,7 @@ npm install figma-metadata-extractor
|
|
|
15
24
|
```typescript
|
|
16
25
|
import { getFigmaMetadata } from 'figma-metadata-extractor';
|
|
17
26
|
|
|
18
|
-
// Extract metadata AND automatically download image assets
|
|
27
|
+
// Extract metadata AND automatically download image assets to disk
|
|
19
28
|
const metadata = await getFigmaMetadata(
|
|
20
29
|
'https://figma.com/file/ABC123/My-Design',
|
|
21
30
|
{
|
|
@@ -26,6 +35,55 @@ const metadata = await getFigmaMetadata(
|
|
|
26
35
|
}
|
|
27
36
|
);
|
|
28
37
|
|
|
38
|
+
// Nodes are enriched with downloadedImage property
|
|
39
|
+
metadata.nodes.forEach(node => {
|
|
40
|
+
if (node.downloadedImage) {
|
|
41
|
+
console.log(node.downloadedImage.filePath);
|
|
42
|
+
console.log(node.downloadedImage.markdown); // 
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Get Images as Buffers (No Disk Write)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { getFigmaMetadata, enrichMetadataWithImages } from 'figma-metadata-extractor';
|
|
51
|
+
import fs from 'fs/promises';
|
|
52
|
+
|
|
53
|
+
// Get metadata with images as ArrayBuffers
|
|
54
|
+
const result = await getFigmaMetadata(
|
|
55
|
+
'https://figma.com/file/ABC123/My-Design',
|
|
56
|
+
{
|
|
57
|
+
apiKey: 'your-figma-api-key',
|
|
58
|
+
downloadImages: true,
|
|
59
|
+
returnBuffer: true // Get images as ArrayBuffer
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// Images are returned separately, metadata is not enriched
|
|
64
|
+
console.log(`Downloaded ${result.images.length} images as buffers`);
|
|
65
|
+
|
|
66
|
+
// Process buffers (upload to S3, convert format, etc.)
|
|
67
|
+
const savedPaths: string[] = [];
|
|
68
|
+
for (const image of result.images) {
|
|
69
|
+
// Example: Save to disk after processing
|
|
70
|
+
const buffer = Buffer.from(image.buffer);
|
|
71
|
+
const path = `./processed/${Date.now()}.png`;
|
|
72
|
+
await fs.writeFile(path, buffer);
|
|
73
|
+
savedPaths.push(path);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Optionally enrich metadata with saved file paths
|
|
77
|
+
const enrichedMetadata = enrichMetadataWithImages(result, savedPaths, {
|
|
78
|
+
useRelativePaths: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Now nodes have downloadedImage properties
|
|
82
|
+
enrichedMetadata.nodes.forEach(node => {
|
|
83
|
+
if (node.downloadedImage) {
|
|
84
|
+
console.log(node.downloadedImage.markdown);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
29
87
|
```
|
|
30
88
|
|
|
31
89
|
### Get Metadata Only (No Downloads)
|
|
@@ -98,13 +156,25 @@ Extracts comprehensive metadata from a Figma file including layout, content, vis
|
|
|
98
156
|
- `outputFormat?: 'json' | 'yaml' | 'object'` - Output format (default: 'object')
|
|
99
157
|
- `depth?: number` - Maximum depth to traverse the node tree
|
|
100
158
|
- `downloadImages?: boolean` - Automatically download image assets and enrich metadata (default: false)
|
|
101
|
-
- `localPath?: string` - Local path for downloaded images (
|
|
159
|
+
- `localPath?: string` - Local path for downloaded images (optional if returnBuffer is true)
|
|
102
160
|
- `imageFormat?: 'png' | 'svg'` - Image format for downloads (default: 'png')
|
|
103
161
|
- `pngScale?: number` - Export scale for PNG images (default: 2)
|
|
162
|
+
- `returnBuffer?: boolean` - Return images as ArrayBuffer instead of saving to disk (default: false)
|
|
163
|
+
- `enableLogging?: boolean` - Enable JSON debug log files (default: false)
|
|
104
164
|
|
|
105
165
|
**Returns:** Promise<FigmaMetadataResult | string>
|
|
106
166
|
|
|
107
|
-
|
|
167
|
+
**FigmaMetadataResult:**
|
|
168
|
+
```typescript
|
|
169
|
+
{
|
|
170
|
+
metadata: any; // File metadata
|
|
171
|
+
nodes: any[]; // Design nodes
|
|
172
|
+
globalVars: any; // Styles, colors, etc.
|
|
173
|
+
images?: FigmaImageResult[]; // Only present when downloadImages: true and returnBuffer: true
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
When `downloadImages: true` and `returnBuffer: false`, nodes with image assets will include a `downloadedImage` property:
|
|
108
178
|
```typescript
|
|
109
179
|
{
|
|
110
180
|
filePath: string; // Absolute path
|
|
@@ -115,6 +185,8 @@ When `downloadImages` is true, nodes with image assets will include a `downloade
|
|
|
115
185
|
}
|
|
116
186
|
```
|
|
117
187
|
|
|
188
|
+
When `downloadImages: true` and `returnBuffer: true`, images are returned in the `images` array and nodes are NOT enriched. Use `enrichMetadataWithImages()` to enrich them later after saving buffers to disk.
|
|
189
|
+
|
|
118
190
|
### `downloadFigmaImages(figmaUrl, nodes, options)`
|
|
119
191
|
|
|
120
192
|
Downloads SVG and PNG images from a Figma file.
|
|
@@ -143,6 +215,42 @@ Downloads SVG and PNG images from a Figma file.
|
|
|
143
215
|
|
|
144
216
|
When `returnBuffer` is true, each result will contain a `buffer` property instead of `filePath`.
|
|
145
217
|
|
|
218
|
+
### `enrichMetadataWithImages(metadata, imagePaths, options)`
|
|
219
|
+
|
|
220
|
+
Enriches metadata with saved image file paths after saving buffers to disk.
|
|
221
|
+
|
|
222
|
+
**Parameters:**
|
|
223
|
+
- `metadata` (FigmaMetadataResult): The metadata result from getFigmaMetadata with returnBuffer: true
|
|
224
|
+
- `imagePaths` (string[]): Array of file paths where images were saved (must match order of metadata.images)
|
|
225
|
+
- `options` (object): Configuration options
|
|
226
|
+
- `useRelativePaths?: boolean | string` - How to generate paths (default: true)
|
|
227
|
+
- `localPath?: string` - Base path for relative path calculation
|
|
228
|
+
|
|
229
|
+
**Returns:** FigmaMetadataResult with enriched nodes
|
|
230
|
+
|
|
231
|
+
**Example:**
|
|
232
|
+
```typescript
|
|
233
|
+
// Get metadata with buffers
|
|
234
|
+
const result = await getFigmaMetadata(url, {
|
|
235
|
+
apiKey: 'key',
|
|
236
|
+
downloadImages: true,
|
|
237
|
+
returnBuffer: true
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Save buffers to disk
|
|
241
|
+
const paths = await Promise.all(
|
|
242
|
+
result.images.map((img, i) =>
|
|
243
|
+
fs.writeFile(`./images/img-${i}.png`, Buffer.from(img.buffer))
|
|
244
|
+
.then(() => `./images/img-${i}.png`)
|
|
245
|
+
)
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// Enrich metadata with file paths
|
|
249
|
+
const enriched = enrichMetadataWithImages(result, paths, {
|
|
250
|
+
useRelativePaths: true
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
146
254
|
### `downloadFigmaFrameImage(figmaUrl, options)`
|
|
147
255
|
|
|
148
256
|
Downloads a single frame image from a Figma URL that contains a node-id parameter.
|
package/dist/index.cjs
CHANGED
|
@@ -1447,7 +1447,8 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1447
1447
|
imageFormat = "png",
|
|
1448
1448
|
pngScale = 2,
|
|
1449
1449
|
useRelativePaths = true,
|
|
1450
|
-
enableLogging = false
|
|
1450
|
+
enableLogging = false,
|
|
1451
|
+
returnBuffer = false
|
|
1451
1452
|
} = options;
|
|
1452
1453
|
Logger.enableLogging = enableLogging;
|
|
1453
1454
|
if (!apiKey && !oauthToken) {
|
|
@@ -1489,8 +1490,8 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1489
1490
|
globalVars
|
|
1490
1491
|
};
|
|
1491
1492
|
if (downloadImages) {
|
|
1492
|
-
if (!localPath) {
|
|
1493
|
-
throw new Error("localPath is required when downloadImages is true");
|
|
1493
|
+
if (!returnBuffer && !localPath) {
|
|
1494
|
+
throw new Error("localPath is required when downloadImages is true and returnBuffer is false");
|
|
1494
1495
|
}
|
|
1495
1496
|
Logger.log("Discovering and downloading image assets...");
|
|
1496
1497
|
const imageAssets = findImageAssets(nodes, globalVars);
|
|
@@ -1502,12 +1503,20 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1502
1503
|
}));
|
|
1503
1504
|
const downloadResults = await figmaService.downloadImages(
|
|
1504
1505
|
fileKey,
|
|
1505
|
-
localPath,
|
|
1506
|
+
localPath || "",
|
|
1506
1507
|
imageNodes,
|
|
1507
|
-
{
|
|
1508
|
+
{
|
|
1509
|
+
pngScale: imageFormat === "png" ? pngScale : void 0,
|
|
1510
|
+
returnBuffer
|
|
1511
|
+
}
|
|
1508
1512
|
);
|
|
1509
|
-
|
|
1510
|
-
|
|
1513
|
+
if (returnBuffer) {
|
|
1514
|
+
result.images = downloadResults;
|
|
1515
|
+
Logger.log(`Successfully downloaded ${downloadResults.length} images as buffers`);
|
|
1516
|
+
} else {
|
|
1517
|
+
result.nodes = enrichNodesWithImages(nodes, imageAssets, downloadResults, useRelativePaths, localPath);
|
|
1518
|
+
Logger.log(`Successfully downloaded and enriched ${downloadResults.length} images`);
|
|
1519
|
+
}
|
|
1511
1520
|
}
|
|
1512
1521
|
}
|
|
1513
1522
|
if (outputFormat === "json") {
|
|
@@ -1652,7 +1661,7 @@ function enrichNodesWithImages(nodes, imageAssets, downloadResults, useRelativeP
|
|
|
1652
1661
|
const imageMap = /* @__PURE__ */ new Map();
|
|
1653
1662
|
imageAssets.forEach((asset, index) => {
|
|
1654
1663
|
const result = downloadResults[index];
|
|
1655
|
-
if (result) {
|
|
1664
|
+
if (result && result.filePath) {
|
|
1656
1665
|
let pathForMarkup;
|
|
1657
1666
|
if (useRelativePaths === false) {
|
|
1658
1667
|
pathForMarkup = result.filePath;
|
package/dist/index.js
CHANGED
|
@@ -1445,7 +1445,8 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1445
1445
|
imageFormat = "png",
|
|
1446
1446
|
pngScale = 2,
|
|
1447
1447
|
useRelativePaths = true,
|
|
1448
|
-
enableLogging = false
|
|
1448
|
+
enableLogging = false,
|
|
1449
|
+
returnBuffer = false
|
|
1449
1450
|
} = options;
|
|
1450
1451
|
Logger.enableLogging = enableLogging;
|
|
1451
1452
|
if (!apiKey && !oauthToken) {
|
|
@@ -1487,8 +1488,8 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1487
1488
|
globalVars
|
|
1488
1489
|
};
|
|
1489
1490
|
if (downloadImages) {
|
|
1490
|
-
if (!localPath) {
|
|
1491
|
-
throw new Error("localPath is required when downloadImages is true");
|
|
1491
|
+
if (!returnBuffer && !localPath) {
|
|
1492
|
+
throw new Error("localPath is required when downloadImages is true and returnBuffer is false");
|
|
1492
1493
|
}
|
|
1493
1494
|
Logger.log("Discovering and downloading image assets...");
|
|
1494
1495
|
const imageAssets = findImageAssets(nodes, globalVars);
|
|
@@ -1500,12 +1501,20 @@ async function getFigmaMetadata(figmaUrl, options = {}) {
|
|
|
1500
1501
|
}));
|
|
1501
1502
|
const downloadResults = await figmaService.downloadImages(
|
|
1502
1503
|
fileKey,
|
|
1503
|
-
localPath,
|
|
1504
|
+
localPath || "",
|
|
1504
1505
|
imageNodes,
|
|
1505
|
-
{
|
|
1506
|
+
{
|
|
1507
|
+
pngScale: imageFormat === "png" ? pngScale : void 0,
|
|
1508
|
+
returnBuffer
|
|
1509
|
+
}
|
|
1506
1510
|
);
|
|
1507
|
-
|
|
1508
|
-
|
|
1511
|
+
if (returnBuffer) {
|
|
1512
|
+
result.images = downloadResults;
|
|
1513
|
+
Logger.log(`Successfully downloaded ${downloadResults.length} images as buffers`);
|
|
1514
|
+
} else {
|
|
1515
|
+
result.nodes = enrichNodesWithImages(nodes, imageAssets, downloadResults, useRelativePaths, localPath);
|
|
1516
|
+
Logger.log(`Successfully downloaded and enriched ${downloadResults.length} images`);
|
|
1517
|
+
}
|
|
1509
1518
|
}
|
|
1510
1519
|
}
|
|
1511
1520
|
if (outputFormat === "json") {
|
|
@@ -1650,7 +1659,7 @@ function enrichNodesWithImages(nodes, imageAssets, downloadResults, useRelativeP
|
|
|
1650
1659
|
const imageMap = /* @__PURE__ */ new Map();
|
|
1651
1660
|
imageAssets.forEach((asset, index) => {
|
|
1652
1661
|
const result = downloadResults[index];
|
|
1653
|
-
if (result) {
|
|
1662
|
+
if (result && result.filePath) {
|
|
1654
1663
|
let pathForMarkup;
|
|
1655
1664
|
if (useRelativePaths === false) {
|
|
1656
1665
|
pathForMarkup = result.filePath;
|
package/dist/lib.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export interface FigmaMetadataOptions {
|
|
|
27
27
|
useRelativePaths?: boolean | string;
|
|
28
28
|
/** Enable JSON debug log files (defaults to false) */
|
|
29
29
|
enableLogging?: boolean;
|
|
30
|
+
/** Return images as ArrayBuffer instead of saving to disk (defaults to false) */
|
|
31
|
+
returnBuffer?: boolean;
|
|
30
32
|
}
|
|
31
33
|
export interface FigmaImageOptions {
|
|
32
34
|
/** Export scale for PNG images (defaults to 2) */
|
|
@@ -56,6 +58,7 @@ export interface FigmaMetadataResult {
|
|
|
56
58
|
metadata: any;
|
|
57
59
|
nodes: any[];
|
|
58
60
|
globalVars: any;
|
|
61
|
+
images?: FigmaImageResult[];
|
|
59
62
|
}
|
|
60
63
|
export interface FigmaImageResult {
|
|
61
64
|
filePath?: string;
|
|
@@ -112,6 +115,20 @@ export declare function downloadFigmaImages(figmaUrl: string, nodes: FigmaImageN
|
|
|
112
115
|
* @returns Promise resolving to the download result
|
|
113
116
|
*/
|
|
114
117
|
export declare function downloadFigmaFrameImage(figmaUrl: string, options: FigmaFrameImageOptions): Promise<FigmaImageResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Enrich metadata with saved image file paths
|
|
120
|
+
*
|
|
121
|
+
* Use this function after saving images from buffers to disk to add file path information to the metadata.
|
|
122
|
+
*
|
|
123
|
+
* @param metadata - The metadata result from getFigmaMetadata
|
|
124
|
+
* @param imagePaths - Array of file paths corresponding to the images array
|
|
125
|
+
* @param options - Options for path generation
|
|
126
|
+
* @returns Enriched metadata with downloadedImage properties on nodes
|
|
127
|
+
*/
|
|
128
|
+
export declare function enrichMetadataWithImages(metadata: FigmaMetadataResult, imagePaths: string[], options?: {
|
|
129
|
+
useRelativePaths?: boolean | string;
|
|
130
|
+
localPath?: string;
|
|
131
|
+
}): FigmaMetadataResult;
|
|
115
132
|
export type { SimplifiedDesign } from "./extractors/types.js";
|
|
116
133
|
export type { ExtractorFn, TraversalContext, TraversalOptions, GlobalVars, StyleTypes, } from "./extractors/index.js";
|
|
117
134
|
export { extractFromDesign, simplifyRawFigmaObject, layoutExtractor, textExtractor, visualsExtractor, componentExtractor, allExtractors, layoutAndText, contentOnly, visualsOnly, layoutOnly, collapseSvgContainers, } from "./extractors/index.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-metadata-extractor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Extract metadata and download images from Figma files. A standalone library for accessing Figma design data and downloading frame images programmatically.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|