Skip to content

Commit 0c11c39

Browse files
Allow user to pass in package URL for package reading (#182)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 8c12b2d commit 0c11c39

File tree

12 files changed

+117
-77
lines changed

12 files changed

+117
-77
lines changed

estest/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ meow(
1313
🌈 unicorns 🌈
1414
`,
1515
{
16+
importMeta: import.meta,
1617
flags: {
1718
rainbow: {
1819
type: 'boolean',

index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ type AnyFlag = StringFlag | BooleanFlag | NumberFlag;
2727
type AnyFlags = Record<string, AnyFlag>;
2828

2929
export interface Options<Flags extends AnyFlags> {
30+
/**
31+
Pass in [`import.meta`](https://nodejs.org/dist/latest/docs/api/esm.html#esm_import_meta). This is used to find the correct package.json file.
32+
*/
33+
readonly importMeta: ImportMeta;
34+
3035
/**
3136
Define argument flags.
3237
@@ -151,6 +156,7 @@ export interface Options<Flags extends AnyFlags> {
151156
$ foo
152157
🌈 unicorns✨🌈
153158
`, {
159+
importMeta: import.meta,
154160
booleanDefault: undefined,
155161
flags: {
156162
rainbow: {
@@ -288,6 +294,7 @@ const cli = meow(`
288294
$ foo unicorns --rainbow
289295
🌈 unicorns 🌈
290296
`, {
297+
importMeta: import.meta,
291298
flags: {
292299
rainbow: {
293300
type: 'boolean',

index.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {dirname} from 'node:path';
2+
import {fileURLToPath} from 'node:url';
13
import buildParserOptions from 'minimist-options';
24
import parseArguments from 'yargs-parser';
35
import camelCaseKeys from 'camelcase-keys';
@@ -97,13 +99,18 @@ const validateFlags = (flags, options) => {
9799
}
98100
};
99101

100-
const meow = (helpText, options) => {
102+
const meow = (helpText, options = {}) => {
101103
if (typeof helpText !== 'string') {
102104
options = helpText;
103105
helpText = '';
104106
}
105107

108+
if (!(options.importMeta && options.importMeta.url)) {
109+
throw new TypeError('The `importMeta` option is required. Its value must be `import.meta`.');
110+
}
111+
106112
const foundPackage = readPackageUpSync({
113+
cwd: dirname(fileURLToPath(options.importMeta.url)),
107114
normalize: false
108115
});
109116

index.test-d.ts

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,46 @@ import {expectAssignable, expectType} from 'tsd';
22
import {PackageJson} from 'type-fest';
33
import meow, {Result} from './index.js';
44

5+
const importMeta = import.meta;
6+
57
expectType<Result<never>>(meow('Help text'));
6-
expectType<Result<never>>(meow('Help text', {hardRejection: false}));
8+
expectType<Result<never>>(meow('Help text', {importMeta, hardRejection: false}));
79
expectAssignable<{flags: {foo: number}}>(
8-
meow({flags: {foo: {type: 'number', isRequired: true}}})
10+
meow({importMeta: import.meta, flags: {foo: {type: 'number', isRequired: true}}})
911
);
1012
expectAssignable<{flags: {foo: string}}>(
11-
meow({flags: {foo: {type: 'string', isRequired: true}}})
13+
meow({importMeta, flags: {foo: {type: 'string', isRequired: true}}})
1214
);
1315
expectAssignable<{flags: {foo: boolean}}>(
14-
meow({flags: {foo: {type: 'boolean', isRequired: true}}})
16+
meow({importMeta, flags: {foo: {type: 'boolean', isRequired: true}}})
1517
);
1618
expectAssignable<{flags: {foo: number | undefined}}>(
17-
meow({flags: {foo: {type: 'number'}}})
19+
meow({importMeta, flags: {foo: {type: 'number'}}})
1820
);
1921
expectAssignable<{flags: {foo: string | undefined}}>(
20-
meow({flags: {foo: {type: 'string'}}})
22+
meow({importMeta, flags: {foo: {type: 'string'}}})
2123
);
2224
expectAssignable<{flags: {foo: boolean | undefined}}>(
23-
meow({flags: {foo: {type: 'boolean'}}})
25+
meow({importMeta, flags: {foo: {type: 'boolean'}}})
2426
);
25-
expectType<Result<never>>(meow({description: 'foo'}));
26-
expectType<Result<never>>(meow({description: false}));
27-
expectType<Result<never>>(meow({help: 'foo'}));
28-
expectType<Result<never>>(meow({help: false}));
29-
expectType<Result<never>>(meow({version: 'foo'}));
30-
expectType<Result<never>>(meow({version: false}));
31-
expectType<Result<never>>(meow({autoHelp: false}));
32-
expectType<Result<never>>(meow({autoVersion: false}));
33-
expectType<Result<never>>(meow({pkg: {foo: 'bar'}}));
34-
expectType<Result<never>>(meow({argv: ['foo', 'bar']}));
35-
expectType<Result<never>>(meow({inferType: true}));
36-
expectType<Result<never>>(meow({booleanDefault: true}));
37-
expectType<Result<never>>(meow({booleanDefault: null}));
38-
expectType<Result<never>>(meow({booleanDefault: undefined}));
39-
expectType<Result<never>>(meow({hardRejection: false}));
27+
expectType<Result<never>>(meow({importMeta, description: 'foo'}));
28+
expectType<Result<never>>(meow({importMeta, description: false}));
29+
expectType<Result<never>>(meow({importMeta, help: 'foo'}));
30+
expectType<Result<never>>(meow({importMeta, help: false}));
31+
expectType<Result<never>>(meow({importMeta, version: 'foo'}));
32+
expectType<Result<never>>(meow({importMeta, version: false}));
33+
expectType<Result<never>>(meow({importMeta, autoHelp: false}));
34+
expectType<Result<never>>(meow({importMeta, autoVersion: false}));
35+
expectType<Result<never>>(meow({importMeta, pkg: {foo: 'bar'}}));
36+
expectType<Result<never>>(meow({importMeta, argv: ['foo', 'bar']}));
37+
expectType<Result<never>>(meow({importMeta, inferType: true}));
38+
expectType<Result<never>>(meow({importMeta, booleanDefault: true}));
39+
expectType<Result<never>>(meow({importMeta, booleanDefault: null}));
40+
expectType<Result<never>>(meow({importMeta, booleanDefault: undefined}));
41+
expectType<Result<never>>(meow({importMeta, hardRejection: false}));
4042

4143
const result = meow('Help text', {
44+
importMeta,
4245
flags: {
4346
foo: {type: 'boolean', alias: 'f'},
4447
'foo-bar': {type: 'number'},
@@ -66,6 +69,7 @@ result.showHelp(1);
6669
result.showVersion();
6770

6871
const options = {
72+
importMeta,
6973
flags: {
7074
rainbow: {
7175
type: 'boolean',

readme.md

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,52 +26,11 @@ $ npm install meow
2626
$ ./foo-app.js unicorns --rainbow
2727
```
2828

29-
**CommonJS**
30-
3129
```js
3230
#!/usr/bin/env node
33-
'use strict';
34-
const meow = require('meow');
35-
const foo = require('.');
36-
37-
const cli = meow(`
38-
Usage
39-
$ foo <input>
40-
41-
Options
42-
--rainbow, -r Include a rainbow
43-
44-
Examples
45-
$ foo unicorns --rainbow
46-
🌈 unicorns 🌈
47-
`, {
48-
flags: {
49-
rainbow: {
50-
type: 'boolean',
51-
alias: 'r'
52-
}
53-
}
54-
});
55-
/*
56-
{
57-
input: ['unicorns'],
58-
flags: {rainbow: true},
59-
...
60-
}
61-
*/
62-
63-
foo(cli.input[0], cli.flags);
64-
```
65-
66-
**ES Modules**
67-
68-
```js
69-
#!/usr/bin/env node
70-
import {createRequire} from 'module';
31+
import meow from 'meow';
7132
import foo from './lib/index.js';
7233

73-
const meow = createRequire(import.meta.url)('meow');
74-
7534
const cli = meow(`
7635
Usage
7736
$ foo <input>
@@ -83,6 +42,7 @@ const cli = meow(`
8342
$ foo unicorns --rainbow
8443
🌈 unicorns 🌈
8544
`, {
45+
importMeta: import.meta,
8646
flags: {
8747
rainbow: {
8848
type: 'boolean',
@@ -126,6 +86,12 @@ Shortcut for the `help` option.
12686

12787
Type: `object`
12888

89+
##### importMeta
90+
91+
Type: `object`
92+
93+
Pass in [`import.meta`](https://nodejs.org/dist/latest/docs/api/esm.html#esm_import_meta). This is used to find the correct package.json file.
94+
12995
##### flags
13096

13197
Type: `object`
@@ -253,7 +219,7 @@ __Caution: Explicitly specifying `undefined` for `booleanDefault` has different
253219
Example:
254220

255221
```js
256-
const meow = require('meow');
222+
const meow from 'meow';
257223

258224
const cli = meow(`
259225
Usage
@@ -268,6 +234,7 @@ const cli = meow(`
268234
$ foo
269235
🌈 unicorns✨🌈
270236
`, {
237+
importMeta: import.meta,
271238
booleanDefault: undefined,
272239
flags: {
273240
rainbow: {

test/fixtures/fixture-allow-unknown-flags.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import meow from '../../index.js';
33

44
const cli = meow({
5+
importMeta: import.meta,
56
description: 'Custom description',
67
help: `
78
Usage

test/fixtures/fixture-required-function.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import meow from '../../index.js';
33

44
const cli = meow({
5+
importMeta: import.meta,
56
description: 'Custom description',
67
help: `
78
Usage

test/fixtures/fixture-required-multiple.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import meow from '../../index.js';
33

44
const cli = meow({
5+
importMeta: import.meta,
56
description: 'Custom description',
67
help: `
78
Usage

test/fixtures/fixture-required.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import meow from '../../index.js';
44

55
const cli = meow({
6+
importMeta: import.meta,
67
description: 'Custom description',
78
help: `
89
Usage

test/fixtures/fixture.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import meow from '../../index.js';
33

44
const cli = meow({
5+
importMeta: import.meta,
56
description: 'Custom description',
67
help: `
78
Usage

0 commit comments

Comments
 (0)