From 95471fd768a095a1c4a6491c2ff831767d3afa52 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Tue, 25 Jan 2022 22:42:35 -0500 Subject: [PATCH 1/3] feat: store end of flags in -- property --- src/type-flag.ts | 11 +++++++--- src/types.ts | 4 +++- tests/type-flag.spec.ts | 46 ++++++++++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/type-flag.ts b/src/type-flag.ts index a620683..36d7f08 100644 --- a/src/type-flag.ts +++ b/src/type-flag.ts @@ -15,6 +15,7 @@ import { const isAliasPattern = /^-[\da-z]+/i; const isFlagPattern = /^--[\w-]{2,}/; +const END_OF_FLAGS = '--'; /** type-flag: typed argv parser @@ -44,7 +45,9 @@ export function typeFlag( const parsed: TypeFlag = { flags: createFlagsObject(schemas), unknownFlags: {}, - _: [], + _: Object.assign([], { + [END_OF_FLAGS]: [], + }), }; let expectingValue: undefined | ((value?: string | boolean) => void); @@ -98,8 +101,10 @@ export function typeFlag( for (let i = 0; i < argv.length; i += 1) { const argvElement = argv[i]; - if (argvElement === '--') { - parsed._.push(...argv.slice(i + 1)); + if (argvElement === END_OF_FLAGS) { + const endOfFlags = argv.slice(i + 1); + parsed._[END_OF_FLAGS] = endOfFlags; + parsed._.push(...endOfFlags); break; } diff --git a/src/types.ts b/src/types.ts index ed2a3c5..cd32f31 100644 --- a/src/types.ts +++ b/src/types.ts @@ -94,5 +94,7 @@ export type TypeFlag = { unknownFlags: { [flag: string]: (string | boolean)[]; }; - _: string[]; + _: string[] & { + '--': string[]; + }; }; diff --git a/tests/type-flag.spec.ts b/tests/type-flag.spec.ts index 4618679..db08fa6 100644 --- a/tests/type-flag.spec.ts +++ b/tests/type-flag.spec.ts @@ -157,7 +157,7 @@ describe('Parsing', () => { const parsed = typeFlag({}, ['-invalidAlias']); expect(parsed).toStrictEqual({ - _: [], + _: Object.assign([], { '--': [] }), flags: {}, unknownFlags: { i: [true, true, true], @@ -180,7 +180,14 @@ describe('Parsing', () => { expect(parsed.flags.flagA).toBe(''); expect(parsed.flags.flagB).toBe(undefined); - expect(parsed._).toStrictEqual(['--flagB']); + expect(parsed._).toStrictEqual( + Object.assign( + ['--flagB'], + { + '--': ['--flagB'], + }, + ), + ); }); test('strings, booleans, numbers', () => { @@ -193,7 +200,12 @@ describe('Parsing', () => { expect(parsed.flags.string).toBe(''); expect(parsed.flags.boolean).toBe(true); expect(parsed.flags.number).toBe(Number.NaN); - expect(parsed._).toStrictEqual(['world']); + expect(parsed._).toStrictEqual( + Object.assign( + ['world'], + { '--': [] }, + ), + ); }); test('convert kebab-case to camelCase', () => { @@ -226,7 +238,12 @@ describe('Parsing', () => { expect(parsed.flags.string).toBe(''); expect(parsed.flags.boolean).toBe(true); expect(parsed.flags.number).toBe(Number.NaN); - expect(parsed._).toStrictEqual(['world']); + expect(parsed._).toStrictEqual( + Object.assign( + ['world'], + { '--': [] }, + ), + ); }); test('flag: - to allow the use of = in values (or vice versa)', () => { @@ -266,7 +283,12 @@ describe('Parsing', () => { expect(parsed.flags.string).toBe(''); expect(parsed.flags.boolean).toBe(true); expect(Object.keys(parsed.flags)).toStrictEqual(['string', 'boolean']); - expect(parsed._).toStrictEqual(['world']); + expect(parsed._).toStrictEqual( + Object.assign( + ['world'], + { '--': [] }, + ), + ); }); test('unknown flags', () => { @@ -309,7 +331,12 @@ describe('Parsing', () => { unknownString: ['hello', true], 'kebab-case': [true], }); - expect(parsed._).toStrictEqual(['a']); + expect(parsed._).toStrictEqual( + Object.assign( + ['a'], + { '--': [] }, + ), + ); }); test('custom type', () => { @@ -356,7 +383,12 @@ describe('Parsing', () => { expect(parsed.flags.number).toBe(Number.NaN); expect(parsed.flags.stringArray).toStrictEqual(['a', 'b']); expect(parsed.flags.numberArray).toStrictEqual([1, 2]); - expect(parsed._).toStrictEqual(['world']); + expect(parsed._).toStrictEqual( + Object.assign( + ['world'], + { '--': [] }, + ), + ); }); describe('Default flag value', () => { From 37f8cac8ffb97bccd359f2b0c8b443502dd65354 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Tue, 25 Jan 2022 22:52:29 -0500 Subject: [PATCH 2/3] test: update dts --- tests/type-flag.test-d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/type-flag.test-d.ts b/tests/type-flag.test-d.ts index 651a155..903ba17 100644 --- a/tests/type-flag.test-d.ts +++ b/tests/type-flag.test-d.ts @@ -38,7 +38,7 @@ type ExpectedType = { unknownFlags: { [flag: string]:(string | boolean)[]; }; - _: string[]; + _: string[] & { '--': string[] }; }; expectType(parsed); From 78ef5b583f82c48faf5ead3d2c43879f3cbbb114 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Fri, 28 Jan 2022 17:10:00 -0500 Subject: [PATCH 3/3] docs: end of flags --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 03d86ad..964869b 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,9 @@ $ node ./cli --some-string 'hello' --some-boolean --some-number 3 unknownFlags: { [flagName: string]: (string | boolean)[] } - _: string[] + _: string[] & { + '--': string[] + } } ``` @@ -195,7 +197,7 @@ This outputs the following: ### Arguments All argument values are stored in the `_` property. -Everything after `--` will not be parsed and be treated as arguments. +Everything after `--` (end-of-flags) is treated as arguments and will be stored in the `_['--']` property. ```sh $ node ./cli --boolean value --string "hello world" "another value" -- --string "goodbye world" @@ -204,7 +206,16 @@ $ node ./cli --boolean value --string "hello world" "another value" -- --string This outputs the following: ```json5 { - _: ['value', 'another value', '--string', 'goodbye world'] + _: [ + 'value', + 'another value', + '--string', + 'goodbye world', + '--': [ + '--string', + 'goodbye world' + ] + ] // ... } ```