97 lines
2.7 KiB
TypeScript
Executable file
97 lines
2.7 KiB
TypeScript
Executable file
/**
|
|
* Cache management for locale validation
|
|
*/
|
|
|
|
import { readFileSync, readdirSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
import { join, dirname } from 'path';
|
|
import { createHash } from 'crypto';
|
|
import type { ValidationCache } from './types.js';
|
|
|
|
export function hashContent(content: string): string {
|
|
return createHash('sha256').update(content).digest('hex').slice(0, 16);
|
|
}
|
|
|
|
/**
|
|
* Get a hash of the docs/ directory content to detect changes.
|
|
* Uses file paths + modification times as a fast proxy for content changes.
|
|
*/
|
|
export function getDocsHash(docsDir: string): string {
|
|
const hash = createHash('sha256');
|
|
|
|
function walkDir(dir: string): void {
|
|
try {
|
|
const entries = readdirSync(dir, { withFileTypes: true });
|
|
for (const entry of entries) {
|
|
const fullPath = join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
if (entry.name !== 'node_modules' && entry.name !== '.git') {
|
|
walkDir(fullPath);
|
|
}
|
|
} else if (entry.name.endsWith('.md') || entry.name.endsWith('.json')) {
|
|
// Include file path and content hash
|
|
const content = readFileSync(fullPath, 'utf-8');
|
|
hash.update(fullPath);
|
|
hash.update(hashContent(content));
|
|
}
|
|
}
|
|
} catch {
|
|
// Directory doesn't exist or can't be read
|
|
}
|
|
}
|
|
|
|
walkDir(docsDir);
|
|
return hash.digest('hex').slice(0, 16);
|
|
}
|
|
|
|
export function loadCache(
|
|
cacheFile: string,
|
|
docsDir: string,
|
|
clearCache: boolean,
|
|
noCache: boolean
|
|
): { cache: ValidationCache; docsChanged: boolean } {
|
|
const currentDocsHash = getDocsHash(docsDir);
|
|
|
|
if (clearCache || noCache) {
|
|
return {
|
|
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
|
|
docsChanged: false,
|
|
};
|
|
}
|
|
|
|
try {
|
|
if (existsSync(cacheFile)) {
|
|
const cached = JSON.parse(readFileSync(cacheFile, 'utf-8')) as ValidationCache;
|
|
|
|
// Check if docs have changed
|
|
if (cached.docsHash !== currentDocsHash) {
|
|
return {
|
|
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
|
|
docsChanged: true,
|
|
};
|
|
}
|
|
|
|
return { cache: cached, docsChanged: false };
|
|
}
|
|
} catch {
|
|
// Cache corrupted, start fresh
|
|
}
|
|
|
|
return {
|
|
cache: { version: '1.0', docsHash: currentDocsHash, entries: {} },
|
|
docsChanged: false,
|
|
};
|
|
}
|
|
|
|
export function saveCache(cacheFile: string, cache: ValidationCache, noCache: boolean): void {
|
|
if (noCache) return;
|
|
|
|
const cacheDir = dirname(cacheFile);
|
|
if (!existsSync(cacheDir)) {
|
|
mkdirSync(cacheDir, { recursive: true });
|
|
}
|
|
writeFileSync(cacheFile, JSON.stringify(cache, null, 2));
|
|
}
|
|
|
|
export function getCacheKey(file: string, fieldPath: string): string {
|
|
return `${file}:${fieldPath}`;
|
|
}
|