File size: 2,457 Bytes
f6dcaa7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #!/usr/bin/env node
// Validate the scroll registry and manifests with the same checks the page runs.
// node tools/validate_scroll.mjs all scrolls in scrolls/index.json
// node tools/validate_scroll.mjs path/to/manifest.json [--local]
// --local applies the limits used for "Open your own" (as a visitor's browser would).
// Exit code 1 if anything is wrong. Git LFS pointer files count as present.
import { readFileSync, statSync, existsSync } from 'node:fs';
import { dirname, resolve, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { validateManifest, validateRegistry, LOCAL_LIMITS, REGISTRY_LIMITS, peelOrder } from '../lib/manifest.js';
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
const args = process.argv.slice(2);
const local = args.includes('--local');
const paths = args.filter((a) => !a.startsWith('--'));
let bad = 0;
function lfsSize(p) {
// an LFS pointer stands for the real file: report the size it records
const st = statSync(p);
if (st.size < 400) { const t = readFileSync(p, 'utf8'); const m = /^version https:\/\/git-lfs.*\nsize (\d+)/m.exec(t); if (m) return +m[1]; }
return st.size;
}
function check(manifestPath, trusted) {
let m;
try { m = JSON.parse(readFileSync(manifestPath, 'utf8')); }
catch (e) { console.log(`FAIL ${manifestPath}: ${e.message}`); bad++; return; }
const base = resolve(dirname(manifestPath), m.base || '');
const v = validateManifest(m, {
trusted, limits: trusted ? REGISTRY_LIMITS : LOCAL_LIMITS,
fileSize: (p) => { const f = join(base, p); return existsSync(f) ? lfsSize(f) : null; },
});
const n = v.ok ? peelOrder(m).length : 0;
console.log(`${v.ok ? 'ok ' : 'FAIL'} ${manifestPath}${v.ok ? `: ${m.id}, ${n} windings, ${m.layers.length} layers, ${v.files.length} files` : ''}`);
for (const e of v.errors) console.log(` error: ${e}`);
for (const w of v.warnings) console.log(` note: ${w}`);
if (!v.ok) bad++;
}
if (paths.length) for (const p of paths) check(resolve(p), !local);
else {
const reg = JSON.parse(readFileSync(join(root, 'scrolls/index.json'), 'utf8'));
const r = validateRegistry(reg);
console.log(`${r.ok ? 'ok ' : 'FAIL'} scrolls/index.json: ${reg.scrolls?.length ?? 0} scrolls`);
for (const e of r.errors) console.log(` error: ${e}`);
if (!r.ok) bad++;
for (const s of reg.scrolls || []) check(join(root, s.manifest), true);
}
process.exit(bad ? 1 : 0);
|