Skip to content

Commit f1036df

Browse files
BendingBendersindresorhus
authored andcommittedMar 19, 2019
Add TypeScript definition (#116)
1 parent f36715c commit f1036df

File tree

5 files changed

+262
-10
lines changed

5 files changed

+262
-10
lines changed
 

‎index.d.ts

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import {PackageJson} from 'type-fest';
2+
import {Options as MinimistOptions} from 'minimist-options';
3+
4+
export interface Options {
5+
/**
6+
Define argument flags.
7+
8+
The key is the flag name and the value is an object with any of:
9+
10+
- `type`: Type of value. (Possible values: `string` `boolean`)
11+
- `alias`: Usually used to define a short flag alias.
12+
- `default`: Default value when the flag is not specified.
13+
14+
@example
15+
```
16+
flags: {
17+
unicorn: {
18+
type: 'string',
19+
alias: 'u',
20+
default: 'rainbow'
21+
}
22+
}
23+
```
24+
*/
25+
readonly flags?: MinimistOptions;
26+
27+
/**
28+
Description to show above the help text. Default: The package.json `"description"` property.
29+
30+
Set it to `false` to disable it altogether.
31+
*/
32+
readonly description?: string | false;
33+
34+
/**
35+
The help text you want shown.
36+
37+
The input is reindented and starting/ending newlines are trimmed which means you can use a [template literal](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/template_strings) without having to care about using the correct amount of indent.
38+
39+
The description will be shown above your help text automatically.
40+
41+
Set it to `false` to disable it altogether.
42+
*/
43+
readonly help?: string | false;
44+
45+
/**
46+
Set a custom version output. Default: The package.json `"version"` property.
47+
48+
Set it to `false` to disable it altogether.
49+
*/
50+
readonly version?: string | false;
51+
52+
/**
53+
Automatically show the help text when the `--help` flag is present. Useful to set this value to `false` when a CLI manages child CLIs with their own help text.
54+
*/
55+
readonly autoHelp?: boolean;
56+
57+
/**
58+
Automatically show the version text when the `--version` flag is present. Useful to set this value to `false` when a CLI manages child CLIs with their own version text.
59+
*/
60+
readonly autoVersion?: boolean;
61+
62+
/**
63+
package.json as an `Object`. Default: Closest package.json upwards.
64+
65+
_You most likely don't need this option._
66+
*/
67+
readonly pkg?: {[key: string]: unknown};
68+
69+
/**
70+
Custom arguments object.
71+
72+
@default process.argv.slice(2)
73+
*/
74+
readonly argv?: ReadonlyArray<string>;
75+
76+
/**
77+
Infer the argument type.
78+
79+
By default, the argument `5` in `$ foo 5` becomes a string. Enabling this would infer it as a number.
80+
81+
@default false
82+
*/
83+
readonly inferType?: boolean;
84+
85+
/**
86+
Value of `boolean` flags not defined in `argv`. If set to `undefined` the flags not defined in `argv` will be excluded from the result. The `default` value set in `boolean` flags take precedence over `booleanDefault`.
87+
88+
__Caution: Explicitly specifying undefined for `booleanDefault` has different meaning from omitting key itself.__
89+
90+
@example
91+
```
92+
const cli = meow(`
93+
Usage
94+
$ foo
95+
96+
Options
97+
--rainbow, -r Include a rainbow
98+
--unicorn, -u Include a unicorn
99+
--no-sparkles Exclude sparkles
100+
101+
Examples
102+
$ foo
103+
🌈 unicorns✨🌈
104+
`, {
105+
booleanDefault: undefined,
106+
flags: {
107+
rainbow: {
108+
type: 'boolean',
109+
default: true,
110+
alias: 'r'
111+
},
112+
unicorn: {
113+
type: 'boolean',
114+
default: false,
115+
alias: 'u'
116+
},
117+
cake: {
118+
type: 'boolean',
119+
alias: 'c'
120+
},
121+
sparkles: {
122+
type: 'boolean',
123+
default: true
124+
}
125+
}
126+
});
127+
128+
//{
129+
// flags: {
130+
// rainbow: true,
131+
// unicorn: false,
132+
// sparkles: true
133+
// },
134+
// unnormalizedFlags: {
135+
// rainbow: true,
136+
// r: true,
137+
// unicorn: false,
138+
// u: false,
139+
// sparkles: true
140+
// },
141+
// …
142+
//}
143+
```
144+
*/
145+
readonly booleanDefault?: boolean | null | undefined;
146+
147+
/**
148+
Whether to use [hard-rejection](https://github.com/sindresorhus/hard-rejection) or not. Disabling this can be useful if you need to handle `process.on('unhandledRejection')` yourself.
149+
150+
@default true
151+
*/
152+
readonly hardRejection?: boolean;
153+
}
154+
155+
export interface Result {
156+
/**
157+
Non-flag arguments.
158+
*/
159+
input: string[];
160+
161+
/**
162+
Flags converted to camelCase excluding aliases.
163+
*/
164+
flags: {[name: string]: unknown};
165+
166+
/**
167+
Flags converted camelCase including aliases.
168+
*/
169+
unnormalizedFlags: {[name: string]: unknown};
170+
171+
/**
172+
The `package.json` object.
173+
*/
174+
pkg: PackageJson;
175+
176+
/**
177+
The help text used with `--help`.
178+
*/
179+
help: string;
180+
181+
/**
182+
Show the help text and exit with code.
183+
184+
@param exitCode - The exit code to use. Default: `2`.
185+
*/
186+
showHelp(exitCode?: number): void;
187+
188+
/**
189+
Show the version text and exit.
190+
*/
191+
showVersion(): void;
192+
}
193+
194+
/**
195+
@param helpMessage - Shortcut for the `help` option.
196+
*/
197+
export default function meow(helpMessage: string, options?: Options): Result;
198+
export default function meow(options?: Options): Result;

‎index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const normalizePackageData = require('normalize-package-data');
1414
delete require.cache[__filename];
1515
const parentDir = path.dirname(module.parent.filename);
1616

17-
module.exports = (helpText, options) => {
17+
const meow = (helpText, options) => {
1818
if (typeof helpText !== 'string') {
1919
options = helpText;
2020
helpText = '';
@@ -126,3 +126,6 @@ module.exports = (helpText, options) => {
126126
showVersion
127127
};
128128
};
129+
130+
module.exports = meow;
131+
module.exports.default = meow;

‎index.test-d.ts

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {expectType} from 'tsd-check';
2+
import {PackageJson} from 'type-fest';
3+
import meow, {Result} from '.';
4+
5+
expectType<Result>(meow('Help text'));
6+
expectType<Result>(meow('Help text', {hardRejection: false}));
7+
expectType<Result>(
8+
meow({
9+
flags: {
10+
unicorn: {
11+
type: 'boolean',
12+
alias: 'u'
13+
},
14+
fooBar: {
15+
type: 'string',
16+
default: 'foo'
17+
}
18+
}
19+
})
20+
);
21+
expectType<Result>(meow({description: 'foo'}));
22+
expectType<Result>(meow({description: false}));
23+
expectType<Result>(meow({help: 'foo'}));
24+
expectType<Result>(meow({help: false}));
25+
expectType<Result>(meow({version: 'foo'}));
26+
expectType<Result>(meow({version: false}));
27+
expectType<Result>(meow({autoHelp: false}));
28+
expectType<Result>(meow({autoVersion: false}));
29+
expectType<Result>(meow({pkg: {foo: 'bar'}}));
30+
expectType<Result>(meow({argv: ['foo', 'bar']}));
31+
expectType<Result>(meow({inferType: true}));
32+
expectType<Result>(meow({booleanDefault: true}));
33+
expectType<Result>(meow({booleanDefault: null}));
34+
expectType<Result>(meow({booleanDefault: undefined}));
35+
expectType<Result>(meow({hardRejection: false}));
36+
37+
const result = meow('Help text');
38+
39+
expectType<string[]>(result.input);
40+
expectType<{[name: string]: unknown}>(result.flags);
41+
expectType<{[name: string]: unknown}>(result.unnormalizedFlags);
42+
expectType<PackageJson>(result.pkg);
43+
expectType<string>(result.help);
44+
45+
result.showHelp();
46+
result.showHelp(1);
47+
result.showVersion();

‎package.json

+12-8
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
"node": ">=8"
1414
},
1515
"scripts": {
16-
"test": "xo && ava"
16+
"test": "xo && ava && tsd-check"
1717
},
1818
"files": [
19-
"index.js"
19+
"index.js",
20+
"index.d.ts"
2021
],
2122
"keywords": [
2223
"cli",
@@ -38,21 +39,24 @@
3839
"console"
3940
],
4041
"dependencies": {
42+
"@types/minimist": "^1.2.0",
4143
"camelcase-keys": "^5.0.0",
42-
"decamelize-keys": "^1.0.0",
44+
"decamelize-keys": "^1.1.0",
4345
"hard-rejection": "^1.0.0",
44-
"minimist-options": "^3.0.1",
45-
"normalize-package-data": "^2.3.4",
46+
"minimist-options": "^4.0.1",
47+
"normalize-package-data": "^2.5.0",
4648
"read-pkg-up": "^4.0.0",
4749
"redent": "^2.0.0",
4850
"trim-newlines": "^2.0.0",
51+
"type-fest": "^0.2.0",
4952
"yargs-parser": "^11.0.0"
5053
},
5154
"devDependencies": {
52-
"ava": "^0.25.0",
55+
"ava": "^1.3.1",
5356
"execa": "^1.0.0",
54-
"indent-string": "^3.0.0",
55-
"xo": "^0.23.0"
57+
"indent-string": "^3.2.0",
58+
"tsd-check": "^0.3.0",
59+
"xo": "^0.24.0"
5660
},
5761
"xo": {
5862
"rules": {

‎readme.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Returns an `Object` with:
7777
- `unnormalizedFlags` *(Object)* - Flags converted camelCase including aliases
7878
- `pkg` *(Object)* - The `package.json` object
7979
- `help` *(string)* - The help text used with `--help`
80-
- `showHelp([code=2])` *(Function)* - Show the help text and exit with `code`
80+
- `showHelp([exitCode=2])` *(Function)* - Show the help text and exit with `exitCode`
8181
- `showVersion()` *(Function)* - Show the version text and exit
8282

8383
#### helpText

0 commit comments

Comments
 (0)
Please sign in to comment.