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
JavaScript
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
;