/
antonnov
/
aaaaaaauto
Обзор
Документация
Войти
/
antonnov
/
aaaaaaauto
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/token-parser.js
94 строки
3 KB
Anton211
first_commit
28 июл 2026, 15:16
28 июл 2026, 15:16
79799f0
Код
Авторство
О чём код?
const fs = require('fs'); const path = require('path'); const postcss = require('postcss'); const postcssValuesParser = require('postcss-values-parser'); function extractTokensFromCss(cssText) { const tokens = { colors: new Set(), spacing: new Set(), typography: new Set(), raw: [], }; const result = postcss.parse(cssText); result.walkDecls((decl) => { const value = decl.value.trim(); if (!value) return; if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value) || value.startsWith('rgb') || value.startsWith('hsl')) { tokens.colors.add(value); tokens.raw.push({ type: 'color', prop: decl.prop, value, node: decl }); } else if (/^\d+(\.\d+)?(px|rem|em|vh|vw|%)$/.test(value) || value === '0') { tokens.spacing.add(value); tokens.raw.push({ type: 'spacing', prop: decl.prop, value, node: decl }); } else if (/font|line-height|letter-spacing|font-weight/i.test(decl.prop)) { tokens.typography.add(value); tokens.raw.push({ type: 'typography', prop: decl.prop, value, node: decl }); } }); return tokens; } function loadTokens(dsPath) { const candidates = [ path.join(dsPath, 'tokens'), path.join(dsPath, 'src', 'tokens'), path.join(dsPath, 'theme.js'), path.join(dsPath, 'src', 'theme.js'), path.join(dsPath, 'design-tokens.json'), path.join(dsPath, 'src', 'design-tokens.json'), ]; const found = candidates.find((p) => fs.existsSync(p)); if (!found) { return { colors: new Set(), spacing: new Set(), typography: new Set(), raw: [] }; } const stat = fs.statSync(found); if (stat.isDirectory()) { const allTokens = { colors: new Set(), spacing: new Set(), typography: new Set(), raw: [] }; const files = fs.readdirSync(found).filter((f) => /\.(css|scss|less|json|js|ts)$/.test(f)); for (const file of files) { const fullPath = path.join(found, file); const text = fs.readFileSync(fullPath, 'utf8'); if (/(css|scss|less)/.test(file)) { const parsed = extractTokensFromCss(text); parsed.colors.forEach((c) => allTokens.colors.add(c)); parsed.spacing.forEach((s) => allTokens.spacing.add(s)); parsed.typography.forEach((t) => allTokens.typography.add(t)); allTokens.raw.push(...parsed.raw); } } return allTokens; } const text = fs.readFileSync(found, 'utf8'); if (found.endsWith('.json')) { try { const json = JSON.parse(text); const allTokens = { colors: new Set(), spacing: new Set(), typography: new Set(), raw: [] }; const walk = (obj) => { for (const key of Object.keys(obj)) { const val = obj[key]; if (typeof val === 'string') { if (/^#|rgb|hsl/.test(val)) allTokens.colors.add(val); else if (/^\d/.test(val)) allTokens.spacing.add(val); else if (/font|line-height/i.test(key)) allTokens.typography.add(val); } else if (val && typeof val === 'object') { walk(val); } } }; walk(json); return allTokens; } catch { return { colors: new Set(), spacing: new Set(), typography: new Set(), raw: [] }; } } return extractTokensFromCss(text); } module.exports = { loadTokens };