UNPKG

color-cleaner

Version:

A CLI tool to clean and consolidate colors in your project files.

96 lines (82 loc) 4.38 kB
import fs from 'fs'; import path from 'path'; import { printUpdate } from './prettyConsoleService.js'; const cssNamedColors = [ 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'transparent', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen' ]; const COLOR_PATTERNS = [ /rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)/gi, /rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)/gi, /#[0-9a-f]{3,8}/gi, /hsl\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*\)/gi, /hsla\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*,\s*[\d.]+\s*\)/gi, new RegExp(`\\b(${cssNamedColors.join('|')})\\b`, 'gi') ]; export async function replaceColorsWithVariable(groups) { const palette = new Map(); const fileContents = new Map(); // First pass: Map each CSS variable to its first encountered color for (const group of groups) { const cssVariable = group.cssVariable; if (!palette.has(cssVariable)) { const firstColor = group.items[0].color; palette.set(cssVariable, firstColor); } } // Second pass: Process files for (const group of groups) { const cssVariable = group.cssVariable; for (const item of group.items) { const { currentPath, lineNumber, color, originalColor } = item; try { const filePath = path.resolve(currentPath); if (!fileContents.has(filePath)) { const content = await fs.promises.readFile(filePath, 'utf8'); fileContents.set(filePath, content.split('\n')); } const lines = fileContents.get(filePath); if (lines[lineNumber - 1]) { const line = lines[lineNumber - 1]; let newLine = line; for (const pattern of COLOR_PATTERNS) { const matches = line.match(pattern) || []; for (const match of matches) { const colorToCompare = originalColor || color; if (match.toLowerCase() === colorToCompare.toLowerCase()) { newLine = newLine.replace(match, `var(${cssVariable})`); } } } lines[lineNumber - 1] = newLine; } await fs.promises.writeFile(filePath, lines.join('\n'), 'utf8'); printUpdate(currentPath, lineNumber); } catch (error) { console.error(`Error processing file ${currentPath}:`, error); } } } return palette; }