All files / bin avenx.js

84.72% Statements 61/72
66.66% Branches 8/12
100% Functions 2/2
84.72% Lines 61/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x 247x   247x   247x 247x 247x               247x 247x 247x 247x 247x 247x 26x 26x 26x 26x 247x 247x 247x 247x 247x   247x 247x 247x   247x 247x 247x 3x 3x 247x 244x 244x 51x 51x 244x 244x 244x 244x 244x 26x 244x 244x  
#!/usr/bin/env node
 
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { AvenxCLI } from './cli.js';
import { red } from './colors.js';
import { reportFatal } from './fatal.js';
 
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'), 'utf8'));
 
const [, , command, ...args] = process.argv;
 
const MIN_NODE_VERSION = [18, 0, 0];
const current = process.versions.node.split('.').map(Number);
 
function compareVersions(current, required) {
  for (let i = 0; i < required.length; i++) {
    if (current[i] > required[i]) return true;
    if (current[i] < required[i]) return false;
  }
  return true;
}
 
if (!compareVersions(current, MIN_NODE_VERSION)) {
  console.error(
    red(
      `Avenx requires Node.js ${MIN_NODE_VERSION.join('.')} or later.\n` + `Current version: ${process.versions.node}`,
    ),
  );
  process.exit(1);
}
 
/**
 * Human-readable label for the command being run, used in failure headlines.
 * @param {string} name - The command name.
 * @returns {string} The label.
 */
function actionLabel(name) {
  const labels = { build: 'Build', b: 'Build', watch: 'Build', w: 'Build', serve: 'Dev server' };
  return labels[name] || `avenx ${name || ''}`.trim();
}
 
// Nothing may fail silently. An error thrown from a callback or a promise that
// nobody awaited would otherwise print a bare trace, or in some Node versions
// not fail the process at all — which is the whole class of bug this guards.
process.on('unhandledRejection', (reason) => {
  reportFatal(reason, actionLabel(command));
});
 
process.on('uncaughtException', (error) => {
  reportFatal(error, actionLabel(command));
});
 
if (command === '-v' || command === '--version') {
  console.log('Avenx-JS v' + packageJson.version);
  process.exit(0);
} else {
  const options = {};
  if (command === 'init') {
    options.baseDir = process.cwd();
  }
  const cli = new AvenxCLI(options);
 
  // run() is async. Awaiting it is what lets a compiler failure reach the exit
  // code instead of resolving into nothing after the process has moved on.
  cli.run(command, args).catch((error) => {
    reportFatal(error, actionLabel(command));
  });
}