tiny-bin
Version:
A library for building tiny and beautiful command line apps.
82 lines (81 loc) • 3.04 kB
JavaScript
/* IMPORT */
import getCurrentPackage from 'get-current-package';
import process from 'node:process';
import colors from 'tiny-colors';
import parseArgv from 'tiny-parse-argv';
import updater from 'tiny-updater';
import Logger from './logger.js';
import Metadata from './metadata.js';
import Commands from './commands.js';
import CommandDefault from './command_default.js';
import CommandHelp from './command_help.js';
import CommandVersion from './command_version.js';
import Option from './option.js';
import { defer } from '../utils.js';
/* MAIN */
class Bin {
/* CONSTRUCTOR */
constructor(options) {
/* VARIABLES */
this.stdout = new Logger(this, console.log);
this.stderr = new Logger(this, console.error);
this.metadata = new Metadata(this);
this.commands = new Commands(this);
this.metadata.name = options.name;
this.metadata.description = options.description;
const fallback = new CommandDefault(this);
const help = new CommandHelp(this);
const version = new CommandVersion(this);
this.commands.register(fallback);
this.commands.register(help);
this.commands.register(version);
this.command = fallback;
this.command.options.register(new Option(this, { name: '--help', description: 'Display help for the command' }));
this.command.options.register(new Option(this, { name: '--version, -v', description: 'Display the version number' }));
this.command.options.register(new Option(this, { name: '--no-color, --no-colors', description: 'Disable colored output', hidden: true }));
}
/* API */
fail(message) {
this.stderr.print();
this.stderr.indent();
this.stderr.print(colors.red(message));
this.stderr.dedent();
this.stderr.print();
process.exit(1);
}
async run(argv = process.argv.slice(2)) {
// process.title = this.metadata.name; //FIXME: It seems useless inside VSCODE, and not working as expected inside Terminal.app, so...
if (!this.metadata.package) {
const pkg = getCurrentPackage();
if (pkg) {
const { name, version } = pkg;
this.metadata.package = name;
this.metadata.version = version;
}
}
if (this.metadata.package && this.metadata.updater) {
defer(() => {
updater({
name: this.metadata.package,
version: this.metadata.version,
ttl: 43200000
});
});
}
try {
const options = parseArgv(argv);
await this.commands.run(this.command.name, options, argv);
if (this.metadata.exiter) {
process.exit();
}
}
catch (error) {
console.error(error);
if (this.metadata.exiter) {
process.exit(1);
}
}
}
}
/* EXPORT */
export default Bin;