From 8a4cecd1004ef4c871728778dcb6cf564a0cbbbb Mon Sep 17 00:00:00 2001 From: Tommy Date: Sun, 27 Aug 2023 18:06:13 -0500 Subject: [PATCH 1/7] Fix TypeScript types (#245) --- package.json | 11 +- rollup.config.js | 19 +++- index.d.ts => source/index.d.ts | 0 test-d/build.test-d.ts | 132 ++++++++++++++++++++++ index.test-d.ts => test-d/index.test-d.ts | 4 +- tsconfig.json | 6 +- 6 files changed, 162 insertions(+), 10 deletions(-) rename index.d.ts => source/index.d.ts (100%) create mode 100644 test-d/build.test-d.ts rename index.test-d.ts => test-d/index.test-d.ts (97%) diff --git a/package.json b/package.json index bc65eac..612265a 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "type": "module", "exports": { - "types": "./index.d.ts", + "types": "./build/index.d.ts", "default": "./build/index.js" }, "sideEffects": false, @@ -22,11 +22,10 @@ "scripts": { "prepare": "npm run build", "build": "rollup --config", - "test": "xo && tsd && npm run build && ava" + "test": "xo && npm run build && ava && tsd --typings build/index.d.ts" }, "files": [ - "build", - "index.d.ts" + "build" ], "keywords": [ "cli", @@ -82,10 +81,12 @@ "read-pkg-up": "^10.0.0", "redent": "^4.0.0", "rollup": "^3.27.0", + "rollup-plugin-dts": "^6.0.0", "rollup-plugin-license": "^3.0.1", "trim-newlines": "^5.0.0", "tsd": "^0.28.1", - "type-fest": "^4.2.0", + "type-fest": "^4.3.1", + "typescript": "~5.1.6", "xo": "^0.56.0", "yargs-parser": "^21.1.1" }, diff --git a/rollup.config.js b/rollup.config.js index 55f7ab0..39f5760 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,6 +2,7 @@ import {nodeResolve} from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import json from '@rollup/plugin-json'; import license from 'rollup-plugin-license'; +import {dts} from 'rollup-plugin-dts'; import {globby} from 'globby'; import {createTag, replaceResultTransformer} from 'common-tags'; import {delete_comments as deleteComments} from 'delete_comments'; @@ -17,7 +18,7 @@ const stripComments = createTag( const outputDirectory = 'build'; -export default defineConfig({ +const config = defineConfig({ input: await globby('source/**/*.js'), output: { dir: outputDirectory, @@ -55,3 +56,19 @@ export default defineConfig({ }), ], }); + +const dtsConfig = defineConfig({ + input: './source/index.d.ts', + output: { + file: `./${outputDirectory}/index.d.ts`, + format: 'es', + }, + plugins: [ + dts({ + respectExternal: true, + }), + ], +}); + +// eslint-disable-next-line import/no-anonymous-default-export +export default [config, dtsConfig]; diff --git a/index.d.ts b/source/index.d.ts similarity index 100% rename from index.d.ts rename to source/index.d.ts diff --git a/test-d/build.test-d.ts b/test-d/build.test-d.ts new file mode 100644 index 0000000..ca9d8ee --- /dev/null +++ b/test-d/build.test-d.ts @@ -0,0 +1,132 @@ +import {expectAssignable, expectError, expectType} from 'tsd'; +import type {PackageJson} from 'type-fest'; +import meow, {type Result} from '../build/index.js'; + +type AnyFlag = NonNullable[0]>['flags']>[string]; + +const importMeta = import.meta; + +expectType>(meow('Help text')); +expectType>(meow('Help text', {importMeta, hardRejection: false})); +expectAssignable<{flags: {foo: number}}>( + meow({importMeta: import.meta, flags: {foo: {type: 'number', isRequired: true}}}), +); +expectAssignable<{flags: {foo: string}}>( + meow({importMeta, flags: {foo: {type: 'string', isRequired: true}}}), +); +expectAssignable<{flags: {foo: boolean}}>( + meow({importMeta, flags: {foo: {type: 'boolean', isRequired: true}}}), +); +expectAssignable<{flags: {foo: number | undefined}}>( + meow({importMeta, flags: {foo: {type: 'number'}}}), +); +expectAssignable<{flags: {foo: string | undefined}}>( + meow({importMeta, flags: {foo: {type: 'string'}}}), +); +expectAssignable<{flags: {foo: boolean | undefined}}>( + meow({importMeta, flags: {foo: {type: 'boolean'}}}), +); +expectAssignable<{flags: {foo: number[] | undefined}}>( + meow({importMeta, flags: {foo: {type: 'number', isMultiple: true}}}), +); +expectAssignable<{flags: {foo: string[] | undefined}}>( + meow({importMeta, flags: {foo: {type: 'string', isMultiple: true}}}), +); +expectAssignable<{flags: {foo: boolean[] | undefined}}>( + meow({importMeta, flags: {foo: {type: 'boolean', isMultiple: true}}}), +); +expectType>(meow({importMeta, description: 'foo'})); +expectType>(meow({importMeta, description: false})); +expectType>(meow({importMeta, help: 'foo'})); +expectType>(meow({importMeta, help: false})); +expectType>(meow({importMeta, version: 'foo'})); +expectType>(meow({importMeta, version: false})); +expectType>(meow({importMeta, autoHelp: false})); +expectType>(meow({importMeta, autoVersion: false})); +expectType>(meow({importMeta, pkg: {foo: 'bar'}})); +expectType>(meow({importMeta, argv: ['foo', 'bar']})); +expectType>(meow({importMeta, inferType: true})); +expectType>(meow({importMeta, booleanDefault: true})); +expectType>(meow({importMeta, booleanDefault: null})); +expectType>(meow({importMeta, booleanDefault: undefined})); +expectType>(meow({importMeta, hardRejection: false})); + +const result = meow('Help text', { + importMeta, + flags: { + foo: {type: 'boolean', shortFlag: 'f'}, + 'foo-bar': {type: 'number', aliases: ['foobar', 'fooBar']}, + bar: {type: 'string', default: ''}, + abc: {type: 'string', isMultiple: true}, + baz: {type: 'string', choices: ['rainbow', 'cat', 'unicorn']}, + }, +}); + +expectType(result.input); +expectType(result.pkg); +expectType(result.help); + +expectType(result.flags.foo); +expectType(result.flags.fooBar); +expectType(result.flags.bar); +expectType(result.flags.abc); +expectType(result.flags.baz); +expectType(result.unnormalizedFlags.foo); +expectType(result.unnormalizedFlags.f); +expectType(result.unnormalizedFlags['foo-bar']); +expectType(result.unnormalizedFlags.foobar); +expectType(result.unnormalizedFlags.fooBar); +expectType(result.unnormalizedFlags.bar); +expectType(result.unnormalizedFlags.abc); +expectType(result.unnormalizedFlags.baz); + +result.showHelp(); +result.showHelp(1); +result.showVersion(); + +const options = { + importMeta, + flags: { + rainbow: { + type: 'boolean', + shortFlag: 'r', + }, + }, +} as const; + +meow('', options); + +expectAssignable({type: 'string', default: 'cat'}); +expectAssignable({type: 'number', default: 42}); +expectAssignable({type: 'boolean', default: true}); + +expectAssignable({type: 'string', default: undefined}); +expectAssignable({type: 'number', default: undefined}); +expectAssignable({type: 'boolean', default: undefined}); + +expectAssignable({type: 'string', isMultiple: true, default: ['cat']}); +expectAssignable({type: 'number', isMultiple: true, default: [42]}); +expectAssignable({type: 'boolean', isMultiple: true, default: [false]}); + +expectError({type: 'string', isMultiple: true, default: 'cat'}); +expectError({type: 'number', isMultiple: true, default: 42}); +expectError({type: 'boolean', isMultiple: true, default: false}); + +expectAssignable({type: 'string', choices: ['cat', 'unicorn']}); +expectAssignable({type: 'number', choices: [1, 2]}); +expectAssignable({type: 'boolean', choices: [true, false]}); +expectAssignable({type: 'string', isMultiple: true, choices: ['cat']}); +expectAssignable({type: 'string', isMultiple: false, choices: ['cat']}); + +expectError({type: 'string', choices: 'cat'}); +expectError({type: 'number', choices: 1}); +expectError({type: 'boolean', choices: true}); + +expectError({type: 'string', choices: [1]}); +expectError({type: 'number', choices: ['cat']}); +expectError({type: 'boolean', choices: ['cat']}); + +expectAssignable({choices: ['cat']}); +expectAssignable({choices: [1]}); +expectAssignable({choices: [true]}); +expectError({choices: ['cat', 1, true]}); diff --git a/index.test-d.ts b/test-d/index.test-d.ts similarity index 97% rename from index.test-d.ts rename to test-d/index.test-d.ts index 09250a7..aa5bf91 100644 --- a/index.test-d.ts +++ b/test-d/index.test-d.ts @@ -1,6 +1,8 @@ import {expectAssignable, expectError, expectType} from 'tsd'; import type {PackageJson} from 'type-fest'; -import meow, {type Result, type AnyFlag} from './index.js'; +import meow, {type Result} from '../source/index.js'; + +type AnyFlag = NonNullable[0]>['flags']>[string]; const importMeta = import.meta; diff --git a/tsconfig.json b/tsconfig.json index a97b4b7..3a0a364 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { - "files": [ - "index.d.ts", - "index.test-d.ts", + "include": [ + "source/index.d.ts", + "test-d", ], "compilerOptions": { "strict": true, From 1d083266d4c4f3b37da22693cf22235ca7fe9fb5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 28 Aug 2023 01:09:28 +0200 Subject: [PATCH 2/7] 12.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 612265a..2ceac05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meow", - "version": "12.1.0", + "version": "12.1.1", "description": "CLI app helper", "license": "MIT", "repository": "sindresorhus/meow", From 2ecd29d2ba70dca7e81d4630f88c4af13f8e7b28 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 22 Dec 2023 20:47:30 +0100 Subject: [PATCH 3/7] Require Node.js 18 --- .github/funding.yml | 4 ---- .github/workflows/main.yml | 4 ++-- package.json | 38 +++++++++++++++++++------------------- rollup.config.js | 2 +- source/options.js | 2 +- 5 files changed, 23 insertions(+), 27 deletions(-) delete mode 100644 .github/funding.yml diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index d867f68..0000000 --- a/.github/funding.yml +++ /dev/null @@ -1,4 +0,0 @@ -github: sindresorhus -open_collective: sindresorhus -tidelift: npm/meow -custom: https://sindresorhus.com/donate diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1ed55d5..a023591 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,8 +14,8 @@ jobs: - 18 - 16 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/package.json b/package.json index 2ceac05..4be0556 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "sideEffects": false, "engines": { - "node": ">=16.10" + "node": ">=18" }, "scripts": { "prepare": "npm run build", @@ -54,39 +54,39 @@ "hard-rejection", "minimist-options", "normalize-package-data", - "read-pkg-up", + "read-package-up", "redent", "trim-newlines", "type-fest", "yargs-parser" ], "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.3", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.1.0", - "@types/minimist": "^1.2.2", - "ava": "^5.3.1", - "camelcase-keys": "^8.0.2", + "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-json": "^6.1.0", + "@rollup/plugin-node-resolve": "^15.2.3", + "@types/minimist": "^1.2.5", + "ava": "^6.0.1", + "camelcase-keys": "^9.1.2", "common-tags": "^2.0.0-alpha.1", "decamelize": "^6.0.0", "decamelize-keys": "^2.0.1", "delete_comments": "^0.0.2", - "execa": "^7.2.0", - "globby": "^13.2.2", + "execa": "^8.0.1", + "globby": "^14.0.0", "hard-rejection": "^2.1.0", "indent-string": "^5.0.0", "minimist-options": "4.1.0", - "normalize-package-data": "^5.0.0", - "read-pkg": "^8.0.0", - "read-pkg-up": "^10.0.0", + "normalize-package-data": "^6.0.0", + "read-package-up": "^11.0.0", + "read-pkg": "^9.0.1", "redent": "^4.0.0", - "rollup": "^3.27.0", - "rollup-plugin-dts": "^6.0.0", - "rollup-plugin-license": "^3.0.1", + "rollup": "^4.9.1", + "rollup-plugin-dts": "^6.1.0", + "rollup-plugin-license": "^3.2.0", "trim-newlines": "^5.0.0", - "tsd": "^0.28.1", - "type-fest": "^4.3.1", - "typescript": "~5.1.6", + "tsd": "^0.30.0", + "type-fest": "^4.8.3", + "typescript": "^5.3.3", "xo": "^0.56.0", "yargs-parser": "^21.1.1" }, diff --git a/rollup.config.js b/rollup.config.js index 39f5760..db0976e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -44,7 +44,7 @@ const config = defineConfig({ moduleSideEffects: 'no-external', }, plugins: [ - nodeResolve(), + nodeResolve({exportConditions: ['node']}), commonjs({ include: 'node_modules/**', }), diff --git a/source/options.js b/source/options.js index 05169ef..2c7d5cd 100644 --- a/source/options.js +++ b/source/options.js @@ -1,7 +1,7 @@ import process from 'node:process'; import {dirname} from 'node:path'; import {fileURLToPath} from 'node:url'; -import {readPackageUpSync} from 'read-pkg-up'; +import {readPackageUpSync} from 'read-package-up'; import {decamelizeFlagKey, joinFlagKeys} from './utils.js'; const validateOptions = options => { From a7bdf6e771d4614281107fba1520d5a86f48c654 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 22 Dec 2023 21:15:12 +0100 Subject: [PATCH 4/7] 13.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4be0556..4e32da3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meow", - "version": "12.1.1", + "version": "13.0.0", "description": "CLI app helper", "license": "MIT", "repository": "sindresorhus/meow", From 99fe7a601c375ee1d070ef80b1664424b669238b Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 4 Jan 2024 08:45:03 +0700 Subject: [PATCH 5/7] Remove `hardRejection` option Fixes #250 --- package.json | 2 -- readme.md | 7 ------- source/index.d.ts | 2 ++ source/index.js | 6 ------ source/options.js | 1 - test-d/build.test-d.ts | 4 ++-- 6 files changed, 4 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 4e32da3..7a79802 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,6 @@ "camelcase-keys", "decamelize", "decamelize-keys", - "hard-rejection", "minimist-options", "normalize-package-data", "read-package-up", @@ -73,7 +72,6 @@ "delete_comments": "^0.0.2", "execa": "^8.0.1", "globby": "^14.0.0", - "hard-rejection": "^2.1.0", "indent-string": "^5.0.0", "minimist-options": "4.1.0", "normalize-package-data": "^6.0.0", diff --git a/readme.md b/readme.md index d6a9eeb..6e6146f 100644 --- a/readme.md +++ b/readme.md @@ -285,13 +285,6 @@ const cli = meow(` */ ``` -##### hardRejection - -Type: `boolean`\ -Default: `true` - -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. - ##### allowUnknownFlags Type `boolean`\ diff --git a/source/index.d.ts b/source/index.d.ts index b7c240b..427e1ae 100644 --- a/source/index.d.ts +++ b/source/index.d.ts @@ -294,9 +294,11 @@ export type Options = { // eslint-disable-next-line @typescript-eslint/ban-types readonly booleanDefault?: boolean | null | undefined; + // TODO: Remove this in meow 14. /** 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. + @deprecated This is the default behavior since Node.js 16, so this option is moot. @default true */ readonly hardRejection?: boolean; diff --git a/source/index.js b/source/index.js index 3bc1865..e71aaad 100644 --- a/source/index.js +++ b/source/index.js @@ -3,7 +3,6 @@ import parseArguments from 'yargs-parser'; import camelCaseKeys from 'camelcase-keys'; import {trimNewlines} from 'trim-newlines'; import redent from 'redent'; -import hardRejection from 'hard-rejection'; import normalizePackageData from 'normalize-package-data'; import {buildOptions} from './options.js'; import {buildParserOptions} from './parser.js'; @@ -89,11 +88,6 @@ const buildResult = (options, parserOptions) => { const meow = (helpText, options = {}) => { const parsedOptions = buildOptions(helpText, options); - - if (parsedOptions.hardRejection) { - hardRejection(); - } - const parserOptions = buildParserOptions(parsedOptions); const result = buildResult(parsedOptions, parserOptions); diff --git a/source/options.js b/source/options.js index 2c7d5cd..8a331cf 100644 --- a/source/options.js +++ b/source/options.js @@ -78,7 +78,6 @@ export const buildOptions = (helpText, options) => { autoHelp: true, autoVersion: true, booleanDefault: false, - hardRejection: true, allowUnknownFlags: true, allowParentFlags: true, ...options, diff --git a/test-d/build.test-d.ts b/test-d/build.test-d.ts index ca9d8ee..29ec7de 100644 --- a/test-d/build.test-d.ts +++ b/test-d/build.test-d.ts @@ -7,7 +7,7 @@ type AnyFlag = NonNullable[0]>['flags']>[str const importMeta = import.meta; expectType>(meow('Help text')); -expectType>(meow('Help text', {importMeta, hardRejection: false})); +expectType>(meow('Help text', {importMeta})); expectAssignable<{flags: {foo: number}}>( meow({importMeta: import.meta, flags: {foo: {type: 'number', isRequired: true}}}), ); @@ -49,7 +49,7 @@ expectType>(meow({importMeta, inferType: true})); expectType>(meow({importMeta, booleanDefault: true})); expectType>(meow({importMeta, booleanDefault: null})); expectType>(meow({importMeta, booleanDefault: undefined})); -expectType>(meow({importMeta, hardRejection: false})); +expectType>(meow({importMeta})); const result = meow('Help text', { importMeta, From 4f0fecae0f16e31fb00dbb58d9d7949687381860 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 4 Jan 2024 08:45:28 +0700 Subject: [PATCH 6/7] Meta tweaks --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7a79802..2a9b3da 100644 --- a/package.json +++ b/package.json @@ -78,12 +78,12 @@ "read-package-up": "^11.0.0", "read-pkg": "^9.0.1", "redent": "^4.0.0", - "rollup": "^4.9.1", + "rollup": "^4.9.2", "rollup-plugin-dts": "^6.1.0", "rollup-plugin-license": "^3.2.0", "trim-newlines": "^5.0.0", - "tsd": "^0.30.0", - "type-fest": "^4.8.3", + "tsd": "^0.30.3", + "type-fest": "^4.9.0", "typescript": "^5.3.3", "xo": "^0.56.0", "yargs-parser": "^21.1.1" From fd0bc62ce47781e11da506b8e38e8668eb78a584 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 4 Jan 2024 08:48:33 +0700 Subject: [PATCH 7/7] 13.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a9b3da..ae8cb49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meow", - "version": "13.0.0", + "version": "13.1.0", "description": "CLI app helper", "license": "MIT", "repository": "sindresorhus/meow",