libs/@guardian/source/scripts/create-icons/get-svgs-from-figma.ts (66 lines of code) (raw):

import 'dotenv/config'; interface FigmaComponentsResponse { meta: { components: Array<{ containing_frame?: { name: string; }; name: string; node_id: string; description: string; }>; }; } interface FigmaImagesResponse { images: Record<string, string>; } export const ICON_FILE = 'b2qv2OMLoNCYnP01ipfrP7'; if (!process.env.FIGMA_TOKEN) { console.log('FIGMA_TOKEN not set. Please add it to your .env file.'); console.log('See https://www.figma.com/developers/api#access-tokens'); process.exit(1); } const FIGMA_API_OPTIONS = { headers: { 'X-Figma-Token': process.env.FIGMA_TOKEN, }, }; const figmaApi = async <T>(url: string): Promise<T> => { const response = await fetch( `https://api.figma.com/v1/${url}`, FIGMA_API_OPTIONS, ); return response.json() as Promise<T>; }; export const getIconsFromFigma = async () => { // Get a list of available (figma) components from Figma // https://www.figma.com/developers/api#library-items-types const figmaComponents = ( await figmaApi<FigmaComponentsResponse>(`files/${ICON_FILE}/components`) ).meta.components; // filter out the icons from the list of figma components const figmaIconComponents = figmaComponents.filter((c) => { return ( // Only get icons that are in a certain frame c.containing_frame && c.containing_frame.name === 'UI icons 24x24' ); }); const iconIds = figmaIconComponents.map(({ node_id }) => node_id).join(','); // Get the URLs we can fetch actual images from from Figma // https://www.figma.com/developers/api#get-images-endpoint const figmaIconSvgUrlsByNodeId = ( await figmaApi<FigmaImagesResponse>( `images/${ICON_FILE}/?ids=${iconIds}&format=svg`, ) ).images; const icons = []; for (const icon of figmaIconComponents) { const url = figmaIconSvgUrlsByNodeId[icon.node_id]; if (url) { console.log(`Fetching ${icon.name}.svg`); // Fetch SVG markup from Figma const response = await fetch(url); const svg = await response.text(); icons.push({ name: icon.name, svg, }); } else { throw new Error('No URL found for icon'); } } return icons; };