Beispiel
commander 15.0.0: Configure Option.preset alongside Option.default to prevent bare optional option flags from resolving to boolean true and bypassing custom argParser
Verifiziertes Beispiel für npm commander 15.0.0: Configure Option.preset alongside Option.default to prevent bare optional option flags from resolving to…
sha256:9ed29f29e55e4074676913ca3bb9009038881ff559b26efc27a6df45e0d7e648
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 3
- Signaturschlüssel, die es gebaut haben
- 3
Deklarierte Umgebung
node linux x64 node node npm
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-16 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-09-08 |
Fall
HOW- Ziel
- Configure Option.preset alongside Option.default to prevent bare optional option flags from resolving to boolean true and bypassing custom argParser
- Pakete
- Symbole
-
- Option.preset
- Option.default
- Option.argParser
- Option.conflicts
- Command.getOptionValueSource
- Command
- Option
- Umgebung
- node
- Erstellt
- 2026-08-16T16:15:21Z
Contract
- Passing an option with optional argument without a value sets its parsed option value to boolean true and skips argParser unless Option.preset() is configured.
- assert omitted option with optional argument evaluates to Option.default() with source 'default'
- assert Option.preset() supplies the fallback value and invokes argParser when an optional argument flag is passed bare
- assert explicit CLI argument overrides Option.preset() with source 'cli'
- assert getOptionValueSource() distinguishes between 'cli', 'env', and 'default' sources
- assert Option.conflicts() rejects mutually exclusive flags with CommanderError code commander.conflictingOption
Dateien
- NOTES.md
- csx.json
- package-lock.json
- package.json
- src/index.mjs
- test/contract.mjs
Quelltext
# Notes on Commander Option.preset vs Option.default and Option.conflicts
## What search_known_solution answered
`search_known_solution` returned existing samples `sha256:05e524cd641f3e66c380604099a1c591c4fbe976012949d4819b1f3ec255ed9f` (subcommand action argument unpacking, `optsWithGlobals`, `--no-` prefix handling, and `parseInt` radix traps), `sha256:b953db7ef30e702f31dca9192e6ef548a50589157551d3ada4896bd8624d6d8d` (boolean environment variable parsing), and `sha256:e9734b35dd9bf261570327aa6767cba61b29225dbb1b6eebc59d47cb344f1141` (paired boolean option defaults). This sample demonstrates a different trap: the behavioral divergence between `Option.default()` and `Option.preset()` on options with optional value parameters (`[value]`), custom `argParser` bypass on bare flags, option provenance tracking with `getOptionValueSource()`, and mutual exclusion enforcement with `Option.conflicts()`.
## What a model would write instead
A model configuring an option with an optional argument like `new Option('-c, --config [path]').default('config.json')` assumes `.default()` supplies the fallback filepath when the flag is passed without an argument (`--config`), expecting `opts().config` to always resolve to a string and custom `argParser` callbacks to always parse the value into the expected domain type.
## How the wrong version fails
It fails silently with a green build in loose tests because `opts().config` evaluates to boolean `true` when `--config` is passed without an argument, bypassing `argParser` and causing downstream code like path resolution or file reading to crash at runtime with `TypeError: The "path" argument must be of type string. Received boolean (true)`.
{"case":{"believed":"Calling Option.default() on an option with an optional value argument defines the fallback string when the flag is passed without a parameter.","caseId":"case:sha256:c165515ac936330897aa853a78d22deb085c394c0f8b65a4be42c80326f77d73","contract":["Passing an option with optional argument without a value sets its parsed option value to boolean true and skips argParser unless Option.preset() is configured.","assert omitted option with optional argument evaluates to Option.default() with source 'default'","assert Option.preset() supplies the fallback value and invokes argParser when an optional argument flag is passed bare","assert explicit CLI argument overrides Option.preset() with source 'cli'","assert getOptionValueSource() distinguishes between 'cli', 'env', and 'default' sources","assert Option.conflicts() rejects mutually exclusive flags with CommanderError code commander.conflictingOption"],"goal":"Configure Option.preset alongside Option.default to prevent bare optional option flags from resolving to boolean true and bypassing custom argParser","kind":"HOW","packages":["pkg:npm/commander@15.0.0"],"schemaVersion":1,"symbols":["Option.preset","Option.default","Option.argParser","Option.conflicts","Command.getOptionValueSource","Command","Option"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/commander@15.0.0"],"schemaVersion":1,"symbols":["Option.preset","Option.default","Option.argParser","Option.conflicts","Command.getOptionValueSource","Command","Option"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-commander-preset-default-traps",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-commander-preset-default-traps",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"commander": "15.0.0"
}
},
"node_modules/commander": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz",
"integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==",
"license": "MIT",
"engines": {
"node": ">=22.12.0"
}
}
}
}
{
"name": "sample-commander-preset-default-traps",
"version": "1.0.0",
"private": true,
"type": "module",
"license": "MIT-0",
"dependencies": {
"commander": "15.0.0"
}
}
import { Command, Option } from 'commander';
/**
* Creates a CLI command demonstrating the distinction between Option.default()
* and Option.preset() for options with optional arguments ([value]).
*
* When an option defines an optional argument (e.g., `-c, --config [path]`):
* - `.default(val)` applies ONLY when the option flag is omitted entirely.
* - Passing `--config` without a parameter evaluates to boolean `true` (skipping `argParser`)
* UNLESS `.preset(val)` is explicitly configured.
* - `.preset(val)` defines the value used when the flag is specified without an argument.
*
* @param {Object} [options]
* @param {boolean} [options.usePreset=false] - Whether to configure Option.preset()
* @param {string} [options.defaultVal='default.json'] - Default value when flag is omitted
* @param {string} [options.presetVal='preset.json'] - Preset value when flag is passed bare
* @returns {Command}
*/
export function createConfigCli({
usePreset = false,
defaultVal = 'default.json',
presetVal = 'preset.json',
} = {}) {
const program = new Command();
program
.name('config-cli')
.exitOverride()
.configureOutput({ writeErr: () => {} });
const configOpt = new Option('-c, --config [path]', 'configuration file path')
.default(defaultVal);
if (usePreset) {
configOpt.preset(presetVal);
}
program.addOption(configOpt);
return program;
}
/**
* Creates a CLI command demonstrating custom argument parsing with optional values.
* Without `.preset()`, passing `-p` bare assigns boolean `true` and bypasses `argParser`.
* With `.preset('3000')`, passing `-p` bare passes `'3000'` through `argParser`, returning `3000`.
*
* @param {Object} [options]
* @param {boolean} [options.usePreset=false]
* @returns {Command}
*/
export function createPortCli({ usePreset = false } = {}) {
const program = new Command();
program
.name('port-cli')
.exitOverride()
.configureOutput({ writeErr: () => {} });
const portOpt = new Option('-p, --port [number]', 'server port')
.default(8080)
.argParser((val) => parseInt(val, 10));
if (usePreset) {
portOpt.preset('3000');
}
program.addOption(portOpt);
return program;
}
/**
* Creates a CLI command demonstrating Option.conflicts() mutual exclusion.
*
* @returns {Command}
*/
export function createConflictCli() {
const program = new Command();
program
.name('output-cli')
.exitOverride()
.configureOutput({ writeErr: () => {} });
program
.addOption(new Option('-s, --silent', 'suppress output').conflicts('verbose'))
.addOption(new Option('-v, --verbose', 'detailed output'));
return program;
}
import { strict as assert } from 'node:assert';
import { CommanderError } from 'commander';
import { createConfigCli, createPortCli, createConflictCli } from '../src/index.mjs';
// --- Trap 1: Optional Option Argument without Preset Yields Boolean true ---
// Contradiction of believed: developers assume .default('default.json') sets the value
// when '--config' is supplied without an argument.
// In reality, Commander sets opts().config = true (boolean) and getOptionValueSource() = 'cli'.
const naiveCli = createConfigCli({ usePreset: false, defaultVal: 'default.json' });
naiveCli.parse(['--config'], { from: 'user' });
assert.strictEqual(
typeof naiveCli.opts().config,
'boolean',
'passing --config without argument sets value to boolean type, not string default'
);
assert.strictEqual(
naiveCli.opts().config,
true,
'passing --config without argument evaluates to boolean true when preset is absent'
);
assert.strictEqual(
naiveCli.getOptionValueSource('config'),
'cli',
'option source is cli when flag is supplied on command line'
);
// --- Trap 2: Option.default() Applies ONLY when Flag is Completely Omitted ---
const omittedCli = createConfigCli({ usePreset: false, defaultVal: 'default.json' });
omittedCli.parse([], { from: 'user' });
assert.strictEqual(
omittedCli.opts().config,
'default.json',
'omitted option resolves to default string value'
);
assert.strictEqual(
omittedCli.getOptionValueSource('config'),
'default',
'omitted option source is default'
);
// --- Trap 3: Option.preset() Correctly Supplies Fallback for Bare Flags ---
const presetCli = createConfigCli({
usePreset: true,
defaultVal: 'default.json',
presetVal: 'preset.json',
});
presetCli.parse(['--config'], { from: 'user' });
assert.strictEqual(
presetCli.opts().config,
'preset.json',
'Option.preset() supplies fallback string when flag is passed without argument'
);
assert.strictEqual(
presetCli.getOptionValueSource('config'),
'cli',
'option source with preset flag is cli'
);
// --- Trap 4: Explicit CLI Argument Overrides Preset ---
const explicitCli = createConfigCli({
usePreset: true,
defaultVal: 'default.json',
presetVal: 'preset.json',
});
explicitCli.parse(['--config', 'custom.json'], { from: 'user' });
assert.strictEqual(
explicitCli.opts().config,
'custom.json',
'explicit argument overrides preset value'
);
assert.strictEqual(
explicitCli.getOptionValueSource('config'),
'cli',
'explicit argument option source is cli'
);
// --- Trap 5: Custom argParser Bypass on Bare Flag vs Preset Execution ---
// Without preset: bare -p sets port to boolean true, bypassing argParser
const naivePortCli = createPortCli({ usePreset: false });
naivePortCli.parse(['-p'], { from: 'user' });
assert.strictEqual(
naivePortCli.opts().port,
true,
'bare optional flag without preset bypasses argParser and evaluates to boolean true'
);
// With preset: bare -p runs preset string through argParser to produce integer 3000
const presetPortCli = createPortCli({ usePreset: true });
presetPortCli.parse(['-p'], { from: 'user' });
assert.strictEqual(
presetPortCli.opts().port,
3000,
'Option.preset() passes preset string to custom argParser yielding parsed number'
);
// --- Trap 6: Mutual Exclusion via Option.conflicts() ---
const conflictCli = createConflictCli();
assert.throws(
() => conflictCli.parse(['--silent', '--verbose'], { from: 'user' }),
(err) =>
err instanceof CommanderError &&
err.code === 'commander.conflictingOption' &&
err.message.includes("cannot be used with option '-v, --verbose'"),
'Option.conflicts() rejects mutually exclusive flags with CommanderError commander.conflictingOption'
);
console.log('CONTRACT PASS: Option.preset vs Option.default, argParser execution, and Option.conflicts verified');