sparkle-design-cli
Version:
Sparkle Design CSS Generator - デザインシステムCSSを設定ファイルから生成するツール
171 lines (146 loc) • 5.5 kB
JavaScript
/**
* Sparkle Design CSS Generator
* メインの CSS 生成処理
*/
import fs from 'fs';
import path from 'path';
import { REGEX, PATHS, MESSAGES } from './constants.js';
import {
loadConfig,
loadTemplate,
loadColors,
loadGrayMapping,
loadRadiusMapping,
} from './file-loader.js';
import { generateColorTokens, hexToRgba, hexToOklch } from './color-utils.js';
import {
manageFontImports,
extractFontImports,
removeFontImportsFromCSS,
updateGlobalsWithFonts,
} from './font-manager.js';
/**
* テンプレート変数を設定値で置換する
* @param {string} template CSSテンプレート
* @param {Object} config 設定オブジェクト
* @param {Object} grayMapping グレーマッピング
* @param {Object} radiusMapping Radiusマッピング
* @param {Object} colors 色定義
* @returns {string} 処理済みのCSS
*/
function processTemplate(template, config, grayMapping, radiusMapping, colors) {
let processedCSS = template;
// 1. 色のトークンを生成して置換
const colorTokens = generateColorTokens(colors, grayMapping, config.primary);
// プレースホルダーを色のトークンで置換(改行を含む)
processedCSS = processedCSS.replace(REGEX.COLOR_TOKENS_PLACEHOLDER, `\n${colorTokens}\n`);
// 2. 基本的な設定値による置換
Object.entries(config).forEach(([key, value]) => {
// 通常のプレースホルダー(CSS用 - スペースはそのまま)
const placeholder = `{{${key.toUpperCase().replace('-', '_')}}}`;
processedCSS = processedCSS.replace(new RegExp(placeholder, 'g'), value);
// フォントファミリーの場合はURL用のプレースホルダーも生成(スペースを+に置き換え)
if (key.toLowerCase().includes('font')) {
const urlPlaceholder = `{{${key.toUpperCase().replace('-', '_')}_URL}}`;
const urlValue = value.replace(/\s+/g, '+');
processedCSS = processedCSS.replace(new RegExp(urlPlaceholder, 'g'), urlValue);
}
});
// 3. Radiusの一括置換
if (config.radius && radiusMapping[config.radius]) {
const radiusValues = radiusMapping[config.radius];
Object.entries(radiusValues).forEach(([semanticName, radiusValue]) => {
if (semanticName === 'round') return; // roundは特別扱い
const semanticPattern = REGEX.RADIUS_SEMANTIC_PATTERN(semanticName);
processedCSS = processedCSS.replace(
semanticPattern,
`--radius-${semanticName}: var(--radius-${radiusValue})`
);
});
console.log(MESSAGES.RADIUS_APPLIED(config.radius));
}
console.log(MESSAGES.TEMPLATE_PROCESSED);
return processedCSS;
}
/**
* 生成されたCSSをファイルに書き出す
* @param {string} cssContent CSS内容
* @param {string|null} outputPath カスタム出力パス(オプション)
*/
function writeCSS(cssContent, outputPath = null) {
// カスタムパスが指定されていない場合は実行場所からsrc/appディレクトリに出力
const defaultOutputPath = path.resolve(
process.cwd(),
...PATHS.DEFAULT_OUTPUT_DIR,
'sparkle-design.css'
);
const resolvedOutputPath = outputPath ? path.resolve(outputPath) : defaultOutputPath;
try {
// 出力ディレクトリが存在しない場合は作成
const outputDir = path.dirname(resolvedOutputPath);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
fs.writeFileSync(resolvedOutputPath, cssContent, 'utf8');
console.log(MESSAGES.CSS_GENERATED(resolvedOutputPath));
} catch (error) {
console.error(MESSAGES.CSS_WRITE_FAILED(error.message));
process.exit(1);
}
}
/**
* メイン処理
* @param {string|null} configPath カスタム設定ファイルのパス(オプション)
* @param {string|null} outputPath カスタム出力パス(オプション)
*/
export function generateCSS(configPath = null, outputPath = null) {
console.log(MESSAGES.START);
// 1. 設定ファイルを読み込み
const config = loadConfig(configPath);
// 2. テンプレートを読み込み
const template = loadTemplate();
// 3. colors.json、gray.json、radius.csvを読み込み
const colors = loadColors();
const grayMapping = loadGrayMapping();
const radiusMapping = loadRadiusMapping();
// 4. テンプレートを設定値で処理
const processedCSS = processTemplate(template, config, grayMapping, radiusMapping, colors);
// 5. CSSファイルを書き出し
const defaultOutputPath = path.resolve(
process.cwd(),
...PATHS.DEFAULT_OUTPUT_DIR,
'sparkle-design.css'
);
const resolvedOutputPath = outputPath ? path.resolve(outputPath) : defaultOutputPath;
writeCSS(processedCSS, outputPath);
// 6. フォント管理の自動処理を実行
console.log(MESSAGES.FONT_MANAGEMENT_START);
manageFontImports(resolvedOutputPath);
console.log(MESSAGES.SUCCESS);
}
// スクリプトが直接実行された場合のみメイン処理を実行
if (import.meta.url === `file://${process.argv[1]}`) {
generateCSS();
}
// テスト用エクスポート
export {
// メイン関数
processTemplate,
writeCSS,
// ファイル読み込み
loadConfig,
loadTemplate,
loadColors,
loadGrayMapping,
loadRadiusMapping,
// カラー変換
hexToRgba,
hexToOklch,
generateColorTokens,
// フォント管理
extractFontImports,
removeFontImportsFromCSS,
updateGlobalsWithFonts,
manageFontImports,
};