figma-metadata-extractor 1.0.9 → 1.0.11

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/dist/index.cjs CHANGED
@@ -420,7 +420,7 @@ class FigmaService {
420
420
  cropTransform,
421
421
  requiresImageDimensions,
422
422
  returnBuffer
423
- ) : null;
423
+ ).then((result) => ({ ...result, nodeId })) : null;
424
424
  }).filter((promise) => promise !== null);
425
425
  if (pngDownloads.length > 0) {
426
426
  downloadPromises.push(Promise.all(pngDownloads));
@@ -443,7 +443,7 @@ class FigmaService {
443
443
  cropTransform,
444
444
  requiresImageDimensions,
445
445
  returnBuffer
446
- ) : null;
446
+ ).then((result) => ({ ...result, nodeId })) : null;
447
447
  }).filter((promise) => promise !== null);
448
448
  if (svgDownloads.length > 0) {
449
449
  downloadPromises.push(Promise.all(svgDownloads));
@@ -1630,6 +1630,59 @@ async function downloadFigmaFrameImage(figmaUrl, options) {
1630
1630
  throw new Error(`Failed to download frame image: ${error instanceof Error ? error.message : String(error)}`);
1631
1631
  }
1632
1632
  }
1633
+ function getImageNodeInfo(metadata) {
1634
+ if (!metadata.images || metadata.images.length === 0) {
1635
+ return [];
1636
+ }
1637
+ const imageAssets = findImageAssets(metadata.nodes, metadata.globalVars);
1638
+ return imageAssets.map((asset) => ({
1639
+ nodeId: asset.id,
1640
+ name: asset.name
1641
+ }));
1642
+ }
1643
+ function enrichMetadataWithImages(metadata, imagePaths, options = {}) {
1644
+ const { useRelativePaths = true, localPath } = options;
1645
+ if (!metadata.images || metadata.images.length === 0) {
1646
+ return metadata;
1647
+ }
1648
+ const imageAssets = findImageAssets(metadata.nodes, metadata.globalVars);
1649
+ let downloadResults;
1650
+ if (Array.isArray(imagePaths)) {
1651
+ if (imagePaths.length !== metadata.images.length) {
1652
+ throw new Error(`Number of image paths (${imagePaths.length}) must match number of images (${metadata.images.length})`);
1653
+ }
1654
+ downloadResults = imagePaths.map((filePath, index) => ({
1655
+ filePath,
1656
+ finalDimensions: metadata.images[index].finalDimensions,
1657
+ wasCropped: metadata.images[index].wasCropped,
1658
+ cssVariables: metadata.images[index].cssVariables
1659
+ }));
1660
+ } else {
1661
+ downloadResults = imageAssets.map((asset) => {
1662
+ const filePath = imagePaths[asset.id];
1663
+ if (!filePath) {
1664
+ throw new Error(`No image path provided for node ID: ${asset.id}`);
1665
+ }
1666
+ const imageMetadata = metadata.images.find((img) => img.nodeId === asset.id);
1667
+ return {
1668
+ filePath,
1669
+ finalDimensions: imageMetadata?.finalDimensions || { width: 0, height: 0 },
1670
+ wasCropped: imageMetadata?.wasCropped || false,
1671
+ cssVariables: imageMetadata?.cssVariables
1672
+ };
1673
+ });
1674
+ }
1675
+ const enrichedNodes = enrichNodesWithImages(
1676
+ metadata.nodes,
1677
+ imageAssets,
1678
+ downloadResults,
1679
+ useRelativePaths
1680
+ );
1681
+ return {
1682
+ ...metadata,
1683
+ nodes: enrichedNodes
1684
+ };
1685
+ }
1633
1686
  function sanitizeFileName(name) {
1634
1687
  return name.replace(/[^a-z0-9]/gi, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
1635
1688
  }
@@ -1706,8 +1759,10 @@ exports.componentExtractor = componentExtractor;
1706
1759
  exports.contentOnly = contentOnly;
1707
1760
  exports.downloadFigmaFrameImage = downloadFigmaFrameImage;
1708
1761
  exports.downloadFigmaImages = downloadFigmaImages;
1762
+ exports.enrichMetadataWithImages = enrichMetadataWithImages;
1709
1763
  exports.extractFromDesign = extractFromDesign;
1710
1764
  exports.getFigmaMetadata = getFigmaMetadata;
1765
+ exports.getImageNodeInfo = getImageNodeInfo;
1711
1766
  exports.layoutAndText = layoutAndText;
1712
1767
  exports.layoutExtractor = layoutExtractor;
1713
1768
  exports.layoutOnly = layoutOnly;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { getFigmaMetadata, downloadFigmaImages, downloadFigmaFrameImage, type FigmaMetadataOptions, type FigmaImageOptions, type FigmaFrameImageOptions, type FigmaImageNode, type FigmaMetadataResult, type FigmaImageResult, } from "./lib.js";
1
+ export { getFigmaMetadata, downloadFigmaImages, downloadFigmaFrameImage, enrichMetadataWithImages, getImageNodeInfo, type FigmaMetadataOptions, type FigmaImageOptions, type FigmaFrameImageOptions, type FigmaImageNode, type FigmaMetadataResult, type FigmaImageResult, } from "./lib.js";
2
2
  export type { SimplifiedDesign } from "./extractors/types.js";
3
3
  export type { ExtractorFn, TraversalContext, TraversalOptions, GlobalVars, StyleTypes, } from "./extractors/index.js";
4
4
  export { extractFromDesign, simplifyRawFigmaObject, layoutExtractor, textExtractor, visualsExtractor, componentExtractor, allExtractors, layoutAndText, contentOnly, visualsOnly, layoutOnly, collapseSvgContainers, } from "./extractors/index.js";
package/dist/index.js CHANGED
@@ -418,7 +418,7 @@ class FigmaService {
418
418
  cropTransform,
419
419
  requiresImageDimensions,
420
420
  returnBuffer
421
- ) : null;
421
+ ).then((result) => ({ ...result, nodeId })) : null;
422
422
  }).filter((promise) => promise !== null);
