Skip to content

Commit

Permalink
Add aliases option (#226)
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-mitchell committed Mar 20, 2023
1 parent 14e870d commit 901b9fc
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
5 changes: 4 additions & 1 deletion index.d.ts
Expand Up @@ -21,6 +21,7 @@ export type Flag<Type extends FlagType, Default, IsMultiple = false> = {
readonly default?: Default;
readonly isRequired?: boolean | IsRequiredPredicate;
readonly isMultiple?: IsMultiple;
readonly aliases?: string[];
};

type StringFlag = Flag<'string', string> | Flag<'string', string[], true>;
Expand All @@ -47,6 +48,7 @@ export type Options<Flags extends AnyFlags> = {
If it's only known at runtime whether the flag is required or not you can pass a Function instead of a boolean, which based on the given flags and other non-flag arguments should decide if the flag is required.
- `isMultiple`: Indicates a flag can be set multiple times. Values are turned into an array. (Default: false)
Multiple values are provided by specifying the flag multiple times, for example, `$ foo -u rainbow -u cat`. Space- or comma-separated values are *not* supported.
- `aliases`: Other names for the flag.
Note that flags are always defined using a camel-case key (`myKey`), but will match arguments in kebab-case (`--my-key`).
Expand All @@ -64,7 +66,8 @@ export type Options<Flags extends AnyFlags> = {
}
return false;
}
},
aliases: ['unicorns']
}
}
```
Expand Down
15 changes: 15 additions & 0 deletions index.js
Expand Up @@ -97,6 +97,15 @@ const buildParserFlags = ({flags, booleanDefault}) => {
delete flag.isMultiple;
}

if (Array.isArray(flag.aliases)) {
if (flag.alias) {
flag.aliases.push(flag.alias);
}

flag.alias = flag.aliases;
delete flag.aliases;
}

parserFlags[flagKey] = flag;
}

Expand Down Expand Up @@ -235,6 +244,12 @@ const meow = (helpText, options = {}) => {
validateFlags(flags, options);

for (const flagValue of Object.values(options.flags)) {
if (Array.isArray(flagValue.aliases)) {
for (const alias of flagValue.aliases) {
delete flags[alias];
}
}

delete flags[flagValue.shortFlag];
}

Expand Down
4 changes: 3 additions & 1 deletion index.test-d.ts
Expand Up @@ -53,7 +53,7 @@ const result = meow('Help text', {
importMeta,
flags: {
foo: {type: 'boolean', shortFlag: 'f'},
'foo-bar': {type: 'number'},
'foo-bar': {type: 'number', aliases: ['foobar', 'fooBar']},
bar: {type: 'string', default: ''},
abc: {type: 'string', isMultiple: true},
},
Expand All @@ -70,6 +70,8 @@ expectType<string[] | undefined>(result.flags.abc);
expectType<boolean | undefined>(result.unnormalizedFlags.foo);
expectType<unknown>(result.unnormalizedFlags.f);
expectType<number | undefined>(result.unnormalizedFlags['foo-bar']);
expectType<unknown>(result.unnormalizedFlags.foobar);
expectType<unknown>(result.unnormalizedFlags.fooBar);
expectType<string>(result.unnormalizedFlags.bar);
expectType<string[] | undefined>(result.unnormalizedFlags.abc);

Expand Down
4 changes: 3 additions & 1 deletion readme.md
Expand Up @@ -112,6 +112,7 @@ The key is the flag name in camel-case and the value is an object with any of:
- The function should return a `boolean`, true if the flag is required, otherwise false.
- `isMultiple`: Indicates a flag can be set multiple times. Values are turned into an array. (Default: false)
- Multiple values are provided by specifying the flag multiple times, for example, `$ foo -u rainbow -u cat`. Space- or comma-separated values are [currently *not* supported](https://github.com/sindresorhus/meow/issues/164).
- `aliases`: Other names for the flag.

Note that flags are always defined using a camel-case key (`myKey`), but will match arguments in kebab-case (`--my-key`).

Expand All @@ -130,7 +131,8 @@ flags: {
}

return false;
}
},
aliases: ['unicorns']
}
}
```
Expand Down
63 changes: 63 additions & 0 deletions test/test.js
Expand Up @@ -602,6 +602,69 @@ test('suggests renaming alias to shortFlag', t => {
}, {message: 'The option `alias` has been renamed to `shortFlag`. The following flags need to be updated: `foo`, `bar`'});
});

test('aliases - accepts one', t => {
t.deepEqual(meow({
importMeta,
argv: ['--foo=baz'],
flags: {
fooBar: {
type: 'string',
aliases: ['foo'],
},
},
}).flags, {
fooBar: 'baz',
});
});

test('aliases - accepts multiple', t => {
t.deepEqual(meow({
importMeta,
argv: ['--foo=baz1', '--bar=baz2'],
flags: {
fooBar: {
type: 'string',
aliases: ['foo', 'bar'],
isMultiple: true,
},
},
}).flags, {
fooBar: ['baz1', 'baz2'],
});
});

test('aliases - can be a short flag', t => {
t.deepEqual(meow({
importMeta,
argv: ['--f=baz'],
flags: {
fooBar: {
type: 'string',
aliases: ['f'],
},
},
}).flags, {
fooBar: 'baz',
});
});

test('aliases - works with short flag', t => {
t.deepEqual(meow({
importMeta,
argv: ['--foo=baz1', '--bar=baz2', '-f=baz3'],
flags: {
fooBar: {
type: 'string',
shortFlag: 'f',
aliases: ['foo', 'bar'],
isMultiple: true,
},
},
}).flags, {
fooBar: ['baz1', 'baz2', 'baz3'],
});
});

if (NODE_MAJOR_VERSION >= 14) {
test('supports es modules', async t => {
try {
Expand Down

0 comments on commit 901b9fc

Please sign in to comment.