Changes
5 changed files (+0/-258)
-
-
@@ -1,36 +0,0 @@# generateStaticFigmaFile _Internal utility script (not published)_ A helper tool to download a Figma Frame as an API response JSON file and a rendered SVG image file. ## Usage ```sh $ yarn generate-static-figma-file -t <Figma Personall Access Token> -u <Figma file URL> -o <Output directory> # You can also invoke by below $ yarn workspace @figspec/generate-static-figma-file generate <...args> # or this $ cd scripts/generateStaticFigmaFile $ yarn generate <...args> ``` This script loads `.env` file at the root of the repository with `dotenv` package. If the `--token` option is absent, the script will use environment variable `FIGMA_TOKEN` instead. ``` # <repo root>/.env FIGMA_TOKEN=<Figma Personal Access Token> ``` ```sh $ yarn generate-static-figma-file <...args except --token> ``` For more information, please refer tool's help. ```sh $ yarn generate-static-figma-file --help ```
-
-
-
@@ -1,41 +0,0 @@import fetch from "node-fetch"; export async function fetchFile(client, fileKey) { const fileResponse = await client.file(fileKey); const frames = listAllFrames(fileResponse.data.document); const imageResponse = await client.fileImages(fileKey, { ids: frames.map((frame) => frame.id), scale: 1, format: "svg", }); const images = []; for (const [nodeId, image] of Object.entries(imageResponse.data.images)) { const res = await fetch(image); images.push({ nodeId, data: await res.buffer(), }); } return { response: fileResponse.data, images, }; } function listAllFrames(node) { if ("absoluteBoundingBox" in node) { return [node]; } if (!node.children || node.children.length === 0) { return []; } return node.children.map(listAllFrames).flat(); }
-
-
-
@@ -1,42 +0,0 @@import fetch from "node-fetch"; export async function fetchNode(client, fileKey, nodeId) { const [nodes, imageResponse] = await Promise.all([ client.fileNodes(fileKey, { ids: [nodeId] }), client.fileImages(fileKey, { ids: [nodeId], scale: 1, format: "svg", }), ]); if (imageResponse.data.err) { throw new Error(`Failed to render nodes: ${imageResponse.data.err}`); } const [image] = await Promise.all( Object.entries(imageResponse.data.images) .filter((image) => image[0] === nodeId) .map(async ([nodeId, image]) => { if (!image) { throw new Error(`Failed to render a node (node-id=${nodeId}`); } const res = await fetch(image); if (res.status !== 200) { throw new Error( `Failed to fetch a rendered image: node-id=${nodeId}, url=${image}` ); } return res.buffer(); }) ); if (!image) { throw new Error("Image not found."); } return { response: nodes.data, image }; }
-
-
-
@@ -1,125 +0,0 @@import { program } from "commander"; import * as dotenv from "dotenv"; import * as Figma from "figma-js"; import * as fs from "fs/promises"; import * as path from "path"; import { URL, fileURLToPath } from "url"; import pkg from "./package.json"; import { fetchFile } from "./fetchFile.mjs"; import { fetchNode } from "./fetchNode.mjs"; const isFigmaURL = (url) => /https:\/\/([w.-]+.)?figma.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?$/.test( url ); program .version(pkg.version) .option("-o, --outDir <outDir>", "Directory to download", process.cwd()) .option("-t, --token <token>", "Personal Access Token for Figma API") .option("-u, --url <url>", "Figma file/node url to fetch") .option("--pretty", "Pretty print JSON"); async function main() { const token = program.token || process.env.FIGMA_TOKEN; if (!token) { console.error("Personal Access Token is required."); process.exit(1); } if (!program.url) { console.error("File/Node url is required."); process.exit(1); } if (!isFigmaURL(program.url)) { console.error("The URL is not a valid Figma URL."); process.exit(1); } const url = new URL(program.url); const fileKey = url.pathname.split("/")[2]; const nodeId = url.searchParams.get("node-id") || null; const figma = Figma.Client({ personalAccessToken: token, }); const files = await (async () => { if (nodeId) { const node = await fetchNode(figma, fileKey, nodeId); return [ { filename: `${nodeId}.json`, data: program.pretty ? JSON.stringify(node.response, null, 2) : JSON.stringify(node.response), }, { filename: `${nodeId}.svg`, data: node.image, }, ]; } const file = await fetchFile(figma, fileKey); return [ { filename: "file.json", data: program.pretty ? JSON.stringify(file.response, null, 2) : JSON.stringify(file.response), }, ...file.images.map((image) => ({ filename: `${image.nodeId}.svg`, data: image.data, })), ]; })(); const outDir = path.resolve( path.isAbsolute(program.outDir) ? program.outDir : path.resolve(process.env.INIT_CWD, program.outDir), fileKey ); try { await fs.rmdir(outDir, { recursive: true, }); } catch (err) { // Ignore when the dir does not exist if (err.code !== "ENOENT") { throw err; } } await fs.mkdir(outDir, { recursive: true, }); await Promise.all( files.map(async (file) => { await fs.writeFile(path.resolve(outDir, file.filename), file.data); }) ); } dotenv.config({ path: path.resolve( path.dirname(fileURLToPath(import.meta.url)), "../../.env" ), }); program.parse(); main().catch((err) => { console.error(err); process.exit(1); });
-
-
-
@@ -1,14 +0,0 @@{ "name": "@figspec/generate-static-figma-file", "version": "0.1.0", "private": true, "type": "module", "dependencies": { "commander": "^6.1.0", "figma-js": "^1.13.0", "node-fetch": "^2.6.1" }, "scripts": { "generate": "node --experimental-json-modules ./index.mjs" } }
-