tiny-bin
Version:
A library for building tiny and beautiful command line apps.
62 lines (61 loc) • 2.32 kB
JavaScript
/* IMPORT */
import Addon from './addon.js';
import { castArray } from '../utils.js';
/* MAIN */
class Option extends Addon {
/* CONSTRUCTOR */
constructor(bin, options) {
super(bin);
this.data = this.parse(options.name, options.type);
this.ids = this.data.alls;
this.name = options.name;
this.description = options.description;
this.section = options.section || '';
this.deprecated = !!options.deprecated;
this.eager = !!options.eager;
this.hidden = !!options.hidden;
this.incompatible = castArray(options.incompatible || []);
this.required = !!options.required;
this.variadic = options.name.includes('...');
this.default = options.default;
this.enum = options.enum;
this.validate = options.validate;
if (this.eager && !this.data.args.length) {
this.bin.fail(`Eager option must not be boolean: "${this.name}"`);
}
if (this.eager && !this.variadic) {
this.bin.fail(`Eager option must be variadic: "${this.name}"`);
}
}
/* PRIVATE API */
parse(name, forceType) {
const longsPositive = [];
const longs = [];
const shorts = [];
const args = [];
const re = /--([a-z0-9-\.]+)|-([a-zA-Z\.])|<([^>.]+(?:\.\.\.)?)>|([\s,])|([^])/g;
name.replace(re, (_, long, short, arg, spacer, invalid) => {
if (long && long.startsWith('no-'))
longsPositive.push(long.slice(3));
if (long)
longs.push(long);
if (short)
shorts.push(short);
if (arg)
args.push(arg);
if (invalid)
this.bin.fail(`Invalid option: "${name}"`);
return _;
});
if (!longs.length && !shorts.length)
this.bin.fail(`Option must define at least a longhand or a shorthand: "${name}"`);
if (args.length > 1)
this.bin.fail(`Option can define at most one argument: "${name}"`);
const type = forceType || (args.length ? 'string' : 'boolean');
const alls = [...longsPositive, ...longs, ...shorts];
const data = { type, alls, longs, shorts, args };
return data;
}
}
/* EXPORT */
export default Option;