Skip to content

Commit

Permalink
Allow user to pass in package URL for package reading (#182)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
LitoMore and sindresorhus committed May 5, 2021
1 parent 8c12b2d commit 0c11c39
Show file tree
Hide file tree
Showing 12 changed files with 117 additions and 77 deletions.
1 change: 1 addition & 0 deletions estest/index.js
Expand Up @@ -13,6 +13,7 @@ meow(
🌈 unicorns 🌈
`,
{
importMeta: import.meta,
flags: {
rainbow: {
type: 'boolean',
Expand Down
7 changes: 7 additions & 0 deletions index.d.ts
Expand Up @@ -27,6 +27,11 @@ type AnyFlag = StringFlag | BooleanFlag | NumberFlag;
type AnyFlags = Record<string, AnyFlag>;

export interface Options<Flags extends AnyFlags> {
/**
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.
*/
readonly importMeta: ImportMeta;

/**
Define argument flags.
Expand Down Expand Up @@ -151,6 +156,7 @@ export interface Options<Flags extends AnyFlags> {
$ foo
🌈 unicorns✨🌈
`, {
importMeta: import.meta,
booleanDefault: undefined,
flags: {
rainbow: {
Expand Down Expand Up @@ -288,6 +294,7 @@ const cli = meow(`
$ foo unicorns --rainbow
🌈 unicorns 🌈
`, {
importMeta: import.meta,
flags: {
rainbow: {
type: 'boolean',
Expand Down
9 changes: 8 additions & 1 deletion index.js
@@ -1,3 +1,5 @@
import {dirname} from 'node:path';
import {fileURLToPath} from 'node:url';
import buildParserOptions from 'minimist-options';
import parseArguments from 'yargs-parser';
import camelCaseKeys from 'camelcase-keys';
Expand Down Expand Up @@ -97,13 +99,18 @@ const validateFlags = (flags, options) => {
}
};

const meow = (helpText, options) => {
const meow = (helpText, options = {}) => {
if (typeof helpText !== 'string') {
options = helpText;
helpText = '';
}

if (!(options.importMeta && options.importMeta.url)) {
throw new TypeError('The `importMeta` option is required. Its value must be `import.meta`.');
}

const foundPackage = readPackageUpSync({
cwd: dirname(fileURLToPath(options.importMeta.url)),
normalize: false
});

Expand Down
48 changes: 26 additions & 22 deletions index.test-d.ts
Expand Up @@ -2,43 +2,46 @@ import {expectAssignable, expectType} from 'tsd';
import {PackageJson} from 'type-fest';
import meow, {Result} from './index.js';

const importMeta = import.meta;

expectType<Result<never>>(meow('Help text'));
expectType<Result<never>>(meow('Help text', {hardRejection: false}));
expectType<Result<never>>(meow('Help text', {importMeta, hardRejection: false}));
expectAssignable<{flags: {foo: number}}>(
meow({flags: {foo: {type: 'number', isRequired: true}}})
meow({importMeta: import.meta, flags: {foo: {type: 'number', isRequired: true}}})
);
expectAssignable<{flags: {foo: string}}>(
meow({flags: {foo: {type: 'string', isRequired: true}}})
meow({importMeta, flags: {foo: {type: 'string', isRequired: true}}})
);
expectAssignable<{flags: {foo: boolean}}>(
meow({flags: {foo: {type: 'boolean', isRequired: true}}})
meow({importMeta, flags: {foo: {type: 'boolean', isRequired: true}}})
);
expectAssignable<{flags: {foo: number | undefined}}>(
meow({flags: {foo: {type: 'number'}}})
meow({importMeta, flags: {foo: {type: 'number'}}})
);
expectAssignable<{flags: {foo: string | undefined}}>(
meow({flags: {foo: {type: 'string'}}})
meow({importMeta, flags: {foo: {type: 'string'}}})
);
expectAssignable<{flags: {foo: boolean | undefined}}>(
meow({flags: {foo: {type: 'boolean'}}})
meow({importMeta, flags: {foo: {type: 'boolean'}}})
);
expectType<Result<never>>(meow({description: 'foo'}));
expectType<Result<never>>(meow({description: false}));
expectType<Result<never>>(meow({help: 'foo'}));
expectType<Result<never>>(meow({help: false}));
expectType<Result<never>>(meow({version: 'foo'}));
expectType<Result<never>>(meow({version: false}));
expectType<Result<never>>(meow({autoHelp: false}));
expectType<Result<never>>(meow({autoVersion: false}));
expectType<Result<never>>(meow({pkg: {foo: 'bar'}}));
expectType<Result<never>>(meow({argv: ['foo', 'bar']}));
expectType<Result<never>>(meow({inferType: true}));
expectType<Result<never>>(meow({booleanDefault: true}));
expectType<Result<never>>(meow({booleanDefault: null}));
expectType<Result<never>>(meow({booleanDefault: undefined}));
expectType<Result<never>>(meow({hardRejection: false}));
expectType<Result<never>>(meow({importMeta, description: 'foo'}));
expectType<Result<never>>(meow({importMeta, description: false}));
expectType<Result<never>>(meow({importMeta, help: 'foo'}));
expectType<Result<never>>(meow({importMeta, help: false}));
expectType<Result<never>>(meow({importMeta, version: 'foo'}));
expectType<Result<never>>(meow({importMeta, version: false}));
expectType<Result<never>>(meow({importMeta, autoHelp: false}));
expectType<Result<never>>(meow({importMeta, autoVersion: false}));
expectType<Result<never>>(meow({importMeta, pkg: {foo: 'bar'}}));
expectType<Result<never>>(meow({importMeta, argv: ['foo', 'bar']}));
expectType<Result<never>>(meow({importMeta, inferType: true}));
expectType<Result<never>>(meow({importMeta, booleanDefault: true}));
expectType<Result<never>>(meow({importMeta, booleanDefault: null}));
expectType<Result<never>>(meow({importMeta, booleanDefault: undefined}));
expectType<Result<never>>(meow({importMeta, hardRejection: false}));

const result = meow('Help text', {
importMeta,
flags: {
foo: {type: 'boolean', alias: 'f'},
'foo-bar': {type: 'number'},
Expand Down Expand Up @@ -66,6 +69,7 @@ result.showHelp(1);
result.showVersion();

const options = {
importMeta,
flags: {
rainbow: {
type: 'boolean',
Expand Down
53 changes: 10 additions & 43 deletions readme.md
Expand Up @@ -26,52 +26,11 @@ $ npm install meow
$ ./foo-app.js unicorns --rainbow
```

**CommonJS**

```js
#!/usr/bin/env node
'use strict';
const meow = require('meow');
const foo = require('.');

const cli = meow(`
Usage
$ foo <input>
Options
--rainbow, -r Include a rainbow
Examples
$ foo unicorns --rainbow
🌈 unicorns 🌈
`, {
flags: {
rainbow: {
type: 'boolean',
alias: 'r'
}
}
});
/*
{
input: ['unicorns'],
flags: {rainbow: true},
...
}
*/

foo(cli.input[0], cli.flags);
```

**ES Modules**

```js
#!/usr/bin/env node
import {createRequire} from 'module';
import meow from 'meow';
import foo from './lib/index.js';

const meow = createRequire(import.meta.url)('meow');

const cli = meow(`
Usage
$ foo <input>
Expand All @@ -83,6 +42,7 @@ const cli = meow(`
$ foo unicorns --rainbow
🌈 unicorns 🌈
`, {
importMeta: import.meta,
flags: {
rainbow: {
type: 'boolean',
Expand Down Expand Up @@ -126,6 +86,12 @@ Shortcut for the `help` option.

Type: `object`

##### importMeta

Type: `object`

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.

##### flags

Type: `object`
Expand Down Expand Up @@ -253,7 +219,7 @@ __Caution: Explicitly specifying `undefined` for `booleanDefault` has different
Example:

```js
const meow = require('meow');
const meow from 'meow';

const cli = meow(`
Usage
Expand All @@ -268,6 +234,7 @@ const cli = meow(`
$ foo
🌈 unicorns✨🌈
`, {
importMeta: import.meta,
booleanDefault: undefined,
flags: {
rainbow: {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/fixture-allow-unknown-flags.js
Expand Up @@ -2,6 +2,7 @@
import meow from '../../index.js';

const cli = meow({
importMeta: import.meta,
description: 'Custom description',
help: `
Usage
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/fixture-required-function.js
Expand Up @@ -2,6 +2,7 @@
import meow from '../../index.js';

const cli = meow({
importMeta: import.meta,
description: 'Custom description',
help: `
Usage
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/fixture-required-multiple.js
Expand Up @@ -2,6 +2,7 @@
import meow from '../../index.js';

const cli = meow({
importMeta: import.meta,
description: 'Custom description',
help: `
Usage
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/fixture-required.js
Expand Up @@ -3,6 +3,7 @@
import meow from '../../index.js';

const cli = meow({
importMeta: import.meta,
description: 'Custom description',
help: `
Usage
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/fixture.js
Expand Up @@ -2,6 +2,7 @@
import meow from '../../index.js';

const cli = meow({
importMeta: import.meta,
description: 'Custom description',
help: `
Usage
Expand Down

0 comments on commit 0c11c39

Please sign in to comment.