#!/usr/bin/env node /** * Static sanity check for the single-file app. * * node scripts/check-html.mjs [index.html] [--net] * * Verifies that the document is well formed, that the ES-module import map is * present and valid, that the three.js + OrbitControls module scripts are there * and that the inline module body actually parses as an ES module (delegated to * `node --check`). Also cross-checks that every element id used by the script * exists in the markup, and — with --net — that the CDN entry points resolve. */ import { readFileSync, writeFileSync, mkdtempSync, rmSync, existsSync } from 'node:fs'; import { execFileSync } from 'node:child_process'; import { tmpdir } from 'node:os'; import { join, resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const argv = process.argv.slice(2).filter((a) => !a.startsWith('--')); const flags = process.argv.slice(2).filter((a) => a.startsWith('--')); const file = resolve(root, argv[0] || 'index.html'); const results = []; const ok = (name, detail = '') => results.push([true, name, detail]); const bad = (name, detail = '') => results.push([false, name, detail]); const warn = (name, detail = '') => results.push([null, name, detail]); const assert = (cond, msg) => { if (!cond) throw new Error(msg); }; const html = readFileSync(file, 'utf8'); /* ---------------------------------------------------------------- doctype */ try { assert(/^\s*/i.test(html), 'missing '); assert(/]*lang="en"/i.test(html), ' has no lang attribute'); assert(/]+charset="utf-8"/i.test(html), 'missing '); assert(/