@greensight/gts 1.0.0-alpha.5 → 1.0.0-alpha.6
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/classes/Config/index.d.ts.map +1 -1
- package/index.cjs +8 -0
- package/{index.js → index.mjs} +49 -46
- package/package.json +10 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/Config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/classes/Config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,EAAE,CAAC;CACtB;AAED,qBAAa,MAAM;IACf,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAmB;WAE5C,MAAM;IAQN,IAAI,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;CAYvD"}
|
package/index.cjs
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";var U=Object.defineProperty;var z=(o,e,r)=>e in o?U(o,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):o[e]=r;var b=(o,e,r)=>z(o,typeof e!="symbol"?e+"":e,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("path"),K=require("ts-import"),k=require("node:fs"),p=require("node:fs/promises"),T=require("node:path"),u=class u{static resolveReadPath(e){if(!e||!e.trim())throw new Error("File path must be a non-empty string");return T.resolve(u.baseDir,e)}static resolveWritePath(e,r){const t=T.resolve(u.baseDir,r??"");return{targetDir:t,targetPath:T.resolve(t,e)}}static handleReadError(e,r){throw e.code==="ENOENT"?new Error(`File not found: ${r}`):new Error(`Failed to read file "${r}": ${e.message??String(e)}`)}static async read(e,r="utf8"){const t=u.resolveReadPath(e);try{return await p.readFile(t,{encoding:r})}catch(s){u.handleReadError(s,t)}}static async readBuffer(e){const r=u.resolveReadPath(e);try{return await p.readFile(r)}catch(t){u.handleReadError(t,r)}}static async readJson(e){const r=u.resolveReadPath(e);try{const t=await p.readFile(r,{encoding:"utf8"});try{return JSON.parse(t)}catch(s){throw new Error(`Failed to parse JSON from "${r}": ${s.message}`)}}catch(t){u.handleReadError(t,r)}}static async write(e,r="",t={}){const{directory:s,overwrite:n=!0}=t,{targetDir:a,targetPath:l}=u.resolveWritePath(e,s);if(!n&&k.existsSync(l))throw new Error(`File ${l} already exists`);return await p.mkdir(a,{recursive:!0}),await p.writeFile(l,r,{encoding:"utf8"}),l}static async writeWithExtension(e,r,t="",s){const n=r.startsWith(".")?r:`.${r}`,a=`${e}${n}`;return u.write(a,t,s)}static exists(e){const r=u.resolveReadPath(e);return k.existsSync(r)}static async delete(e,r){const{targetPath:t}=u.resolveWritePath(e,r);k.existsSync(t)&&await p.rm(t,{force:!0})}};b(u,"baseDir",process.cwd());let h=u;const v=class v{static async create(){if(h.exists(v.configFileName))throw new Error("The file already exists");await h.write(v.configFileName,"",{overwrite:!1})}async load(){try{const e=await K.tsImport.compile(`${H.resolve(process.cwd(),v.configFileName)}`);if(!e)throw new Error;return e.default}catch(e){console.error("Cannot find module gts.config.ts",e)}}};b(v,"configFileName","gts.config.ts");let x=v;const Q=o=>{const e=new URLSearchParams;return Object.keys(o).forEach(r=>{Array.isArray(o[r])?o[r].forEach(t=>e.append(`${r}[]`,t)):e.append(r,o[r])}),e},Z=(o,e=50)=>{const r=[];for(let t=0;t<o.length;t+=e)r.push(o.slice(t,t+e));return r};class R{constructor(e,r){b(this,"figmaToken");b(this,"fileId");b(this,"onTimeMeasureHandler");this.figmaToken=e,this.fileId=r}setOnTimeMeasureHandler(e){this.onTimeMeasureHandler=e}static async returnJSON(e){const r=await e.json();if(!e.ok){let t="Request failed";throw new Error(t)}return r}async performControlledRequest(e,{params:r={},timeout:t=3e4,abortController:s=new AbortController}={}){var g;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?`?${Q(n)}`:""}`;console.log("endpoinWithParams=",a);const l=setTimeout(()=>s.abort(),t),i={"Content-Type":"application/json",...this.figmaToken&&{"X-Figma-Token":this.figmaToken}},d={method:"GET",headers:i,signal:s.signal},m=performance.now(),f=await fetch(`${a}`,d);clearTimeout(l);const $=performance.now()-m;return(g=this.onTimeMeasureHandler)==null||g.call(this,a,i,$),f}async request(e,r){var s;const t=await this.performControlledRequest(e,{...r});return(s=t.headers.get("content-type"))!=null&&s.includes("application/json")?R.returnJSON(t):t}async getComponents(){return this.request(`/files/${this.fileId}/components`)}async getStyles(){return this.request(`/files/${this.fileId}/styles`)}async getNodes(e){const r=Z(e).map(n=>this.request(`/files/${this.fileId}/nodes`,{params:{ids:n.join(",")}})),t=await Promise.all(r);return{...t[0],nodes:t.reduce((n,a)=>({...n,...a.nodes}),{})}}}const _=async()=>{const e=await new x().load();if(!e)throw new Error("Заполнить ошибку через нейронку");const{figmaToken:r,fileId:t,modules:s}=e,n=new R(r,t);await Promise.all(s.map(a=>a.executor({figmaApiClient:n})))},ee=async()=>{await x.create(),console.log("\x1B[32m%s\x1B[0m","✔️ Configuration file created gts.config.ts")},re=({r:o,g:e,b:r})=>{const t=s=>`0${s.toString(16)}`.slice(-2);return`#${t(o)}${t(e)}${t(r)}`},N=({opacity:o,r:e,g:r,b:t})=>{const s=[e,r,t].map(n=>Math.round(n*255));return o<1?`rgba(${s[0]}, ${s[1]}, ${s[2]}, ${o})`:re({r:s[0],g:s[1],b:s[2]})},V=(o,e=0)=>{const r=Math.atan2(o[1].y-o[0].y,o[1].x-o[0].x);return Math.round(r*180/Math.PI)+e},C=o=>o.reduce((e,r)=>{const t=Number((r.position*100).toFixed(1));return[...e,`${N({opacity:r.color.a,r:r.color.r,g:r.color.g,b:r.color.b})}${t>0&&t<100?` ${t}%`:""}`]},[]).join(", "),W=o=>{const e=o[0].x,r=o[0].y,t=(e*100).toFixed(2),s=(r*100).toFixed(2);return{centerX:t,centerY:s}},oe=o=>{const{gradientHandlePositions:e,gradientStops:r}=o,t=V(e,90),s=C(r);return`linear-gradient(${t}deg, ${s})`},te=o=>{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);return{radiusX:l,radiusY:i}},se=o=>{const{gradientHandlePositions:e,gradientStops:r}=o,{centerX:t,centerY:s}=W(e),{radiusX:n,radiusY:a}=te(e),l=C(r);return`radial-gradient(${n}% ${a}% at ${t}% ${s}%, ${l})`},ne=o=>{const{gradientHandlePositions:e,gradientStops:r}=o,t=V(e,30),{centerX:s,centerY:n}=W(e),a=C(r);return`conic-gradient(from ${t}deg at ${s}% ${n}%, ${a})`},ae=o=>{const e=o.type;return e==="SOLID"?N({opacity:o.color.a,r:o.color.r,g:o.color.g,b:o.color.b}):e==="GRADIENT_LINEAR"?oe(o):e==="GRADIENT_RADIAL"?se(o):e==="GRADIENT_ANGULAR"?ne(o):""},J=(o,e)=>{if(!e.length)return"";const r=e.map(t=>` ${t}`).join(`
|
|
2
|
+
`);return`${o} {
|
|
3
|
+
${r}
|
|
4
|
+
}`},ce=o=>`.${o.replace(/\s+/g,"-").toLowerCase()}`,le=o=>o.replaceAll(/ /g,"").split("/").at(-1),ie=o=>`--${o}`,de=o=>o.reduce((e,r)=>{const t=ie(r.name);return typeof r.value=="object"?Object.entries(r.value).forEach(([s,n])=>{e[s]||(e[s]=[]),e[s].push(`${t}: ${n};`)}):e.root.push(`${t}: ${r.value};`),e},{root:[]}),ue=o=>{const e=J(":root",o.root),r=Object.entries(o).reduce((t,[s,n])=>{if(s==="root"||!n.length)return t;const a=J(ce(s),n);return a&&t.push(a),t},[]).join(`
|
|
5
|
+
|
|
6
|
+
`);return[e,r].filter(Boolean).join(`
|
|
7
|
+
|
|
8
|
+
`)},ge=o=>{const e=o.reduce((r,t)=>({...r,[t.name]:t.value}),{});return JSON.stringify(e)},fe=async(o,e,r,t,s,n)=>{await Promise.all([h.delete(s,r),h.delete(n,t)]);const a=h.write(s,o,{directory:r}),l=h.write(n,e,{directory:t});await Promise.all([a,l])},B=async({colorTokens:o,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:s})=>{const n=de(o),a=ue(n),l=ge(o);await fe(l,a,e,r,t,s)},he=({input:o,output:{jsonDir:e,stylesDir:r,jsonFileName:t="colors.json",cssFileName:s="colors.css"}})=>({name:"styles/colors",executor:async({figmaApiClient:n})=>{try{console.log("[styles/colors] Fetching styles from Figma...");const l=(await n.getStyles()).meta.styles,i=(o==null?void 0:o.variablePaths)||[],d=l.filter(c=>c.style_type==="FILL");if(console.log(`[styles/colors] Found ${d.length} color styles`),d.length===0){console.warn("[styles/colors] No color styles found in Figma file");return}console.log(`[styles/colors] Fetching ${d.length} color nodes from Figma...`);const m=await n.getNodes(d.map(c=>c.node_id)),f=Object.entries(m.nodes);let $=[];if(i.length>1){console.log(`[styles/colors] Reading ${i.length} variable files...`);try{$=await Promise.all(i.map(async c=>{try{return await h.readJson(c)}catch(y){throw console.error(`[styles/colors] Failed to read variable file: ${c}`,y),y}}))}catch(c){throw console.error("[styles/colors] Error reading variable files:",c),new Error(`Failed to read variable files: ${c.message}`)}}console.log(`[styles/colors] Processing ${f.length} color nodes...`);const g=f.reduce((c,[,y])=>{var w,j,O;try{const{document:E}=y,P=le(E.name);if(E.type!=="RECTANGLE")return c;const F=(w=E.fills)==null?void 0:w[0];if(!F)return c;if(F.type==="SOLID"&&$.length>1){const M=(O=(j=F.boundVariables)==null?void 0:j.color)==null?void 0:O.id;if(M){const A=$.reduce((q,G)=>{var L;const D=(L=Object.entries(G).find(([,S])=>S.$extensions["com.figma.variableId"]===M))==null?void 0:L[1];if(D){const{components:S,alpha:X}=D.$value,Y=N({opacity:X,r:S[0],g:S[1],b:S[2]});return{...q,[G.$extensions["com.figma.modeName"]]:Y}}return q},{});if(Object.keys(A).length>1)return[...c,{name:P,value:A}]}}const I=ae(F);return I?[...c,{name:P,value:I}]:c}catch(E){return console.warn("[styles/colors] Error processing color node:",E),c}},[]);if(console.log(`[styles/colors] Generated ${g.length} color tokens`),g.length===0){console.warn("[styles/colors] No color tokens generated. Check your Figma styles configuration.");return}console.log(`[styles/colors] Writing files to ${e} and ${r}...`),await B({colorTokens:g,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:s}),console.log("[styles/colors] ✅ Successfully generated color files")}catch(a){const l=a instanceof Error?a.message:String(a);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}}}),me=({input:{variablePaths:o},output:{jsonDir:e,stylesDir:r,jsonFileName:t="colors.json",cssFileName:s="colors.css"}})=>({name:"variables/colors",executor:async()=>{try{if(!o.length)throw new Error("At least one variable file path is required");console.log(`[variables/colors] Reading ${o.length} variable files...`);const n=await Promise.all(o.map(async i=>{try{return console.log(`[variables/colors] Reading file: ${i}`),await h.readJson(i)}catch(d){throw console.error(`[variables/colors] Failed to read variable file: ${i}`,d),new Error(`Failed to read variable file "${i}": ${d.message}`)}}));console.log(`[variables/colors] Processing ${n.length} variable files...`);const a=new Map;n.forEach((i,d)=>{try{if(!i.$extensions||!i.$extensions["com.figma.modeName"]){console.warn(`[variables/colors] File ${o[d]} is missing modeName in extensions`);return}const m=i.$extensions["com.figma.modeName"];Object.entries(i).forEach(([f,$])=>{if(f!=="$extensions")try{const g=$;if(!g||g.$type!=="color")return;if(!g.$value||!g.$value.components){console.warn(`[variables/colors] Variable "${f}" in mode "${m}" has invalid structure`);return}const{components:c,alpha:y}=g.$value,w=N({opacity:y??1,r:c[0],g:c[1],b:c[2]});a.has(f)||a.set(f,{}),a.get(f)[m]=w}catch(g){console.warn(`[variables/colors] Error processing variable "${f}" in mode "${m}":`,g)}})}catch(m){console.error(`[variables/colors] Error processing file ${o[d]}:`,m)}});const l=Array.from(a.entries()).map(([i,d])=>({name:i,value:Object.keys(d).length>1?d:Object.values(d)[0]}));if(console.log(`[variables/colors] Generated ${l.length} color tokens`),l.length===0){console.warn("[variables/colors] No color tokens generated. Check your variable files structure.");return}console.log(`[variables/colors] Writing files to ${e} and ${r}...`),await B({colorTokens:l,jsonDir:e,stylesDir:r,jsonFileName:t,cssFileName:s}),console.log("[variables/colors] ✅ Successfully generated color files")}catch(n){const a=n instanceof Error?n.message:String(n);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}}});exports.colorsFromStyles=he;exports.colorsFromVariables=me;exports.generate=_;exports.init=ee;
|
package/{index.js → index.mjs}
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
var U = Object.defineProperty;
|
|
2
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
|
|
4
|
-
import
|
|
3
|
+
var p = (o, e, r) => z(o, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
+
import H from "path";
|
|
5
|
+
import { tsImport as K } from "ts-import";
|
|
5
6
|
import { existsSync as N } from "node:fs";
|
|
6
|
-
import { readFile as k, mkdir as
|
|
7
|
+
import { readFile as k, mkdir as Q, writeFile as Z, rm as _ } from "node:fs/promises";
|
|
7
8
|
import { resolve as R } from "node:path";
|
|
8
9
|
const d = class d {
|
|
9
10
|
static resolveReadPath(e) {
|
|
@@ -56,7 +57,7 @@ const d = class d {
|
|
|
56
57
|
const { directory: s, overwrite: n = !0 } = t, { targetDir: a, targetPath: l } = d.resolveWritePath(e, s);
|
|
57
58
|
if (!n && N(l))
|
|
58
59
|
throw new Error(`File ${l} already exists`);
|
|
59
|
-
return await
|
|
60
|
+
return await Q(a, { recursive: !0 }), await Z(l, r, { encoding: "utf8" }), l;
|
|
60
61
|
}
|
|
61
62
|
static async writeWithExtension(e, r, t = "", s) {
|
|
62
63
|
const n = r.startsWith(".") ? r : `.${r}`, a = `${e}${n}`;
|
|
@@ -68,20 +69,22 @@ const d = class d {
|
|
|
68
69
|
}
|
|
69
70
|
static async delete(e, r) {
|
|
70
71
|
const { targetPath: t } = d.resolveWritePath(e, r);
|
|
71
|
-
N(t) && await
|
|
72
|
+
N(t) && await _(t, { force: !0 });
|
|
72
73
|
}
|
|
73
74
|
};
|
|
74
|
-
|
|
75
|
+
p(d, "baseDir", process.cwd());
|
|
75
76
|
let m = d;
|
|
76
|
-
const
|
|
77
|
+
const b = class b {
|
|
77
78
|
static async create() {
|
|
78
|
-
if (m.exists(
|
|
79
|
+
if (m.exists(b.configFileName))
|
|
79
80
|
throw new Error("The file already exists");
|
|
80
|
-
await m.write(
|
|
81
|
+
await m.write(b.configFileName, "", { overwrite: !1 });
|
|
81
82
|
}
|
|
82
83
|
async load() {
|
|
83
84
|
try {
|
|
84
|
-
const e = await
|
|
85
|
+
const e = await K.compile(
|
|
86
|
+
`${H.resolve(process.cwd(), b.configFileName)}`
|
|
87
|
+
);
|
|
85
88
|
if (!e) throw new Error();
|
|
86
89
|
return e.default;
|
|
87
90
|
} catch (e) {
|
|
@@ -89,14 +92,14 @@ const p = class p {
|
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
};
|
|
92
|
-
b
|
|
93
|
-
let F =
|
|
94
|
-
const
|
|
95
|
+
p(b, "configFileName", "gts.config.ts");
|
|
96
|
+
let F = b;
|
|
97
|
+
const ee = (o) => {
|
|
95
98
|
const e = new URLSearchParams();
|
|
96
99
|
return Object.keys(o).forEach((r) => {
|
|
97
100
|
Array.isArray(o[r]) ? o[r].forEach((t) => e.append(`${r}[]`, t)) : e.append(r, o[r]);
|
|
98
101
|
}), e;
|
|
99
|
-
},
|
|
102
|
+
}, re = (o, e = 50) => {
|
|
100
103
|
const r = [];
|
|
101
104
|
for (let t = 0; t < o.length; t += e)
|
|
102
105
|
r.push(o.slice(t, t + e));
|
|
@@ -104,9 +107,9 @@ const _ = (o) => {
|
|
|
104
107
|
};
|
|
105
108
|
class T {
|
|
106
109
|
constructor(e, r) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
p(this, "figmaToken");
|
|
111
|
+
p(this, "fileId");
|
|
112
|
+
p(this, "onTimeMeasureHandler");
|
|
110
113
|
this.figmaToken = e, this.fileId = r;
|
|
111
114
|
}
|
|
112
115
|
setOnTimeMeasureHandler(e) {
|
|
@@ -122,7 +125,7 @@ class T {
|
|
|
122
125
|
}
|
|
123
126
|
async performControlledRequest(e, { params: r = {}, timeout: t = 3e4, abortController: s = new AbortController() } = {}) {
|
|
124
127
|
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 ? `?${
|
|
128
|
+
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 ? `?${ee(n)}` : ""}`;
|
|
126
129
|
console.log("endpoinWithParams=", a);
|
|
127
130
|
const l = setTimeout(() => s.abort(), t), i = {
|
|
128
131
|
"Content-Type": "application/json",
|
|
@@ -150,7 +153,7 @@ class T {
|
|
|
150
153
|
return this.request(`/files/${this.fileId}/styles`);
|
|
151
154
|
}
|
|
152
155
|
async getNodes(e) {
|
|
153
|
-
const r =
|
|
156
|
+
const r = re(e).map(
|
|
154
157
|
(n) => this.request(`/files/${this.fileId}/nodes`, { params: { ids: n.join(",") } })
|
|
155
158
|
), t = await Promise.all(r);
|
|
156
159
|
return {
|
|
@@ -159,7 +162,7 @@ class T {
|
|
|
159
162
|
};
|
|
160
163
|
}
|
|
161
164
|
}
|
|
162
|
-
const
|
|
165
|
+
const ve = async () => {
|
|
163
166
|
const e = await new F().load();
|
|
164
167
|
if (!e)
|
|
165
168
|
throw new Error("Заполнить ошибку через нейронку");
|
|
@@ -177,14 +180,14 @@ const be = async () => {
|
|
|
177
180
|
// ]
|
|
178
181
|
s.map((a) => a.executor({ figmaApiClient: n }))
|
|
179
182
|
);
|
|
180
|
-
},
|
|
183
|
+
}, Ee = async () => {
|
|
181
184
|
await F.create(), console.log("\x1B[32m%s\x1B[0m", "✔️ Configuration file created gts.config.ts");
|
|
182
|
-
},
|
|
185
|
+
}, oe = ({ r: o, g: e, b: r }) => {
|
|
183
186
|
const t = (s) => `0${s.toString(16)}`.slice(-2);
|
|
184
187
|
return `#${t(o)}${t(e)}${t(r)}`;
|
|
185
188
|
}, S = ({ opacity: o, r: e, g: r, b: t }) => {
|
|
186
189
|
const s = [e, r, t].map((n) => Math.round(n * 255));
|
|
187
|
-
return o < 1 ? `rgba(${s[0]}, ${s[1]}, ${s[2]}, ${o})` :
|
|
190
|
+
return o < 1 ? `rgba(${s[0]}, ${s[1]}, ${s[2]}, ${o})` : oe({ r: s[0], g: s[1], b: s[2] });
|
|
188
191
|
}, W = (o, e = 0) => {
|
|
189
192
|
const r = Math.atan2(
|
|
190
193
|
o[1].y - o[0].y,
|
|
@@ -205,26 +208,26 @@ const be = async () => {
|
|
|
205
208
|
}, []).join(", "), V = (o) => {
|
|
206
209
|
const e = o[0].x, r = o[0].y, t = (e * 100).toFixed(2), s = (r * 100).toFixed(2);
|
|
207
210
|
return { centerX: t, centerY: s };
|
|
208
|
-
},
|
|
211
|
+
}, te = (o) => {
|
|
209
212
|
const { gradientHandlePositions: e, gradientStops: r } = o, t = W(e, 90), s = C(r);
|
|
210
213
|
return `linear-gradient(${t}deg, ${s})`;
|
|
211
|
-
},
|
|
214
|
+
}, se = (o) => {
|
|
212
215
|
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
216
|
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
217
|
}, ne = (o) => {
|
|
218
|
+
const { gradientHandlePositions: e, gradientStops: r } = o, { centerX: t, centerY: s } = V(e), { radiusX: n, radiusY: a } = se(e), l = C(r);
|
|
219
|
+
return `radial-gradient(${n}% ${a}% at ${t}% ${s}%, ${l})`;
|
|
220
|
+
}, ae = (o) => {
|
|
218
221
|
const { gradientHandlePositions: e, gradientStops: r } = o, t = W(e, 30), { centerX: s, centerY: n } = V(e), a = C(r);
|
|
219
222
|
return `conic-gradient(from ${t}deg at ${s}% ${n}%, ${a})`;
|
|
220
|
-
},
|
|
223
|
+
}, ce = (o) => {
|
|
221
224
|
const e = o.type;
|
|
222
225
|
return e === "SOLID" ? S({
|
|
223
226
|
opacity: o.color.a,
|
|
224
227
|
r: o.color.r,
|
|
225
228
|
g: o.color.g,
|
|
226
229
|
b: o.color.b
|
|
227
|
-
}) : e === "GRADIENT_LINEAR" ?
|
|
230
|
+
}) : e === "GRADIENT_LINEAR" ? te(o) : e === "GRADIENT_RADIAL" ? ne(o) : e === "GRADIENT_ANGULAR" ? ae(o) : "";
|
|
228
231
|
}, J = (o, e) => {
|
|
229
232
|
if (!e.length) return "";
|
|
230
233
|
const r = e.map((t) => ` ${t}`).join(`
|
|
@@ -232,18 +235,18 @@ const be = async () => {
|
|
|
232
235
|
return `${o} {
|
|
233
236
|
${r}
|
|
234
237
|
}`;
|
|
235
|
-
},
|
|
238
|
+
}, le = (o) => `.${o.replace(/\s+/g, "-").toLowerCase()}`, ie = (o) => o.replaceAll(/ /g, "").split("/").at(-1), ge = (o) => `--${o}`, de = (o) => o.reduce(
|
|
236
239
|
(e, r) => {
|
|
237
|
-
const t =
|
|
240
|
+
const t = ge(r.name);
|
|
238
241
|
return typeof r.value == "object" ? Object.entries(r.value).forEach(([s, n]) => {
|
|
239
242
|
e[s] || (e[s] = []), e[s].push(`${t}: ${n};`);
|
|
240
243
|
}) : e.root.push(`${t}: ${r.value};`), e;
|
|
241
244
|
},
|
|
242
245
|
{ root: [] }
|
|
243
|
-
),
|
|
246
|
+
), ue = (o) => {
|
|
244
247
|
const e = J(":root", o.root), r = Object.entries(o).reduce((t, [s, n]) => {
|
|
245
248
|
if (s === "root" || !n.length) return t;
|
|
246
|
-
const a = J(
|
|
249
|
+
const a = J(le(s), n);
|
|
247
250
|
return a && t.push(a), t;
|
|
248
251
|
}, []).join(`
|
|
249
252
|
|
|
@@ -251,10 +254,10 @@ ${r}
|
|
|
251
254
|
return [e, r].filter(Boolean).join(`
|
|
252
255
|
|
|
253
256
|
`);
|
|
254
|
-
},
|
|
257
|
+
}, fe = (o) => {
|
|
255
258
|
const e = o.reduce((r, t) => ({ ...r, [t.name]: t.value }), {});
|
|
256
259
|
return JSON.stringify(e);
|
|
257
|
-
},
|
|
260
|
+
}, me = async (o, e, r, t, s, n) => {
|
|
258
261
|
await Promise.all([m.delete(s, r), m.delete(n, t)]);
|
|
259
262
|
const a = m.write(s, o, { directory: r }), l = m.write(n, e, { directory: t });
|
|
260
263
|
await Promise.all([a, l]);
|
|
@@ -265,9 +268,9 @@ ${r}
|
|
|
265
268
|
jsonFileName: t,
|
|
266
269
|
cssFileName: s
|
|
267
270
|
}) => {
|
|
268
|
-
const n =
|
|
269
|
-
await
|
|
270
|
-
},
|
|
271
|
+
const n = de(o), a = ue(n), l = fe(o);
|
|
272
|
+
await me(l, a, e, r, t, s);
|
|
273
|
+
}, xe = ({
|
|
271
274
|
input: o,
|
|
272
275
|
output: { jsonDir: e, stylesDir: r, jsonFileName: t = "colors.json", cssFileName: s = "colors.css" }
|
|
273
276
|
}) => ({
|
|
@@ -303,7 +306,7 @@ ${r}
|
|
|
303
306
|
const u = f.reduce((c, [, y]) => {
|
|
304
307
|
var w, j, O;
|
|
305
308
|
try {
|
|
306
|
-
const { document: v } = y, P =
|
|
309
|
+
const { document: v } = y, P = ie(v.name);
|
|
307
310
|
if (v.type !== "RECTANGLE") return c;
|
|
308
311
|
const x = (w = v.fills) == null ? void 0 : w[0];
|
|
309
312
|
if (!x) return c;
|
|
@@ -336,7 +339,7 @@ ${r}
|
|
|
336
339
|
];
|
|
337
340
|
}
|
|
338
341
|
}
|
|
339
|
-
const I =
|
|
342
|
+
const I = ce(x);
|
|
340
343
|
return I ? [
|
|
341
344
|
...c,
|
|
342
345
|
{
|
|
@@ -364,7 +367,7 @@ ${r}
|
|
|
364
367
|
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
368
|
}
|
|
366
369
|
}
|
|
367
|
-
}),
|
|
370
|
+
}), Fe = ({
|
|
368
371
|
input: { variablePaths: o },
|
|
369
372
|
output: { jsonDir: e, stylesDir: r, jsonFileName: t = "colors.json", cssFileName: s = "colors.css" }
|
|
370
373
|
}) => ({
|
|
@@ -447,8 +450,8 @@ ${r}
|
|
|
447
450
|
}
|
|
448
451
|
});
|
|
449
452
|
export {
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
453
|
+
xe as colorsFromStyles,
|
|
454
|
+
Fe as colorsFromVariables,
|
|
455
|
+
ve as generate,
|
|
456
|
+
Ee as init
|
|
454
457
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@greensight/gts",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.6",
|
|
4
4
|
"description": "Generate design tokens from Figma",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"figma",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"typescript"
|
|
13
13
|
],
|
|
14
14
|
"private": false,
|
|
15
|
-
"type": "module",
|
|
16
15
|
"engines": {
|
|
17
16
|
"node": ">=16.0.0"
|
|
18
17
|
},
|
|
@@ -28,8 +27,15 @@
|
|
|
28
27
|
"ts-import": "2.0.40"
|
|
29
28
|
},
|
|
30
29
|
"types": "./index.d.ts",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
30
|
+
"main": "./index.cjs",
|
|
31
|
+
"module": "./index.mjs",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./index.d.ts",
|
|
35
|
+
"import": "./index.mjs",
|
|
36
|
+
"require": "./index.cjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
33
39
|
"bin": {
|
|
34
40
|
"gts-init": "./bin/init.js",
|
|
35
41
|
"gts-generate": "./bin/generate.js"
|