From 89219d906f3d50a2a7072f410e080c9e7ca939ec Mon Sep 17 00:00:00 2001 From: zan mlakar Date: Wed, 7 Oct 2026 19:41:23 +0200 Subject: [PATCH] fix: support single-dash boolean negation without short option groups --- lib/yargs-parser.ts | 4 +++- test/yargs-parser.mjs | 56 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/lib/yargs-parser.ts b/lib/yargs-parser.ts index 48a2d0f2..15f77bda 100644 --- a/lib/yargs-parser.ts +++ b/lib/yargs-parser.ts @@ -109,7 +109,9 @@ export class YargsParser { keys: [] } const negative = /^-([0-9]+(\.[0-9]+)?|\.[0-9]+)$/ - const negatedBoolean = new RegExp('^--' + configuration['negation-prefix'] + '(.+)') + const negatedBoolean = new RegExp( + (configuration['short-option-groups'] ? '^--' : '^--?') + configuration['negation-prefix'] + '(.+)' + ) ;([] as ArrayOption[]).concat(opts.array || []).filter(Boolean).forEach(function (opt) { const key = typeof opt === 'object' ? opt.key : opt diff --git a/test/yargs-parser.mjs b/test/yargs-parser.mjs index 4c692375..76b0df8e 100644 --- a/test/yargs-parser.mjs +++ b/test/yargs-parser.mjs @@ -2530,6 +2530,62 @@ describe('yargs-parser', function () { }) describe('boolean negation', function () { + it('negates single-dash long options when short option groups are disabled', function () { + const parsed = parser(['-no-window'], { + configuration: { 'short-option-groups': false } + }) + + expect(parsed.window).to.equal(false) + expect(parsed['no-window']).to.equal(undefined) + }) + + it('uses the custom negation prefix for single-dash long options', function () { + const parsed = parser(['-without-window'], { + configuration: { + 'short-option-groups': false, + 'negation-prefix': 'without-' + } + }) + + expect(parsed.window).to.equal(false) + }) + + it('recognizes known single-dash negated options with aliases and arrays', function () { + const parsed = parser(['-no-window', '-no-unknown'], { + boolean: ['window'], + array: ['window'], + alias: { window: 'w' }, + configuration: { + 'short-option-groups': false, + 'unknown-options-as-args': true + } + }) + + expect(parsed.window).to.deep.equal([false]) + expect(parsed.w).to.deep.equal([false]) + expect(parsed._).to.deep.equal(['-no-unknown']) + }) + + it('respects disabled boolean negation for single-dash long options', function () { + const parsed = parser(['-no-window'], { + configuration: { + 'short-option-groups': false, + 'boolean-negation': false + } + }) + + expect(parsed['no-window']).to.equal(true) + expect(parsed.window).to.equal(undefined) + }) + + it('preserves short option groups for arguments resembling negated options', function () { + const parsed = parser(['-no-x']) + + expect(parsed.n).to.equal(true) + expect(parsed.o).to.equal('-x') + expect(parsed.x).to.equal(undefined) + }) + it('does not negate arguments prefixed with --no-', function () { const parsed = parser(['--no-dice'], { configuration: {