diff --git a/src/type-flag.ts b/src/type-flag.ts index d4b6397..2671cba 100644 --- a/src/type-flag.ts +++ b/src/type-flag.ts @@ -4,10 +4,11 @@ import type { TypeFlag, } from './types'; import { + hasOwn, createRegistry, normalizeBoolean, applyParser, - hasOwn, + finalizeFlags, } from './utils'; import { argvIterator, @@ -42,7 +43,7 @@ export const typeFlag = ( } = {}, ) => { const { ignoreUnknown } = options; - const [flagRegistry, flags] = createRegistry(schemas); + const flagRegistry = createRegistry(schemas); const unknownFlags: ParsedFlags['unknownFlags'] = {}; const _ = [] as unknown as ParsedFlags['_']; _[DOUBLE_DASH] = []; @@ -50,7 +51,7 @@ export const typeFlag = ( argvIterator(argv, { onFlag(name, explicitValue, index) { if (hasOwn(flagRegistry, name)) { - const [parser, values] = flagRegistry[name]; + const [values, parser] = flagRegistry[name]; const flagValue = normalizeBoolean(parser, explicitValue); const getFollowingValue = (value?: string | boolean) => { values.push( @@ -87,7 +88,7 @@ export const typeFlag = ( type Result = TypeFlag; return { - flags, + flags: finalizeFlags(schemas, flagRegistry), unknownFlags, _, } as { diff --git a/src/utils.ts b/src/utils.ts index 2dec537..95e51fd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -61,15 +61,6 @@ export const applyParser = ( return typeFunction(value); }; -type FlagParsingData = [ - parser: TypeFunction, - values: unknown[], -]; - -type FlagRegistry = { - [flagName: string]: FlagParsingData; -}; - const reservedCharactersPattern = /[\s.:=]/; const validateFlagName = ( @@ -91,18 +82,31 @@ const validateFlagName = ( } }; +type FlagParsingData = [ + values: unknown[], + parser: TypeFunction, + isArray: boolean, + schema: FlagTypeOrSchema, +]; + +type FlagRegistry = { + [flagName: string]: FlagParsingData; +}; + export const createRegistry = ( schemas: Flags, ) => { const registry: FlagRegistry = {}; - const flags: Record = {}; - const setFlag = (name: string, value: any) => { - if (hasOwn(registry, name)) { - throw new Error(`Duplicate flags named ${stringify(name)}`); + const setFlag = ( + flagName: string, + data: FlagParsingData, + ) => { + if (hasOwn(registry, flagName)) { + throw new Error(`Duplicate flags named ${stringify(flagName)}`); } - registry[name] = value; + registry[flagName] = data; }; for (const flagName in schemas) { @@ -112,27 +116,11 @@ export const createRegistry = ( validateFlagName(flagName); const schema = schemas[flagName]; - const [parser, isArray] = parseFlagType(schema); - const values: unknown[] = []; - const flagData = [parser, values]; - - Object.defineProperty(flags, flagName, { - enumerable: true, - get() { - if ( - values.length === 0 - && 'default' in schema - ) { - let { default: defaultValue } = schema; - if (typeof defaultValue === 'function') { - defaultValue = defaultValue(); - } - return defaultValue; - } - - return isArray ? values : values.pop(); - }, - }); + const flagData: FlagParsingData = [ + [], + ...parseFlagType(schema), + schema, + ]; setFlag(flagName, flagData); @@ -157,5 +145,34 @@ export const createRegistry = ( } } - return [registry, flags] as const; + return registry; +}; + +export const finalizeFlags = ( + schemas: Flags, + registry: FlagRegistry, +) => { + const flags: Record = {}; + + for (const flagName in schemas) { + if (!hasOwn(schemas, flagName)) { + continue; + } + + const [values, , isArray, schema] = registry[flagName]; + if ( + values.length === 0 + && 'default' in schema + ) { + let { default: defaultValue } = schema; + if (typeof defaultValue === 'function') { + defaultValue = defaultValue(); + } + flags[flagName] = defaultValue; + } else { + flags[flagName] = isArray ? values : values.pop(); + } + } + + return flags; };