figma-json-tree 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -0
- package/dist/cli/index.js +1138 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/figma-html.js +95 -0
- package/dist/figma-html.js.map +1 -0
- package/dist/figma-json-fetch.js +53 -0
- package/dist/figma-json-fetch.js.map +1 -0
- package/dist/figma-tree.js +808 -0
- package/dist/figma-tree.js.map +1 -0
- package/dist/types/cli/args.d.ts +27 -0
- package/dist/types/cli/args.d.ts.map +1 -0
- package/dist/types/cli/commands/download.d.ts +4 -0
- package/dist/types/cli/commands/download.d.ts.map +1 -0
- package/dist/types/cli/commands/export.d.ts +3 -0
- package/dist/types/cli/commands/export.d.ts.map +1 -0
- package/dist/types/cli/commands/query.d.ts +3 -0
- package/dist/types/cli/commands/query.d.ts.map +1 -0
- package/dist/types/cli/env.d.ts +2 -0
- package/dist/types/cli/env.d.ts.map +1 -0
- package/dist/types/cli/html/input.d.ts +5 -0
- package/dist/types/cli/html/input.d.ts.map +1 -0
- package/dist/types/cli/index.d.ts +3 -0
- package/dist/types/cli/index.d.ts.map +1 -0
- package/dist/types/cli/output.d.ts +4 -0
- package/dist/types/cli/output.d.ts.map +1 -0
- package/dist/types/cli/run.d.ts +8 -0
- package/dist/types/cli/run.d.ts.map +1 -0
- package/dist/types/figma-html/attributes.d.ts +4 -0
- package/dist/types/figma-html/attributes.d.ts.map +1 -0
- package/dist/types/figma-html/classes.d.ts +3 -0
- package/dist/types/figma-html/classes.d.ts.map +1 -0
- package/dist/types/figma-html/escape.d.ts +2 -0
- package/dist/types/figma-html/escape.d.ts.map +1 -0
- package/dist/types/figma-html/index.d.ts +3 -0
- package/dist/types/figma-html/index.d.ts.map +1 -0
- package/dist/types/figma-html/renderer.d.ts +5 -0
- package/dist/types/figma-html/renderer.d.ts.map +1 -0
- package/dist/types/figma-html/types.d.ts +4 -0
- package/dist/types/figma-html/types.d.ts.map +1 -0
- package/dist/types/figma-html/validate.d.ts +3 -0
- package/dist/types/figma-html/validate.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/client.d.ts +8 -0
- package/dist/types/figma-json-fetch/client.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/endpoints.d.ts +3 -0
- package/dist/types/figma-json-fetch/endpoints.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/errors.d.ts +7 -0
- package/dist/types/figma-json-fetch/errors.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/index.d.ts +4 -0
- package/dist/types/figma-json-fetch/index.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/request.d.ts +3 -0
- package/dist/types/figma-json-fetch/request.d.ts.map +1 -0
- package/dist/types/figma-json-fetch/types.d.ts +9 -0
- package/dist/types/figma-json-fetch/types.d.ts.map +1 -0
- package/dist/types/figma-tree/index.d.ts +10 -0
- package/dist/types/figma-tree/index.d.ts.map +1 -0
- package/dist/types/figma-tree/input/normalize.d.ts +11 -0
- package/dist/types/figma-tree/input/normalize.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/converters/diagnostics.d.ts +3 -0
- package/dist/types/figma-tree/ir/converters/diagnostics.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/converters/layout.d.ts +4 -0
- package/dist/types/figma-tree/ir/converters/layout.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/converters/style.d.ts +6 -0
- package/dist/types/figma-tree/ir/converters/style.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/converters/text.d.ts +4 -0
- package/dist/types/figma-tree/ir/converters/text.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/model/document.d.ts +12 -0
- package/dist/types/figma-tree/ir/model/document.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/model/types.d.ts +61 -0
- package/dist/types/figma-tree/ir/model/types.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/pipeline.d.ts +5 -0
- package/dist/types/figma-tree/ir/pipeline.d.ts.map +1 -0
- package/dist/types/figma-tree/ir/plugins/run.d.ts +11 -0
- package/dist/types/figma-tree/ir/plugins/run.d.ts.map +1 -0
- package/dist/types/figma-tree/model/types.d.ts +30 -0
- package/dist/types/figma-tree/model/types.d.ts.map +1 -0
- package/dist/types/figma-tree/model/value.d.ts +4 -0
- package/dist/types/figma-tree/model/value.d.ts.map +1 -0
- package/dist/types/figma-tree/selector/match.d.ts +4 -0
- package/dist/types/figma-tree/selector/match.d.ts.map +1 -0
- package/dist/types/figma-tree/selector/parser.d.ts +3 -0
- package/dist/types/figma-tree/selector/parser.d.ts.map +1 -0
- package/dist/types/figma-tree/selector/types.d.ts +24 -0
- package/dist/types/figma-tree/selector/types.d.ts.map +1 -0
- package/dist/types/figma-tree/tailwind/convert.d.ts +3 -0
- package/dist/types/figma-tree/tailwind/convert.d.ts.map +1 -0
- package/dist/types/figma-tree/tailwind/style.d.ts +6 -0
- package/dist/types/figma-tree/tailwind/style.d.ts.map +1 -0
- package/dist/types/figma-tree/tree/figma-tree.d.ts +39 -0
- package/dist/types/figma-tree/tree/figma-tree.d.ts.map +1 -0
- package/dist/types/figma-tree/tree/records.d.ts +5 -0
- package/dist/types/figma-tree/tree/records.d.ts.map +1 -0
- package/docs/api.md +89 -0
- package/docs/architecture.md +70 -0
- package/docs/html.md +90 -0
- package/docs/ir.md +84 -0
- package/docs/verification.md +33 -0
- package/package.json +57 -0
|
@@ -0,0 +1,1138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs as e } from "node:util";
|
|
3
|
+
import { readFile as t, writeFile as n } from "node:fs/promises";
|
|
4
|
+
//#region src/figma-json-fetch/endpoints.ts
|
|
5
|
+
var r = "https://api.figma.com/v1";
|
|
6
|
+
function i(e) {
|
|
7
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(e)) throw TypeError("Expected a non-empty Figma file key");
|
|
8
|
+
return new URL(`${r}/files/${encodeURIComponent(e)}`);
|
|
9
|
+
}
|
|
10
|
+
function a(e, t) {
|
|
11
|
+
if (!t.length || t.some((e) => !/^I?\d+:\d+(?:;I?\d+:\d+)*$/.test(e))) throw TypeError("Expected API node IDs such as 49:7390 or I49:7403;38:5243");
|
|
12
|
+
let n = i(e);
|
|
13
|
+
return n.pathname += "/nodes", n.searchParams.set("ids", [...new Set(t)].join(",")), n;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/figma-json-fetch/errors.ts
|
|
17
|
+
var o = class extends Error {
|
|
18
|
+
status;
|
|
19
|
+
retryAfter;
|
|
20
|
+
name = "FigmaHTTPError";
|
|
21
|
+
constructor(e, t) {
|
|
22
|
+
super(`Figma API request failed (HTTP ${e})${t ? `; Retry-After: ${t}` : ""}`), this.status = e, this.retryAfter = t;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/figma-json-fetch/request.ts
|
|
27
|
+
async function s(e, t, n, r) {
|
|
28
|
+
let i = await e(t, {
|
|
29
|
+
headers: {
|
|
30
|
+
"X-Figma-Token": n,
|
|
31
|
+
Accept: "application/json"
|
|
32
|
+
},
|
|
33
|
+
signal: r.signal,
|
|
34
|
+
redirect: "error"
|
|
35
|
+
});
|
|
36
|
+
if (!i.ok) throw new o(i.status, i.headers.get("retry-after"));
|
|
37
|
+
return await i.json();
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/figma-json-fetch/client.ts
|
|
41
|
+
var c = class {
|
|
42
|
+
#e;
|
|
43
|
+
#t;
|
|
44
|
+
constructor(e) {
|
|
45
|
+
if (typeof e.token != "string" || !e.token.trim()) throw TypeError("A Figma token is required");
|
|
46
|
+
this.#e = e.token, this.#t = e.fetch ?? globalThis.fetch.bind(globalThis);
|
|
47
|
+
}
|
|
48
|
+
getFile(e, t = {}) {
|
|
49
|
+
return s(this.#t, i(e), this.#e, t);
|
|
50
|
+
}
|
|
51
|
+
getNodes(e, t, n = {}) {
|
|
52
|
+
return s(this.#t, a(e, t), this.#e, n);
|
|
53
|
+
}
|
|
54
|
+
}, l = "Usage:\n figma-json-tree download --file FILE_KEY [--nodes 49:7390,49:7391] [--out file.json] [--force]\n figma-json-tree query --input file.json --selector 'FRAME[name=\"Hover Card\"]' [--out node.json] [--force]\n figma-json-tree queryAll --input file.json --selector '[name=\"Hover Card\"]' [--out nodes.json] [--force]\n figma-json-tree queryAll --input file.json --name-regex '^ToBe' [--regex-flags i]\n figma-json-tree export --input file.json --selector 'FRAME[name=\"Hover Card\"]' --format html [--styles inline|tailwind] [--out page.html] [--force]\n figma-json-tree export --input design.ir.json --format html [--styles tailwind]\n\nUse either --selector or --name-regex. --regex-flags applies only to --name-regex.\nquery returns the first original subtree or null; queryAll returns an array (possibly empty).\nInputs: parsed file/node API responses or a single subtree saved as JSON.\nAuthentication: FIGMA_TOKEN is required only for download. Queries and exports read local files.\nexport accepts original Figma JSON, standard IR or Tailwind IR and exports one root.\nFor export, --format defaults to html. Styles default to inline (Tailwind for Tailwind IR).\nexport returns body contents only: no doctype, html, head, body, style or script tags.\nTailwind exports contain classes and residual inline styles; the host project builds the CSS.\nWithout --out, JSON or exported HTML is written to stdout. Existing files require --force.\n", u = {
|
|
55
|
+
out: { type: "string" },
|
|
56
|
+
force: {
|
|
57
|
+
type: "boolean",
|
|
58
|
+
default: !1
|
|
59
|
+
},
|
|
60
|
+
help: {
|
|
61
|
+
type: "boolean",
|
|
62
|
+
short: "h"
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
function d(e) {
|
|
66
|
+
if (e !== void 0 && !e.trim()) throw Error("--out must be a non-empty path");
|
|
67
|
+
}
|
|
68
|
+
function ee(t) {
|
|
69
|
+
let { values: n } = e({
|
|
70
|
+
args: t,
|
|
71
|
+
strict: !0,
|
|
72
|
+
options: {
|
|
73
|
+
...u,
|
|
74
|
+
file: { type: "string" },
|
|
75
|
+
nodes: { type: "string" }
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (n.help) return "help";
|
|
79
|
+
if (!n.file) throw Error("--file FILE_KEY is required");
|
|
80
|
+
if (n.nodes !== void 0 && !n.nodes.trim()) throw Error("--nodes must contain at least one node ID");
|
|
81
|
+
return d(n.out), {
|
|
82
|
+
command: "download",
|
|
83
|
+
fileKey: n.file,
|
|
84
|
+
nodeIds: n.nodes?.split(",").map((e) => e.trim()),
|
|
85
|
+
out: n.out,
|
|
86
|
+
force: n.force
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function te(e, t, n) {
|
|
90
|
+
if (e !== void 0 == (t !== void 0)) throw Error("Provide exactly one of --selector or --name-regex");
|
|
91
|
+
if (e !== void 0) {
|
|
92
|
+
if (n !== void 0) throw Error("--regex-flags requires --name-regex");
|
|
93
|
+
if (!e.trim()) throw Error("--selector must be non-empty");
|
|
94
|
+
return e;
|
|
95
|
+
}
|
|
96
|
+
return { name: new RegExp(t, n) };
|
|
97
|
+
}
|
|
98
|
+
function f(t, n) {
|
|
99
|
+
let { values: r } = e({
|
|
100
|
+
args: n,
|
|
101
|
+
strict: !0,
|
|
102
|
+
options: {
|
|
103
|
+
...u,
|
|
104
|
+
input: { type: "string" },
|
|
105
|
+
selector: { type: "string" },
|
|
106
|
+
"name-regex": { type: "string" },
|
|
107
|
+
"regex-flags": { type: "string" }
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
if (r.help) return "help";
|
|
111
|
+
if (!r.input?.trim()) throw Error("--input must specify a local JSON file");
|
|
112
|
+
return d(r.out), {
|
|
113
|
+
command: t,
|
|
114
|
+
input: r.input,
|
|
115
|
+
selector: te(r.selector, r["name-regex"], r["regex-flags"]),
|
|
116
|
+
out: r.out,
|
|
117
|
+
force: r.force
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function ne(t) {
|
|
121
|
+
let { values: n } = e({
|
|
122
|
+
args: t,
|
|
123
|
+
strict: !0,
|
|
124
|
+
options: {
|
|
125
|
+
...u,
|
|
126
|
+
input: { type: "string" },
|
|
127
|
+
selector: { type: "string" },
|
|
128
|
+
format: {
|
|
129
|
+
type: "string",
|
|
130
|
+
default: "html"
|
|
131
|
+
},
|
|
132
|
+
styles: { type: "string" }
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
if (n.help) return "help";
|
|
136
|
+
if (!n.input?.trim()) throw Error("--input must specify a local JSON file");
|
|
137
|
+
if (n.format !== "html") throw Error("--format currently supports only html");
|
|
138
|
+
if (n.styles !== void 0 && n.styles !== "inline" && n.styles !== "tailwind") throw Error("--styles must be inline or tailwind");
|
|
139
|
+
if (n.selector !== void 0 && !n.selector.trim()) throw Error("--selector must be non-empty");
|
|
140
|
+
return d(n.out), {
|
|
141
|
+
command: "export",
|
|
142
|
+
input: n.input,
|
|
143
|
+
selector: n.selector,
|
|
144
|
+
styles: n.styles,
|
|
145
|
+
out: n.out,
|
|
146
|
+
force: n.force
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function re(e) {
|
|
150
|
+
let [t, ...n] = e;
|
|
151
|
+
if (e.length === 1 && (t === "--help" || t === "-h")) return "help";
|
|
152
|
+
if (t === "download") return ee(n);
|
|
153
|
+
if (t === "query" || t === "queryAll") return f(t, n);
|
|
154
|
+
if (t === "export") return ne(n);
|
|
155
|
+
throw Error("Expected download, query, queryAll or export; use --help");
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/cli/output.ts
|
|
159
|
+
async function p(e, t, n, r) {
|
|
160
|
+
await m(`${JSON.stringify(e, null, 2)}\n`, t, n, r);
|
|
161
|
+
}
|
|
162
|
+
async function m(e, t, r, i) {
|
|
163
|
+
t ? await n(t, e, { flag: r ? "w" : "wx" }) : i(e);
|
|
164
|
+
}
|
|
165
|
+
function ie(e, t) {
|
|
166
|
+
let n = e instanceof Error ? e.message : "Unknown error";
|
|
167
|
+
return t ? n.split(t).join("[redacted]") : n;
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/cli/commands/download.ts
|
|
171
|
+
async function ae(e, t, n) {
|
|
172
|
+
await p(e.nodeIds ? await t.getNodes(e.fileKey, e.nodeIds) : await t.getFile(e.fileKey), e.out, e.force, n);
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
//#region src/figma-html/classes.ts
|
|
176
|
+
function oe(e) {
|
|
177
|
+
return e.replace(/\[((?:[a-z-]+:)?)([+-]?(?:\d+\.\d+|\.\d+))([a-z%]*)\]/gi, (e, t, n, r) => `[${t}${Number(Number(n).toFixed(2))}${r}]`);
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/figma-html/escape.ts
|
|
181
|
+
var h = {
|
|
182
|
+
"&": "&",
|
|
183
|
+
"<": "<",
|
|
184
|
+
">": ">",
|
|
185
|
+
"\"": """,
|
|
186
|
+
"'": "'"
|
|
187
|
+
};
|
|
188
|
+
function g(e) {
|
|
189
|
+
return e.replace(/[&<>"']/g, (e) => h[e]);
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/figma-html/attributes.ts
|
|
193
|
+
function _(e) {
|
|
194
|
+
if (e.startsWith("--")) return e;
|
|
195
|
+
let t = e.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`);
|
|
196
|
+
return t.startsWith("ms-") ? `-${t}` : t;
|
|
197
|
+
}
|
|
198
|
+
function v(e) {
|
|
199
|
+
return Object.entries(e).map(([e, t]) => `${_(e)}:${t}`).join(";");
|
|
200
|
+
}
|
|
201
|
+
function y(e, t) {
|
|
202
|
+
let n = [
|
|
203
|
+
["data-figma-id", e.source.id],
|
|
204
|
+
["data-figma-name", e.source.name],
|
|
205
|
+
["data-figma-type", e.source.type]
|
|
206
|
+
];
|
|
207
|
+
t && "className" in e && e.className && n.push(["class", oe(e.className)]);
|
|
208
|
+
let r = v(e.visible ? e.style : {
|
|
209
|
+
...e.style,
|
|
210
|
+
display: "none"
|
|
211
|
+
});
|
|
212
|
+
r && n.push(["style", r]);
|
|
213
|
+
let i = n.map(([e, t]) => ` ${e}="${g(t)}"`).join("");
|
|
214
|
+
return e.visible ? i : `${i} hidden`;
|
|
215
|
+
}
|
|
216
|
+
//#endregion
|
|
217
|
+
//#region src/figma-html/validate.ts
|
|
218
|
+
function b(e) {
|
|
219
|
+
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
220
|
+
}
|
|
221
|
+
function se(e, t) {
|
|
222
|
+
if (!b(e) || !b(e.source) || typeof e.source.id != "string" || typeof e.source.name != "string" || typeof e.source.type != "string" || typeof e.visible != "boolean" || !b(e.style) || !Array.isArray(e.children)) throw TypeError("Expected an IR node with source, visible, style and children");
|
|
223
|
+
if (e.text !== void 0 && (!b(e.text) || typeof e.text.characters != "string")) throw TypeError(`Invalid text in IR node ${e.source.id}`);
|
|
224
|
+
if (t && typeof e.className != "string") throw TypeError(`Missing className in Tailwind node ${e.source.id}`);
|
|
225
|
+
for (let [t, n] of Object.entries(e.style)) {
|
|
226
|
+
if (!/^(?:--[\w-]+|[a-zA-Z][a-zA-Z0-9-]*)$/.test(t)) throw TypeError(`Invalid CSS property in IR node ${e.source.id}`);
|
|
227
|
+
if (typeof n != "string" && (typeof n != "number" || !Number.isFinite(n))) throw TypeError(`Invalid CSS value in IR node ${e.source.id}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function x(e) {
|
|
231
|
+
if (!b(e) || e.schemaVersion !== 1 || !Array.isArray(e.diagnostics) || e.target !== void 0 && e.target !== "tailwind-v4") throw TypeError("Expected a standard IR document or Tailwind v4 IR (schemaVersion 1)");
|
|
232
|
+
let t = e.target === "tailwind-v4", n = [e.root], r = /* @__PURE__ */ new Set();
|
|
233
|
+
for (; n.length;) {
|
|
234
|
+
let e = n.pop();
|
|
235
|
+
if (r.has(e)) throw TypeError("IR children must be an acyclic tree");
|
|
236
|
+
r.add(e), se(e, t);
|
|
237
|
+
for (let t of e.children) n.push(t);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region src/figma-html/renderer.ts
|
|
242
|
+
function ce(e) {
|
|
243
|
+
x(e);
|
|
244
|
+
let t = "target" in e && e.target === "tailwind-v4", n = [], r = [e.root];
|
|
245
|
+
for (; r.length;) {
|
|
246
|
+
let e = r.pop();
|
|
247
|
+
if (typeof e == "string") {
|
|
248
|
+
n.push(e);
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
n.push(`<div${y(e, t)}>`), e.text && n.push(g(e.text.characters)), r.push("</div>");
|
|
252
|
+
for (let t = e.children.length - 1; t >= 0; t--) r.push(e.children[t]);
|
|
253
|
+
}
|
|
254
|
+
return n.join("");
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/figma-tree/model/value.ts
|
|
258
|
+
function S(e) {
|
|
259
|
+
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
260
|
+
}
|
|
261
|
+
function C(e) {
|
|
262
|
+
let t = [e], n = /* @__PURE__ */ new WeakSet();
|
|
263
|
+
for (; t.length;) {
|
|
264
|
+
let e = t.pop();
|
|
265
|
+
if (typeof e == "object" && e && !n.has(e)) {
|
|
266
|
+
n.add(e);
|
|
267
|
+
for (let n of Object.values(e)) t.push(n);
|
|
268
|
+
Object.freeze(e);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return e;
|
|
272
|
+
}
|
|
273
|
+
function w(e) {
|
|
274
|
+
return typeof e == "number" && Number.isFinite(e) ? e : void 0;
|
|
275
|
+
}
|
|
276
|
+
//#endregion
|
|
277
|
+
//#region src/figma-tree/input/normalize.ts
|
|
278
|
+
var T = class extends Error {
|
|
279
|
+
name = "FigmaInputError";
|
|
280
|
+
};
|
|
281
|
+
function E(e, t) {
|
|
282
|
+
if (S(t)) for (let [n, r] of Object.entries(t)) S(r) && e.set(n, r);
|
|
283
|
+
}
|
|
284
|
+
function le(e) {
|
|
285
|
+
let t = [...e], n = /* @__PURE__ */ new WeakSet();
|
|
286
|
+
for (; t.length;) {
|
|
287
|
+
let e = t.pop();
|
|
288
|
+
if (!S(e) || typeof e.id != "string" || typeof e.name != "string" || typeof e.type != "string") throw new T("Each node must contain string id, name and type fields");
|
|
289
|
+
if (n.has(e)) throw new T("Input must be a JSON tree without cyclic or shared node objects");
|
|
290
|
+
if (n.add(e), e.children !== void 0) {
|
|
291
|
+
if (!Array.isArray(e.children)) throw new T(`Invalid children for node ${e.id}`);
|
|
292
|
+
for (let n of e.children) t.push(n);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function D(e) {
|
|
297
|
+
if (!S(e)) throw new T("Expected a parsed Figma response or node object");
|
|
298
|
+
let t = /* @__PURE__ */ new Map(), n = [], r = [];
|
|
299
|
+
if (E(t, e.components), typeof e.type == "string") r.push(e);
|
|
300
|
+
else if (S(e.document)) r.push(e.document);
|
|
301
|
+
else if (S(e.nodes)) for (let [i, a] of Object.entries(e.nodes)) if (a === null) n.push({
|
|
302
|
+
code: "missing-node",
|
|
303
|
+
nodeId: i,
|
|
304
|
+
message: "Figma returned null for this node"
|
|
305
|
+
});
|
|
306
|
+
else if (S(a) && S(a.document)) r.push(a.document), E(t, a.components);
|
|
307
|
+
else throw new T(`Invalid node response entry: ${i}`);
|
|
308
|
+
else throw new T("Expected document, nodes, or a single node");
|
|
309
|
+
le(r);
|
|
310
|
+
try {
|
|
311
|
+
let e = structuredClone({
|
|
312
|
+
roots: r,
|
|
313
|
+
components: t,
|
|
314
|
+
diagnostics: n
|
|
315
|
+
});
|
|
316
|
+
C(e.roots);
|
|
317
|
+
for (let t of e.components.values()) C(t);
|
|
318
|
+
return e;
|
|
319
|
+
} catch (e) {
|
|
320
|
+
throw new T(`Input must be structured-cloneable JSON: ${e instanceof Error ? e.message : "invalid value"}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/figma-tree/tailwind/style.ts
|
|
325
|
+
var O = {
|
|
326
|
+
display: {
|
|
327
|
+
flex: "flex",
|
|
328
|
+
none: "hidden"
|
|
329
|
+
},
|
|
330
|
+
position: {
|
|
331
|
+
relative: "relative",
|
|
332
|
+
absolute: "absolute"
|
|
333
|
+
},
|
|
334
|
+
boxSizing: { "border-box": "box-border" },
|
|
335
|
+
flexDirection: {
|
|
336
|
+
row: "flex-row",
|
|
337
|
+
column: "flex-col"
|
|
338
|
+
},
|
|
339
|
+
flexWrap: { wrap: "flex-wrap" },
|
|
340
|
+
justifyContent: {
|
|
341
|
+
"flex-start": "justify-start",
|
|
342
|
+
"flex-end": "justify-end",
|
|
343
|
+
center: "justify-center",
|
|
344
|
+
"space-between": "justify-between"
|
|
345
|
+
},
|
|
346
|
+
alignItems: {
|
|
347
|
+
"flex-start": "items-start",
|
|
348
|
+
"flex-end": "items-end",
|
|
349
|
+
center: "items-center",
|
|
350
|
+
baseline: "items-baseline"
|
|
351
|
+
},
|
|
352
|
+
alignContent: { "space-between": "content-between" },
|
|
353
|
+
alignSelf: { stretch: "self-stretch" },
|
|
354
|
+
overflow: { hidden: "overflow-hidden" },
|
|
355
|
+
borderStyle: { solid: "border-solid" },
|
|
356
|
+
textAlign: {
|
|
357
|
+
left: "text-left",
|
|
358
|
+
right: "text-right",
|
|
359
|
+
center: "text-center",
|
|
360
|
+
justify: "text-justify"
|
|
361
|
+
},
|
|
362
|
+
fontStyle: { italic: "italic" },
|
|
363
|
+
textDecorationLine: {
|
|
364
|
+
underline: "underline",
|
|
365
|
+
"line-through": "line-through"
|
|
366
|
+
},
|
|
367
|
+
textTransform: {
|
|
368
|
+
uppercase: "uppercase",
|
|
369
|
+
lowercase: "lowercase",
|
|
370
|
+
capitalize: "capitalize"
|
|
371
|
+
},
|
|
372
|
+
whiteSpace: { "pre-wrap": "whitespace-pre-wrap" },
|
|
373
|
+
flexGrow: { 1: "grow" },
|
|
374
|
+
flexShrink: { 0: "shrink-0" },
|
|
375
|
+
width: {
|
|
376
|
+
"100%": "w-full",
|
|
377
|
+
"fit-content": "w-fit"
|
|
378
|
+
},
|
|
379
|
+
height: {
|
|
380
|
+
"100%": "h-full",
|
|
381
|
+
"fit-content": "h-fit"
|
|
382
|
+
}
|
|
383
|
+
}, k = {
|
|
384
|
+
width: "w",
|
|
385
|
+
height: "h",
|
|
386
|
+
minWidth: "min-w",
|
|
387
|
+
maxWidth: "max-w",
|
|
388
|
+
minHeight: "min-h",
|
|
389
|
+
maxHeight: "max-h",
|
|
390
|
+
left: "left",
|
|
391
|
+
top: "top",
|
|
392
|
+
gap: "gap",
|
|
393
|
+
rowGap: "gap-y",
|
|
394
|
+
columnGap: "gap-x",
|
|
395
|
+
paddingTop: "pt",
|
|
396
|
+
paddingRight: "pr",
|
|
397
|
+
paddingBottom: "pb",
|
|
398
|
+
paddingLeft: "pl",
|
|
399
|
+
borderRadius: "rounded",
|
|
400
|
+
borderTopLeftRadius: "rounded-tl",
|
|
401
|
+
borderTopRightRadius: "rounded-tr",
|
|
402
|
+
borderBottomLeftRadius: "rounded-bl",
|
|
403
|
+
borderBottomRightRadius: "rounded-br",
|
|
404
|
+
borderWidth: "border",
|
|
405
|
+
borderTopWidth: "border-t",
|
|
406
|
+
borderRightWidth: "border-r",
|
|
407
|
+
borderBottomWidth: "border-b",
|
|
408
|
+
borderLeftWidth: "border-l",
|
|
409
|
+
backgroundColor: "bg",
|
|
410
|
+
color: "text",
|
|
411
|
+
borderColor: "border",
|
|
412
|
+
fontSize: "text",
|
|
413
|
+
fontWeight: "font",
|
|
414
|
+
lineHeight: "leading",
|
|
415
|
+
letterSpacing: "tracking",
|
|
416
|
+
opacity: "opacity",
|
|
417
|
+
flexBasis: "basis"
|
|
418
|
+
};
|
|
419
|
+
function A(e, t) {
|
|
420
|
+
let n = k[e], r = String(t);
|
|
421
|
+
if (n && !/[\s[\]_'"\\;]/.test(r)) return `${n}-[${e === "fontSize" ? "length:" : e === "fontWeight" ? "number:" : ""}${r}]`;
|
|
422
|
+
}
|
|
423
|
+
function j(e) {
|
|
424
|
+
let t = [], n = {};
|
|
425
|
+
for (let [r, i] of Object.entries(e)) {
|
|
426
|
+
let e = O[r]?.[String(i)] ?? A(r, i);
|
|
427
|
+
e ? t.push(e) : n[r] = i;
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
className: [...new Set(t)].join(" "),
|
|
431
|
+
style: n
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
//#endregion
|
|
435
|
+
//#region src/figma-tree/tailwind/convert.ts
|
|
436
|
+
function M(e) {
|
|
437
|
+
let t = structuredClone(e), n = [], r = [t.root];
|
|
438
|
+
for (; r.length;) {
|
|
439
|
+
let e = r.pop();
|
|
440
|
+
n.push(e);
|
|
441
|
+
for (let t of e.children) r.push(t);
|
|
442
|
+
}
|
|
443
|
+
let i = /* @__PURE__ */ new Map();
|
|
444
|
+
for (let e of n.reverse()) i.set(e, {
|
|
445
|
+
...e,
|
|
446
|
+
...j(e.style),
|
|
447
|
+
children: e.children.map((e) => i.get(e))
|
|
448
|
+
});
|
|
449
|
+
return {
|
|
450
|
+
schemaVersion: 1,
|
|
451
|
+
target: "tailwind-v4",
|
|
452
|
+
root: i.get(t.root),
|
|
453
|
+
diagnostics: t.diagnostics
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
//#endregion
|
|
457
|
+
//#region src/figma-tree/ir/model/document.ts
|
|
458
|
+
var N = class {
|
|
459
|
+
#e;
|
|
460
|
+
constructor(e) {
|
|
461
|
+
this.#e = C(structuredClone(e));
|
|
462
|
+
}
|
|
463
|
+
get schemaVersion() {
|
|
464
|
+
return 1;
|
|
465
|
+
}
|
|
466
|
+
get root() {
|
|
467
|
+
return this.#e.root;
|
|
468
|
+
}
|
|
469
|
+
get diagnostics() {
|
|
470
|
+
return this.#e.diagnostics;
|
|
471
|
+
}
|
|
472
|
+
toJSON() {
|
|
473
|
+
return structuredClone(this.#e);
|
|
474
|
+
}
|
|
475
|
+
toTailwind() {
|
|
476
|
+
return M(this.#e);
|
|
477
|
+
}
|
|
478
|
+
}, P = class extends Error {
|
|
479
|
+
pluginName;
|
|
480
|
+
nodeId;
|
|
481
|
+
name = "IRPluginError";
|
|
482
|
+
constructor(e, t, n) {
|
|
483
|
+
super(`IR plugin "${e}" failed for node ${t}`, { cause: n }), this.pluginName = e, this.nodeId = t;
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
function F(e) {
|
|
487
|
+
if (!S(e) || !S(e.source) || typeof e.source.id != "string" || typeof e.source.name != "string" || typeof e.source.type != "string" || ![
|
|
488
|
+
"container",
|
|
489
|
+
"text",
|
|
490
|
+
"shape",
|
|
491
|
+
"instance",
|
|
492
|
+
"unknown"
|
|
493
|
+
].includes(String(e.kind)) || typeof e.visible != "boolean" || !Array.isArray(e.children) || !S(e.layout) || ![
|
|
494
|
+
"none",
|
|
495
|
+
"horizontal",
|
|
496
|
+
"vertical"
|
|
497
|
+
].includes(String(e.layout.mode)) || typeof e.layout.wrap != "boolean" || !S(e.size) || ![
|
|
498
|
+
"FIXED",
|
|
499
|
+
"HUG",
|
|
500
|
+
"FILL"
|
|
501
|
+
].includes(String(e.size.widthMode)) || ![
|
|
502
|
+
"FIXED",
|
|
503
|
+
"HUG",
|
|
504
|
+
"FILL"
|
|
505
|
+
].includes(String(e.size.heightMode)) || !S(e.style) || !S(e.extensions)) throw TypeError("Plugin must return a standard IRNode");
|
|
506
|
+
for (let t of Object.values(e.style)) if (typeof t != "string" && (typeof t != "number" || !Number.isFinite(t))) throw TypeError("Invalid IR style value");
|
|
507
|
+
for (let t of ["width", "height"]) {
|
|
508
|
+
let n = e.size[t];
|
|
509
|
+
if (n !== void 0 && (typeof n != "number" || !Number.isFinite(n))) throw TypeError("Invalid IR size");
|
|
510
|
+
}
|
|
511
|
+
if (e.text !== void 0 && (!S(e.text) || typeof e.text.characters != "string")) throw TypeError("Invalid IR text");
|
|
512
|
+
}
|
|
513
|
+
function I(e, t = /* @__PURE__ */ new Set()) {
|
|
514
|
+
if (e !== null && typeof e != "string" && typeof e != "boolean" && !(typeof e == "number" && Number.isFinite(e))) {
|
|
515
|
+
if (typeof e != "object" || !Array.isArray(e) && Object.getPrototypeOf(e) !== Object.prototype && Object.getPrototypeOf(e) !== null) throw TypeError("Extensions must contain JSON values");
|
|
516
|
+
if (t.has(e)) throw TypeError("Cyclic extension value");
|
|
517
|
+
t.add(e);
|
|
518
|
+
for (let n of Object.values(e)) I(n, t);
|
|
519
|
+
t.delete(e);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function L(e) {
|
|
523
|
+
let t = [e], n = /* @__PURE__ */ new Set();
|
|
524
|
+
for (; t.length;) {
|
|
525
|
+
let e = t.pop();
|
|
526
|
+
if (n.has(e)) throw TypeError("IR children must form a tree");
|
|
527
|
+
n.add(e), F(e), I(e.extensions);
|
|
528
|
+
for (let n of e.children) t.push(n);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
function R(e, t, n) {
|
|
532
|
+
let r = Object.freeze({
|
|
533
|
+
source: t.source,
|
|
534
|
+
parent: t.parent?.source,
|
|
535
|
+
component: t.component
|
|
536
|
+
});
|
|
537
|
+
return n.reduce((e, n) => {
|
|
538
|
+
try {
|
|
539
|
+
let t = n.transform(C(e), r);
|
|
540
|
+
return L(t), structuredClone(t);
|
|
541
|
+
} catch (e) {
|
|
542
|
+
throw new P(n.name, t.source.id, e);
|
|
543
|
+
}
|
|
544
|
+
}, e);
|
|
545
|
+
}
|
|
546
|
+
//#endregion
|
|
547
|
+
//#region src/figma-tree/selector/types.ts
|
|
548
|
+
var z = [
|
|
549
|
+
"id",
|
|
550
|
+
"name",
|
|
551
|
+
"type",
|
|
552
|
+
"visible",
|
|
553
|
+
"componentName"
|
|
554
|
+
], B = class extends Error {
|
|
555
|
+
name = "SelectorSyntaxError";
|
|
556
|
+
};
|
|
557
|
+
//#endregion
|
|
558
|
+
//#region src/figma-tree/tree/records.ts
|
|
559
|
+
function* V(e) {
|
|
560
|
+
let t = [...e].reverse();
|
|
561
|
+
for (; t.length;) {
|
|
562
|
+
let e = t.pop();
|
|
563
|
+
yield e;
|
|
564
|
+
for (let n = e.children.length - 1; n >= 0; n--) t.push(e.children[n]);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
function H(e) {
|
|
568
|
+
let t = /* @__PURE__ */ new Map(), n = [...e];
|
|
569
|
+
for (; n.length;) {
|
|
570
|
+
let e = n.pop();
|
|
571
|
+
e.type === "COMPONENT" && t.set(e.id, e.name);
|
|
572
|
+
for (let t of e.children ?? []) n.push(t);
|
|
573
|
+
}
|
|
574
|
+
return t;
|
|
575
|
+
}
|
|
576
|
+
function U(e) {
|
|
577
|
+
let t = H(e.roots), n = [], r = e.roots.map((e) => ({
|
|
578
|
+
source: e,
|
|
579
|
+
parent: void 0
|
|
580
|
+
})).reverse();
|
|
581
|
+
for (; r.length;) {
|
|
582
|
+
let { source: i, parent: a } = r.pop(), o = typeof i.componentId == "string" ? i.componentId : void 0, s = o ? e.components.get(o) : void 0, c = {
|
|
583
|
+
source: i,
|
|
584
|
+
parent: a,
|
|
585
|
+
children: [],
|
|
586
|
+
componentName: s?.name ?? (o ? t.get(o) : void 0),
|
|
587
|
+
component: s
|
|
588
|
+
};
|
|
589
|
+
a ? a.children.push(c) : n.push(c);
|
|
590
|
+
let l = i.children ?? [];
|
|
591
|
+
for (let e = l.length - 1; e >= 0; e--) r.push({
|
|
592
|
+
source: l[e],
|
|
593
|
+
parent: c
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
return n;
|
|
597
|
+
}
|
|
598
|
+
//#endregion
|
|
599
|
+
//#region src/figma-tree/ir/converters/style.ts
|
|
600
|
+
function W(e) {
|
|
601
|
+
return Math.round(Math.max(0, Math.min(1, w(e) ?? 0)) * 255);
|
|
602
|
+
}
|
|
603
|
+
function G(e) {
|
|
604
|
+
if (!S(e) || e.type !== "SOLID" || !S(e.color)) return;
|
|
605
|
+
let { color: t } = e, n = Math.max(0, Math.min(1, (w(t.a) ?? 1) * (w(e.opacity) ?? 1)));
|
|
606
|
+
return `rgba(${W(t.r)},${W(t.g)},${W(t.b)},${Number(n.toFixed(6))})`;
|
|
607
|
+
}
|
|
608
|
+
function K(e) {
|
|
609
|
+
return Array.isArray(e) ? e.filter((e) => S(e) && e.visible !== !1) : [];
|
|
610
|
+
}
|
|
611
|
+
function ue(e) {
|
|
612
|
+
let t = {}, n = K(e.fills), r = n.length === 1 ? G(n[0]) : void 0;
|
|
613
|
+
r && (t[e.type === "TEXT" ? "color" : "backgroundColor"] = r);
|
|
614
|
+
let i = K(e.strokes), a = i.length === 1 ? G(i[0]) : void 0;
|
|
615
|
+
if (a) {
|
|
616
|
+
t.borderColor = a, t.borderStyle = "solid";
|
|
617
|
+
let n = w(e.strokeWeight);
|
|
618
|
+
if (n !== void 0 && (t.borderWidth = `${n}px`), S(e.individualStrokeWeights)) for (let [n, r] of Object.entries({
|
|
619
|
+
top: "borderTopWidth",
|
|
620
|
+
right: "borderRightWidth",
|
|
621
|
+
bottom: "borderBottomWidth",
|
|
622
|
+
left: "borderLeftWidth"
|
|
623
|
+
})) {
|
|
624
|
+
let i = w(e.individualStrokeWeights[n]);
|
|
625
|
+
i !== void 0 && (t[r] = `${i}px`);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
let o = w(e.cornerRadius);
|
|
629
|
+
if (o !== void 0 && (t.borderRadius = `${o}px`), Array.isArray(e.rectangleCornerRadii)) {
|
|
630
|
+
let n = [
|
|
631
|
+
"borderTopLeftRadius",
|
|
632
|
+
"borderTopRightRadius",
|
|
633
|
+
"borderBottomRightRadius",
|
|
634
|
+
"borderBottomLeftRadius"
|
|
635
|
+
];
|
|
636
|
+
e.rectangleCornerRadii.forEach((e, r) => {
|
|
637
|
+
n[r] && w(e) !== void 0 && (t[n[r]] = `${e}px`);
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
e.type === "ELLIPSE" && (t.borderRadius = "50%");
|
|
641
|
+
let s = w(e.opacity);
|
|
642
|
+
return s !== void 0 && (t.opacity = s), e.visible === !1 && (t.display = "none"), t;
|
|
643
|
+
}
|
|
644
|
+
//#endregion
|
|
645
|
+
//#region src/figma-tree/ir/converters/diagnostics.ts
|
|
646
|
+
function de(e, t) {
|
|
647
|
+
let n = e.source, r = [];
|
|
648
|
+
t && r.push("type");
|
|
649
|
+
for (let e of ["fills", "strokes"]) {
|
|
650
|
+
let t = K(n[e]);
|
|
651
|
+
(t.length > 1 || t.some((e) => e.type !== "SOLID")) && r.push(e);
|
|
652
|
+
}
|
|
653
|
+
return Array.isArray(n.effects) && n.effects.some((e) => S(e) && e.visible !== !1) && r.push("effects"), S(n.styleOverrideTable) && Object.keys(n.styleOverrideTable).length && r.push("styleOverrideTable"), (n.type === "VECTOR" || n.type === "BOOLEAN_OPERATION" || n.type === "STAR" || n.type === "REGULAR_POLYGON" || n.type === "LINE") && r.push("vectorGeometry"), n.layoutMode === "GRID" && r.push("layoutMode"), typeof n.rotation == "number" && n.rotation !== 0 && r.push("rotation"), typeof n.itemSpacing == "number" && n.itemSpacing < 0 && r.push("itemSpacing"), K(n.strokes).length && n.strokeAlign && n.strokeAlign !== "INSIDE" && r.push("strokeAlign"), n.isMask === !0 && r.push("isMask"), typeof n.cornerSmoothing == "number" && n.cornerSmoothing > 0 && r.push("cornerSmoothing"), r.map((e) => ({
|
|
654
|
+
code: "unsupported-property",
|
|
655
|
+
nodeId: n.id,
|
|
656
|
+
property: e,
|
|
657
|
+
message: `${e} is not fully represented in the basic IR`
|
|
658
|
+
}));
|
|
659
|
+
}
|
|
660
|
+
//#endregion
|
|
661
|
+
//#region src/figma-tree/ir/converters/layout.ts
|
|
662
|
+
function q(e, t) {
|
|
663
|
+
return e === "FIXED" || e === "HUG" || e === "FILL" ? e : t;
|
|
664
|
+
}
|
|
665
|
+
function J(e, t) {
|
|
666
|
+
let n = e.source.layoutMode === "HORIZONTAL", r = t === "width" === n ? e.source.primaryAxisSizingMode : e.source.counterAxisSizingMode, i = e.parent?.source.layoutMode === "HORIZONTAL", a = t === "width" === i;
|
|
667
|
+
return (e.parent?.source.layoutMode === "HORIZONTAL" || e.parent?.source.layoutMode === "VERTICAL") && (a && e.source.layoutGrow === 1 || !a && e.source.layoutAlign === "STRETCH") ? "FILL" : r === "AUTO" ? "HUG" : "FIXED";
|
|
668
|
+
}
|
|
669
|
+
function fe(e) {
|
|
670
|
+
let t = S(e.source.absoluteBoundingBox) ? e.source.absoluteBoundingBox : {}, n = S(e.source.size) ? e.source.size : {};
|
|
671
|
+
return {
|
|
672
|
+
width: w(n.x) ?? w(t.width),
|
|
673
|
+
height: w(n.y) ?? w(t.height),
|
|
674
|
+
widthMode: q(e.source.layoutSizingHorizontal, J(e, "width")),
|
|
675
|
+
heightMode: q(e.source.layoutSizingVertical, J(e, "height"))
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function Y(e, t, n, r, i, a) {
|
|
679
|
+
if (r === "FIXED") n !== void 0 && (e[t] = `${n}px`);
|
|
680
|
+
else if (r === "HUG") e[t] = "fit-content";
|
|
681
|
+
else {
|
|
682
|
+
let n = i.parent?.source.layoutMode === "HORIZONTAL" ? "width" : "height", r = ["HORIZONTAL", "VERTICAL"].includes(String(i.parent?.source.layoutMode));
|
|
683
|
+
!a && r && n === t ? (e.flexGrow = 1, e.flexBasis = "0px", e[t === "width" ? "minWidth" : "minHeight"] = "0px") : !a && r ? e.alignSelf = "stretch" : e[t] = "100%";
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
function pe(e) {
|
|
687
|
+
let t = e.source;
|
|
688
|
+
if (t.layoutMode !== "HORIZONTAL" && t.layoutMode !== "VERTICAL") return {};
|
|
689
|
+
let n = {
|
|
690
|
+
display: "flex",
|
|
691
|
+
flexDirection: t.layoutMode === "HORIZONTAL" ? "row" : "column"
|
|
692
|
+
};
|
|
693
|
+
typeof t.primaryAxisAlignItems == "string" && (n.justifyContent = {
|
|
694
|
+
MIN: "flex-start",
|
|
695
|
+
MAX: "flex-end",
|
|
696
|
+
CENTER: "center",
|
|
697
|
+
SPACE_BETWEEN: "space-between"
|
|
698
|
+
}[t.primaryAxisAlignItems] ?? "flex-start"), n.alignItems = typeof t.counterAxisAlignItems == "string" ? {
|
|
699
|
+
MIN: "flex-start",
|
|
700
|
+
MAX: "flex-end",
|
|
701
|
+
CENTER: "center",
|
|
702
|
+
BASELINE: "baseline"
|
|
703
|
+
}[t.counterAxisAlignItems] ?? "flex-start" : "flex-start";
|
|
704
|
+
let r = w(t.itemSpacing);
|
|
705
|
+
r !== void 0 && r >= 0 && (n.gap = `${r}px`);
|
|
706
|
+
for (let e of [
|
|
707
|
+
"paddingTop",
|
|
708
|
+
"paddingRight",
|
|
709
|
+
"paddingBottom",
|
|
710
|
+
"paddingLeft"
|
|
711
|
+
]) {
|
|
712
|
+
let r = w(t[e]);
|
|
713
|
+
r !== void 0 && (n[e] = `${r}px`);
|
|
714
|
+
}
|
|
715
|
+
if (t.layoutWrap === "WRAP") {
|
|
716
|
+
n.flexWrap = "wrap";
|
|
717
|
+
let e = w(t.counterAxisSpacing);
|
|
718
|
+
e !== void 0 && e >= 0 && (n[t.layoutMode === "HORIZONTAL" ? "rowGap" : "columnGap"] = `${e}px`), t.counterAxisAlignContent === "SPACE_BETWEEN" && (n.alignContent = "space-between");
|
|
719
|
+
}
|
|
720
|
+
return n;
|
|
721
|
+
}
|
|
722
|
+
function me(e, t) {
|
|
723
|
+
if (t) return { position: "relative" };
|
|
724
|
+
let n = e.parent?.source;
|
|
725
|
+
if (!(e.source.layoutPositioning === "ABSOLUTE" || n && n.layoutMode !== "HORIZONTAL" && n.layoutMode !== "VERTICAL")) return {
|
|
726
|
+
position: "relative",
|
|
727
|
+
flexShrink: 0
|
|
728
|
+
};
|
|
729
|
+
let r = S(e.source.absoluteBoundingBox) ? e.source.absoluteBoundingBox : {}, i = S(n?.absoluteBoundingBox) ? n.absoluteBoundingBox : {}, a = w(r.x), o = w(r.y);
|
|
730
|
+
return {
|
|
731
|
+
position: "absolute",
|
|
732
|
+
...a === void 0 ? {} : { left: `${a - (w(i.x) ?? 0)}px` },
|
|
733
|
+
...o === void 0 ? {} : { top: `${o - (w(i.y) ?? 0)}px` }
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
function he(e, t) {
|
|
737
|
+
let n = fe(e), r = {
|
|
738
|
+
boxSizing: "border-box",
|
|
739
|
+
...me(e, t),
|
|
740
|
+
...pe(e)
|
|
741
|
+
};
|
|
742
|
+
Y(r, "width", n.width, n.widthMode, e, t), Y(r, "height", n.height, n.heightMode, e, t);
|
|
743
|
+
for (let t of [
|
|
744
|
+
"minWidth",
|
|
745
|
+
"maxWidth",
|
|
746
|
+
"minHeight",
|
|
747
|
+
"maxHeight"
|
|
748
|
+
]) {
|
|
749
|
+
let n = w(e.source[t]);
|
|
750
|
+
n !== void 0 && (r[t] = `${n}px`);
|
|
751
|
+
}
|
|
752
|
+
return e.source.clipsContent === !0 && (r.overflow = "hidden"), {
|
|
753
|
+
size: n,
|
|
754
|
+
layout: {
|
|
755
|
+
mode: e.source.layoutMode === "HORIZONTAL" ? "horizontal" : e.source.layoutMode === "VERTICAL" ? "vertical" : "none",
|
|
756
|
+
wrap: e.source.layoutWrap === "WRAP"
|
|
757
|
+
},
|
|
758
|
+
style: r
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
//#endregion
|
|
762
|
+
//#region src/figma-tree/ir/converters/text.ts
|
|
763
|
+
function ge(e) {
|
|
764
|
+
if (e.type !== "TEXT") return {};
|
|
765
|
+
let t = S(e.style) ? e.style : {}, n = { whiteSpace: "pre-wrap" };
|
|
766
|
+
typeof t.fontFamily == "string" && (n.fontFamily = t.fontFamily);
|
|
767
|
+
let r = w(t.fontSize), i = w(t.fontWeight);
|
|
768
|
+
if (r !== void 0 && (n.fontSize = `${r}px`), i !== void 0 && (n.fontWeight = i), t.italic === !0 && (n.fontStyle = "italic"), typeof t.textAlignHorizontal == "string") {
|
|
769
|
+
let e = {
|
|
770
|
+
LEFT: "left",
|
|
771
|
+
RIGHT: "right",
|
|
772
|
+
CENTER: "center",
|
|
773
|
+
JUSTIFIED: "justify"
|
|
774
|
+
};
|
|
775
|
+
e[t.textAlignHorizontal] && (n.textAlign = e[t.textAlignHorizontal]);
|
|
776
|
+
}
|
|
777
|
+
let a = w(t.lineHeightPx);
|
|
778
|
+
t.lineHeightUnit === "FONT_SIZE_%" && w(t.lineHeightPercentFontSize) !== void 0 ? n.lineHeight = `${t.lineHeightPercentFontSize}%` : a !== void 0 && (n.lineHeight = `${a}px`);
|
|
779
|
+
let o = w(t.letterSpacing);
|
|
780
|
+
o !== void 0 && (n.letterSpacing = `${o}px`), t.textDecoration === "UNDERLINE" && (n.textDecorationLine = "underline"), t.textDecoration === "STRIKETHROUGH" && (n.textDecorationLine = "line-through");
|
|
781
|
+
let s = {
|
|
782
|
+
UPPER: "uppercase",
|
|
783
|
+
LOWER: "lowercase",
|
|
784
|
+
TITLE: "capitalize"
|
|
785
|
+
};
|
|
786
|
+
return typeof t.textCase == "string" && s[t.textCase] && (n.textTransform = s[t.textCase]), n;
|
|
787
|
+
}
|
|
788
|
+
//#endregion
|
|
789
|
+
//#region src/figma-tree/ir/pipeline.ts
|
|
790
|
+
function X(e) {
|
|
791
|
+
return e === "TEXT" ? "text" : e === "INSTANCE" ? "instance" : [
|
|
792
|
+
"DOCUMENT",
|
|
793
|
+
"CANVAS",
|
|
794
|
+
"FRAME",
|
|
795
|
+
"GROUP",
|
|
796
|
+
"COMPONENT",
|
|
797
|
+
"COMPONENT_SET",
|
|
798
|
+
"SECTION"
|
|
799
|
+
].includes(e) ? "container" : [
|
|
800
|
+
"RECTANGLE",
|
|
801
|
+
"ELLIPSE",
|
|
802
|
+
"LINE",
|
|
803
|
+
"VECTOR",
|
|
804
|
+
"BOOLEAN_OPERATION",
|
|
805
|
+
"STAR",
|
|
806
|
+
"REGULAR_POLYGON"
|
|
807
|
+
].includes(e) ? "shape" : "unknown";
|
|
808
|
+
}
|
|
809
|
+
function _e(e, t, n) {
|
|
810
|
+
let r = e.source, i = he(e, n);
|
|
811
|
+
return {
|
|
812
|
+
source: {
|
|
813
|
+
id: r.id,
|
|
814
|
+
name: r.name,
|
|
815
|
+
type: r.type,
|
|
816
|
+
...e.componentName ? { componentName: e.componentName } : {}
|
|
817
|
+
},
|
|
818
|
+
kind: X(r.type),
|
|
819
|
+
visible: r.visible !== !1,
|
|
820
|
+
...i,
|
|
821
|
+
style: {
|
|
822
|
+
...i.style,
|
|
823
|
+
...ge(r),
|
|
824
|
+
...ue(r)
|
|
825
|
+
},
|
|
826
|
+
...r.type === "TEXT" ? { text: { characters: typeof r.characters == "string" ? r.characters : "" } } : {},
|
|
827
|
+
children: t,
|
|
828
|
+
extensions: {}
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function ve(e, t) {
|
|
832
|
+
let n = [...V([e])], r = /* @__PURE__ */ new Map(), i = [];
|
|
833
|
+
for (let i of [...n].reverse()) {
|
|
834
|
+
let n = _e(i, i.children.map((e) => r.get(e)), i === e);
|
|
835
|
+
r.set(i, R(n, i, t));
|
|
836
|
+
}
|
|
837
|
+
for (let e of n) i.push(...de(e, X(e.source.type) === "unknown"));
|
|
838
|
+
return new N({
|
|
839
|
+
schemaVersion: 1,
|
|
840
|
+
root: r.get(e),
|
|
841
|
+
diagnostics: i
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
//#endregion
|
|
845
|
+
//#region src/figma-tree/selector/match.ts
|
|
846
|
+
function ye(e, t) {
|
|
847
|
+
return t === "componentName" ? e.componentName : t === "visible" ? e.source.visible ?? !0 : e.source[t];
|
|
848
|
+
}
|
|
849
|
+
function be(e, t) {
|
|
850
|
+
let n = ye(e, t.key);
|
|
851
|
+
if (t.operator === "exists") return n !== void 0;
|
|
852
|
+
if (t.operator === "=") return n === t.value;
|
|
853
|
+
if (typeof n != "string") return !1;
|
|
854
|
+
if (t.operator === "regex") {
|
|
855
|
+
let e = t.value;
|
|
856
|
+
return new RegExp(e.source, e.flags).test(n);
|
|
857
|
+
}
|
|
858
|
+
let r = t.value;
|
|
859
|
+
return t.operator === "*=" ? n.includes(r) : t.operator === "^=" ? n.startsWith(r) : n.endsWith(r);
|
|
860
|
+
}
|
|
861
|
+
function xe(e, t) {
|
|
862
|
+
return (!t.type || e.source.type === t.type) && t.tests.every((t) => be(e, t));
|
|
863
|
+
}
|
|
864
|
+
function Se(e, t, n) {
|
|
865
|
+
let r = [{
|
|
866
|
+
node: e,
|
|
867
|
+
index: t.length - 1
|
|
868
|
+
}];
|
|
869
|
+
for (; r.length;) {
|
|
870
|
+
let e = r.pop(), i = t[e.index];
|
|
871
|
+
if (e.node === n || !xe(e.node, i)) continue;
|
|
872
|
+
if (e.index === 0) return !0;
|
|
873
|
+
let a = e.node.parent;
|
|
874
|
+
for (; a && a !== n && (r.push({
|
|
875
|
+
node: a,
|
|
876
|
+
index: e.index - 1
|
|
877
|
+
}), i.relation !== "child");) a = a.parent;
|
|
878
|
+
}
|
|
879
|
+
return !1;
|
|
880
|
+
}
|
|
881
|
+
//#endregion
|
|
882
|
+
//#region src/figma-tree/selector/parser.ts
|
|
883
|
+
function Ce(e) {
|
|
884
|
+
let t = [], n = 0, r;
|
|
885
|
+
for (; n < e.length;) {
|
|
886
|
+
for (; /\s/.test(e[n] ?? "") && n < e.length;) n++;
|
|
887
|
+
let i = n, a = !1, o = "";
|
|
888
|
+
for (; n < e.length;) {
|
|
889
|
+
let t = e[n];
|
|
890
|
+
if (o) t === "\\" ? n++ : t === o && (o = "");
|
|
891
|
+
else if (t === "\"" || t === "'") o = t;
|
|
892
|
+
else if (t === "[") {
|
|
893
|
+
if (a) throw new B("Nested brackets are not supported");
|
|
894
|
+
a = !0;
|
|
895
|
+
} else if (t === "]") {
|
|
896
|
+
if (!a) throw new B("Unexpected closing bracket");
|
|
897
|
+
a = !1;
|
|
898
|
+
} else if (!a && (t === ">" || /\s/.test(t))) break;
|
|
899
|
+
n++;
|
|
900
|
+
}
|
|
901
|
+
if (o || a) throw new B("Unclosed attribute or quoted value");
|
|
902
|
+
if (n === i) throw new B("Expected a selector before combinator");
|
|
903
|
+
for (t.push({
|
|
904
|
+
text: e.slice(i, n),
|
|
905
|
+
relation: r
|
|
906
|
+
}); n < e.length && /\s/.test(e[n]);) n++;
|
|
907
|
+
if (n === e.length) break;
|
|
908
|
+
if (r = e[n] === ">" ? "child" : "descendant", r === "child") {
|
|
909
|
+
for (n++; n < e.length && /\s/.test(e[n]);) n++;
|
|
910
|
+
if (n === e.length) throw new B("Expected selector after >");
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
return t;
|
|
914
|
+
}
|
|
915
|
+
function Z(e) {
|
|
916
|
+
if (!z.includes(e)) throw new B(`Unsupported attribute: ${e}`);
|
|
917
|
+
}
|
|
918
|
+
function we(e) {
|
|
919
|
+
let t = /^\s*([A-Za-z][A-Za-z0-9]*)\s*(?:(\*=|\^=|\$=|=)\s*(.*?)\s*)?$/.exec(e);
|
|
920
|
+
if (!t) throw new B(`Invalid attribute: [${e}]`);
|
|
921
|
+
let n = t[1];
|
|
922
|
+
Z(n);
|
|
923
|
+
let r = t[2];
|
|
924
|
+
if (!r) return {
|
|
925
|
+
key: n,
|
|
926
|
+
operator: "exists"
|
|
927
|
+
};
|
|
928
|
+
let i = t[3];
|
|
929
|
+
if (n === "visible") {
|
|
930
|
+
if (r !== "=" || !/^(true|false)$/.test(i)) throw new B("visible requires an unquoted boolean equality");
|
|
931
|
+
return {
|
|
932
|
+
key: n,
|
|
933
|
+
operator: r,
|
|
934
|
+
value: i === "true"
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
let a = /^(["'])([\s\S]*)\1$/.exec(i);
|
|
938
|
+
if (!a) throw new B("String attribute values must be quoted");
|
|
939
|
+
let o = a[2], s = "";
|
|
940
|
+
for (let e = 0; e < o.length; e++) if (o[e] === "\\") {
|
|
941
|
+
if (e + 1 === o.length) throw new B("Incomplete escape");
|
|
942
|
+
s += o[++e];
|
|
943
|
+
} else {
|
|
944
|
+
if (o[e] === a[1]) throw new B("Unescaped quote in attribute");
|
|
945
|
+
s += o[e];
|
|
946
|
+
}
|
|
947
|
+
return {
|
|
948
|
+
key: n,
|
|
949
|
+
operator: r,
|
|
950
|
+
value: s
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
function Te(e) {
|
|
954
|
+
let t = /^(\*|[A-Z][A-Z0-9_]*)/.exec(e)?.[1], n = t?.length ?? 0, r = [];
|
|
955
|
+
for (; n < e.length;) {
|
|
956
|
+
if (e[n] !== "[") throw new B(`Unsupported selector near: ${e.slice(n)}`);
|
|
957
|
+
let t = ++n, i = "";
|
|
958
|
+
for (; n < e.length;) {
|
|
959
|
+
let t = e[n];
|
|
960
|
+
if (i) t === "\\" ? n++ : t === i && (i = "");
|
|
961
|
+
else if (t === "\"" || t === "'") i = t;
|
|
962
|
+
else if (t === "]") break;
|
|
963
|
+
n++;
|
|
964
|
+
}
|
|
965
|
+
r.push(we(e.slice(t, n))), n++;
|
|
966
|
+
}
|
|
967
|
+
if (!t && !r.length) throw new B("Empty selector");
|
|
968
|
+
return {
|
|
969
|
+
type: t === "*" ? void 0 : t,
|
|
970
|
+
tests: r
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
function Ee(e) {
|
|
974
|
+
if (typeof e == "string") {
|
|
975
|
+
if (!e.trim()) throw new B("Empty selector");
|
|
976
|
+
return Ce(e.trim()).map(({ text: e, relation: t }) => ({
|
|
977
|
+
...Te(e),
|
|
978
|
+
relation: t
|
|
979
|
+
}));
|
|
980
|
+
}
|
|
981
|
+
if (!e || typeof e != "object" || Array.isArray(e)) throw new B("Expected a string or condition object");
|
|
982
|
+
return [{ tests: Object.entries(e).map(([e, t]) => {
|
|
983
|
+
if (Z(e), e === "visible" ? typeof t != "boolean" : typeof t != "string" && !(t instanceof RegExp)) throw new B(`Invalid condition for ${e}`);
|
|
984
|
+
return {
|
|
985
|
+
key: e,
|
|
986
|
+
operator: t instanceof RegExp ? "regex" : "=",
|
|
987
|
+
value: t
|
|
988
|
+
};
|
|
989
|
+
}) }];
|
|
990
|
+
}
|
|
991
|
+
//#endregion
|
|
992
|
+
//#region src/figma-tree/tree/figma-tree.ts
|
|
993
|
+
var De = class {
|
|
994
|
+
plugins;
|
|
995
|
+
#e = /* @__PURE__ */ new WeakMap();
|
|
996
|
+
constructor(e) {
|
|
997
|
+
this.plugins = e;
|
|
998
|
+
}
|
|
999
|
+
wrap(e) {
|
|
1000
|
+
let t = this.#e.get(e);
|
|
1001
|
+
return t || (t = new Oe(e, this), this.#e.set(e, t)), t;
|
|
1002
|
+
}
|
|
1003
|
+
*search(e, t, n) {
|
|
1004
|
+
let r = Ee(t), i = /* @__PURE__ */ new Set();
|
|
1005
|
+
for (let t of V(e)) !i.has(t.source.id) && Se(t, r, n) && (i.add(t.source.id), yield this.wrap(t));
|
|
1006
|
+
}
|
|
1007
|
+
}, Oe = class {
|
|
1008
|
+
#e;
|
|
1009
|
+
#t;
|
|
1010
|
+
constructor(e, t) {
|
|
1011
|
+
this.#e = e, this.#t = t;
|
|
1012
|
+
}
|
|
1013
|
+
get id() {
|
|
1014
|
+
return this.#e.source.id;
|
|
1015
|
+
}
|
|
1016
|
+
get name() {
|
|
1017
|
+
return this.#e.source.name;
|
|
1018
|
+
}
|
|
1019
|
+
get type() {
|
|
1020
|
+
return this.#e.source.type;
|
|
1021
|
+
}
|
|
1022
|
+
get componentName() {
|
|
1023
|
+
return this.#e.componentName;
|
|
1024
|
+
}
|
|
1025
|
+
get children() {
|
|
1026
|
+
return Object.freeze(this.#e.children.map((e) => this.#t.wrap(e)));
|
|
1027
|
+
}
|
|
1028
|
+
query(e) {
|
|
1029
|
+
return this.#t.search(this.#e.children, e, this.#e).next().value;
|
|
1030
|
+
}
|
|
1031
|
+
queryAll(e) {
|
|
1032
|
+
return [...this.#t.search(this.#e.children, e, this.#e)];
|
|
1033
|
+
}
|
|
1034
|
+
toJSON() {
|
|
1035
|
+
return structuredClone(this.#e.source);
|
|
1036
|
+
}
|
|
1037
|
+
toIR(e = {}) {
|
|
1038
|
+
return ve(this.#e, [...this.#t.plugins, ...e.plugins ?? []]);
|
|
1039
|
+
}
|
|
1040
|
+
}, Q = class e {
|
|
1041
|
+
#e;
|
|
1042
|
+
#t;
|
|
1043
|
+
diagnostics;
|
|
1044
|
+
constructor(e, t) {
|
|
1045
|
+
let n = D(e);
|
|
1046
|
+
this.#e = U(n), this.#t = new De(Object.freeze([...t.irPlugins ?? []])), this.diagnostics = C(n.diagnostics);
|
|
1047
|
+
}
|
|
1048
|
+
static fromJson(t, n = {}) {
|
|
1049
|
+
return new e(t, n);
|
|
1050
|
+
}
|
|
1051
|
+
get roots() {
|
|
1052
|
+
return Object.freeze(this.#e.map((e) => this.#t.wrap(e)));
|
|
1053
|
+
}
|
|
1054
|
+
query(e) {
|
|
1055
|
+
return this.#t.search(this.#e, e).next().value;
|
|
1056
|
+
}
|
|
1057
|
+
queryAll(e) {
|
|
1058
|
+
return [...this.#t.search(this.#e, e)];
|
|
1059
|
+
}
|
|
1060
|
+
};
|
|
1061
|
+
//#endregion
|
|
1062
|
+
//#region src/cli/html/input.ts
|
|
1063
|
+
function ke(e) {
|
|
1064
|
+
return typeof e == "object" && !!e && "root" in e;
|
|
1065
|
+
}
|
|
1066
|
+
function Ae(e, t) {
|
|
1067
|
+
if (ke(e)) {
|
|
1068
|
+
if (t !== void 0) throw Error("--selector is only supported for original Figma JSON");
|
|
1069
|
+
return x(e), e;
|
|
1070
|
+
}
|
|
1071
|
+
let n = Q.fromJson(e);
|
|
1072
|
+
if (t === void 0 && n.roots.length !== 1) throw Error("Specify --selector when the Figma input does not have exactly one root");
|
|
1073
|
+
let r = t === void 0 ? n.roots[0] : n.query(t);
|
|
1074
|
+
if (!r) throw Error("No Figma node matched the export selector");
|
|
1075
|
+
return r.toIR();
|
|
1076
|
+
}
|
|
1077
|
+
function $(e, t, n) {
|
|
1078
|
+
let r = Ae(e, t);
|
|
1079
|
+
if ("target" in r && r.target === "tailwind-v4") {
|
|
1080
|
+
if (n === "inline") throw Error("Tailwind IR has no original inline styles; use standard IR for --styles inline");
|
|
1081
|
+
return r;
|
|
1082
|
+
}
|
|
1083
|
+
if (n === "tailwind") {
|
|
1084
|
+
let e = {
|
|
1085
|
+
schemaVersion: r.schemaVersion,
|
|
1086
|
+
root: r.root,
|
|
1087
|
+
diagnostics: r.diagnostics
|
|
1088
|
+
};
|
|
1089
|
+
return new N(structuredClone(e)).toTailwind();
|
|
1090
|
+
}
|
|
1091
|
+
return r;
|
|
1092
|
+
}
|
|
1093
|
+
//#endregion
|
|
1094
|
+
//#region src/cli/commands/export.ts
|
|
1095
|
+
async function je(e, n, r) {
|
|
1096
|
+
let i = $(JSON.parse(await t(e.input, "utf8")), e.selector, e.styles);
|
|
1097
|
+
await m(ce(i), e.out, e.force, n), i.diagnostics.length && r(`HTML exported with ${i.diagnostics.length} IR diagnostics; unsupported design features may be omitted.\n`);
|
|
1098
|
+
}
|
|
1099
|
+
//#endregion
|
|
1100
|
+
//#region src/cli/commands/query.ts
|
|
1101
|
+
async function Me(e, n) {
|
|
1102
|
+
let r = Q.fromJson(JSON.parse(await t(e.input, "utf8")));
|
|
1103
|
+
await p(e.command === "query" ? r.query(e.selector)?.toJSON() ?? null : r.queryAll(e.selector).map((e) => e.toJSON()), e.out, e.force, n);
|
|
1104
|
+
}
|
|
1105
|
+
//#endregion
|
|
1106
|
+
//#region src/cli/env.ts
|
|
1107
|
+
function Ne(e) {
|
|
1108
|
+
let t = e.FIGMA_TOKEN;
|
|
1109
|
+
if (!t?.trim()) throw Error("FIGMA_TOKEN environment variable is required");
|
|
1110
|
+
return t;
|
|
1111
|
+
}
|
|
1112
|
+
//#endregion
|
|
1113
|
+
//#region src/cli/run.ts
|
|
1114
|
+
async function Pe(e, t) {
|
|
1115
|
+
try {
|
|
1116
|
+
let n = re(e);
|
|
1117
|
+
return n === "help" ? (t.stdout(l), 0) : (n.command === "download" ? await ae(n, new c({
|
|
1118
|
+
token: Ne(t.env),
|
|
1119
|
+
fetch: t.fetch
|
|
1120
|
+
}), t.stdout) : n.command === "export" ? await je(n, t.stdout, t.stderr) : await Me(n, t.stdout), 0);
|
|
1121
|
+
} catch (e) {
|
|
1122
|
+
return t.stderr(`${ie(e, t.env.FIGMA_TOKEN)}\n`), 1;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
//#endregion
|
|
1126
|
+
//#region src/cli/index.ts
|
|
1127
|
+
process.exitCode = await Pe(process.argv.slice(2), {
|
|
1128
|
+
env: process.env,
|
|
1129
|
+
stdout: (e) => {
|
|
1130
|
+
process.stdout.write(e);
|
|
1131
|
+
},
|
|
1132
|
+
stderr: (e) => {
|
|
1133
|
+
process.stderr.write(e);
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
//#endregion
|
|
1137
|
+
|
|
1138
|
+
//# sourceMappingURL=index.js.map
|