@greensight/gts 1.0.0-alpha.4 → 1.0.0-alpha.5

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 CHANGED
@@ -1,4 +1,4 @@
1
- # @greensight/gts
1
+ # Greensight Token System
2
2
 
3
3
  Generate design tokens from Figma.
4
4
 
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { generate } from './commands/generate';
2
2
  export { init } from './commands/init';
3
+ export type { IGtsConfig } from './classes/Config';
4
+ export * from './modules/colors';
3
5
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,cAAc,kBAAkB,CAAC"}
package/index.js CHANGED
@@ -1,87 +1,87 @@
1
- var k = Object.defineProperty;
2
- var x = (n, e, t) => e in n ? k(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
- var l = (n, e, t) => x(n, typeof e != "symbol" ? e + "" : e, t);
4
- import { tsImport as F } from "ts-import";
5
- import { existsSync as h } from "node:fs";
6
- import { readFile as u, mkdir as O, writeFile as b, rm as j } from "node:fs/promises";
7
- import { resolve as w } from "node:path";
8
- const a = class a {
1
+ var U = Object.defineProperty;
2
+ var z = (o, e, r) => e in o ? U(o, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : o[e] = r;
3
+ var b = (o, e, r) => z(o, typeof e != "symbol" ? e + "" : e, r);
4
+ import { tsImport as H } from "ts-import";
5
+ import { existsSync as N } from "node:fs";
6
+ import { readFile as k, mkdir as K, writeFile as Q, rm as Z } from "node:fs/promises";
7
+ import { resolve as R } from "node:path";
8
+ const d = class d {
9
9
  static resolveReadPath(e) {
10
10
  if (!e || !e.trim())
11
11
  throw new Error("File path must be a non-empty string");
12
- return w(a.baseDir, e);
12
+ return R(d.baseDir, e);
13
13
  }
14
- static resolveWritePath(e, t) {
15
- const r = w(a.baseDir, t ?? "");
14
+ static resolveWritePath(e, r) {
15
+ const t = R(d.baseDir, r ?? "");
16
16
  return {
17
- targetDir: r,
18
- targetPath: w(r, e)
17
+ targetDir: t,
18
+ targetPath: R(t, e)
19
19
  };
20
20
  }
21
- static handleReadError(e, t) {
22
- throw e.code === "ENOENT" ? new Error(`File not found: ${t}`) : new Error(
23
- `Failed to read file "${t}": ${e.message ?? String(e)}`
21
+ static handleReadError(e, r) {
22
+ throw e.code === "ENOENT" ? new Error(`File not found: ${r}`) : new Error(
23
+ `Failed to read file "${r}": ${e.message ?? String(e)}`
24
24
  );
25
25
  }
26
- static async read(e, t = "utf8") {
27
- const r = a.resolveReadPath(e);
26
+ static async read(e, r = "utf8") {
27
+ const t = d.resolveReadPath(e);
28
28
  try {
29
- return await u(r, { encoding: t });
29
+ return await k(t, { encoding: r });
30
30
  } catch (s) {
31
- a.handleReadError(s, r);
31
+ d.handleReadError(s, t);
32
32
  }
33
33
  }
34
34
  static async readBuffer(e) {
35
- const t = a.resolveReadPath(e);
35
+ const r = d.resolveReadPath(e);
36
36
  try {
37
- return await u(t);
38
- } catch (r) {
39
- a.handleReadError(r, t);
37
+ return await k(r);
38
+ } catch (t) {
39
+ d.handleReadError(t, r);
40
40
  }
41
41
  }
42
42
  static async readJson(e) {
43
- const t = a.resolveReadPath(e);
43
+ const r = d.resolveReadPath(e);
44
44
  try {
45
- const r = await u(t, { encoding: "utf8" });
45
+ const t = await k(r, { encoding: "utf8" });
46
46
  try {
47
- return JSON.parse(r);
47
+ return JSON.parse(t);
48
48
  } catch (s) {
49
- throw new Error(`Failed to parse JSON from "${t}": ${s.message}`);
49
+ throw new Error(`Failed to parse JSON from "${r}": ${s.message}`);
50
50
  }
51
- } catch (r) {
52
- a.handleReadError(r, t);
51
+ } catch (t) {
52
+ d.handleReadError(t, r);
53
53
  }
54
54
  }
55
- static async write(e, t = "", r = {}) {
56
- const { directory: s, overwrite: o = !0 } = r, { targetDir: i, targetPath: c } = a.resolveWritePath(e, s);
57
- if (!o && h(c))
58
- throw new Error(`File ${c} already exists`);
59
- return await O(i, { recursive: !0 }), await b(c, t, { encoding: "utf8" }), c;
55
+ static async write(e, r = "", t = {}) {
56
+ const { directory: s, overwrite: n = !0 } = t, { targetDir: a, targetPath: l } = d.resolveWritePath(e, s);
57
+ if (!n && N(l))
58
+ throw new Error(`File ${l} already exists`);
59
+ return await K(a, { recursive: !0 }), await Q(l, r, { encoding: "utf8" }), l;
60
60
  }
61
- static async writeWithExtension(e, t, r = "", s) {
62
- const o = t.startsWith(".") ? t : `.${t}`, i = `${e}${o}`;
63
- return a.write(i, r, s);
61
+ static async writeWithExtension(e, r, t = "", s) {
62
+ const n = r.startsWith(".") ? r : `.${r}`, a = `${e}${n}`;
63
+ return d.write(a, t, s);
64
64
  }
65
65
  static exists(e) {
66
- const t = a.resolveReadPath(e);
67
- return h(t);
66
+ const r = d.resolveReadPath(e);
67
+ return N(r);
68
68
  }
69
- static async delete(e, t) {
70
- const { targetPath: r } = a.resolveWritePath(e, t);
71
- h(r) && await j(r, { force: !0 });
69
+ static async delete(e, r) {
70
+ const { targetPath: t } = d.resolveWritePath(e, r);
71
+ N(t) && await Z(t, { force: !0 });
72
72
  }
73
73
  };
74
- l(a, "baseDir", process.cwd());
75
- let f = a;
76
- const d = class d {
74
+ b(d, "baseDir", process.cwd());
75
+ let m = d;
76
+ const p = class p {
77
77
  static async create() {
78
- if (f.exists(d.configFileName))
78
+ if (m.exists(p.configFileName))
79
79
  throw new Error("The file already exists");
80
- await f.write(d.configFileName, "", { overwrite: !1 });
80
+ await m.write(p.configFileName, "", { overwrite: !1 });
81
81
  }
82
82
  async load() {
83
83
  try {
84
- const e = await F.compile(d.configFileName);
84
+ const e = await H.compile(p.configFileName);
85
85
  if (!e) throw new Error();
86
86
  return e.default;
87
87
  } catch (e) {
@@ -89,59 +89,59 @@ const d = class d {
89
89
  }
90
90
  }
91
91
  };
92
- l(d, "configFileName", "gts.config.ts");
93
- let m = d;
94
- const I = (n) => {
92
+ b(p, "configFileName", "gts.config.ts");
93
+ let F = p;
94
+ const _ = (o) => {
95
95
  const e = new URLSearchParams();
96
- return Object.keys(n).forEach((t) => {
97
- Array.isArray(n[t]) ? n[t].forEach((r) => e.append(`${t}[]`, r)) : e.append(t, n[t]);
96
+ return Object.keys(o).forEach((r) => {
97
+ Array.isArray(o[r]) ? o[r].forEach((t) => e.append(`${r}[]`, t)) : e.append(r, o[r]);
98
98
  }), e;
99
- }, q = (n, e = 50) => {
100
- const t = [];
101
- for (let r = 0; r < n.length; r += e)
102
- t.push(n.slice(r, r + e));
103
- return t;
99
+ }, ee = (o, e = 50) => {
100
+ const r = [];
101
+ for (let t = 0; t < o.length; t += e)
102
+ r.push(o.slice(t, t + e));
103
+ return r;
104
104
  };
105
- class g {
106
- constructor(e, t) {
107
- l(this, "figmaToken");
108
- l(this, "fileId");
109
- l(this, "onTimeMeasureHandler");
110
- this.figmaToken = e, this.fileId = t;
105
+ class T {
106
+ constructor(e, r) {
107
+ b(this, "figmaToken");
108
+ b(this, "fileId");
109
+ b(this, "onTimeMeasureHandler");
110
+ this.figmaToken = e, this.fileId = r;
111
111
  }
112
112
  setOnTimeMeasureHandler(e) {
113
113
  this.onTimeMeasureHandler = e;
114
114
  }
115
115
  static async returnJSON(e) {
116
- const t = await e.json();
116
+ const r = await e.json();
117
117
  if (!e.ok) {
118
- let r = "Request failed";
119
- throw new Error(r);
118
+ let t = "Request failed";
119
+ throw new Error(t);
120
120
  }
121
- return t;
121
+ return r;
122
122
  }
123
- async performControlledRequest(e, { params: t = {}, timeout: r = 3e4, abortController: s = new AbortController() } = {}) {
124
- var y;
125
- const o = Object.entries(t).reduce((E, [N, P]) => typeof P < "u" ? { ...E, [N]: P } : E, {}), i = `https://api.figma.com/v1${e}${o && Object.keys(o).length ? `?${I(o)}` : ""}`;
126
- console.log("endpoinWithParams=", i);
127
- const c = setTimeout(() => s.abort(), r), p = {
123
+ async performControlledRequest(e, { params: r = {}, timeout: t = 3e4, abortController: s = new AbortController() } = {}) {
124
+ var u;
125
+ const n = Object.entries(r).reduce((c, [y, w]) => typeof w < "u" ? { ...c, [y]: w } : c, {}), a = `https://api.figma.com/v1${e}${n && Object.keys(n).length ? `?${_(n)}` : ""}`;
126
+ console.log("endpoinWithParams=", a);
127
+ const l = setTimeout(() => s.abort(), t), i = {
128
128
  "Content-Type": "application/json",
129
129
  ...this.figmaToken && { "X-Figma-Token": this.figmaToken }
130
- }, $ = {
130
+ }, g = {
131
131
  method: "GET",
132
- headers: p,
132
+ headers: i,
133
133
  signal: s.signal
134
- }, T = performance.now(), R = await fetch(`${i}`, $);
135
- clearTimeout(c);
136
- const v = performance.now() - T;
137
- return (y = this.onTimeMeasureHandler) == null || y.call(this, i, p, v), R;
134
+ }, h = performance.now(), f = await fetch(`${a}`, g);
135
+ clearTimeout(l);
136
+ const $ = performance.now() - h;
137
+ return (u = this.onTimeMeasureHandler) == null || u.call(this, a, i, $), f;
138
138
  }
139
- async request(e, t) {
139
+ async request(e, r) {
140
140
  var s;
141
- const r = await this.performControlledRequest(e, {
142
- ...t
141
+ const t = await this.performControlledRequest(e, {
142
+ ...r
143
143
  });
144
- return (s = r.headers.get("content-type")) != null && s.includes("application/json") ? g.returnJSON(r) : r;
144
+ return (s = t.headers.get("content-type")) != null && s.includes("application/json") ? T.returnJSON(t) : t;
145
145
  }
146
146
  async getComponents() {
147
147
  return this.request(`/files/${this.fileId}/components`);
@@ -150,20 +150,20 @@ class g {
150
150
  return this.request(`/files/${this.fileId}/styles`);
151
151
  }
152
152
  async getNodes(e) {
153
- const t = q(e).map(
154
- (o) => this.request(`/files/${this.fileId}/nodes`, { params: { ids: o.join(",") } })
155
- ), r = await Promise.all(t);
153
+ const r = ee(e).map(
154
+ (n) => this.request(`/files/${this.fileId}/nodes`, { params: { ids: n.join(",") } })
155
+ ), t = await Promise.all(r);
156
156
  return {
157
- ...r[0],
158
- nodes: r.reduce((o, i) => ({ ...o, ...i.nodes }), {})
157
+ ...t[0],
158
+ nodes: t.reduce((n, a) => ({ ...n, ...a.nodes }), {})
159
159
  };
160
160
  }
161
161
  }
162
- const J = async () => {
163
- const e = await new m().load();
162
+ const be = async () => {
163
+ const e = await new F().load();
164
164
  if (!e)
165
165
  throw new Error("Заполнить ошибку через нейронку");
166
- const { figmaToken: t, fileId: r, modules: s } = e, o = new g(t, r);
166
+ const { figmaToken: r, fileId: t, modules: s } = e, n = new T(r, t);
167
167
  await Promise.all(
168
168
  // [
169
169
  // colorsFromStyles({
@@ -175,12 +175,280 @@ const J = async () => {
175
175
  // output: { jsonDir: './fromVariables', stylesDir: './fromVariables' },
176
176
  // }),
177
177
  // ]
178
- s.map((i) => i.executor({ figmaApiClient: o }))
178
+ s.map((a) => a.executor({ figmaApiClient: n }))
179
179
  );
180
- }, A = async () => {
181
- await m.create(), console.log("\x1B[32m%s\x1B[0m", "✔️ Configuration file created gts.config.ts");
182
- };
180
+ }, pe = async () => {
181
+ await F.create(), console.log("\x1B[32m%s\x1B[0m", "✔️ Configuration file created gts.config.ts");
182
+ }, re = ({ r: o, g: e, b: r }) => {
183
+ const t = (s) => `0${s.toString(16)}`.slice(-2);
184
+ return `#${t(o)}${t(e)}${t(r)}`;
185
+ }, S = ({ opacity: o, r: e, g: r, b: t }) => {
186
+ const s = [e, r, t].map((n) => Math.round(n * 255));
187
+ return o < 1 ? `rgba(${s[0]}, ${s[1]}, ${s[2]}, ${o})` : re({ r: s[0], g: s[1], b: s[2] });
188
+ }, W = (o, e = 0) => {
189
+ const r = Math.atan2(
190
+ o[1].y - o[0].y,
191
+ o[1].x - o[0].x
192
+ );
193
+ return Math.round(r * 180 / Math.PI) + e;
194
+ }, C = (o) => o.reduce((e, r) => {
195
+ const t = Number((r.position * 100).toFixed(1));
196
+ return [
197
+ ...e,
198
+ `${S({
199
+ opacity: r.color.a,
200
+ r: r.color.r,
201
+ g: r.color.g,
202
+ b: r.color.b
203
+ })}${t > 0 && t < 100 ? ` ${t}%` : ""}`
204
+ ];
205
+ }, []).join(", "), V = (o) => {
206
+ const e = o[0].x, r = o[0].y, t = (e * 100).toFixed(2), s = (r * 100).toFixed(2);
207
+ return { centerX: t, centerY: s };
208
+ }, oe = (o) => {
209
+ const { gradientHandlePositions: e, gradientStops: r } = o, t = W(e, 90), s = C(r);
210
+ return `linear-gradient(${t}deg, ${s})`;
211
+ }, te = (o) => {
212
+ const e = o[0].x, r = o[0].y, t = o[1].x, s = o[1].y, n = o[2].x, a = o[2].y, l = (Math.sqrt((n - e) ** 2 + (a - r) ** 2) * 100).toFixed(2), i = (Math.sqrt((t - e) ** 2 + (s - r) ** 2) * 100).toFixed(2);
213
+ return { radiusX: l, radiusY: i };
214
+ }, se = (o) => {
215
+ const { gradientHandlePositions: e, gradientStops: r } = o, { centerX: t, centerY: s } = V(e), { radiusX: n, radiusY: a } = te(e), l = C(r);
216
+ return `radial-gradient(${n}% ${a}% at ${t}% ${s}%, ${l})`;
217
+ }, ne = (o) => {
218
+ const { gradientHandlePositions: e, gradientStops: r } = o, t = W(e, 30), { centerX: s, centerY: n } = V(e), a = C(r);
219
+ return `conic-gradient(from ${t}deg at ${s}% ${n}%, ${a})`;
220
+ }, ae = (o) => {
221
+ const e = o.type;
222
+ return e === "SOLID" ? S({
223
+ opacity: o.color.a,
224
+ r: o.color.r,
225
+ g: o.color.g,
226
+ b: o.color.b
227
+ }) : e === "GRADIENT_LINEAR" ? oe(o) : e === "GRADIENT_RADIAL" ? se(o) : e === "GRADIENT_ANGULAR" ? ne(o) : "";
228
+ }, J = (o, e) => {
229
+ if (!e.length) return "";
230
+ const r = e.map((t) => ` ${t}`).join(`
231
+ `);
232
+ return `${o} {
233
+ ${r}
234
+ }`;
235
+ }, ce = (o) => `.${o.replace(/\s+/g, "-").toLowerCase()}`, le = (o) => o.replaceAll(/ /g, "").split("/").at(-1), ie = (o) => `--${o}`, ge = (o) => o.reduce(
236
+ (e, r) => {
237
+ const t = ie(r.name);
238
+ return typeof r.value == "object" ? Object.entries(r.value).forEach(([s, n]) => {
239
+ e[s] || (e[s] = []), e[s].push(`${t}: ${n};`);
240
+ }) : e.root.push(`${t}: ${r.value};`), e;
241
+ },
242
+ { root: [] }
243
+ ), de = (o) => {
244
+ const e = J(":root", o.root), r = Object.entries(o).reduce((t, [s, n]) => {
245
+ if (s === "root" || !n.length) return t;
246
+ const a = J(ce(s), n);
247
+ return a && t.push(a), t;
248
+ }, []).join(`
249
+
250
+ `);
251
+ return [e, r].filter(Boolean).join(`
252
+
253
+ `);
254
+ }, ue = (o) => {
255
+ const e = o.reduce((r, t) => ({ ...r, [t.name]: t.value }), {});
256
+ return JSON.stringify(e);
257
+ }, fe = async (o, e, r, t, s, n) => {
258
+ await Promise.all([m.delete(s, r), m.delete(n, t)]);
259
+ const a = m.write(s, o, { directory: r }), l = m.write(n, e, { directory: t });
260
+ await Promise.all([a, l]);
261
+ }, B = async ({
262
+ colorTokens: o,
263
+ jsonDir: e,
264
+ stylesDir: r,
265
+ jsonFileName: t,
266
+ cssFileName: s
267
+ }) => {
268
+ const n = ge(o), a = de(n), l = ue(o);
269
+ await fe(l, a, e, r, t, s);
270
+ }, ve = ({
271
+ input: o,
272
+ output: { jsonDir: e, stylesDir: r, jsonFileName: t = "colors.json", cssFileName: s = "colors.css" }
273
+ }) => ({
274
+ name: "styles/colors",
275
+ executor: async ({ figmaApiClient: n }) => {
276
+ try {
277
+ console.log("[styles/colors] Fetching styles from Figma...");
278
+ const l = (await n.getStyles()).meta.styles, i = (o == null ? void 0 : o.variablePaths) || [], g = l.filter((c) => c.style_type === "FILL");
279
+ if (console.log(`[styles/colors] Found ${g.length} color styles`), g.length === 0) {
280
+ console.warn("[styles/colors] No color styles found in Figma file");
281
+ return;
282
+ }
283
+ console.log(`[styles/colors] Fetching ${g.length} color nodes from Figma...`);
284
+ const h = await n.getNodes(g.map((c) => c.node_id)), f = Object.entries(h.nodes);
285
+ let $ = [];
286
+ if (i.length > 1) {
287
+ console.log(`[styles/colors] Reading ${i.length} variable files...`);
288
+ try {
289
+ $ = await Promise.all(
290
+ i.map(async (c) => {
291
+ try {
292
+ return await m.readJson(c);
293
+ } catch (y) {
294
+ throw console.error(`[styles/colors] Failed to read variable file: ${c}`, y), y;
295
+ }
296
+ })
297
+ );
298
+ } catch (c) {
299
+ throw console.error("[styles/colors] Error reading variable files:", c), new Error(`Failed to read variable files: ${c.message}`);
300
+ }
301
+ }
302
+ console.log(`[styles/colors] Processing ${f.length} color nodes...`);
303
+ const u = f.reduce((c, [, y]) => {
304
+ var w, j, O;
305
+ try {
306
+ const { document: v } = y, P = le(v.name);
307
+ if (v.type !== "RECTANGLE") return c;
308
+ const x = (w = v.fills) == null ? void 0 : w[0];
309
+ if (!x) return c;
310
+ if (x.type === "SOLID" && $.length > 1) {
311
+ const M = (O = (j = x.boundVariables) == null ? void 0 : j.color) == null ? void 0 : O.id;
312
+ if (M) {
313
+ const A = $.reduce((G, D) => {
314
+ var q;
315
+ const L = (q = Object.entries(D).find(
316
+ ([, E]) => E.$extensions["com.figma.variableId"] === M
317
+ )) == null ? void 0 : q[1];
318
+ if (L) {
319
+ const { components: E, alpha: X } = L.$value, Y = S({
320
+ opacity: X,
321
+ r: E[0],
322
+ g: E[1],
323
+ b: E[2]
324
+ });
325
+ return { ...G, [D.$extensions["com.figma.modeName"]]: Y };
326
+ }
327
+ return G;
328
+ }, {});
329
+ if (Object.keys(A).length > 1)
330
+ return [
331
+ ...c,
332
+ {
333
+ name: P,
334
+ value: A
335
+ }
336
+ ];
337
+ }
338
+ }
339
+ const I = ae(x);
340
+ return I ? [
341
+ ...c,
342
+ {
343
+ name: P,
344
+ value: I
345
+ }
346
+ ] : c;
347
+ } catch (v) {
348
+ return console.warn("[styles/colors] Error processing color node:", v), c;
349
+ }
350
+ }, []);
351
+ if (console.log(`[styles/colors] Generated ${u.length} color tokens`), u.length === 0) {
352
+ console.warn("[styles/colors] No color tokens generated. Check your Figma styles configuration.");
353
+ return;
354
+ }
355
+ console.log(`[styles/colors] Writing files to ${e} and ${r}...`), await B({
356
+ colorTokens: u,
357
+ jsonDir: e,
358
+ stylesDir: r,
359
+ jsonFileName: t,
360
+ cssFileName: s
361
+ }), console.log("[styles/colors] ✅ Successfully generated color files");
362
+ } catch (a) {
363
+ const l = a instanceof Error ? a.message : String(a);
364
+ throw console.error("[styles/colors] ❌ Failed to generate colors from styles:", l), a instanceof Error && a.stack && console.error("[styles/colors] Stack trace:", a.stack), a;
365
+ }
366
+ }
367
+ }), Ee = ({
368
+ input: { variablePaths: o },
369
+ output: { jsonDir: e, stylesDir: r, jsonFileName: t = "colors.json", cssFileName: s = "colors.css" }
370
+ }) => ({
371
+ name: "variables/colors",
372
+ executor: async () => {
373
+ try {
374
+ if (!o.length)
375
+ throw new Error("At least one variable file path is required");
376
+ console.log(`[variables/colors] Reading ${o.length} variable files...`);
377
+ const n = await Promise.all(
378
+ o.map(async (i) => {
379
+ try {
380
+ return console.log(`[variables/colors] Reading file: ${i}`), await m.readJson(i);
381
+ } catch (g) {
382
+ throw console.error(`[variables/colors] Failed to read variable file: ${i}`, g), new Error(`Failed to read variable file "${i}": ${g.message}`);
383
+ }
384
+ })
385
+ );
386
+ console.log(`[variables/colors] Processing ${n.length} variable files...`);
387
+ const a = /* @__PURE__ */ new Map();
388
+ n.forEach((i, g) => {
389
+ try {
390
+ if (!i.$extensions || !i.$extensions["com.figma.modeName"]) {
391
+ console.warn(
392
+ `[variables/colors] File ${o[g]} is missing modeName in extensions`
393
+ );
394
+ return;
395
+ }
396
+ const h = i.$extensions["com.figma.modeName"];
397
+ Object.entries(i).forEach(([f, $]) => {
398
+ if (f !== "$extensions")
399
+ try {
400
+ const u = $;
401
+ if (!u || u.$type !== "color") return;
402
+ if (!u.$value || !u.$value.components) {
403
+ console.warn(
404
+ `[variables/colors] Variable "${f}" in mode "${h}" has invalid structure`
405
+ );
406
+ return;
407
+ }
408
+ const { components: c, alpha: y } = u.$value, w = S({
409
+ opacity: y ?? 1,
410
+ r: c[0],
411
+ g: c[1],
412
+ b: c[2]
413
+ });
414
+ a.has(f) || a.set(f, {}), a.get(f)[h] = w;
415
+ } catch (u) {
416
+ console.warn(
417
+ `[variables/colors] Error processing variable "${f}" in mode "${h}":`,
418
+ u
419
+ );
420
+ }
421
+ });
422
+ } catch (h) {
423
+ console.error(`[variables/colors] Error processing file ${o[g]}:`, h);
424
+ }
425
+ });
426
+ const l = Array.from(a.entries()).map(([i, g]) => ({
427
+ name: i,
428
+ value: Object.keys(g).length > 1 ? g : Object.values(g)[0]
429
+ }));
430
+ if (console.log(`[variables/colors] Generated ${l.length} color tokens`), l.length === 0) {
431
+ console.warn(
432
+ "[variables/colors] No color tokens generated. Check your variable files structure."
433
+ );
434
+ return;
435
+ }
436
+ console.log(`[variables/colors] Writing files to ${e} and ${r}...`), await B({
437
+ colorTokens: l,
438
+ jsonDir: e,
439
+ stylesDir: r,
440
+ jsonFileName: t,
441
+ cssFileName: s
442
+ }), console.log("[variables/colors] ✅ Successfully generated color files");
443
+ } catch (n) {
444
+ const a = n instanceof Error ? n.message : String(n);
445
+ throw console.error("[variables/colors] ❌ Failed to generate colors from variables:", a), n instanceof Error && n.stack && console.error("[variables/colors] Stack trace:", n.stack), n;
446
+ }
447
+ }
448
+ });
183
449
  export {
184
- J as generate,
185
- A as init
450
+ ve as colorsFromStyles,
451
+ Ee as colorsFromVariables,
452
+ be as generate,
453
+ pe as init
186
454
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greensight/gts",
3
- "version": "1.0.0-alpha.4",
3
+ "version": "1.0.0-alpha.5",
4
4
  "description": "Generate design tokens from Figma",
5
5
  "keywords": [
6
6
  "figma",