← back to Ventura Claw

server/connectors/figma.js

26 lines

// Figma — REAL.
const API = "https://api.figma.com/v1";
function token(c) { const t = c?.FIGMA_TOKEN || process.env.FIGMA_TOKEN; if (!t) throw new Error("FIGMA_TOKEN not set"); return t; }
async function call(method, path, body, c) {
  const r = await fetch(`${API}${path}`, { method, headers: { "X-Figma-Token": token(c), "Content-Type": "application/json" }, body: body ? JSON.stringify(body) : undefined });
  const d = await r.json();
  if (!r.ok) throw new Error(`figma ${path} ${r.status}: ${d.err || JSON.stringify(d).slice(0,200)}`);
  return d;
}
module.exports = {
  meta: { id: "figma", name: "Figma", category: "creative", docsUrl: "https://www.figma.com/developers/api", auth: "oauth2", realImpl: true },
  fields: [{ key: "FIGMA_TOKEN", label: "Personal Access Token", type: "password", required: true, hint: "figma.com/settings > Personal access tokens" }],
  configured(c) { return !!(c?.FIGMA_TOKEN || process.env.FIGMA_TOKEN); },
  async health(c) {
    if (!this.configured(c)) return { ok: false, reason: "no_token" };
    try { const d = await call("GET", "/me", null, c); return { ok: true, user: d.email || d.handle || d.id, plan: d.plan_type || "starter" }; }
    catch (e) { return { ok: false, reason: e.message }; }
  },
  actions: {
    async "me"(_, c) { return call("GET", "/me", null, c); },
    async "file.read"({ key }, c) { if (!key) throw new Error("file key required"); return call("GET", `/files/${key}`, null, c); },
    async "file.comments"({ key }, c) { if (!key) throw new Error("file key required"); return call("GET", `/files/${key}/comments`, null, c); },
    async "team.projects"({ team_id }, c) { if (!team_id) throw new Error("team_id required"); return call("GET", `/teams/${team_id}/projects`, null, c); }
  }
};