190 lines
7.4 KiB
JavaScript
190 lines
7.4 KiB
JavaScript
// Generated, do not edit. sha256:bd50331802703178a5561c2051cfa66fb4fdc608745b61d6cac1576e04cefdc9
|
|
import { readFile, writeFile, mkdir, copyFile, rm, readdir } from 'node:fs/promises';
|
|
import { join, resolve, dirname, basename } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
const MODULES = join(ROOT, 'node_modules');
|
|
const VENDOR = join(ROOT, 'client', 'vendor');
|
|
|
|
function fout(bericht) {
|
|
console.error(`\n[vendor] ${bericht}\n`);
|
|
process.exit(1);
|
|
}
|
|
|
|
export function pinnedVersion(naam, pkgJson) {
|
|
const alles = { ...((pkgJson && pkgJson.dependencies) || {}), ...((pkgJson && pkgJson.devDependencies) || {}) };
|
|
const pin = alles[naam];
|
|
return /^\d+\.\d+\.\d+$/.test(String(pin ?? '')) ? pin : null;
|
|
}
|
|
|
|
export function pinMismatch(naam, installed, pkgJson) {
|
|
const pin = pinnedVersion(naam, pkgJson);
|
|
if (!pin || pin === installed) return null;
|
|
return `${naam} staat op ${installed} in node_modules, maar package.json pint ${pin}.\n`
|
|
+ ' Dat gebeurt na een `git pull` die package.json wijzigde: er is nog niets geinstalleerd.\n'
|
|
+ ' Draai eerst: npm install';
|
|
}
|
|
|
|
let projectPkg = null;
|
|
async function pakketVersie(naam) {
|
|
let versie;
|
|
try {
|
|
versie = JSON.parse(await readFile(join(MODULES, naam, 'package.json'), 'utf8')).version;
|
|
} catch {
|
|
fout(`${naam} niet gevonden in node_modules. Draai eerst: npm install`);
|
|
}
|
|
projectPkg ??= JSON.parse(await readFile(join(ROOT, 'package.json'), 'utf8'));
|
|
const mis = pinMismatch(naam, versie, projectPkg);
|
|
if (mis) fout(mis);
|
|
return versie;
|
|
}
|
|
|
|
async function vendorInter() {
|
|
const naam = '@fontsource-variable/inter';
|
|
const versie = await pakketVersie(naam);
|
|
const bron = join(MODULES, naam);
|
|
const doel = join(VENDOR, 'inter');
|
|
await mkdir(join(doel, 'files'), { recursive: true });
|
|
|
|
let bestanden;
|
|
try {
|
|
bestanden = (await readdir(join(bron, 'files'))).filter(f => f.endsWith('-opsz-normal.woff2'));
|
|
} catch {
|
|
fout(`${naam}/files/ ontbreekt: pakket onvolledig of van vorm veranderd.`);
|
|
}
|
|
if (bestanden.length === 0) fout(`${naam}: geen *-opsz-normal.woff2 gevonden (andere pakketvorm?).`);
|
|
for (const f of bestanden) await copyFile(join(bron, 'files', f), join(doel, 'files', f));
|
|
|
|
let css;
|
|
try {
|
|
css = await readFile(join(bron, 'opsz.css'), 'utf8');
|
|
} catch {
|
|
fout(`${naam}/opsz.css ontbreekt: pakket van vorm veranderd; CSS niet af te leiden.`);
|
|
}
|
|
const gekopieerd = new Set(bestanden);
|
|
const blokken = css.split('@font-face').slice(1)
|
|
.map(b => `@font-face${b.slice(0, b.indexOf('}') + 1)}`)
|
|
.filter(b => {
|
|
const m = b.match(/url\(\.\/files\/([^)]+)\)/);
|
|
return m && gekopieerd.has(basename(m[1]));
|
|
})
|
|
.map(b => b.replace(/'Inter Variable'/g, `'Inter'`));
|
|
|
|
if (blokken.length !== bestanden.length) {
|
|
fout(`Inter: ${bestanden.length} woff2 gekopieerd maar ${blokken.length} @font-face-blokken ` +
|
|
`gevonden. Die twee horen gelijk te zijn; controleer de vorm van opsz.css.`);
|
|
}
|
|
|
|
const kop = [
|
|
'/* GEGENEREERD door scripts/vendor.mjs: niet met de hand bewerken.',
|
|
` * Bron: ${naam} ${versie}, opsz.css (upright subsets).`,
|
|
" * Aangepast: font-family 'Inter Variable' -> 'Inter'. Verder ongewijzigd.",
|
|
' */',
|
|
].join('\n');
|
|
await writeFile(join(doel, 'inter.css'), `${kop}\n\n${blokken.join('\n\n')}\n`, 'utf8');
|
|
|
|
return `${naam} ${versie} → client/vendor/inter/ (${bestanden.length} subsets + inter.css)`;
|
|
}
|
|
|
|
const CHART_LIBS = [
|
|
{ pakket: 'chart.js', bestand: 'dist/chart.umd.js', doelmap: 'chartjs' },
|
|
{ pakket: 'hammerjs', bestand: 'hammer.min.js', doelmap: 'hammerjs' },
|
|
{ pakket: 'chartjs-plugin-zoom', bestand: 'dist/chartjs-plugin-zoom.min.js', doelmap: 'chartjs-plugin-zoom' },
|
|
];
|
|
|
|
async function vendorChartLibs() {
|
|
const regels = [];
|
|
for (const { pakket, bestand, doelmap } of CHART_LIBS) {
|
|
const versie = await pakketVersie(pakket);
|
|
const naam = basename(bestand);
|
|
const doel = join(VENDOR, doelmap);
|
|
await mkdir(doel, { recursive: true });
|
|
|
|
let code;
|
|
try {
|
|
code = await readFile(join(MODULES, pakket, bestand), 'utf8');
|
|
} catch {
|
|
fout(`${pakket}/${bestand} ontbreekt: pakket onvolledig of van vorm veranderd.`);
|
|
}
|
|
const zonderMap = code.replace(/\r?\n\/\/# sourceMappingURL=[^\r\n]*\s*$/, '\n');
|
|
if (/sourceMappingURL/.test(zonderMap)) {
|
|
fout(`${pakket}: sourceMappingURL-verwijzing niet verwijderd: controleer de vorm van ${naam}.`);
|
|
}
|
|
await writeFile(join(doel, naam), zonderMap, 'utf8');
|
|
regels.push(`${pakket} ${versie} → client/vendor/${doelmap}/${naam}`);
|
|
}
|
|
return regels;
|
|
}
|
|
|
|
async function vendorCrypto() {
|
|
const { build } = await import('esbuild');
|
|
const versies = [];
|
|
for (const p of ['@noble/curves', '@noble/hashes', '@noble/ciphers', '@scure/bip32', '@scure/base']) {
|
|
versies.push(`${p} ${await pakketVersie(p)}`);
|
|
}
|
|
const esbuildVersie = await pakketVersie('esbuild');
|
|
|
|
const doel = join(VENDOR, 'crypto');
|
|
await mkdir(doel, { recursive: true });
|
|
const uit = join(doel, 'noble-scure.js');
|
|
|
|
try {
|
|
await build({
|
|
entryPoints: [join(ROOT, 'scripts', 'vendor-entries', 'crypto.js')],
|
|
outfile: uit,
|
|
bundle: true,
|
|
format: 'esm',
|
|
target: ['es2022'],
|
|
minify: true,
|
|
sourcemap: false,
|
|
legalComments: 'none',
|
|
logLevel: 'warning',
|
|
});
|
|
} catch (e) {
|
|
fout(`esbuild kon de crypto-bundel niet bouwen: ${e.message}`);
|
|
}
|
|
|
|
const code = await readFile(uit, 'utf8');
|
|
const verwacht = ['secp256k1', 'schnorr', 'sha256', 'ripemd160', 'HDKey', 'base58check', 'bech32', 'bech32m',
|
|
'bytesToHex', 'hexToBytes', 'utf8ToBytes', 'concatBytes',
|
|
'chacha20', 'hkdfExtract', 'hkdfExpand', 'hmac', 'base64'];
|
|
const exportRegel = code.match(/export\s*\{[^}]*\}/g)?.join(' ') ?? '';
|
|
const missend = verwacht.filter(n => !new RegExp(`\\b${n}\\b`).test(exportRegel));
|
|
if (missend.length) {
|
|
fout(`crypto-bundel mist exports: ${missend.join(', ')}. Controleer scripts/vendor-entries/crypto.js.`);
|
|
}
|
|
|
|
const kb = Math.round(code.length / 1024);
|
|
return `${versies.join(' + ')} → client/vendor/crypto/noble-scure.js (${kb} KB, gebundeld met esbuild ${esbuildVersie})`;
|
|
}
|
|
|
|
async function vendorQr() {
|
|
const pakket = 'qrcode-generator';
|
|
const versie = await pakketVersie(pakket);
|
|
const doel = join(VENDOR, 'qrcode');
|
|
await mkdir(doel, { recursive: true });
|
|
let code;
|
|
try {
|
|
code = await readFile(join(MODULES, pakket, 'dist', 'qrcode.mjs'), 'utf8');
|
|
} catch {
|
|
fout(`${pakket}/dist/qrcode.mjs ontbreekt: pakket onvolledig of van vorm veranderd.`);
|
|
}
|
|
if (!/export default qrcode;/.test(code) || /^\s*import\s/m.test(code) || /sourceMappingURL/.test(code)) {
|
|
fout(`${pakket}: dist/qrcode.mjs heeft niet de verwachte vorm (één default export, geen imports, geen sourcemap).`);
|
|
}
|
|
await writeFile(join(doel, 'qrcode.mjs'), code, 'utf8');
|
|
return `${pakket} ${versie} → client/vendor/qrcode/qrcode.mjs`;
|
|
}
|
|
|
|
async function main() {
|
|
await rm(VENDOR, { recursive: true, force: true });
|
|
await mkdir(VENDOR, { recursive: true });
|
|
|
|
const regels = [await vendorInter(), ...(await vendorChartLibs()), await vendorCrypto(), await vendorQr()];
|
|
console.log('[vendor] klaar:');
|
|
for (const r of regels) console.log(` - ${r}`);
|
|
}
|
|
|
|
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) await main();
|