Files
kefu/admin-web/scripts/verify-token-build.mjs
T
2026-09-28 10:02:50 +08:00

31 lines
1.6 KiB
JavaScript

import { readFileSync, existsSync } from 'node:fs';
import { resolve, dirname, relative, extname } from 'node:path';
// Inspect only the graph reached from index.html; old chunks left in dist do not count.
export function verifyTokenBuild(directory) {
const root = resolve(directory);
const visited = new Set();
function visit(path) {
path = resolve(path);
const rel = relative(root, path);
if (rel.startsWith('..') || !existsSync(path) || visited.has(path)) return;
visited.add(path);
const text = readFileSync(path, 'utf8');
for (const match of text.matchAll(/["'`]((?:\.{0,2}\/)?[\w./-]+\.js)["'`]/g)) {
const ref = match[1];
visit(ref.startsWith('/') ? resolve(root, ref.slice(1)) : resolve(dirname(path), ref));
}
}
visit(resolve(root, 'index.html'));
const stats = [...visited].filter((path) => /[\\/]call-stats-[^\\/]+\.js$/.test(path));
if (stats.length !== 1 || !readFileSync(stats[0], 'utf8').includes('ModelUsageStats-')) {
throw new Error('The active call statistics page does not include Token usage. Refusing this build.');
}
const usage = [...visited].filter((path) => /[\\/]ModelUsageStats-[^\\/]+\.js$/.test(path));
const hasApi = [...visited].some((path) => extname(path) === '.js' && readFileSync(path, 'utf8').includes('/stats/model-usage/log'));
if (!usage.length || !hasApi) throw new Error('The active Token component or usage API is missing.');
return { page: relative(root, stats[0]), component: relative(root, usage[0]), assets: visited.size };
}
console.log(JSON.stringify(verifyTokenBuild(process.argv[2] || 'dist')));