import { generateKey } from "./utils/keygen.js";
/** Recursively extracts text nodes from a Figma document */
export function extractTextNodes(node, currentFrame = "") {
let texts = [];
// Skip invisible nodes
if (node.visible === false) {
return texts;
}
// If this node is a FRAME or COMPONENT, treat it as a new group
if (node.type === "FRAME" || node.type === "COMPONENT" || node.type === "COMPONENT_SET") {
currentFrame = node.name.trim().toLowerCase().replace(/\s+/g, "_");
}
// Extract visible text nodes
if (node.type === "TEXT" && node.characters?.trim()) {
const key = generateKey(node.characters);
texts.push({
frame: currentFrame || "global",
key,
value: node.characters.trim(),
});
}
// Dive deeper into children
if (node.children && Array.isArray(node.children)) {
for (const child of node.children) {
texts = texts.concat(extractTextNodes(child, currentFrame));
}
}
return texts;
}
/** Convert extracted text nodes into nested JSON by frame */
export function toNestedJSON(texts) {
const result = {};
for (const { frame, key, value } of texts) {
if (!result[frame]) result[frame] = {};
result[frame][key] = value;
}
return result;
}