UNPKG

tinyargs

Version:

A tiny and flexible command-line argument parser for Node.js and Deno.

117 lines (116 loc) 3.3 kB
// src/index.ts var pushOrSet = (obj, key, value) => { if (Array.isArray(obj[key])) { obj[key].push(value); } else { obj[key] = value; } }; var parseFlag = (parsed, args, currentIndex, opt, flag) => { if (opt.type === Boolean) { pushOrSet(parsed, opt.name, true); } else { const nextValue = args[++currentIndex]; if (nextValue === void 0) { if (opt.optionalValue) { pushOrSet(parsed, opt.name, true); } else { throw new Error(`missing value for ${flag}`); } } else { pushOrSet(parsed, opt.name, opt.type(nextValue)); } } return currentIndex; }; var parsePositional = (parsed, args, currentIndex, opt) => { if (!opt.multiple) { parsed[opt.name] = opt.type(args[currentIndex]); return currentIndex; } const values = [opt.type(args[currentIndex])]; for (let i = currentIndex + 1; i < args.length; i++) { const value = args[i]; if (value && value[0] === "-" && opt.multiple !== "include-flags") { break; } else if (value) { currentIndex += 1; values.push(opt.type(value)); } } parsed[opt.name] = values; return currentIndex; }; var splitShortFlags = (arg) => { if (/^-[a-zA-Z]/.test(arg)) { return arg.slice(1).split("").map((flag) => `-${flag}`); } return [arg]; }; var parse = (args, options) => { const parsed = { _: [] }; let stopped = false; const skippedPositionalArgs = /* @__PURE__ */ new Set(); args = args.reduce((res, arg) => { if (arg[0] === "-") { let equalSignIndex = arg.indexOf("="); if (equalSignIndex > 0) { res.push(...splitShortFlags(arg.slice(0, equalSignIndex)), arg.slice(equalSignIndex + 1)); } else { res.push(...splitShortFlags(arg)); } } else { res.push(arg); } return res; }, []); for (let i = 0; i < args.length; i++) { const flag = args[i]; const flagName = flag.replace(/^-{1,2}/, ""); if (stopped) { parsed._.push(flag); continue; } if (flag.startsWith("-")) { const opt = options.find((o) => { var _a; return !o.positional && (o.name === flagName || ((_a = o.flags) == null ? void 0 : _a.includes(flagName))) && (!o.when || o.when(parsed)); }); if (opt) { if (opt.multiple) { parsed[opt.name] = parsed[opt.name] || []; } i = parseFlag(parsed, args, i, opt, flag); if (opt.stop) { stopped = true; } } else { throw new Error(`unknown flag: ${flag}`); } } else { const opt = options.find((o) => { return o.positional && parsed[o.name] === void 0 && (!o.when || o.when(parsed) || !skippedPositionalArgs.add(o.name)); }); if (opt) { i = parsePositional(parsed, args, i, opt); if (opt.stop) { stopped = true; } } else { throw new Error(`unknown positional argument: ${flag}`); } } } for (const opt of options) { if (opt.positional && !opt.optionalValue && parsed[opt.name] === void 0 && !skippedPositionalArgs.has(opt.name)) { if (opt.when && !opt.when(parsed)) { continue; } throw new Error(`missing positional argument: ${opt.name}`); } } return parsed; }; export { parse };