@@ -27,18 +27,15 @@ class BaseCommand {
2727 const { aliases : cmdAliases } = require ( './utils/cmd-list' )
2828 const seenExclusive = new Set ( )
2929 const wrapWidth = 80
30- let { description, usage = [ '' ] , name, params } = this
30+ const { description, usage = [ '' ] , name } = this
3131
32- let definitionsPool = { }
32+ // Resolve to a definitions array: if the command has its own definitions, use
33+ // those directly; otherwise resolve params from the global definitions pool.
34+ let cmdDefs
3335 if ( this . definitions ) {
34- definitionsPool = { ...definitions , ...this . definitions }
35- // Auto-populate params from definitions if not explicitly set
36- if ( ! params && this . definitions ) {
37- params = Object . values ( this . definitions ) . map ( def => def . key )
38- }
39- } else {
40- // Don't mutate this.definitions - just use definitions directly
41- definitionsPool = definitions
36+ cmdDefs = this . definitions
37+ } else if ( this . params ) {
38+ cmdDefs = this . params . map ( p => definitions [ p ] ) . filter ( Boolean )
4239 }
4340
4441 // If this is a subcommand, prepend parent name
@@ -70,22 +67,22 @@ class BaseCommand {
7067 fullUsage . push ( `Run "npm ${ name } <subcommand> --help" for more info on a subcommand.` )
7168 }
7269
73- if ( params ) {
70+ if ( cmdDefs ) {
71+ const cmdDefsKeys = new Set ( cmdDefs . map ( d => d . key ) )
7472 let results = ''
7573 let line = ''
76- for ( const param of params ) {
74+ for ( const def of cmdDefs ) {
7775 /* istanbul ignore next */
78- if ( seenExclusive . has ( param ) ) {
76+ if ( seenExclusive . has ( def . key ) ) {
7977 continue
8078 }
81- const exclusive = definitionsPool [ param ] ?. exclusive
82- let paramUsage = definitionsPool [ param ] ?. usage
83- if ( exclusive ) {
79+ let paramUsage = def . usage
80+ if ( def . exclusive ) {
8481 const exclusiveParams = [ paramUsage ]
85- seenExclusive . add ( param )
86- for ( const e of exclusive ) {
82+ for ( const e of def . exclusive ) {
8783 seenExclusive . add ( e )
88- exclusiveParams . push ( definitionsPool [ e ] . usage )
84+ const eDef = cmdDefs . find ( d => d . key === e ) || definitions [ e ]
85+ exclusiveParams . push ( eDef ?. usage )
8986 }
9087 paramUsage = `${ exclusiveParams . join ( '|' ) } `
9188 }
@@ -101,18 +98,17 @@ class BaseCommand {
10198 fullUsage . push ( [ results , line ] . filter ( Boolean ) . join ( '\n' ) )
10299
103100 // Add flag descriptions
104- if ( params . length > 0 && includeDescriptions ) {
101+ if ( cmdDefs . length > 0 && includeDescriptions ) {
105102 fullUsage . push ( '' )
106- for ( const param of params ) {
107- if ( seenExclusive . has ( param ) ) {
103+ for ( const def of cmdDefs ) {
104+ if ( seenExclusive . has ( def . key ) && ! cmdDefsKeys . has ( def . key ) ) {
108105 continue
109106 }
110- const def = definitionsPool [ param ]
111- if ( def ?. description ) {
107+ if ( def . description ) {
112108 const desc = def . description . trim ( ) . split ( '\n' ) [ 0 ]
113109 const shortcuts = def . short ? `-${ def . short } |` : ''
114110 const aliases = ( def . alias || [ ] ) . map ( v => `--${ v } ` ) . join ( '|' )
115- const mainFlag = `--${ param } `
111+ const mainFlag = `--${ def . key } `
116112 const flagName = [ shortcuts , mainFlag , aliases ] . filter ( Boolean ) . join ( '|' )
117113 const requiredNote = def . required ? ' (required)' : ''
118114 fullUsage . push ( ` ${ flagName } ${ requiredNote } ` )
@@ -282,15 +278,15 @@ class BaseCommand {
282278 }
283279
284280 flags ( depth = 1 ) {
285- const commandDefinitions = this . constructor . definitions || { }
281+ const commandDefinitions = this . constructor . definitions || [ ]
286282
287283 // Build types, shorthands, and defaults from definitions
288284 const types = { }
289285 const defaults = { }
290286 const cmdShorthands = { }
291287 const aliasMap = { } // Track which aliases map to which main keys
292288
293- for ( const def of Object . values ( commandDefinitions ) ) {
289+ for ( const def of commandDefinitions ) {
294290 defaults [ def . key ] = def . default
295291 types [ def . key ] = def . type
296292
@@ -329,7 +325,7 @@ class BaseCommand {
329325 }
330326
331327 // Validate flags - only if command has definitions (new system)
332- if ( this . constructor . definitions && Object . keys ( this . constructor . definitions ) . length > 0 ) {
328+ if ( this . constructor . definitions && this . constructor . definitions . length > 0 ) {
333329 this . #validateFlags( parsed , commandDefinitions , remains )
334330 }
335331
@@ -360,7 +356,7 @@ class BaseCommand {
360356
361357 // Only include keys that are defined in commandDefinitions (main keys only)
362358 const filtered = { }
363- for ( const def of Object . values ( commandDefinitions ) ) {
359+ for ( const def of commandDefinitions ) {
364360 if ( def . key in parsed ) {
365361 filtered [ def . key ] = parsed [ def . key ]
366362 }
@@ -373,12 +369,12 @@ class BaseCommand {
373369 // Build a set of all valid flag names (global + command-specific + shorthands)
374370 const validFlags = new Set ( [
375371 ...Object . keys ( definitions ) ,
376- ...Object . keys ( commandDefinitions ) ,
372+ ...commandDefinitions . map ( d => d . key ) ,
377373 ...Object . keys ( shorthands ) , // Add global shorthands like 'verbose', 'dd', etc.
378374 ] )
379375
380376 // Add aliases to valid flags
381- for ( const def of Object . values ( commandDefinitions ) ) {
377+ for ( const def of commandDefinitions ) {
382378 if ( def . alias && Array . isArray ( def . alias ) ) {
383379 for ( const alias of def . alias ) {
384380 validFlags . add ( alias )
@@ -402,7 +398,7 @@ class BaseCommand {
402398
403399 // Remove warnings for command-specific definitions that npm's global config
404400 // doesn't know about (these were queued as "unknown" during config.load())
405- for ( const def of Object . values ( commandDefinitions ) ) {
401+ for ( const def of commandDefinitions ) {
406402 this . npm . config . removeWarning ( def . key )
407403 if ( def . alias && Array . isArray ( def . alias ) ) {
408404 for ( const alias of def . alias ) {
0 commit comments