// Utility to import Figma designs and convert them to basic React components import type { Message } from 'ai'; import { generateId } from './fileUtils'; import { escapeBoltTags } from './projectCommands'; /** * Extract the file key from a Figma URL */ function extractFileKey(url: string): string { const match = url.match(/file\/(\w+)/); if (!match) { throw new Error('Invalid Figma URL'); } return match[1]; } interface GeneratedComponent { name: string; code: string; } /** * Recursively collect frame nodes from the Figma document */ function collectFrames(node: any, frames: any[]) { if (node.type === 'FRAME') { frames.push(node); } if (Array.isArray(node.children)) { node.children.forEach((child: any) => collectFrames(child, frames)); } } function figmaFramesToComponents(frames: any[]): GeneratedComponent[] { return frames.map((frame) => { const name = frame.name.replace(/[^a-zA-Z0-9]/g, '') || 'Component'; const code = `export function ${name}() {\n return
${frame.name}
;\n}`; return { name, code }; }); } /** * Create chat messages from a Figma design */ export async function createChatFromFigma(figmaUrl: string, token: string): Promise { const fileKey = extractFileKey(figmaUrl); const res = await fetch(`https://api.figma.com/v1/files/${fileKey}`, { headers: { 'X-Figma-Token': token }, }); if (!res.ok) { throw new Error(`Failed to fetch Figma file: ${res.status}`); } const data = (await res.json()) as { document: unknown }; const frames: any[] = []; collectFrames((data as any).document, frames); const components = figmaFramesToComponents(frames); const componentActions = components .map( (c) => `${escapeBoltTags(c.code)}`, ) .join('\n'); const assistantMessage: Message = { role: 'assistant', content: `Converted Figma design from ${figmaUrl} to React components.\n${componentActions}`, id: generateId(), createdAt: new Date(), }; const userMessage: Message = { role: 'user', content: `Import design from ${figmaUrl}`, id: generateId(), createdAt: new Date(), }; return [userMessage, assistantMessage]; }