UNPKG

w1-system-font-validator

Version:

VS Code extension for validating W1 System font variables (both fontConfig.json and localFontConfig.json)

245 lines 10.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigDetector = void 0; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const vscode = __importStar(require("vscode")); class ConfigDetector { constructor() { this.configWatcher = null; this.setupConfigWatcher(); } /** * Find project root by looking for project boundary markers */ findProjectRoot(filePath) { let currentDir = path.dirname(filePath); const workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(filePath)); const workspaceRoot = workspaceFolder?.uri.fsPath; while (currentDir !== path.dirname(currentDir)) { // Stop at workspace boundary if (workspaceRoot && currentDir === workspaceRoot) { const projectMarkers = ["package.json", ".git", "next.config.js", "tsconfig.json"]; for (const marker of projectMarkers) { if (fs.existsSync(path.join(currentDir, marker))) { return currentDir; } } break; } // Check for project boundary markers const projectMarkers = ["package.json", ".git", "next.config.js", "tsconfig.json"]; for (const marker of projectMarkers) { if (fs.existsSync(path.join(currentDir, marker))) { return currentDir; } } currentDir = path.dirname(currentDir); } return null; } /** * Detect and load font configurations for a specific file */ async detectFontConfig(filePath) { const projectRoot = this.findProjectRoot(filePath); const result = { hasFontConfig: false, hasLocalFontConfig: false, }; if (!projectRoot) { // No project root found return result; } // Check for fontConfig.json (package-based fonts) - new location first, then legacy const newFontConfigPath = path.join(projectRoot, "src/w1-system-config/w1-system-font-manager/fontConfig.json"); const legacyFontConfigPath = path.join(projectRoot, "fontConfig.json"); let fontConfigPath = null; if (fs.existsSync(newFontConfigPath)) { fontConfigPath = newFontConfigPath; } else if (fs.existsSync(legacyFontConfigPath)) { fontConfigPath = legacyFontConfigPath; } if (fontConfigPath) { try { const fontConfigContent = fs.readFileSync(fontConfigPath, "utf8"); const fontConfig = JSON.parse(fontConfigContent); result.hasFontConfig = true; result.fontConfigPath = fontConfigPath; result.fontConfig = fontConfig; // fontConfig.json loaded successfully } catch (error) { console.error(`[W1 Font Validator] Error loading fontConfig.json:`, error); } } // Check for localFontConfig.json (local file-based fonts) - new location first, then legacy const newLocalFontConfigPath = path.join(projectRoot, "src/w1-system-config/w1-system-local-font-manager/localFontConfig.json"); const legacyLocalFontConfigPath = path.join(projectRoot, "localFontConfig.json"); let localFontConfigPath = null; if (fs.existsSync(newLocalFontConfigPath)) { localFontConfigPath = newLocalFontConfigPath; } else if (fs.existsSync(legacyLocalFontConfigPath)) { localFontConfigPath = legacyLocalFontConfigPath; } if (localFontConfigPath) { try { const localFontConfigContent = fs.readFileSync(localFontConfigPath, "utf8"); const localFontConfig = JSON.parse(localFontConfigContent); result.hasLocalFontConfig = true; result.localFontConfigPath = localFontConfigPath; result.localFontConfig = localFontConfig; // localFontConfig.json loaded successfully } catch (error) { console.error(`[W1 Font Validator] Error loading localFontConfig.json:`, error); } } return result; } /** * Get all valid font-family variables from both configurations */ getValidFontFamilies(projectConfig) { const validFamilies = new Set(); // Add package-based font families if (projectConfig.fontConfig) { Object.values(projectConfig.fontConfig.roles).forEach((role) => { if (role.variables?.family) { validFamilies.add(role.variables.family); } }); } // Add local font families if (projectConfig.localFontConfig) { if (projectConfig.localFontConfig.detailedRoles) { Object.values(projectConfig.localFontConfig.detailedRoles).forEach((role) => { if (role.variables?.family) { validFamilies.add(role.variables.family); } }); } // Also add from validVariables array (fallback) projectConfig.localFontConfig.validVariables?.forEach((variable) => { if (variable.startsWith("--fontfamily_")) { validFamilies.add(variable); } }); } return validFamilies; } /** * Get available weights for a specific font-family variable */ getAvailableWeights(projectConfig, fontFamilyVar) { // Check package-based fonts if (projectConfig.fontConfig) { for (const role of Object.values(projectConfig.fontConfig.roles)) { if (role.variables?.family === fontFamilyVar) { // Extract weight keys from the availableWeights object return Object.keys(role.availableWeights || {}).filter((key) => role.availableWeights[key] !== null); } } } // Check local fonts (now uses same object format as package fonts) if (projectConfig.localFontConfig?.detailedRoles) { for (const role of Object.values(projectConfig.localFontConfig.detailedRoles)) { if (role.variables?.family === fontFamilyVar) { // Same object format: {"400": {...}, "400_italic": {...}} const weightsObject = role.availableWeights; return Object.keys(weightsObject || {}).filter((key) => weightsObject[key] !== null); } } } return []; } /** * Check if a font-family variable supports italics */ supportsItalics(projectConfig, fontFamilyVar) { // Check package-based fonts if (projectConfig.fontConfig) { for (const role of Object.values(projectConfig.fontConfig.roles)) { if (role.variables?.family === fontFamilyVar) { return role.hasItalics || false; } } } // Check local fonts if (projectConfig.localFontConfig?.detailedRoles) { for (const role of Object.values(projectConfig.localFontConfig.detailedRoles)) { if (role.variables?.family === fontFamilyVar) { return role.hasItalics || false; } } } return false; } /** * Setup file system watchers for configuration changes */ setupConfigWatcher() { // Watch both new and legacy locations this.configWatcher = vscode.workspace.createFileSystemWatcher("**/{fontConfig.json,localFontConfig.json}"); this.configWatcher.onDidChange((uri) => { // Font config changed, will refresh // Trigger re-validation of affected documents this.onConfigChanged(); }); this.configWatcher.onDidCreate((uri) => { // Font config created, will refresh this.onConfigChanged(); }); this.configWatcher.onDidDelete((uri) => { // Font config deleted, will refresh this.onConfigChanged(); }); } onConfigChanged() { // Clear any cached configurations and trigger re-validation // This will be implemented in the main validator vscode.commands.executeCommand("w1FontValidator.refreshConfig"); } dispose() { if (this.configWatcher) { this.configWatcher.dispose(); } } } exports.ConfigDetector = ConfigDetector; //# sourceMappingURL=configDetector.js.map