Mobile-BillTracker/scripts/transpile-node18.js

73 lines
2.3 KiB
JavaScript

#!/usr/bin/env node
// Transpiles the Bill Tracker server's TypeScript sources to plain CommonJS for
// the embedded Node 18.20.4 runtime (nodejs-mobile). Node 18 runs modern JS
// syntax natively, so — unlike the old Node-12 pass — this ONLY strips
// TypeScript; it does not rewrite dependency syntax and does not touch
// node_modules (their JS runs as-is on Node 18).
//
// The server is CommonJS-with-TS: files use require()/module.exports plus
// `import type`/`as typeof import()` for types, and require() each other with
// EXPLICIT `.cts`/`.mts` extensions (115 .cts + 40 .mts call sites). We therefore
// transpile each .cts/.mts file IN PLACE, keeping its original name: esbuild
// strips the types and emits CJS, and Node 18's CommonJS loader loads unknown
// extensions (.cts/.mts) through the default `.js` handler as CommonJS — so every
// explicit-extension require() path keeps resolving with zero path rewriting.
//
// Usage: node transpile-node18.js <serverDir> [<dir> ...]
'use strict';
const fs = require('fs');
const path = require('path');
const esbuild = require('esbuild');
const SKIP_DIRS = new Set(['.bin', 'node_modules', 'dist']);
function loaderFor(file) {
if (/\.(cts|mts|ts)$/.test(file)) return 'ts';
if (/\.(cjs|js)$/.test(file)) return 'js';
return null;
}
function walk(dir, cb) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (SKIP_DIRS.has(entry.name)) continue;
if (entry.isSymbolicLink()) continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) walk(full, cb);
else if (loaderFor(entry.name)) cb(full);
}
}
let count = 0;
let failed = 0;
for (const dir of process.argv.slice(2)) {
if (!fs.existsSync(dir)) continue;
walk(dir, (file) => {
const src = fs.readFileSync(file, 'utf8');
let out;
try {
out = esbuild.transformSync(src, {
loader: loaderFor(file),
format: 'cjs',
target: 'node18',
sourcefile: file,
}).code;
} catch (err) {
console.error(`FAILED ${file}: ${err.message.split('\n')[0]}`);
failed++;
return;
}
if (out !== src) {
fs.writeFileSync(file, out);
count++;
}
});
}
if (failed) {
console.error(`Transpile finished with ${failed} failure(s).`);
process.exit(1);
}
console.log(`Transpiled ${count} file(s) to CommonJS for Node 18.`);