It appears you have a well-structured Git repository with various files, including SVG icons and HTML documents. Here's a brief overview:
This commit is contained in:
396
backend/node_modules/@pkgjs/parseargs/index.js
generated
vendored
Normal file
396
backend/node_modules/@pkgjs/parseargs/index.js
generated
vendored
Normal file
@ -0,0 +1,396 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
ArrayPrototypeForEach,
|
||||
ArrayPrototypeIncludes,
|
||||
ArrayPrototypeMap,
|
||||
ArrayPrototypePush,
|
||||
ArrayPrototypePushApply,
|
||||
ArrayPrototypeShift,
|
||||
ArrayPrototypeSlice,
|
||||
ArrayPrototypeUnshiftApply,
|
||||
ObjectEntries,
|
||||
ObjectPrototypeHasOwnProperty: ObjectHasOwn,
|
||||
StringPrototypeCharAt,
|
||||
StringPrototypeIndexOf,
|
||||
StringPrototypeSlice,
|
||||
StringPrototypeStartsWith,
|
||||
} = require('./internal/primordials');
|
||||
|
||||
const {
|
||||
validateArray,
|
||||
validateBoolean,
|
||||
validateBooleanArray,
|
||||
validateObject,
|
||||
validateString,
|
||||
validateStringArray,
|
||||
validateUnion,
|
||||
} = require('./internal/validators');
|
||||
|
||||
const {
|
||||
kEmptyObject,
|
||||
} = require('./internal/util');
|
||||
|
||||
const {
|
||||
findLongOptionForShort,
|
||||
isLoneLongOption,
|
||||
isLoneShortOption,
|
||||
isLongOptionAndValue,
|
||||
isOptionValue,
|
||||
isOptionLikeValue,
|
||||
isShortOptionAndValue,
|
||||
isShortOptionGroup,
|
||||
useDefaultValueOption,
|
||||
objectGetOwn,
|
||||
optionsGetOwn,
|
||||
} = require('./utils');
|
||||
|
||||
const {
|
||||
codes: {
|
||||
ERR_INVALID_ARG_VALUE,
|
||||
ERR_PARSE_ARGS_INVALID_OPTION_VALUE,
|
||||
ERR_PARSE_ARGS_UNKNOWN_OPTION,
|
||||
ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL,
|
||||
},
|
||||
} = require('./internal/errors');
|
||||
|
||||
function getMainArgs() {
|
||||
// Work out where to slice process.argv for user supplied arguments.
|
||||
|
||||
// Check node options for scenarios where user CLI args follow executable.
|
||||
const execArgv = process.execArgv;
|
||||
if (ArrayPrototypeIncludes(execArgv, '-e') ||
|
||||
ArrayPrototypeIncludes(execArgv, '--eval') ||
|
||||
ArrayPrototypeIncludes(execArgv, '-p') ||
|
||||
ArrayPrototypeIncludes(execArgv, '--print')) {
|
||||
return ArrayPrototypeSlice(process.argv, 1);
|
||||
}
|
||||
|
||||
// Normally first two arguments are executable and script, then CLI arguments
|
||||
return ArrayPrototypeSlice(process.argv, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* In strict mode, throw for possible usage errors like --foo --bar
|
||||
*
|
||||
* @param {object} token - from tokens as available from parseArgs
|
||||
*/
|
||||
function checkOptionLikeValue(token) {
|
||||
if (!token.inlineValue && isOptionLikeValue(token.value)) {
|
||||
// Only show short example if user used short option.
|
||||
const example = StringPrototypeStartsWith(token.rawName, '--') ?
|
||||
`'${token.rawName}=-XYZ'` :
|
||||
`'--${token.name}=-XYZ' or '${token.rawName}-XYZ'`;
|
||||
const errorMessage = `Option '${token.rawName}' argument is ambiguous.
|
||||
Did you forget to specify the option argument for '${token.rawName}'?
|
||||
To specify an option argument starting with a dash use ${example}.`;
|
||||
throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In strict mode, throw for usage errors.
|
||||
*
|
||||
* @param {object} config - from config passed to parseArgs
|
||||
* @param {object} token - from tokens as available from parseArgs
|
||||
*/
|
||||
function checkOptionUsage(config, token) {
|
||||
if (!ObjectHasOwn(config.options, token.name)) {
|
||||
throw new ERR_PARSE_ARGS_UNKNOWN_OPTION(
|
||||
token.rawName, config.allowPositionals);
|
||||
}
|
||||
|
||||
const short = optionsGetOwn(config.options, token.name, 'short');
|
||||
const shortAndLong = `${short ? `-${short}, ` : ''}--${token.name}`;
|
||||
const type = optionsGetOwn(config.options, token.name, 'type');
|
||||
if (type === 'string' && typeof token.value !== 'string') {
|
||||
throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(`Option '${shortAndLong} <value>' argument missing`);
|
||||
}
|
||||
// (Idiomatic test for undefined||null, expecting undefined.)
|
||||
if (type === 'boolean' && token.value != null) {
|
||||
throw new ERR_PARSE_ARGS_INVALID_OPTION_VALUE(`Option '${shortAndLong}' does not take an argument`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store the option value in `values`.
|
||||
*
|
||||
* @param {string} longOption - long option name e.g. 'foo'
|
||||
* @param {string|undefined} optionValue - value from user args
|
||||
* @param {object} options - option configs, from parseArgs({ options })
|
||||
* @param {object} values - option values returned in `values` by parseArgs
|
||||
*/
|
||||
function storeOption(longOption, optionValue, options, values) {
|
||||
if (longOption === '__proto__') {
|
||||
return; // No. Just no.
|
||||
}
|
||||
|
||||
// We store based on the option value rather than option type,
|
||||
// preserving the users intent for author to deal with.
|
||||
const newValue = optionValue ?? true;
|
||||
if (optionsGetOwn(options, longOption, 'multiple')) {
|
||||
// Always store value in array, including for boolean.
|
||||
// values[longOption] starts out not present,
|
||||
// first value is added as new array [newValue],
|
||||
// subsequent values are pushed to existing array.
|
||||
// (note: values has null prototype, so simpler usage)
|
||||
if (values[longOption]) {
|
||||
ArrayPrototypePush(values[longOption], newValue);
|
||||
} else {
|
||||
values[longOption] = [newValue];
|
||||
}
|
||||
} else {
|
||||
values[longOption] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the default option value in `values`.
|
||||
*
|
||||
* @param {string} longOption - long option name e.g. 'foo'
|
||||
* @param {string
|
||||
* | boolean
|
||||
* | string[]
|
||||
* | boolean[]} optionValue - default value from option config
|
||||
* @param {object} values - option values returned in `values` by parseArgs
|
||||
*/
|
||||
function storeDefaultOption(longOption, optionValue, values) {
|
||||
if (longOption === '__proto__') {
|
||||
return; // No. Just no.
|
||||
}
|
||||
|
||||
values[longOption] = optionValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process args and turn into identified tokens:
|
||||
* - option (along with value, if any)
|
||||
* - positional
|
||||
* - option-terminator
|
||||
*
|
||||
* @param {string[]} args - from parseArgs({ args }) or mainArgs
|
||||
* @param {object} options - option configs, from parseArgs({ options })
|
||||
*/
|
||||
function argsToTokens(args, options) {
|
||||
const tokens = [];
|
||||
let index = -1;
|
||||
let groupCount = 0;
|
||||
|
||||
const remainingArgs = ArrayPrototypeSlice(args);
|
||||
while (remainingArgs.length > 0) {
|
||||
const arg = ArrayPrototypeShift(remainingArgs);
|
||||
const nextArg = remainingArgs[0];
|
||||
if (groupCount > 0)
|
||||
groupCount--;
|
||||
else
|
||||
index++;
|
||||
|
||||
// Check if `arg` is an options terminator.
|
||||
// Guideline 10 in https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html
|
||||
if (arg === '--') {
|
||||
// Everything after a bare '--' is considered a positional argument.
|
||||
ArrayPrototypePush(tokens, { kind: 'option-terminator', index });
|
||||
ArrayPrototypePushApply(
|
||||
tokens, ArrayPrototypeMap(remainingArgs, (arg) => {
|
||||
return { kind: 'positional', index: ++index, value: arg };
|
||||
})
|
||||
);
|
||||
break; // Finished processing args, leave while loop.
|
||||
}
|
||||
|
||||
if (isLoneShortOption(arg)) {
|
||||
// e.g. '-f'
|
||||
const shortOption = StringPrototypeCharAt(arg, 1);
|
||||
const longOption = findLongOptionForShort(shortOption, options);
|
||||
let value;
|
||||
let inlineValue;
|
||||
if (optionsGetOwn(options, longOption, 'type') === 'string' &&
|
||||
isOptionValue(nextArg)) {
|
||||
// e.g. '-f', 'bar'
|
||||
value = ArrayPrototypeShift(remainingArgs);
|
||||
inlineValue = false;
|
||||
}
|
||||
ArrayPrototypePush(
|
||||
tokens,
|
||||
{ kind: 'option', name: longOption, rawName: arg,
|
||||
index, value, inlineValue });
|
||||
if (value != null) ++index;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isShortOptionGroup(arg, options)) {
|
||||
// Expand -fXzy to -f -X -z -y
|
||||
const expanded = [];
|
||||
for (let index = 1; index < arg.length; index++) {
|
||||
const shortOption = StringPrototypeCharAt(arg, index);
|
||||
const longOption = findLongOptionForShort(shortOption, options);
|
||||
if (optionsGetOwn(options, longOption, 'type') !== 'string' ||
|
||||
index === arg.length - 1) {
|
||||
// Boolean option, or last short in group. Well formed.
|
||||
ArrayPrototypePush(expanded, `-${shortOption}`);
|
||||
} else {
|
||||
// String option in middle. Yuck.
|
||||
// Expand -abfFILE to -a -b -fFILE
|
||||
ArrayPrototypePush(expanded, `-${StringPrototypeSlice(arg, index)}`);
|
||||
break; // finished short group
|
||||
}
|
||||
}
|
||||
ArrayPrototypeUnshiftApply(remainingArgs, expanded);
|
||||
groupCount = expanded.length;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isShortOptionAndValue(arg, options)) {
|
||||
// e.g. -fFILE
|
||||
const shortOption = StringPrototypeCharAt(arg, 1);
|
||||
const longOption = findLongOptionForShort(shortOption, options);
|
||||
const value = StringPrototypeSlice(arg, 2);
|
||||
ArrayPrototypePush(
|
||||
tokens,
|
||||
{ kind: 'option', name: longOption, rawName: `-${shortOption}`,
|
||||
index, value, inlineValue: true });
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isLoneLongOption(arg)) {
|
||||
// e.g. '--foo'
|
||||
const longOption = StringPrototypeSlice(arg, 2);
|
||||
let value;
|
||||
let inlineValue;
|
||||
if (optionsGetOwn(options, longOption, 'type') === 'string' &&
|
||||
isOptionValue(nextArg)) {
|
||||
// e.g. '--foo', 'bar'
|
||||
value = ArrayPrototypeShift(remainingArgs);
|
||||
inlineValue = false;
|
||||
}
|
||||
ArrayPrototypePush(
|
||||
tokens,
|
||||
{ kind: 'option', name: longOption, rawName: arg,
|
||||
index, value, inlineValue });
|
||||
if (value != null) ++index;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isLongOptionAndValue(arg)) {
|
||||
// e.g. --foo=bar
|
||||
const equalIndex = StringPrototypeIndexOf(arg, '=');
|
||||
const longOption = StringPrototypeSlice(arg, 2, equalIndex);
|
||||
const value = StringPrototypeSlice(arg, equalIndex + 1);
|
||||
ArrayPrototypePush(
|
||||
tokens,
|
||||
{ kind: 'option', name: longOption, rawName: `--${longOption}`,
|
||||
index, value, inlineValue: true });
|
||||
continue;
|
||||
}
|
||||
|
||||
ArrayPrototypePush(tokens, { kind: 'positional', index, value: arg });
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
const parseArgs = (config = kEmptyObject) => {
|
||||
const args = objectGetOwn(config, 'args') ?? getMainArgs();
|
||||
const strict = objectGetOwn(config, 'strict') ?? true;
|
||||
const allowPositionals = objectGetOwn(config, 'allowPositionals') ?? !strict;
|
||||
const returnTokens = objectGetOwn(config, 'tokens') ?? false;
|
||||
const options = objectGetOwn(config, 'options') ?? { __proto__: null };
|
||||
// Bundle these up for passing to strict-mode checks.
|
||||
const parseConfig = { args, strict, options, allowPositionals };
|
||||
|
||||
// Validate input configuration.
|
||||
validateArray(args, 'args');
|
||||
validateBoolean(strict, 'strict');
|
||||
validateBoolean(allowPositionals, 'allowPositionals');
|
||||
validateBoolean(returnTokens, 'tokens');
|
||||
validateObject(options, 'options');
|
||||
ArrayPrototypeForEach(
|
||||
ObjectEntries(options),
|
||||
({ 0: longOption, 1: optionConfig }) => {
|
||||
validateObject(optionConfig, `options.${longOption}`);
|
||||
|
||||
// type is required
|
||||
const optionType = objectGetOwn(optionConfig, 'type');
|
||||
validateUnion(optionType, `options.${longOption}.type`, ['string', 'boolean']);
|
||||
|
||||
if (ObjectHasOwn(optionConfig, 'short')) {
|
||||
const shortOption = optionConfig.short;
|
||||
validateString(shortOption, `options.${longOption}.short`);
|
||||
if (shortOption.length !== 1) {
|
||||
throw new ERR_INVALID_ARG_VALUE(
|
||||
`options.${longOption}.short`,
|
||||
shortOption,
|
||||
'must be a single character'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const multipleOption = objectGetOwn(optionConfig, 'multiple');
|
||||
if (ObjectHasOwn(optionConfig, 'multiple')) {
|
||||
validateBoolean(multipleOption, `options.${longOption}.multiple`);
|
||||
}
|
||||
|
||||
const defaultValue = objectGetOwn(optionConfig, 'default');
|
||||
if (defaultValue !== undefined) {
|
||||
let validator;
|
||||
switch (optionType) {
|
||||
case 'string':
|
||||
validator = multipleOption ? validateStringArray : validateString;
|
||||
break;
|
||||
|
||||
case 'boolean':
|
||||
validator = multipleOption ? validateBooleanArray : validateBoolean;
|
||||
break;
|
||||
}
|
||||
validator(defaultValue, `options.${longOption}.default`);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Phase 1: identify tokens
|
||||
const tokens = argsToTokens(args, options);
|
||||
|
||||
// Phase 2: process tokens into parsed option values and positionals
|
||||
const result = {
|
||||
values: { __proto__: null },
|
||||
positionals: [],
|
||||
};
|
||||
if (returnTokens) {
|
||||
result.tokens = tokens;
|
||||
}
|
||||
ArrayPrototypeForEach(tokens, (token) => {
|
||||
if (token.kind === 'option') {
|
||||
if (strict) {
|
||||
checkOptionUsage(parseConfig, token);
|
||||
checkOptionLikeValue(token);
|
||||
}
|
||||
storeOption(token.name, token.value, options, result.values);
|
||||
} else if (token.kind === 'positional') {
|
||||
if (!allowPositionals) {
|
||||
throw new ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL(token.value);
|
||||
}
|
||||
ArrayPrototypePush(result.positionals, token.value);
|
||||
}
|
||||
});
|
||||
|
||||
// Phase 3: fill in default values for missing args
|
||||
ArrayPrototypeForEach(ObjectEntries(options), ({ 0: longOption,
|
||||
1: optionConfig }) => {
|
||||
const mustSetDefault = useDefaultValueOption(longOption,
|
||||
optionConfig,
|
||||
result.values);
|
||||
if (mustSetDefault) {
|
||||
storeDefaultOption(longOption,
|
||||
objectGetOwn(optionConfig, 'default'),
|
||||
result.values);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
parseArgs,
|
||||
};
|
Reference in New Issue
Block a user