diff --git a/packages/aws-cdk/lib/cli/util/check-unknown-options.ts b/packages/aws-cdk/lib/cli/util/check-unknown-options.ts index dc86eb1f8..261ad4514 100644 --- a/packages/aws-cdk/lib/cli/util/check-unknown-options.ts +++ b/packages/aws-cdk/lib/cli/util/check-unknown-options.ts @@ -30,6 +30,16 @@ function collectKnownOptions(optionDefs: Record): Set { /** Pre-computed set of known global options (static, doesn't depend on argv) */ const globalKnownOptions = collectKnownOptions(config.globalOptions); +/** Reverse mapping from command alias to canonical command name */ +const commandAliasMap = new Map(); +for (const [name, def] of Object.entries(config.commands)) { + if (def.aliases) { + for (const alias of def.aliases) { + commandAliasMap.set(alias, name); + } + } +} + /** yargs internal keys that are always present in argv */ const yargsInternals = new Set(['_', '$0', 'help', 'h', 'version']); @@ -43,20 +53,24 @@ const yargsInternals = new Set(['_', '$0', 'help', 'h', 'version']); */ export function findUnknownOptions(argv: any): string[] { const command = argv._[0]; + const canonicalCommand = commandAliasMap.get(command) ?? command; - const commandDef = config.commands[command]; + const commandDef = config.commands[canonicalCommand]; const commandKnownOptions = commandDef?.options ? collectKnownOptions(commandDef.options) : new Set(); - const positionalArg = commandDef?.arg?.name; + const positionalArgRaw = commandDef?.arg?.name; + const positionalArgs = positionalArgRaw + ? new Set([positionalArgRaw, positionalArgRaw.toLowerCase()]) + : new Set(); const unknown: string[] = []; for (const key of Object.keys(argv)) { if (argv[key] === undefined) { continue; } - if (yargsInternals.has(key) || key === positionalArg) { + if (yargsInternals.has(key) || positionalArgs.has(key)) { continue; } if (globalKnownOptions.has(key) || commandKnownOptions.has(key)) { diff --git a/packages/aws-cdk/test/cli/util/check-unknown-options.test.ts b/packages/aws-cdk/test/cli/util/check-unknown-options.test.ts index b00c01c66..10f6926a9 100644 --- a/packages/aws-cdk/test/cli/util/check-unknown-options.test.ts +++ b/packages/aws-cdk/test/cli/util/check-unknown-options.test.ts @@ -93,6 +93,39 @@ describe('findUnknownOptions', () => { } }); + test('resolves command aliases to canonical names (e.g. ls -> list)', () => { + const argv = { + '_': ['ls'], + '$0': 'cdk', + 'long': true, + 'l': true, + 'showDependencies': false, + 'show-dependencies': false, + 'd': false, + }; + expect(findUnknownOptions(argv)).toEqual([]); + }); + + test('does not report positional args (both original case and lowercase)', () => { + const argv = { + _: ['ack'], + $0: 'cdk', + ID: 12345, + id: 12345, + }; + expect(findUnknownOptions(argv)).toEqual([]); + }); + + test('resolves synth alias (synthesize -> synth)', () => { + const argv = { + _: ['synthesize'], + $0: 'cdk', + exclusively: true, + e: true, + }; + expect(findUnknownOptions(argv)).toEqual([]); + }); + test('still reports truly unknown options even when CDK_ env vars exist', () => { process.env.CDK_INTEG_ATMOSPHERE_POOL = 'test-pool'; try {