UNPKG

argvex

Version:

Lightweight and unopinionated CLI argument parser — just a parsing tool, not a framework

115 lines (114 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ArgvexError = void 0; class ArgvexError extends Error { constructor(argument) { super(`Argument "${argument}" is unrecognized or misplaced.`); } } exports.ArgvexError = ArgvexError; const longflag = (name, value, definition) => { const values = []; let arity = definition?.arity ?? Infinity; if (value != null) { values.push(value); arity = 1; } return { definition: { name, ...definition, arity }, values }; }; const shortflag = (alias, aliases, definition) => { const values = []; let arity = definition?.arity ?? Infinity; if (aliases.indexOf(alias) != aliases.length - 1) { arity = 0; } return { definition: { name: alias, ...definition, arity }, values }; }; const inlineflag = (index, aliases, definition) => { if (definition == null) { return null; } if (definition.arity == 0) { return null; } if (aliases[index + 1] == null) { return null; } return { definition, values: [aliases.substring(index + 1)] }; }; const argvex = (options) => { const { command, argv = command?.split(" ").filter(arg => !!arg) ?? process.argv.slice(2), schema = [], strict = false, additive = false } = options; const definitions = new Map(); for (const { name, alias, arity = Infinity } of schema) { const definition = { name, alias, arity }; definitions.set(name, definition); if (alias != null) { definitions.set(alias, definition); } } let current = null; const _ = []; const flags = {}; for (let i = 0; i < argv.length; i++) { const arg = argv[i]; if (arg == "--") { _.push(...argv.slice(i + 1)); break; } if (arg.startsWith('--')) { const [name, value] = arg.substring(2).split("="); if (name.length == 0) { throw new ArgvexError(arg); } if (strict && !definitions.has(name)) { throw new ArgvexError(arg); } const { definition, values } = longflag(name, value, definitions.get(name)); definitions.set(name, definition); if (additive && flags[name] != null) { values.unshift(...flags[name]); } current = { definition, values }; flags[name] = values; continue; } if (arg.startsWith('-')) { const aliases = arg.substring(1); if (aliases.length == 0) { throw new ArgvexError(arg); } for (let j = 0; j < aliases.length; j++) { const alias = aliases[j]; if (strict && !definitions.has(alias)) { throw new ArgvexError(`-${alias}`); } const inliner = inlineflag(j, aliases, definitions.get(alias)); if (inliner != null) { const { definition, values } = inliner; definitions.set(alias, definition); if (additive && flags[definition.name] != null) { values.unshift(...flags[definition.name]); } current = { definition, values }; flags[definition.name] = values; break; } const { definition, values } = shortflag(alias, aliases, definitions.get(alias)); definitions.set(alias, definition); if (additive && flags[definition.name] != null) { values.unshift(...flags[definition.name]); } current = { definition, values }; flags[definition.name] = values; } continue; } if (current == null || current.values.length >= current.definition.arity) { _.push(arg); continue; } current?.values.push(arg); } return { _, ...flags }; }; exports.default = argvex;