figma-tokens-flattener 1.0.12 → 1.0.13
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/index.js +277 -163
- package/package.json +3 -2
package/index.js
CHANGED
|
@@ -49,11 +49,15 @@ function flattenSeedTokens(seedTokens) {
|
|
|
49
49
|
|
|
50
50
|
let valueToUse;
|
|
51
51
|
|
|
52
|
-
if (
|
|
52
|
+
if (Object.hasOwn(tokenObj, 'value') && typeof tokenObj.value === 'object' && tokenObj.value !== null && Object.hasOwn(tokenObj.value, 'style')) {
|
|
53
|
+
valueToUse = tokenObj.value.style;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
else if (Object.hasOwn(tokenObj, 'value')) {
|
|
53
57
|
valueToUse = tokenObj.value;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
else if (
|
|
60
|
+
else if (Object.hasOwn(tokenObj, 'style') && tokenObj.style && typeof tokenObj.style === 'object' && Object.hasOwn(tokenObj.style, 'value')) {
|
|
57
61
|
valueToUse = tokenObj.style.value;
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -72,6 +76,7 @@ function flattenSeedTokens(seedTokens) {
|
|
|
72
76
|
|
|
73
77
|
flattened[tokenName] = valueToUse;
|
|
74
78
|
})
|
|
79
|
+
|
|
75
80
|
return flattened;
|
|
76
81
|
}
|
|
77
82
|
|
|
@@ -190,145 +195,81 @@ function flattenMapTokensWrapper(mapTokens, seedContext) {
|
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
/* Alias */
|
|
193
|
-
function isDropShadowStructure(obj) {
|
|
194
|
-
if (!obj || typeof obj !== 'object') {
|
|
195
|
-
return false;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const keys = Object.keys(obj);
|
|
199
|
-
if (keys.length === 0) {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
for (const key of keys) {
|
|
204
|
-
if (isNaN(key)) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
198
|
|
|
209
|
-
|
|
210
|
-
if (!
|
|
211
|
-
|
|
199
|
+
function processSingleShadow(shadowDef, contextTokens) {
|
|
200
|
+
if (!shadowDef || typeof shadowDef !== 'object') {
|
|
201
|
+
console.warn(' processSingleShadow: Ожидаемый объект тени, получен:', shadowDef);
|
|
202
|
+
return undefined;
|
|
212
203
|
}
|
|
213
204
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
222
|
-
if (!firstShadow[coordProp] || typeof firstShadow[coordProp] !== 'object' || !firstShadow[coordProp].hasOwnProperty('value')) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
205
|
+
// Проверим наличие необходимых свойств (используем 'in' или 'hasOwn' как рекомендовал тимлид)
|
|
206
|
+
// Но для простоты и т.к. структура известна, можно просто проверить тип.
|
|
207
|
+
// Проверим, есть ли хотя бы 'x', 'y', 'color' как минимум.
|
|
208
|
+
if (typeof shadowDef.x === 'undefined' || typeof shadowDef.y === 'undefined' || typeof shadowDef.color === 'undefined') {
|
|
209
|
+
console.warn(' processSingleShadow: Неверная структура тени, отсутствуют x, y или color:', shadowDef);
|
|
210
|
+
return undefined;
|
|
225
211
|
}
|
|
226
212
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
213
|
+
// Извлекаем и обрабатываем значения
|
|
214
|
+
// Используем flattenMapTokens для разрешения ссылок и вычисления выражений
|
|
215
|
+
const x = flattenMapTokens(shadowDef.x, contextTokens);
|
|
216
|
+
const y = flattenMapTokens(shadowDef.y, contextTokens);
|
|
217
|
+
const blur = flattenMapTokens(shadowDef.blur || '0', contextTokens); // Значение по умолчанию
|
|
218
|
+
const spread = flattenMapTokens(shadowDef.spread || '0', contextTokens); // Значение по умолчанию
|
|
219
|
+
const color = flattenMapTokens(shadowDef.color, contextTokens);
|
|
234
220
|
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
242
|
-
if (!shadow[coordProp] || typeof shadow[coordProp] !== 'object' || !shadow[coordProp].hasOwnProperty('value')) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (!shadow.color || typeof shadow.color !== 'object' || !shadow.color.hasOwnProperty('value')) {
|
|
247
|
-
return false;
|
|
248
|
-
}
|
|
249
|
-
if (shadow.type?.value !== 'dropShadow' && shadow.type !== 'dropShadow') {
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
221
|
+
// Проверяем, все ли значения числовые (или цвет для color)
|
|
222
|
+
// flattenMapTokens может вернуть число, строку или undefined
|
|
223
|
+
if (typeof x !== 'number' || typeof y !== 'number' || typeof blur !== 'number' || typeof spread !== 'number' || typeof color !== 'string') {
|
|
224
|
+
console.warn(` Неверный тип значения в тени: x=${x}(${typeof x}), y=${y}(${typeof y}), blur=${blur}(${typeof blur}), spread=${spread}(${typeof spread}), color=${color}(${typeof color})`);
|
|
225
|
+
return undefined; // Возвращаем undefined, чтобы пропустить эту тень
|
|
252
226
|
}
|
|
253
227
|
|
|
254
|
-
|
|
228
|
+
// Формируем строку для одной тени
|
|
229
|
+
return `${x}px ${y}px ${blur}px ${spread}px ${color}`;
|
|
255
230
|
}
|
|
256
231
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
271
|
-
if (!obj[coordProp] || typeof obj[coordProp] !== 'object' || !obj[coordProp].hasOwnProperty('value')) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (!obj.color || typeof obj.color !== 'object' || !obj.color.hasOwnProperty('value')) {
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (obj.type?.value !== 'dropShadow' && obj.type !== 'dropShadow') {
|
|
281
|
-
return false;
|
|
232
|
+
function processBoxShadow(shadowData, contextTokens) {
|
|
233
|
+
let shadowsArray;
|
|
234
|
+
|
|
235
|
+
if (Array.isArray(shadowData)) {
|
|
236
|
+
// Это массив теней
|
|
237
|
+
shadowsArray = shadowData;
|
|
238
|
+
} else if (typeof shadowData === 'object' && shadowData !== null) {
|
|
239
|
+
// Это одиночный объект тени, обернём в массив для унификации
|
|
240
|
+
shadowsArray = [shadowData];
|
|
241
|
+
} else {
|
|
242
|
+
console.warn(' processBoxShadow: Ожидаемый массив или объект тени, получен:', shadowData);
|
|
243
|
+
return undefined;
|
|
282
244
|
}
|
|
283
245
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
/* Collects the boxShadow string from the dropShadow structure (multiple). */
|
|
288
|
-
function buildBoxShadowString(shadowStructure, contextTokens) {
|
|
289
|
-
const shadowParts = [];
|
|
290
|
-
const keys = Object.keys(shadowStructure).sort((a, b) => parseInt(a) - parseInt(b));
|
|
291
|
-
|
|
292
|
-
for (const key of keys) {
|
|
293
|
-
const shadowDef = shadowStructure[key];
|
|
294
|
-
const shadowString = buildSingleShadowString(shadowDef, contextTokens);
|
|
246
|
+
const processedShadows = [];
|
|
247
|
+
for (const shadowDef of shadowsArray) {
|
|
248
|
+
const shadowString = processSingleShadow(shadowDef, contextTokens);
|
|
295
249
|
if (shadowString) {
|
|
296
|
-
|
|
250
|
+
processedShadows.push(shadowString);
|
|
297
251
|
}
|
|
298
252
|
}
|
|
299
253
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
/* Collects a row for one shadow from the dropShadow structure. */
|
|
305
|
-
function buildSingleShadowString(singleShadowDef, contextTokens) {
|
|
306
|
-
// Extracting and calculating the values
|
|
307
|
-
const x = flattenMapTokens(singleShadowDef.x.value, contextTokens);
|
|
308
|
-
const y = flattenMapTokens(singleShadowDef.y.value, contextTokens);
|
|
309
|
-
const blur = flattenMapTokens(singleShadowDef.blur.value, contextTokens);
|
|
310
|
-
const spread = flattenMapTokens(singleShadowDef.spread.value, contextTokens);
|
|
311
|
-
const color = flattenMapTokens(singleShadowDef.color.value, contextTokens);
|
|
312
|
-
|
|
313
|
-
// Checking if all values are numeric (or color)
|
|
314
|
-
if (typeof x !== 'number' || typeof y !== 'number' || typeof blur !== 'number' || typeof spread !== 'number' || typeof color !== 'string') {
|
|
315
|
-
console.warn(`Invalid value type in dropShadow: x=${x}(${typeof x}), y=${y}(${typeof y}), blur=${blur}(${typeof blur}), spread=${spread}(${typeof spread}), color=${color}(${typeof color})`);
|
|
316
|
-
return undefined; // Returning undefined to skip this shadow
|
|
254
|
+
if (processedShadows.length === 0) {
|
|
255
|
+
console.warn(' processBoxShadow: Не удалось обработать ни одной тени.');
|
|
256
|
+
return undefined;
|
|
317
257
|
}
|
|
318
258
|
|
|
319
|
-
//
|
|
320
|
-
return
|
|
259
|
+
// Объединяем все строки теней в одну строку boxShadow
|
|
260
|
+
return processedShadows.join(', ');
|
|
321
261
|
}
|
|
322
262
|
|
|
323
|
-
|
|
324
|
-
/* An auxiliary function for converting the alias token structure. */
|
|
325
263
|
function flattenAliasTokens(aliasTokens, contextTokens) {
|
|
326
264
|
const flattened = {};
|
|
327
265
|
if (!aliasTokens || typeof aliasTokens !== 'object') {
|
|
328
|
-
console.warn('
|
|
266
|
+
console.warn(' Ожидался объект с alias токенами, но получен:', aliasTokens);
|
|
329
267
|
return flattened;
|
|
330
268
|
}
|
|
331
269
|
|
|
270
|
+
console.log(' Вычисление alias токенов...');
|
|
271
|
+
|
|
272
|
+
// --- ЗАМЕНЕНО: for...in на Object.keys().forEach() ---
|
|
332
273
|
Object.keys(aliasTokens).forEach((tokenName) => {
|
|
333
274
|
const tokenContent = aliasTokens[tokenName];
|
|
334
275
|
|
|
@@ -336,36 +277,225 @@ function flattenAliasTokens(aliasTokens, contextTokens) {
|
|
|
336
277
|
return;
|
|
337
278
|
}
|
|
338
279
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// boxShadow
|
|
349
|
-
const boxShadowValue =
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
// Processing the structure of a single shadow
|
|
354
|
-
const singleShadowValue = buildSingleShadowString(tokenContent, contextTokens);
|
|
355
|
-
|
|
356
|
-
if (singleShadowValue) {
|
|
357
|
-
flattened[tokenName] = singleShadowValue;
|
|
280
|
+
// Проверяем, что объект имеет ожидаемую структуру { "value": "..." }
|
|
281
|
+
// --- ИСПРАВЛЕНО: Используем Object.hasOwn вместо hasOwnProperty ---
|
|
282
|
+
if (tokenContent && typeof tokenContent === 'object' && Object.hasOwn(tokenContent, 'value')) {
|
|
283
|
+
// --- НОВАЯ ПРОВЕРКА: boxShadow (новый формат) ---
|
|
284
|
+
// Проверим, является ли value массивом или объектом с x, y, color
|
|
285
|
+
if (
|
|
286
|
+
(Array.isArray(tokenContent.value) && tokenContent.value.length > 0) ||
|
|
287
|
+
(typeof tokenContent.value === 'object' && tokenContent.value !== null && Object.hasOwn(tokenContent.value, 'x'))
|
|
288
|
+
) {
|
|
289
|
+
// Обработка новой структуры boxShadow (одиночный или множественный)
|
|
290
|
+
const boxShadowValue = processBoxShadow(tokenContent.value, contextTokens);
|
|
291
|
+
if (boxShadowValue !== undefined) {
|
|
292
|
+
flattened[tokenName] = boxShadowValue;
|
|
293
|
+
console.log(` ${tokenName}: (boxShadow array/object structure) -> ${boxShadowValue}`);
|
|
358
294
|
} else {
|
|
359
|
-
console.warn(`
|
|
295
|
+
console.warn(` ${tokenName}: Не удалось обработать boxShadow структуру.`, tokenContent.value);
|
|
296
|
+
// Можно добавить как есть или пропустить
|
|
297
|
+
// flattened[tokenName] = tokenContent.value;
|
|
360
298
|
}
|
|
361
|
-
} else {
|
|
362
|
-
console.warn(`Unsupported structure for alias token ${tokenName}:`, tokenContent);
|
|
363
299
|
}
|
|
300
|
+
// --- КОНЕЦ НОВОЙ ПРОВЕРКИ ---
|
|
301
|
+
else {
|
|
302
|
+
// Это стандартный токен: { "value": "..." }
|
|
303
|
+
const rawValue = tokenContent.value;
|
|
304
|
+
// Обрабатываем значение с помощью вспомогательной функции, аналогичной для map
|
|
305
|
+
// Она должна уметь разрешать ссылки и вычислять выражения
|
|
306
|
+
const processedValue = flattenMapTokens(rawValue, contextTokens);
|
|
307
|
+
flattened[tokenName] = processedValue;
|
|
308
|
+
// console.log(` ${tokenName}: ${rawValue} -> ${processedValue}`); // Опционально: подробное логирование
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
// --- УБРАНО: Проверки на { "style": { "value": ... } } ---
|
|
312
|
+
// Неизвестная структура, просто добавим как есть или выведем предупреждение
|
|
313
|
+
console.warn(` Неподдерживаемая структура для alias токена ${tokenName}:`, tokenContent);
|
|
314
|
+
// Можно добавить как есть, если нужно сохранить:
|
|
315
|
+
// flattened[tokenName] = tokenContent;
|
|
364
316
|
}
|
|
365
|
-
})
|
|
366
|
-
|
|
317
|
+
});
|
|
318
|
+
// --- КОНЕЦ ИЗМЕНЕНИЯ: Закрывающая скобка для forEach ---
|
|
319
|
+
console.log(` Вычислено ${Object.keys(flattened).length} alias токенов.`);
|
|
367
320
|
return flattened;
|
|
368
|
-
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// function isDropShadowStructure(obj) {
|
|
324
|
+
// if (!obj || typeof obj !== 'object') {
|
|
325
|
+
// return false;
|
|
326
|
+
// }
|
|
327
|
+
|
|
328
|
+
// const keys = Object.keys(obj);
|
|
329
|
+
// if (keys.length === 0) {
|
|
330
|
+
// return false;
|
|
331
|
+
// }
|
|
332
|
+
|
|
333
|
+
// for (const key of keys) {
|
|
334
|
+
// if (isNaN(key)) {
|
|
335
|
+
// return false;
|
|
336
|
+
// }
|
|
337
|
+
// }
|
|
338
|
+
|
|
339
|
+
// const firstShadow = obj[keys[0]];
|
|
340
|
+
// if (!firstShadow || typeof firstShadow !== 'object') {
|
|
341
|
+
// return false;
|
|
342
|
+
// }
|
|
343
|
+
|
|
344
|
+
// const expectedProps = ['x', 'y', 'blur', 'spread', 'color', 'type'];
|
|
345
|
+
// for (const prop of expectedProps) {
|
|
346
|
+
// if (!firstShadow.hasOwnProperty(prop)) {
|
|
347
|
+
// return false;
|
|
348
|
+
// }
|
|
349
|
+
// }
|
|
350
|
+
|
|
351
|
+
// for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
352
|
+
// if (!firstShadow[coordProp] || typeof firstShadow[coordProp] !== 'object' || !firstShadow[coordProp].hasOwnProperty('value')) {
|
|
353
|
+
// return false;
|
|
354
|
+
// }
|
|
355
|
+
// }
|
|
356
|
+
|
|
357
|
+
// if (!firstShadow.color || typeof firstShadow.color !== 'object' || !firstShadow.color.hasOwnProperty('value')) {
|
|
358
|
+
// return false;
|
|
359
|
+
// }
|
|
360
|
+
|
|
361
|
+
// if (firstShadow.type?.value !== 'dropShadow' && firstShadow.type !== 'dropShadow') {
|
|
362
|
+
// return false;
|
|
363
|
+
// }
|
|
364
|
+
|
|
365
|
+
// // If the first shadow has passed the test, we will check the rest.
|
|
366
|
+
// for (const key of keys) {
|
|
367
|
+
// const shadow = obj[key];
|
|
368
|
+
// if (!shadow || typeof shadow !== 'object') {
|
|
369
|
+
// return false;
|
|
370
|
+
// }
|
|
371
|
+
// for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
372
|
+
// if (!shadow[coordProp] || typeof shadow[coordProp] !== 'object' || !shadow[coordProp].hasOwnProperty('value')) {
|
|
373
|
+
// return false;
|
|
374
|
+
// }
|
|
375
|
+
// }
|
|
376
|
+
// if (!shadow.color || typeof shadow.color !== 'object' || !shadow.color.hasOwnProperty('value')) {
|
|
377
|
+
// return false;
|
|
378
|
+
// }
|
|
379
|
+
// if (shadow.type?.value !== 'dropShadow' && shadow.type !== 'dropShadow') {
|
|
380
|
+
// return false;
|
|
381
|
+
// }
|
|
382
|
+
// }
|
|
383
|
+
|
|
384
|
+
// return true;
|
|
385
|
+
// }
|
|
386
|
+
|
|
387
|
+
// /* Checks whether the object is a single dropShadow structure. */
|
|
388
|
+
// function isSingleDropShadowStructure(obj) {
|
|
389
|
+
// if (!obj || typeof obj !== 'object') {
|
|
390
|
+
// return false;
|
|
391
|
+
// }
|
|
392
|
+
|
|
393
|
+
// const expectedProps = ['x', 'y', 'blur', 'spread', 'color', 'type'];
|
|
394
|
+
// for (const prop of expectedProps) {
|
|
395
|
+
// if (!obj.hasOwnProperty(prop)) {
|
|
396
|
+
// return false;
|
|
397
|
+
// }
|
|
398
|
+
// }
|
|
399
|
+
|
|
400
|
+
// for (const coordProp of ['x', 'y', 'blur', 'spread']) {
|
|
401
|
+
// if (!obj[coordProp] || typeof obj[coordProp] !== 'object' || !obj[coordProp].hasOwnProperty('value')) {
|
|
402
|
+
// return false;
|
|
403
|
+
// }
|
|
404
|
+
// }
|
|
405
|
+
|
|
406
|
+
// if (!obj.color || typeof obj.color !== 'object' || !obj.color.hasOwnProperty('value')) {
|
|
407
|
+
// return false;
|
|
408
|
+
// }
|
|
409
|
+
|
|
410
|
+
// if (obj.type?.value !== 'dropShadow' && obj.type !== 'dropShadow') {
|
|
411
|
+
// return false;
|
|
412
|
+
// }
|
|
413
|
+
|
|
414
|
+
// return true;
|
|
415
|
+
// }
|
|
416
|
+
|
|
417
|
+
// /* Collects the boxShadow string from the dropShadow structure (multiple). */
|
|
418
|
+
// function buildBoxShadowString(shadowStructure, contextTokens) {
|
|
419
|
+
// const shadowParts = [];
|
|
420
|
+
// const keys = Object.keys(shadowStructure).sort((a, b) => parseInt(a) - parseInt(b));
|
|
421
|
+
|
|
422
|
+
// for (const key of keys) {
|
|
423
|
+
// const shadowDef = shadowStructure[key];
|
|
424
|
+
// const shadowString = buildSingleShadowString(shadowDef, contextTokens);
|
|
425
|
+
// if (shadowString) {
|
|
426
|
+
// shadowParts.push(shadowString);
|
|
427
|
+
// }
|
|
428
|
+
// }
|
|
429
|
+
|
|
430
|
+
// // Combine all the shadows into one line
|
|
431
|
+
// return shadowParts.join(', ');
|
|
432
|
+
// }
|
|
433
|
+
|
|
434
|
+
// /* Collects a row for one shadow from the dropShadow structure. */
|
|
435
|
+
// function buildSingleShadowString(singleShadowDef, contextTokens) {
|
|
436
|
+
// // Extracting and calculating the values
|
|
437
|
+
// const x = flattenMapTokens(singleShadowDef.x.value, contextTokens);
|
|
438
|
+
// const y = flattenMapTokens(singleShadowDef.y.value, contextTokens);
|
|
439
|
+
// const blur = flattenMapTokens(singleShadowDef.blur.value, contextTokens);
|
|
440
|
+
// const spread = flattenMapTokens(singleShadowDef.spread.value, contextTokens);
|
|
441
|
+
// const color = flattenMapTokens(singleShadowDef.color.value, contextTokens);
|
|
442
|
+
|
|
443
|
+
// // Checking if all values are numeric (or color)
|
|
444
|
+
// if (typeof x !== 'number' || typeof y !== 'number' || typeof blur !== 'number' || typeof spread !== 'number' || typeof color !== 'string') {
|
|
445
|
+
// console.warn(`Invalid value type in dropShadow: x=${x}(${typeof x}), y=${y}(${typeof y}), blur=${blur}(${typeof blur}), spread=${spread}(${typeof spread}), color=${color}(${typeof color})`);
|
|
446
|
+
// return undefined; // Returning undefined to skip this shadow
|
|
447
|
+
// }
|
|
448
|
+
|
|
449
|
+
// // Forming a row for one shadow
|
|
450
|
+
// return `${x}px ${y}px ${blur}px ${spread}px ${color}`;
|
|
451
|
+
// }
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
// /* An auxiliary function for converting the alias token structure. */
|
|
455
|
+
// function flattenAliasTokens(aliasTokens, contextTokens) {
|
|
456
|
+
// const flattened = {};
|
|
457
|
+
// if (!aliasTokens || typeof aliasTokens !== 'object') {
|
|
458
|
+
// console.warn('An object with alias tokens was expected, but received:', aliasTokens);
|
|
459
|
+
// return flattened;
|
|
460
|
+
// }
|
|
461
|
+
|
|
462
|
+
// Object.keys(aliasTokens).forEach((tokenName) => {
|
|
463
|
+
// const tokenContent = aliasTokens[tokenName];
|
|
464
|
+
|
|
465
|
+
// if (tokenName[0] === tokenName[0].toUpperCase()) {
|
|
466
|
+
// return;
|
|
467
|
+
// }
|
|
468
|
+
|
|
469
|
+
// if (tokenContent && typeof tokenContent === 'object' && tokenContent.hasOwnProperty('value')) {
|
|
470
|
+
// const rawValue = tokenContent.value;
|
|
471
|
+
// const processedValue = flattenMapTokens(rawValue, contextTokens);
|
|
472
|
+
|
|
473
|
+
// flattened[tokenName] = processedValue;
|
|
474
|
+
// } else {
|
|
475
|
+
// // It can be a complex token, for example, a boxShadow (multiple or single)
|
|
476
|
+
// if (isDropShadowStructure(tokenContent)) {
|
|
477
|
+
|
|
478
|
+
// // boxShadow structure processing (multiple)
|
|
479
|
+
// const boxShadowValue = buildBoxShadowString(tokenContent, contextTokens);
|
|
480
|
+
// flattened[tokenName] = boxShadowValue;
|
|
481
|
+
|
|
482
|
+
// } else if (isSingleDropShadowStructure(tokenContent)) {
|
|
483
|
+
// // Processing the structure of a single shadow
|
|
484
|
+
// const singleShadowValue = buildSingleShadowString(tokenContent, contextTokens);
|
|
485
|
+
|
|
486
|
+
// if (singleShadowValue) {
|
|
487
|
+
// flattened[tokenName] = singleShadowValue;
|
|
488
|
+
// } else {
|
|
489
|
+
// console.warn(`Couldn't form a line for a single shadow ${tokenName}:`, tokenContent);
|
|
490
|
+
// }
|
|
491
|
+
// } else {
|
|
492
|
+
// console.warn(`Unsupported structure for alias token ${tokenName}:`, tokenContent);
|
|
493
|
+
// }
|
|
494
|
+
// }
|
|
495
|
+
// })
|
|
496
|
+
|
|
497
|
+
// return flattened;
|
|
498
|
+
// };
|
|
369
499
|
|
|
370
500
|
function checkAndResolveVarValues(contextTokens) {
|
|
371
501
|
const resolved = {};
|
|
@@ -405,8 +535,8 @@ function flattenDefaultValueTokens(defaultTokens) {
|
|
|
405
535
|
|
|
406
536
|
const extractRefKey = (value) => {
|
|
407
537
|
if (typeof value !== 'string') return null;
|
|
408
|
-
const tokenMatch
|
|
409
|
-
return tokenMatch
|
|
538
|
+
const tokenMatch = value.match(/^\s*\{([^}]+)\}\s*$/);
|
|
539
|
+
return tokenMatch ? tokenMatch[1].trim() : null;
|
|
410
540
|
};
|
|
411
541
|
|
|
412
542
|
// 2) Iterative resolution of "{key}" links
|
|
@@ -443,11 +573,11 @@ function flattenDefaultValueTokens(defaultTokens) {
|
|
|
443
573
|
}
|
|
444
574
|
|
|
445
575
|
// 3) Returning numeric values only
|
|
446
|
-
const numericTokens
|
|
576
|
+
const numericTokens = {};
|
|
447
577
|
for (const [tokenName, tokenValue] of Object.entries(resolved)) {
|
|
448
|
-
if (typeof tokenValue === 'number' && Number.isFinite(tokenValue)) numericTokens
|
|
578
|
+
if (typeof tokenValue === 'number' && Number.isFinite(tokenValue)) numericTokens[tokenName] = tokenValue;
|
|
449
579
|
}
|
|
450
|
-
return numericTokens
|
|
580
|
+
return numericTokens;
|
|
451
581
|
}
|
|
452
582
|
|
|
453
583
|
/* Components */
|
|
@@ -476,23 +606,7 @@ function flattenComponentsTokens(componentsTokens, contextTokens) {
|
|
|
476
606
|
const processedValue = flattenMapTokens(rawValue, contextTokens);
|
|
477
607
|
processedComponentTokens[tokenName] = processedValue;
|
|
478
608
|
} else {
|
|
479
|
-
|
|
480
|
-
if (tokenDefinition && typeof tokenDefinition === 'object' && tokenDefinition.style && typeof tokenDefinition.style === 'object' && Object.hasOwn(tokenDefinition.style, 'value')) {
|
|
481
|
-
const rawValue = tokenDefinition.style.value;
|
|
482
|
-
|
|
483
|
-
const processedValue = flattenMapTokens(rawValue, contextTokens);
|
|
484
|
-
processedComponentTokens[tokenName] = processedValue;
|
|
485
|
-
|
|
486
|
-
} else {
|
|
487
|
-
if (isDropShadowStructure(tokenDefinition)) {
|
|
488
|
-
// Processing of the boxShadowSecondary structure (multiple)
|
|
489
|
-
const boxShadowValue = buildBoxShadowString(tokenDefinition, contextTokens);
|
|
490
|
-
processedComponentTokens[tokenName] = boxShadowValue;
|
|
491
|
-
|
|
492
|
-
} else {
|
|
493
|
-
console.warn(`Unsupported token structure ${componentName}.${tokenName}:`, tokenDefinition);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
609
|
+
console.warn(`Unsupported token structure ${componentName}.${tokenName}:`, tokenDefinition);
|
|
496
610
|
}
|
|
497
611
|
})
|
|
498
612
|
|
|
@@ -512,7 +626,7 @@ function flatten() {
|
|
|
512
626
|
config = JSON.parse(configContent);
|
|
513
627
|
} catch (configError) {
|
|
514
628
|
if (configError.code === 'ENOENT') {
|
|
515
|
-
console.log('The configuration file is
|
|
629
|
+
console.log('The configuration file is figma-tokens-flattener-config.json was not found. We use the path - the root directory.');
|
|
516
630
|
} else {
|
|
517
631
|
console.error('Error when reading or parsing the configuration file:', configError.message);
|
|
518
632
|
// Continue with an empty configuration, by default
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-tokens-flattener",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "A tool for transforming Ant Design tokens from Tokens Studio for Figma (Single file) into flat style mappings for light and dark themes.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"figma-tokens-flattener": "index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
|
+
"test:local": "node index.js"
|
|
11
12
|
},
|
|
12
13
|
"keywords": ["figma", "design-tokens", "tokens", "json", "flattener", "transformer", "parser"],
|
|
13
14
|
"author": "Yurii Sudarskii",
|