CoolFace
Apppublic

Umama-at-Bluchip/Quick-UI

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
index.js196 linesDownload Raw Back to arg
1const flagSymbol = Symbol('arg flag');2 3class ArgError extends Error {4	constructor(msg, code) {5		super(msg);6		this.name = 'ArgError';7		this.code = code;8 9		Object.setPrototypeOf(this, ArgError.prototype);10	}11}12 13function arg(14	opts,15	{16		argv = process.argv.slice(2),17		permissive = false,18		stopAtPositional = false19	} = {}20) {21	if (!opts) {22		throw new ArgError(23			'argument specification object is required',24			'ARG_CONFIG_NO_SPEC'25		);26	}27 28	const result = { _: [] };29 30	const aliases = {};31	const handlers = {};32 33	for (const key of Object.keys(opts)) {34		if (!key) {35			throw new ArgError(36				'argument key cannot be an empty string',37				'ARG_CONFIG_EMPTY_KEY'38			);39		}40 41		if (key[0] !== '-') {42			throw new ArgError(43				`argument key must start with '-' but found: '${key}'`,44				'ARG_CONFIG_NONOPT_KEY'45			);46		}47 48		if (key.length === 1) {49			throw new ArgError(50				`argument key must have a name; singular '-' keys are not allowed: ${key}`,51				'ARG_CONFIG_NONAME_KEY'52			);53		}54 55		if (typeof opts[key] === 'string') {56			aliases[key] = opts[key];57			continue;58		}59 60		let type = opts[key];61		let isFlag = false;62 63		if (64			Array.isArray(type) &&65			type.length === 1 &&66			typeof type[0] === 'function'67		) {68			const [fn] = type;69			type = (value, name, prev = []) => {70				prev.push(fn(value, name, prev[prev.length - 1]));71				return prev;72			};73			isFlag = fn === Boolean || fn[flagSymbol] === true;74		} else if (typeof type === 'function') {75			isFlag = type === Boolean || type[flagSymbol] === true;76		} else {77			throw new ArgError(78				`type missing or not a function or valid array type: ${key}`,79				'ARG_CONFIG_VAD_TYPE'80			);81		}82 83		if (key[1] !== '-' && key.length > 2) {84			throw new ArgError(85				`short argument keys (with a single hyphen) must have only one character: ${key}`,86				'ARG_CONFIG_SHORTOPT_TOOLONG'87			);88		}89 90		handlers[key] = [type, isFlag];91	}92 93	for (let i = 0, len = argv.length; i < len; i++) {94		const wholeArg = argv[i];95 96		if (stopAtPositional && result._.length > 0) {97			result._ = result._.concat(argv.slice(i));98			break;99		}100 101		if (wholeArg === '--') {102			result._ = result._.concat(argv.slice(i + 1));103			break;104		}105 106		if (wholeArg.length > 1 && wholeArg[0] === '-') {107			/* eslint-disable operator-linebreak */108			const separatedArguments =109				wholeArg[1] === '-' || wholeArg.length === 2110					? [wholeArg]111					: wholeArg112							.slice(1)113							.split('')114							.map((a) => `-${a}`);115			/* eslint-enable operator-linebreak */116 117			for (let j = 0; j < separatedArguments.length; j++) {118				const arg = separatedArguments[j];119				const [originalArgName, argStr] =120					arg[1] === '-' ? arg.split(/=(.*)/, 2) : [arg, undefined];121 122				let argName = originalArgName;123				while (argName in aliases) {124					argName = aliases[argName];125				}126 127				if (!(argName in handlers)) {128					if (permissive) {129						result._.push(arg);130						continue;131					} else {132						throw new ArgError(133							`unknown or unexpected option: ${originalArgName}`,134							'ARG_UNKNOWN_OPTION'135						);136					}137				}138 139				const [type, isFlag] = handlers[argName];140 141				if (!isFlag && j + 1 < separatedArguments.length) {142					throw new ArgError(143						`option requires argument (but was followed by another short argument): ${originalArgName}`,144						'ARG_MISSING_REQUIRED_SHORTARG'145					);146				}147 148				if (isFlag) {149					result[argName] = type(true, argName, result[argName]);150				} else if (argStr === undefined) {151					if (152						argv.length < i + 2 ||153						(argv[i + 1].length > 1 &&154							argv[i + 1][0] === '-' &&155							!(156								argv[i + 1].match(/^-?\d*(\.(?=\d))?\d*$/) &&157								(type === Number ||158									// eslint-disable-next-line no-undef159									(typeof BigInt !== 'undefined' && type === BigInt))160							))161					) {162						const extended =163							originalArgName === argName ? '' : ` (alias for ${argName})`;164						throw new ArgError(165							`option requires argument: ${originalArgName}${extended}`,166							'ARG_MISSING_REQUIRED_LONGARG'167						);168					}169 170					result[argName] = type(argv[i + 1], argName, result[argName]);171					++i;172				} else {173					result[argName] = type(argStr, argName, result[argName]);174				}175			}176		} else {177			result._.push(wholeArg);178		}179	}180 181	return result;182}183 184arg.flag = (fn) => {185	fn[flagSymbol] = true;186	return fn;187};188 189// Utility types190arg.COUNT = arg.flag((v, name, existingCount) => (existingCount || 0) + 1);191 192// Expose error class193arg.ArgError = ArgError;194 195module.exports = arg;196