#!/usr/bin/env node const path = require('node:path'); const {Worker} = require('node:worker_threads'); const DEBUG = {parsing: false, timing: false}; const debugEnv = process.env.DEBUG; if (debugEnv) { for (const name in DEBUG) { DEBUG[name] = debugEnv === 'true' || debugEnv === '1' || debugEnv.includes(name); } } const readFile = (file) => require('node:fs/promises').readFile(file, 'utf-8'); const exists = (filename) => require('node:fs/promises') .access(filename) .then(() => true) .catch(() => false); const $env = (env) => (env ? {...process.env, ...env} : process.env); let markId = 0; function measure(name, parent = '', depth = 0) { const start = `${parent}:${name}:${++markId}`; performance.mark(start); function end() { performance.measure(name, { start, detail: {depth, parent}, }); } end.submeasure = (sub) => measure(sub, start, depth + 1); return end; } const color = (code, end) => (str) => `\x1B[${code}m${str}\x1B[${end}m`; const bold = color(1, 22); const dim = color(2, 22); const red = color(31, 39); const panic = (message) => { console.log(red(bold('Error: ') + message)); process.exit(1); }; function json5(json) { try { return JSON.parse(json); } catch (_2) { return (0, eval)(`(${json})`); } } const endPkgParse = measure('parse package.json'); let pkg; const pkgPromise = readFile('package.json').then((json) => { pkg = json5(json); endPkgParse(); return pkg; }); const INITIAL = 0; const COMMAND = 1; const ARGS = 2; function parseShell(script) { script += ' '; const tokenizer = /(if|then|fi|&&|\|\||[ ;"'`()=])/g; const expectedOps = { ')': '(', fi: 'if', }; const stack = []; const logic = []; let context = INITIAL; let token; let index = 0; let lastOp; let lastEnv; let buf = ''; let command = {name: '', args: [], env: {}}; const root = []; let seq = root; const commit = () => { if (context === INITIAL) { if (lastEnv) { if (!command) seq.push((command = {name: '', args: [], env: {}})); command.env[lastEnv] = buf; lastEnv = undefined; } else if (buf) { if (!command) seq.push((command = {name: '', args: [], env: {}})); command.name = buf; context = ARGS; } } else if (context === ARGS) { // unquote if (buf[0] === "'" && buf.at(-1) === "'") { buf = buf.slice(1, -1); } else if (buf[0] === '"' && buf.at(-1) === '"') { buf = buf.slice(1, -1).replaceAll('\\"', '"'); } command.args.push(buf); } buf = ''; }; while ((token = tokenizer.exec(script))) { let op = token[0]; buf += script.substring(index, token.index); index = tokenizer.lastIndex; switch (op) { case '&&': case '||': if (lastOp) continue; seq.push({type: op}); case ';': if (lastOp) continue; commit(); command = null; context = INITIAL; break; case ' ': if (!buf) continue; if (lastOp) { if (buf) buf += ' '; continue; } commit(); break; case '=': if (context === INITIAL && !lastOp) { lastEnv = buf; buf = ''; } else { buf += op; } break; case 'if': if (context !== INITIAL) { buf += op; continue; } logic.push({ type: 'conditional', test: [], consequent: [], alternate: [], }); seq = logic.at(-1)?.test; command = null; context = INITIAL; break; case 'then': if (context !== INITIAL) { buf += op; continue; } seq = logic.at(-1)?.consequent; command = null; context = INITIAL; break; case 'else': if (context !== INITIAL) { buf += op; continue; } seq = logic.at(-1)?.alternate; command = null; context = INITIAL; break; case 'fi': if (context !== INITIAL) { buf += op; continue; } seq = root; if (logic.length) seq.push(logic.pop()); break; case '(': case ')': case '"': case `'`: case '`': buf += op; default: if (op in expectedOps) { const start = expectedOps[op]; if (lastOp !== start) { const line = `${script}\n${'-'.repeat(token.index)}^`; panic(`unexpected "${op}"\n${dim(line)}`); } op = start; } if (lastOp === op) { stack.pop(); lastOp = stack.at(-1); } else { stack.push(op); lastOp = op; } break; } } if (command && seq.at(-1) !== command) seq.push(command); return seq; } async function run(seq, env = {}) { let prev = true; for (const node of seq) { switch (node.type) { case '&&': if (!prev) return; break; case '||': if (prev) return prev; break; case 'conditional': if (await run(node.test, env)) { prev = await run(node.consequent, env); } else if (node.alternate) { prev = await run(node.alternate, env); } break; default: if (node.name === '$npm_execpath' || node.name === 'npm') { let script = node.args.shift(); if (script === 'run') script = node.args.shift(); prev = await runScript(script, node.args, {...env, ...node.env}); } else if (node.name === 'node') { const script = node.args.shift(); prev = await runNode(script, node.args, {...env, ...node.env}); } else if (node.name === 'test') { const a1 = node.args[0].replace( /$([a-z0-9_]+)/g, (_, c) => process.env[c] ?? _, ); const a2 = node.args[2].replace( /$([a-z0-9_]+)/g, (_, c) => process.env[c] ?? _, ); if (node.args[1] === '=') prev = a1 === a2; else if (node.args[1] === '!=') prev = a1 !== a2; } else if (node.name) { // panic(`Unknown command ${node.name} (${node.args})`); prev = await runBin(node.name, node.args, node.env); } else { panic(`Unknown node ${JSON.stringify(node)}`); } } } return prev; } const workerShim = ` const {parentPort} = require('node:worker_threads'); const {dirname, basename, sep} = require('path'); parentPort.once('message', ([mod, filename, args, env, compiledCode]) => { process.stdout.isTTY = process.stdin.isTTY = process.stderr.isTTY = true; process.argv = [process.argv[0], filename].concat(args); module.id = basename(filename); module.filename = __filename = filename; module.path = __dirname = dirname(__filename); Object.assign(process.env, env); parentPort.postMessage(0); const exit = process.exit.bind(process); process.exit = (exitCode) => { process.stdout.end(); process.setUncaughtExceptionCaptureCallback(() => {}); setTimeout(exit, 0, exitCode); }; if (mod && !compiledCode) return import(filename); require = require('node:module').createRequire(require.resolve(filename)); require('vm').runInThisContext(compiledCode || require('fs').readFileSync(filename, 'utf-8'), {filename}); }); `; const workerPool = { workers: [], get: () => workerPool.workers.pop() ?? workerPool.create(), create: () => new Worker(workerShim, {eval: true}), }; workerPool.workers.push(workerPool.create()); const pkgCache = new Map(); function getPkg(filename) { const index = filename.lastIndexOf('/node_modules/'); if (index === -1) return pkgPromise; const pkgName = filename.slice(index + 14).match(/^(@[^/]+\/)?[^/]+/g)[0]; const pkgFile = `${filename.slice(0, index + 14)}${pkgName}/package.json`; const cached = pkgCache.get(pkgFile); if (cached) return cached; const prom = readFile(pkgFile).then(json5); pkgCache.set(pkgFile, prom); return prom; } async function runNode(script, args, env, compiledCode) { if ( process.env.ESBUILD === 'force' && compiledCode === undefined && !script.endsWith('.built.mjs') ) { return runTs(script, args, env); } const scriptId = `node(${script} ${args.join(' ')})`; const done = measure(scriptId); const filename = path.resolve(script); const isModule = filename.endsWith('.mjs') || ((await getPkg(filename)).type === 'module' && !filename.endsWith('.cjs')); return new Promise((resolve) => { const end = done.submeasure('worker start'); const worker = workerPool.get(); worker.postMessage([isModule, filename, args, $env(env), compiledCode]); worker.once('message', done.submeasure('worker init')); worker.once('exit', done); worker.once('exit', resolve); end(); }); } async function runTs(script, args, env) { const end = measure(`esbuild(${script})`); const {build} = require('esbuild'); const outfile = script.endsWith('.mjs') ? script.replace(/([^/]+)\.mjs$/, '.$1.built.mjs') : undefined; if (!outfile && !/\.[a-z]+$/.test(script)) { const [ext, index] = await Promise.all([ exists(`${script}.ts`), exists(`${script}/index.ts`), ]); if (ext) script += '.ts'; else if (index) script += '/index.ts'; } const result = await build({ bundle: true, entryPoints: [script], target: 'node20', platform: 'node', format: outfile ? 'esm' : 'cjs', packages: 'external', write: Boolean(outfile), outfile, treeShaking: true, minifyIdentifiers: true, minifySyntax: true, nodePaths: [], }); if (result.errors.length) { panic(`TS build of ${script} failed:\n${result.errors.join('\n')}`); } if (outfile) { end(); try { return await runNode(outfile, args, env); } finally { require('node:fs').unlink(outfile, Object); } } let code = result.outputFiles[0].text; // move top-level requires to callsites so they only get evaluated when surrounding code is executed const idents = {}; code = code.replace( /(?:^var (import_[a-zA-Z0-9_$]+) = ((?:__toESM\()?require\("[^"]+"\)\)?);?$|\b(import_[a-zA-Z0-9_$]+)\b)/gm, (_, ident, req, ident2) => { if (ident2) return idents[ident2] ?? ident2; idents[ident] = req; return ''; }, ); end(); // process.setSourceMapsEnabled(true); return runNode(script, args, env, code); } const BIN = { 'ts-node': (args, env) => { let script; const remainingArgs = args.filter((arg) => { if (arg[0] === '-' || script) return true; script = arg; return false; }); return runTs(script, remainingArgs, env); }, }; async function runBin(bin, args, env) { if (Object.prototype.hasOwnProperty.call(BIN, bin)) { return BIN[bin](args, env); } let resolvedBin = bin; try { const done = measure(`resolve-bin(${bin} ${args.join(' ')})`); const code = await readFile(`node_modules/.bin/${bin}`); resolvedBin = `node_modules/.bin/${bin}`; // exec node "$basedir/../vite/bin/vite.js" "$@" const match = code.match(/exec +node +"([^"]+)" +"\$@"/)?.[1]; if (!match) throw Error(`Unknown format at node_modules/.bin/${bin}`); const binFile = path.resolve( match.replace('$basedir', './node_modules/.bin'), ); const binRel = path.relative('.', binFile); done(); return runNode(binRel, args, env); } catch (err) { const done = measure(`run-bin(${bin} ${args.join(' ')})`); // console.error(`failed to run "${bin}" seamlessly:`, err); return new Promise((resolve) => { const {spawn} = require('node:child_process'); const proc = spawn(resolvedBin, args, {env: $env(env), stdio: 'inherit'}); // proc.on('error', reject); proc.once('exit', (exitCode) => { done(); resolve(exitCode); }); }); } } async function runScript(scriptName, args, env) { const script = (await pkgPromise).scripts[scriptName]; if (!script) { const bin = path.basename(scriptName); if (await exists(`node_modules/.bin/${bin}`)) { return runBin(bin, args, env); } panic(`Unknown script "${scriptName}".`); } let scriptWithArgs = script; for (const arg of args) scriptWithArgs += ` ${arg}`; const done = measure('parse'); const parsed = parseShell(scriptWithArgs); if (DEBUG.parsing) console.log('parsed: ', scriptWithArgs, parsed); done(); return run(parsed, env); } (async () => { const start = performance.now(); const cmd = path.basename(process.argv[1]); const runner = cmd === 'exec' ? runBin : runScript; const name = process.argv[2]; if (!name) panic('No script name provided.'); try { process.exitCode = await runner(name, process.argv.slice(3)); } finally { let worker; while ((worker = workerPool.workers?.pop())) worker.terminate(); if (DEBUG.timing) { console.log(bold(dim(`Done in ${(performance.now() - start) | 0}ms:`))); const dur = (ms) => (ms < 1 ? `${(ms * 1000) | 0}µs` : `${ms | 0}ms`); for (const entry of performance.getEntriesByType('measure')) { const pfx = entry.detail.depth ? ' '.repeat(entry.detail.depth) : ''; console.log(dim(`${pfx}⏱ ${dur(entry.duration)}: ${entry.name}`)); } } } })();