Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const config = {
export default {
// plugins: ['prettier-plugin-jsdoc'],
singleQuote: true,
overrides: [
Expand All @@ -8,5 +8,3 @@ const config = {
},
],
};

module.exports = config;
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)

Expand Down
12 changes: 6 additions & 6 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -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,
{
Expand Down
2 changes: 0 additions & 2 deletions esm.d.mts

This file was deleted.

16 changes: 0 additions & 16 deletions esm.mjs

This file was deleted.

4 changes: 2 additions & 2 deletions examples/assemble.ts
Original file line number Diff line number Diff line change
@@ -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().

Expand Down
24 changes: 1 addition & 23 deletions index.js
Original file line number Diff line number Diff line change
@@ -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';
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 .",
Expand All @@ -24,14 +24,13 @@
"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"
},
Expand Down
2 changes: 1 addition & 1 deletion tests/arguments.test-d.ts
Original file line number Diff line number Diff line change
@@ -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();
Expand Down
2 changes: 1 addition & 1 deletion tests/assignment.test-d.ts
Original file line number Diff line number Diff line change
@@ -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'
{
Expand Down
2 changes: 1 addition & 1 deletion tests/command-unknown-opts.test-d.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
2 changes: 1 addition & 1 deletion tests/commander.test-d.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/create-argument.test-d.ts
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
2 changes: 1 addition & 1 deletion tests/create-option.test-d.ts
Original file line number Diff line number Diff line change
@@ -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.

Expand Down
2 changes: 1 addition & 1 deletion tests/help.test-d.ts
Original file line number Diff line number Diff line change
@@ -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.
//
Expand Down
2 changes: 1 addition & 1 deletion tests/hook.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expectType } from 'tsd';
import { Command } from '..';
import { Command } from '../index.js';

// 'when add preAction hook then thisCommand strongly typed'
{
Expand Down
2 changes: 1 addition & 1 deletion tests/literal-unions.test-d.ts
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/option-value.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expectType } from 'tsd';
import { Command } from '..';
import { Command } from '../index.js';

// 'when getOptionValue is unknown then key is unknown'
{
Expand Down
2 changes: 1 addition & 1 deletion tests/options.test-d.ts
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
2 changes: 1 addition & 1 deletion tests/processed-args.test-d.ts
Original file line number Diff line number Diff line change
@@ -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

Expand Down
2 changes: 1 addition & 1 deletion tests/subclass.test-d.ts
Original file line number Diff line number Diff line change
@@ -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<Usage extends string = ''> extends Option<Usage> {
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6"],
"module": "nodenext",
"lib": ["ESNext"],
"types": ["node"],
"noImplicitAny": true,
"noImplicitThis": true,
Expand Down
Loading