423
423
  if (pngDownloads.length > 0) {
424
424
  downloadPromises.push(Promise.all(pngDownloads));
@@ -441,7 +441,7 @@ class FigmaService {
441
441
  cropTransform,
442
442
  requiresImageDimensions,
443
443
  returnBuffer
444
- ) : null;
444
+ ).then((result) => ({ ...result, nodeId })) : null;
445
445
  }).filter((promise) => promise !== null);
446
446
  if (svgDownloads.length > 0) {
447
447
  downloadPromises.push(Promise.all(svgDownloads));
@@ -1628,6 +1628,59 @@ async function downloadFigmaFrameImage(figmaUrl, options) {
1628
1628
  throw new Error(`Failed to download frame image: ${error instanceof Error ? error.message : String(error)}`);
1629
1629
  }
1630
1630
  }
1631
+ function getImageNodeInfo(metadata) {
1632
+ if (!metadata.images || metadata.images.length === 0) {
1633
+ return [];
1634
+ }
1635
+ const imageAssets = findImageAssets(metadata.nodes, metadata.globalVars);
1636
+ return imageAssets.map((asset) => ({
1637
+ nodeId: asset.id,
1638
+ name: asset.name
1639
+ }));
1640
+ }
1641
+ function enrichMetadataWithImages(metadata, imagePaths, options = {}) {
1642
+ const { useRelativePaths = true, localPath } = options;
1643
+ if (!metadata.images || metadata.images.length === 0) {
1644
+ return metadata;
1645
+ }
1646
+ const imageAssets = findImageAssets(metadata.nodes, metadata.globalVars);
1647
+ let downloadResults;
1648
+ if (Array.isArray(imagePaths)) {
1649
+ if (imagePaths.length !== metadata.images.length) {
1650
+ throw new Error(`Number of image paths (${imagePaths.length}) must match number of images (${metadata.images.length})`);
1651
+ }
1652
+ downloadResults = imagePaths.map((filePath, index) => ({
1653
+ filePath,
1654
+ finalDimensions: metadata.images[index].finalDimensions,
1655
+ wasCropped: metadata.images[index].wasCropped,
1656
+ cssVariables: metadata.images[index].cssVariables
1657
+ }));
1658
+ } else {
1659
+ downloadResults = imageAssets.map((asset) => {
1660
+ const filePath = imagePaths[asset.id];
1661
+ if (!filePath) {
1662
+ throw new Error(`No image path provided for node ID: ${asset.id}`);
1663
+ }
1664
+ const imageMetadata = metadata.images.find((img) => img.nodeId === asset.id);
1665
+ return {
1666
+ filePath,
1667
+ finalDimensions: imageMetadata?.finalDimensions || { width: 0, height: 0 },
1668
+ wasCropped: imageMetadata?.wasCropped || false,
1669
+ cssVariables: imageMetadata?.cssVariables
1670
+ };
1671
+ });
1672
+ }
1673
+ const enrichedNodes = enrichNodesWithImages(
1674
+ metadata.nodes,
1675
+ imageAssets,
1676
+ downloadResults,
1677
+ useRelativePaths
1678
+ );
1679
+ return {
1680
+ ...metadata,
1681
+ nodes: enrichedNodes
1682
+ };
1683
+ }
1631
1684
  function sanitizeFileName(name) {
1632
1685
  return name.replace(/[^a-z0-9]/gi, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
1633
1686
  }
@@ -1705,8 +1758,10 @@ export {
1705
1758
  contentOnly,
1706
1759
  downloadFigmaFrameImage,
1707
1760
  downloadFigmaImages,
1761
+ enrichMetadataWithImages,
1708
1762
  extractFromDesign,
1709
1763
  getFigmaMetadata,
1764
+ getImageNodeInfo,
1710
1765
  layoutAndText,
1711
1766
  layoutExtractor,
1712
1767
  layoutOnly,
package/dist/lib.d.ts CHANGED
@@ -61,6 +61,7 @@ export interface FigmaMetadataResult {
61
61
  images?: FigmaImageResult[];
62
62
  }
63
63
  export interface FigmaImageResult {
64
+ nodeId?: string;
64
65
  filePath?: string;
65
66
  buffer?: ArrayBuffer;
66
67
  finalDimensions: {
@@ -121,17 +122,58 @@ export declare function downloadFigmaImages(figmaUrl: string, nodes: FigmaImageN
121
122
  * @returns Promise resolving to the download result
122
123
  */
123
124
  export declare function downloadFigmaFrameImage(figmaUrl: string, options: FigmaFrameImageOptions): Promise<FigmaImageResult>;
125
+ /**
126
+ * Get image node information from metadata
127
+ *
128
+ * Returns an array of objects containing node IDs and names for all images in the metadata.
129
+ * Use this to create a mapping between node IDs and uploaded URLs.
130
+ *
131
+ * @param metadata - The metadata result from getFigmaMetadata
132
+ * @returns Array of objects with nodeId and name for each image
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const imageInfo = getImageNodeInfo(metadata);
137
+ * // [{ nodeId: '123:456', name: 'icon' }, { nodeId: '789:012', name: 'logo' }]
138
+ *
139
+ * // Upload images and create mapping
140
+ * const urlMap: Record<string, string> = {};
141
+ * for (const info of imageInfo) {
142
+ * const url = await uploadToS3(metadata.images.find(img => img.nodeId === info.nodeId).buffer);
143
+ * urlMap[info.nodeId] = url;
144
+ * }
145
+ *
146
+ * // Enrich metadata with URLs
147
+ * const enriched = enrichMetadataWithImages(metadata, urlMap);
148
+ * ```
149
+ */
150
+ export declare function getImageNodeInfo(metadata: FigmaMetadataResult): Array<{
151
+ nodeId: string;
152
+ name: string;
153
+ }>;
124
154
  /**
125
155
  * Enrich metadata with saved image file paths
126
156
  *
127
157
  * Use this function after saving images from buffers to disk to add file path information to the metadata.
128
158
  *
129
159
  * @param metadata - The metadata result from getFigmaMetadata
130
- * @param imagePaths - Array of file paths corresponding to the images array
160
+ * @param imagePaths - Array of file paths (ordered) OR object mapping node IDs to paths/URLs
131
161
  * @param options - Options for path generation
132
162
  * @returns Enriched metadata with downloadedImage properties on nodes
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * // Array format (ordered)
167
+ * const enriched = enrichMetadataWithImages(metadata, ['/path/to/img1.png', '/path/to/img2.png']);
168
+ *
169
+ * // Object format (keyed by node ID) - useful after uploading to CDN
170
+ * const enriched = enrichMetadataWithImages(metadata, {
171
+ * '123:456': 'https://cdn.example.com/icon.png',
172
+ * '789:012': 'https://cdn.example.com/logo.png'
173
+ * });
174
+ * ```
133
175
  */
134
- export declare function enrichMetadataWithImages(metadata: FigmaMetadataResult, imagePaths: string[], options?: {
176
+ export declare function enrichMetadataWithImages(metadata: FigmaMetadataResult, imagePaths: string[] | Record<string, string>, options?: {
135
177
  useRelativePaths?: boolean | string;
136
178
  localPath?: string;
137
179
  }): FigmaMetadataResult;
@@ -16,6 +16,7 @@ export declare function getImageDimensions(imagePath: string): Promise<{
16
16
  height: number;
17
17
  }>;
18
18
  export type ImageProcessingResult = {
19
+ nodeId?: string;
19
20
  filePath?: string;
20
21
  buffer?: ArrayBuffer;
21
22
  originalDimensions: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "figma-metadata-extractor",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
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",