structure-validation
Version:
A Node.js CLI tool for validating codebase folder and file structure using a clean declarative configuration. Part of the guardz ecosystem for comprehensive TypeScript development.
164 lines • 5.25 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheService = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
/**
* Infrastructure service for caching validation results and configuration
*/
class CacheService {
constructor(cacheDir = '.structure-validation-cache') {
this.cache = new Map();
this.fileTimestamps = new Map();
this.cacheDir = cacheDir;
this.cacheFile = path_1.default.join(cacheDir, 'cache.json');
this.loadCache();
}
/**
* Get cached value by key
*/
get(key) {
const cached = this.cache.get(key);
if (!cached)
return null;
// Check if cache is still valid
if (cached.expiresAt && Date.now() > cached.expiresAt) {
this.cache.delete(key);
return null;
}
return cached.value;
}
/**
* Set cached value with optional expiration
*/
set(key, value, ttlMs = 5 * 60 * 1000) {
this.cache.set(key, {
value,
expiresAt: Date.now() + ttlMs,
timestamp: Date.now()
});
this.saveCache();
}
/**
* Check if a file has been modified since last cache
*/
isFileModified(filePath) {
try {
const stats = fs_1.default.statSync(filePath);
const lastModified = stats.mtime.getTime();
const cachedTimestamp = this.fileTimestamps.get(filePath);
if (cachedTimestamp === undefined) {
this.fileTimestamps.set(filePath, lastModified);
return true;
}
if (lastModified > cachedTimestamp) {
this.fileTimestamps.set(filePath, lastModified);
return true;
}
return false;
}
catch {
return true; // File doesn't exist or can't be accessed
}
}
/**
* Invalidate cache for specific key
*/
invalidate(key) {
this.cache.delete(key);
this.saveCache();
}
/**
* Clear all cache
*/
clear() {
this.cache.clear();
this.fileTimestamps.clear();
this.saveCache();
}
/**
* Get cache statistics
*/
getStats() {
return {
size: this.cache.size,
keys: Array.from(this.cache.keys())
};
}
/**
* Load cache from disk
*/
loadCache() {
try {
if (!fs_1.default.existsSync(this.cacheDir)) {
fs_1.default.mkdirSync(this.cacheDir, { recursive: true });
return;
}
if (fs_1.default.existsSync(this.cacheFile)) {
const data = fs_1.default.readFileSync(this.cacheFile, 'utf8');
const parsed = JSON.parse(data);
// Restore cache with expiration checking
for (const [key, value] of Object.entries(parsed.cache || {})) {
const cacheEntry = value;
if (cacheEntry.expiresAt && Date.now() < cacheEntry.expiresAt) {
this.cache.set(key, cacheEntry);
}
}
// Restore file timestamps
for (const [filePath, timestamp] of Object.entries(parsed.fileTimestamps || {})) {
this.fileTimestamps.set(filePath, timestamp);
}
}
}
catch (error) {
// If cache is corrupted, start fresh
console.warn('⚠️ Cache corrupted, starting fresh');
this.clear();
}
}
/**
* Save cache to disk
*/
saveCache() {
try {
if (!fs_1.default.existsSync(this.cacheDir)) {
fs_1.default.mkdirSync(this.cacheDir, { recursive: true });
}
const data = {
cache: Object.fromEntries(this.cache),
fileTimestamps: Object.fromEntries(this.fileTimestamps),
version: '1.0.0'
};
fs_1.default.writeFileSync(this.cacheFile, JSON.stringify(data, null, 2));
}
catch (error) {
console.warn('⚠️ Failed to save cache:', error);
}
}
/**
* Generate cache key for configuration
*/
getConfigKey(configPath) {
return `config:${path_1.default.resolve(configPath)}`;
}
/**
* Generate cache key for file discovery
*/
getFileDiscoveryKey(basePath, patterns, configRoot) {
const rootSuffix = configRoot ? `:${configRoot}` : '';
return `files:${path_1.default.resolve(basePath)}:${patterns.sort().join(',')}${rootSuffix}`;
}
/**
* Generate cache key for validation results
*/
getValidationKey(files, rules) {
const filesHash = files.sort().join(',');
const rulesHash = rules.sort().join(',');
return `validation:${filesHash}:${rulesHash}`;
}
}
exports.CacheService = CacheService;
//# sourceMappingURL=CacheService.js.map