diff --git a/.prettierrc.js b/.prettierrc.js index dc0a3dc..a33a32d 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,4 +1,4 @@ -const config = { +export default { // plugins: ['prettier-plugin-jsdoc'], singleQuote: true, overrides: [ @@ -8,5 +8,3 @@ const config = { }, ], }; - -module.exports = config; diff --git a/CHANGELOG.md b/CHANGELOG.md index 713a770..6e781fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ The version numbering does not follow semantic versioning but instead aligns wit ## [15.0.0] (2026-05-29) +`@commander-js/extra-typings` 15 is ESM only. This is expected to be seamless for ESM consumers, but some CommonJS consumers may hit issues with tooling requiring configuration for ESM-only dependencies. See Migration Tips below. + +The release of `@commander-js/extra-typings` 15 moves version 14 into maintenance. `@commander-js/extra-typings` 14 will get security updates for +12 months (to May 2027). For more info see [Release Policy](./docs/release-policy.md). + ### Added - [Release Policy document](./docs/release-policy.md) @@ -20,6 +25,17 @@ The version numbering does not follow semantic versioning but instead aligns wit - *Breaking:* peer dependency on Commander 15.0.x which requires Node.js 22.12 or higher - update dependencies - old major versions now supported for 12 months instead of just previous major version, to give predictable end-of-life date +- now reexporting the global `program` singleton from Commander rather than creating a separate one + +### Migration Tips + +`@commander-js/extra-typings` 15 is ESM only, but this does not mean you need to migrate to ESM to use it. Importing ESM from CommonJS is +supported by Node.js, and Bun, Deno, and TypeScript. Hopefully it Just Works for you! However, you may be using a different runtime or +some other part of your setup that may not yet natively support importing ESM from CommonJS, such as your testing framework +or bundler. + +If you have problems using `@commander-js/extra-typings` 15 in your environment, one option is stay on version 14 for now. `@commander-js/extra-typings` 14 will +get security updates until May 2027 and things will hopefully improve for your setup in the meantime. ## [14.0.0] (2025-05-18) diff --git a/eslint.config.js b/eslint.config.js index 91fb952..bb0c3d6 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,14 +1,14 @@ -const globals = require('globals'); -const esLintjs = require('@eslint/js'); -const { defineConfig } = require('eslint/config'); -const tseslint = require('typescript-eslint'); -const eslintConfigPrettier = require('eslint-config-prettier/flat'); +import globals from 'globals'; +import esLintjs from '@eslint/js'; +import { defineConfig } from 'eslint/config'; +import tseslint from 'typescript-eslint'; +import eslintConfigPrettier from 'eslint-config-prettier'; // Simpler setup than in Commander as not running TypeScript over .js files. const tsconfigTsFiles = ['**/*.{ts,mts}']; // Using tseslint.config adds some type safety and `extends` to simplify customising config array. -module.exports = defineConfig( +export default defineConfig( // Add recommended rules. esLintjs.configs.recommended, { diff --git a/esm.d.mts b/esm.d.mts deleted file mode 100644 index 4b5c693..0000000 --- a/esm.d.mts +++ /dev/null @@ -1,2 +0,0 @@ -// Just reexport the types from cjs definition file. -export * from './index.js'; diff --git a/esm.mjs b/esm.mjs deleted file mode 100644 index cfb03d5..0000000 --- a/esm.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import extraTypingsCommander from './index.js'; - -// wrapper to provide named exports for ESM. -export const { - program, - createCommand, - createArgument, - createOption, - CommanderError, - InvalidArgumentError, - InvalidOptionArgumentError, // deprecated old name - Command, - Argument, - Option, - Help, -} = extraTypingsCommander; diff --git a/examples/assemble.ts b/examples/assemble.ts index 15bd899..a0767ac 100644 --- a/examples/assemble.ts +++ b/examples/assemble.ts @@ -1,5 +1,5 @@ -import { createProgram, type ProgramOpts } from './assemble-program'; -import { createSub, type SubOpts } from './assemble-sub'; +import { createProgram, type ProgramOpts } from './assemble-program.js'; +import { createSub, type SubOpts } from './assemble-sub.js'; // Example of strongly typed globals in a subcommand which is added to program using .addCommand(). diff --git a/index.js b/index.js index 09d0b3b..a343051 100644 --- a/index.js +++ b/index.js @@ -1,23 +1 @@ -const commander = require('commander'); - -exports = module.exports = {}; - -// Return a different global program than commander, -// and don't also return it as default export. -exports.program = new commander.Command(); - -/** - * Expose classes. The FooT versions are just types, so return Commander original implementations! - */ - -exports.Argument = commander.Argument; -exports.Command = commander.Command; -exports.CommanderError = commander.CommanderError; -exports.Help = commander.Help; -exports.InvalidArgumentError = commander.InvalidArgumentError; -exports.InvalidOptionArgumentError = commander.InvalidArgumentError; // Deprecated -exports.Option = commander.Option; - -exports.createCommand = commander.createCommand; -exports.createOption = commander.createOption; -exports.createArgument = commander.createArgument; +export * from 'commander'; diff --git a/package.json b/package.json index 5139bb7..a9caec8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@commander-js/extra-typings", "version": "15.0.0", "description": "Infer strong typings for commander options and action handlers", - "main": "index.js", + "main": "./index.js", "scripts": { "check": "npm run check:type && npm run check:lint && npm run check:format", "check:format": "prettier --check .", @@ -19,19 +19,16 @@ "url": "git+https://github.com/commander-js/extra-typings.git" }, "files": [ - "esm.mjs", - "esm.d.mts", "index.js", "index.d.ts" ], - "type": "commonjs", + "type": "module", "exports": { ".": { - "require": "./index.js", - "import": "./esm.mjs" + "types": "./index.d.ts", + "default": "./index.js" } }, - "types": "index.d.ts", "tsd": { "directory": "tests" }, diff --git a/tests/arguments.test-d.ts b/tests/arguments.test-d.ts index f8ece0d..a48830e 100644 --- a/tests/arguments.test-d.ts +++ b/tests/arguments.test-d.ts @@ -1,5 +1,5 @@ import { expectType, expectAssignable } from 'tsd'; -import { Command, Argument, OptionValues } from '..'; +import { Command, Argument, OptionValues } from '../index.js'; // Reusing same program variable through tests for convenience. const program = new Command(); diff --git a/tests/assignment.test-d.ts b/tests/assignment.test-d.ts index 1c2a155..e468e82 100644 --- a/tests/assignment.test-d.ts +++ b/tests/assignment.test-d.ts @@ -1,5 +1,5 @@ import { expectAssignable, expectNotAssignable } from 'tsd'; -import { Command, CommandUnknownOpts, Option } from '..'; +import { Command, CommandUnknownOpts, Option } from '../index.js'; // 'when assign Command to CommandUnknownOpts then no error' { diff --git a/tests/command-unknown-opts.test-d.ts b/tests/command-unknown-opts.test-d.ts index a8acb00..2a8604d 100644 --- a/tests/command-unknown-opts.test-d.ts +++ b/tests/command-unknown-opts.test-d.ts @@ -1,4 +1,4 @@ -import { Command, CommandUnknownOpts } from '..'; +import { Command, CommandUnknownOpts } from '../index.js'; import { expectType } from 'tsd'; // Fallback location for CommandUnknownOpts if not better file for the test. diff --git a/tests/commander.test-d.ts b/tests/commander.test-d.ts index 58d72e9..01c17f8 100644 --- a/tests/commander.test-d.ts +++ b/tests/commander.test-d.ts @@ -1,4 +1,4 @@ -import * as commander from '../index'; +import * as commander from '../index.js'; import { expectType, expectAssignable } from 'tsd'; // This is a copy of the TypeScript tests in Commander to see diff --git a/tests/create-argument.test-d.ts b/tests/create-argument.test-d.ts index de4a904..4b29936 100644 --- a/tests/create-argument.test-d.ts +++ b/tests/create-argument.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command, createArgument } from '..'; +import { Command, createArgument } from '../index.js'; // Doing end-to-end test, rather than checking created Argument directly. diff --git a/tests/create-option.test-d.ts b/tests/create-option.test-d.ts index 4f9a07d..6e5bfe0 100644 --- a/tests/create-option.test-d.ts +++ b/tests/create-option.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command, createOption } from '..'; +import { Command, createOption } from '../index.js'; // Doing end-to-end test, rather than checking created Option directly. diff --git a/tests/help.test-d.ts b/tests/help.test-d.ts index 5381ad8..8654086 100644 --- a/tests/help.test-d.ts +++ b/tests/help.test-d.ts @@ -1,5 +1,5 @@ import { expectType, expectAssignable } from 'tsd'; -import { Help, Command, CommandUnknownOpts, Option } from '..'; +import { Help, Command, CommandUnknownOpts, Option } from '../index.js'; // Still exploring when to use Command/CommandUnknownOpts in Help. // diff --git a/tests/hook.test-d.ts b/tests/hook.test-d.ts index b5ada23..107f494 100644 --- a/tests/hook.test-d.ts +++ b/tests/hook.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command } from '..'; +import { Command } from '../index.js'; // 'when add preAction hook then thisCommand strongly typed' { diff --git a/tests/literal-unions.test-d.ts b/tests/literal-unions.test-d.ts index a181c34..04ec9a4 100644 --- a/tests/literal-unions.test-d.ts +++ b/tests/literal-unions.test-d.ts @@ -1,5 +1,5 @@ import { expectType, expectAssignable } from 'tsd'; -import { Command, Option, OptionValues } from '..'; +import { Command, Option, OptionValues } from '../index.js'; const program = new Command(); program.setOptionValueWithSource('key', 'value', 'cli'); // expected source used by Commander diff --git a/tests/option-value.test-d.ts b/tests/option-value.test-d.ts index 912b4f1..e3879db 100644 --- a/tests/option-value.test-d.ts +++ b/tests/option-value.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command } from '..'; +import { Command } from '../index.js'; // 'when getOptionValue is unknown then key is unknown' { diff --git a/tests/options.test-d.ts b/tests/options.test-d.ts index 369695b..c7353db 100644 --- a/tests/options.test-d.ts +++ b/tests/options.test-d.ts @@ -1,5 +1,5 @@ import { expectType, expectAssignable } from 'tsd'; -import { Command, Option, OptionValues } from '..'; +import { Command, Option, OptionValues } from '../index.js'; function myParseInt(arg: string, previous: number): number { return parseInt(arg); diff --git a/tests/processed-args.test-d.ts b/tests/processed-args.test-d.ts index 08e873e..c69903f 100644 --- a/tests/processed-args.test-d.ts +++ b/tests/processed-args.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command } from '..'; +import { Command } from '../index.js'; // Doing a subset of the full tests in arguments.test-d.ts diff --git a/tests/subclass.test-d.ts b/tests/subclass.test-d.ts index 4aaf181..34ae357 100644 --- a/tests/subclass.test-d.ts +++ b/tests/subclass.test-d.ts @@ -1,5 +1,5 @@ import { expectType } from 'tsd'; -import { Command, Option } from '..'; +import { Command, Option } from '../index.js'; // Breaking: need to add type parameter for use in super constructor class MyOption extends Option { diff --git a/tsconfig.json b/tsconfig.json index 39dd1fc..615067d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "module": "commonjs", - "lib": ["es6"], + "module": "nodenext", + "lib": ["ESNext"], "types": ["node"], "noImplicitAny": true, "noImplicitThis": true,