feat: per-command configs via INI [section] syntax#9223
Conversation
| if (!hasOwnProperty(conf.raw, commandName)) { | ||
| conf.raw[commandName] = {} | ||
| } | ||
| conf.raw[commandName][key] = val |
There was a problem hiding this comment.
idk if we pass in the command list to config right now but we should, then we can use that as the de facto list and key off of that
| // Also update raw data | ||
| const conf = this.data.get(where) | ||
| if (hasOwnProperty(conf.raw, commandName)) { | ||
| delete conf.raw[commandName][key] |
|
These wont mesh well with the [trust] command config, meaning trust may not obey these because it parses flags differently and ignores the global config. Ideally we standardize all the old flags into the new way of doing things? |
|
| Command | Config meaning |
|---|---|
access |
Default access level for publishing |
audit |
Whether to run audit on install |
cache |
Cache directory path |
diff |
Diff options |
fund |
Whether to show fund message |
link |
Link behavior |
prefix |
Global/local prefix path |
shrinkwrap |
Whether to write shrinkwrap |
version |
Version bump behavior |
For example, this is ambiguous:
access=restricted
[access]
registry=https://registry.npmjs.org/Is [access] a config value for the access key, or a command-specific section for npm access?
Proposed solution: command- prefix
Use [command-<name>] syntax to namespace command sections:
access=restricted
[command-access]
registry=https://registry.npmjs.org/This avoids all collisions today and keeps the door open for other prefixed sections in the future (e.g. hypothetically [registry-<name>] for per-registry config).
Need to decide on this before merging — it affects the section detection logic, --command flag handling, and docs.
Alternative: Detect object values and treat as command sections regardlessAnother option is to keep the unprefixed So we could disambiguate at parse time: // ini.parse() returns:
{
"access": "restricted", // string → normal config value
"publish": { // object → command section
"registry": "https://registry.npmjs.org/"
}
}If This means the current implementation already handles it — Tradeoff:
|
Overview
Adds support for command-specific configuration in
.npmrcfiles using standard INI section syntax:Any existing npm config option can be scoped to a specific command by placing it under a
[command]section header. This is a framework-level feature — no new per-command flags need to be defined.CLI support
Precedence
Command-specific sections always beat non-sectioned values from any file layer, but env vars and CLI flags still win:
Within the command layer, file sources cascade normally (builtin < global < user < project).
Backward compatibility
inipackage has always supported[section]syntax. Old npm sees section objects as unknown config keys, emits a warning (Unknown project config "publish"), and ignores them. Sections survive save round-trips viaini.stringify(). No breakage.inipackage (v6.0.0) blocks__proto__sections.setCommandConfig/deleteCommandConfigadditionally validate against unsafe keys and usehasOwnProperty()checks.Changes
workspaces/config/lib/index.js— Core: section detection in#loadObject, newcommandconfig layer,applyCommand(),setCommandConfig(),deleteCommandConfig(),getCommandConfig()lib/npm.js— Callsconfig.applyCommand(command)after command name resolutionlib/commands/config.js—--commandflag for set/get/deleteworkspaces/config/lib/definitions/definitions.js— Newcommandconfig definitionworkspaces/config/test/index.js— 10 test cases covering parsing, precedence, save round-trip, set/get/deletedocs/lib/content/configuring-npm/npmrc.md— Documentation for[command]sectionsCloses #8261