Added opts.handleBackslashesForSpecialFlagChars and fixed/clarified the code for backslashes & clarified opts.lowerCaseInputValues & opts.lowerCaseFlagValues descriptions
This commit is contained in:
parent
49d74d9de5
commit
815bb52510
69
index.js
69
index.js
@ -120,6 +120,7 @@ function validateAndFillDefaults(opts) {
|
|||||||
validateOrDefaultIfUnset(opts, 'lowerCaseFlags', 'boolean', true);
|
validateOrDefaultIfUnset(opts, 'lowerCaseFlags', 'boolean', true);
|
||||||
validateOrDefaultIfUnset(opts, 'resolveFlagValueTypes', 'boolean', true);
|
validateOrDefaultIfUnset(opts, 'resolveFlagValueTypes', 'boolean', true);
|
||||||
validateOrDefaultIfUnset(opts, 'allowNullDefaultFlagValues', 'boolean', true);
|
validateOrDefaultIfUnset(opts, 'allowNullDefaultFlagValues', 'boolean', true);
|
||||||
|
validateOrDefaultIfUnset(opts, 'handleBackslashesForSpecialFlagChars', 'boolean', true);
|
||||||
|
|
||||||
|
|
||||||
validateOrDefaultIfUnset(opts, 'automaticBooleanFlagNegation', 'object', {});
|
validateOrDefaultIfUnset(opts, 'automaticBooleanFlagNegation', 'object', {});
|
||||||
@ -525,8 +526,9 @@ function runFlagValueTypeResolving(opts, flagVal, flagConfig) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} arg
|
* @param {string} arg
|
||||||
|
* @param {DefaultParserOptsType} opts
|
||||||
*/
|
*/
|
||||||
function argMetaCreator(arg) {
|
function argMetaCreator(arg, opts) {
|
||||||
const argsStr = new StringConsumer(arg);
|
const argsStr = new StringConsumer(arg);
|
||||||
|
|
||||||
/** return meta flags */
|
/** return meta flags */
|
||||||
@ -560,11 +562,24 @@ function argMetaCreator(arg) {
|
|||||||
readingMinusSignCount = false;
|
readingMinusSignCount = false;
|
||||||
|
|
||||||
/** Flag has an assigned value in the arg*/
|
/** Flag has an assigned value in the arg*/
|
||||||
if(char === "=" && isFlag && !isBackslashed && !hasPotentialFlagAssignedValue) {
|
if(char === "=" && isFlag) {
|
||||||
|
if(!isBackslashed) {
|
||||||
|
if(!hasPotentialFlagAssignedValue) {
|
||||||
hasPotentialFlagAssignedValue = true;
|
hasPotentialFlagAssignedValue = true;
|
||||||
unescapedEqualSignPos = argsStr.getPointer()-1;
|
unescapedEqualSignPos = argsStr.getPointer()-1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(hasFlagAssignedValue) {
|
||||||
|
/** Consume the backslash */
|
||||||
|
flagAssignedValue = flagAssignedValue.slice(0, -1)
|
||||||
|
} else {
|
||||||
|
/** Consume the backslash */
|
||||||
|
flagKey = flagKey.slice(0, -1)
|
||||||
|
}
|
||||||
|
isBackslashed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Making sure there is indeed something after the initial - */
|
/** Making sure there is indeed something after the initial - */
|
||||||
if(isPotentialFlag && !isFlag) {
|
if(isPotentialFlag && !isFlag) {
|
||||||
@ -589,16 +604,27 @@ function argMetaCreator(arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Idk how to feel about the partial backslashes handling here, most other flag parsers don't handle it but it seems mostly logical to me
|
// Weird and gross handling of backslashes, but explicit, 'defined' (in ./types.d.ts -> ParserOpts.handleBackslashesForSpecialFlagChars) and toggleable
|
||||||
if(char === '\\' && !isBackslashed)
|
if(char === '\\') {
|
||||||
|
if(opts.handleBackslashesForSpecialFlagChars) {
|
||||||
|
if(!isBackslashed) {
|
||||||
|
if(isFlag && argsStr.hasNext() && argsStr.peek() === '-') {
|
||||||
|
/** Consume the backslash */
|
||||||
|
flagKey = flagKey.slice(0, -1)
|
||||||
|
}
|
||||||
|
else
|
||||||
isBackslashed = true;
|
isBackslashed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(isBackslashed)
|
else if(isBackslashed)
|
||||||
isBackslashed = false;
|
isBackslashed = false;
|
||||||
}
|
}
|
||||||
return { isFlag, minusSignCount, flagKey, hasFlagAssignedValue, flagAssignedValue, unescapedEqualSignPos };
|
return { isFlag, minusSignCount, flagKey, hasFlagAssignedValue, flagAssignedValue, unescapedEqualSignPos };
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Integrate this function in the main argMetaCreator function, redundant while loop;
|
// // * Impossibel to easily integrate due to backslash lookahead handling for the flag key
|
||||||
|
// // ^ ~~TODO~~: ~Integrate this function in the main argMetaCreator function, redundant while loop;~~
|
||||||
/**
|
/**
|
||||||
* @param {string[]} shorthandFlags
|
* @param {string[]} shorthandFlags
|
||||||
* @param {string} shorthandString
|
* @param {string} shorthandString
|
||||||
@ -683,7 +709,7 @@ function parser(argv, opts) {
|
|||||||
|
|
||||||
let lookingForFlagVal = false;
|
let lookingForFlagVal = false;
|
||||||
argv.forEach((arg) => {
|
argv.forEach((arg) => {
|
||||||
const meta = argMetaCreator(arg);
|
const meta = argMetaCreator(arg, opts);
|
||||||
if(meta.isFlag) {
|
if(meta.isFlag) {
|
||||||
/** If allow singular dashlong flags, just fall through to the full flag handling */
|
/** If allow singular dashlong flags, just fall through to the full flag handling */
|
||||||
/** Redundant hasFullFlag given later might getFullFlag but yk easier implementation like this */
|
/** Redundant hasFullFlag given later might getFullFlag but yk easier implementation like this */
|
||||||
@ -729,7 +755,20 @@ function parser(argv, opts) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (lookingForFlagVal) {
|
else {
|
||||||
|
let inputVal = arg;
|
||||||
|
|
||||||
|
// Hardcoded edge case, not a fan, but if it has more than one backslash, it was never gonna be a flag anyways
|
||||||
|
if(opts.handleBackslashesForSpecialFlagChars && inputVal.startsWith('\\-'))
|
||||||
|
inputVal = inputVal.slice(1);
|
||||||
|
|
||||||
|
if(!lookingForFlagVal) {
|
||||||
|
if(opts.lowerCaseInputValues)
|
||||||
|
inputVal = inputVal.toLowerCase();
|
||||||
|
input.push(inputVal);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const flag = flags.at(-1);
|
const flag = flags.at(-1);
|
||||||
/** @readonly */
|
/** @readonly */
|
||||||
let flagConfig = flag.flagConfig
|
let flagConfig = flag.flagConfig
|
||||||
@ -747,26 +786,18 @@ function parser(argv, opts) {
|
|||||||
if(flagConfig !== undefined && flagConfig.type !== undefined)
|
if(flagConfig !== undefined && flagConfig.type !== undefined)
|
||||||
flagType = flagConfig.type;
|
flagType = flagConfig.type;
|
||||||
|
|
||||||
const castableType = getCastableType(arg);
|
const castableType = getCastableType(inputVal);
|
||||||
|
|
||||||
if(['string', 'any', castableType].includes(flagType) || (castableType === 'number' && flagType === 'bigint'))
|
if(['string', 'any', castableType].includes(flagType) || (castableType === 'number' && flagType === 'bigint'))
|
||||||
flag.value = arg;
|
flag.value = inputVal;
|
||||||
else {
|
else {
|
||||||
if(opts.lowerCaseInputValues)
|
if(opts.lowerCaseInputValues)
|
||||||
input.push(arg.toLowerCase());
|
inputVal = inputVal.toLowerCase();
|
||||||
else
|
input.push(inputVal);
|
||||||
input.push(arg);
|
|
||||||
}
|
}
|
||||||
lookingForFlagVal = false;
|
lookingForFlagVal = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if(opts.lowerCaseInputValues)
|
|
||||||
input.push(arg.toLowerCase());
|
|
||||||
else
|
|
||||||
input.push(arg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const flagReturnObj = {};
|
const flagReturnObj = {};
|
||||||
|
|||||||
23
types.d.ts
vendored
23
types.d.ts
vendored
@ -59,10 +59,29 @@ export interface ParserOpts<Flags extends FlagsI> {
|
|||||||
behaviorOnInputError?: 'throw' | 'log' | 'log&exit' | 'ignore';
|
behaviorOnInputError?: 'throw' | 'log' | 'log&exit' | 'ignore';
|
||||||
/** Wether to allow default flag values set to null being valid @default true */
|
/** Wether to allow default flag values set to null being valid @default true */
|
||||||
allowNullDefaultFlagValues?: boolean;
|
allowNullDefaultFlagValues?: boolean;
|
||||||
/** If enabled, makes all input values lowercase @default false */
|
/**
|
||||||
|
* If enabled, makes all input values lowercase after flag processing. It does not apply to 'values' that get naturally assigned to flags
|
||||||
|
* (eg: `['--flag', 'VALUE']` -> `{ 'flag': 'VALUE' }`)
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
lowerCaseInputValues?: boolean
|
lowerCaseInputValues?: boolean
|
||||||
/** If enabled, makes all string flag values lowercase after flag processing @default false */
|
/**
|
||||||
|
* If enabled, makes all string flag values lowercase. It applies to any string flag values, either naturally assigned (eg: `['--flag', 'VALUE']` -> `{ flags: { 'flag': 'value' } }`)
|
||||||
|
* or directly assigned (eg: `['--flag=VALUE']` -> `{ flags: { 'flag': 'value' } }`)
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
lowerCaseFlagValues?: boolean
|
lowerCaseFlagValues?: boolean
|
||||||
|
/**
|
||||||
|
* If disabled, does not acknowledge or consume backslashes, making flag assignments (=) and designated flag characters (--) inescapable within flags
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* #### It needs to be noted that backslashes are only ever handled/consumed in flags AND if they impact special flag characters (ie: minus signs (-) and equal signs (=));
|
||||||
|
* The only exception is a backslash escaping a flag character (-) at the very beginning of a value (ie: '\--not_a_flag'), which will be consumed with this option
|
||||||
|
* enabled but not counted as a flag (ie: `['\--not_a_flag']` -> `{ input: ['--not_a_flag'], flags: {} }`), and not consumed but also not counted as a flag with it
|
||||||
|
* disabled (ie: `['\--not_a_flag']` -> `{ input: ['\--not_a_flag'], flags: {} }`).
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
handleBackslashesForSpecialFlagChars?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function __type__getType(e: any) { return typeof e };
|
function __type__getType(e: any) { return typeof e };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user