1# `@npmcli/config` 2 3Configuration management for the npm cli. 4 5This module is the spiritual descendant of 6[`npmconf`](http://npm.im/npmconf), and the code that once lived in npm's 7`lib/config/` folder. 8 9It does the management of configuration files that npm uses, but 10importantly, does _not_ define all the configuration defaults or types, as 11those parts make more sense to live within the npm CLI itself. 12 13The only exceptions: 14 15- The `prefix` config value has some special semantics, setting the local 16 prefix if specified on the CLI options and not in global mode, or the 17 global prefix otherwise. 18- The `project` config file is loaded based on the local prefix (which can 19 only be set by the CLI config options, and otherwise defaults to a walk 20 up the folder tree to the first parent containing a `node_modules` 21 folder, `package.json` file, or `package-lock.json` file.) 22- The `userconfig` value, as set by the environment and CLI (defaulting to 23 `~/.npmrc`, is used to load user configs. 24- The `globalconfig` value, as set by the environment, CLI, and 25 `userconfig` file (defaulting to `$PREFIX/etc/npmrc`) is used to load 26 global configs. 27- A `builtin` config, read from a `npmrc` file in the root of the npm 28 project itself, overrides all defaults. 29 30The resulting hierarchy of configs: 31 32- CLI switches. eg `--some-key=some-value` on the command line. These are 33 parsed by [`nopt`](http://npm.im/nopt), which is not a great choice, but 34 it's the one that npm has used forever, and changing it will be 35 difficult. 36- Environment variables. eg `npm_config_some_key=some_value` in the 37 environment. There is no way at this time to modify this prefix. 38- INI-formatted project configs. eg `some-key = some-value` in the 39 `localPrefix` folder (ie, the `cwd`, or its nearest parent that contains 40 either a `node_modules` folder or `package.json` file.) 41- INI-formatted userconfig file. eg `some-key = some-value` in `~/.npmrc`. 42 The `userconfig` config value can be overridden by the `cli`, `env`, or 43 `project` configs to change this value. 44- INI-formatted globalconfig file. eg `some-key = some-value` in 45 the `globalPrefix` folder, which is inferred by looking at the location 46 of the node executable, or the `prefix` setting in the `cli`, `env`, 47 `project`, or `userconfig`. The `globalconfig` value at any of those 48 levels can override this. 49- INI-formatted builtin config file. eg `some-key = some-value` in 50 `/usr/local/lib/node_modules/npm/npmrc`. This is not configurable, and 51 is determined by looking in the `npmPath` folder. 52- Default values (passed in by npm when it loads this module). 53 54## USAGE 55 56```js 57const Config = require('@npmcli/config') 58const { shorthands, definitions, flatten } = require('@npmcli/config/lib/definitions') 59 60const conf = new Config({ 61 // path to the npm module being run 62 npmPath: resolve(__dirname, '..'), 63 definitions, 64 shorthands, 65 flatten, 66 // optional, defaults to process.argv 67 // argv: [] <- if you are using this package in your own cli 68 // and dont want to have colliding argv 69 argv: process.argv, 70 // optional, defaults to process.env 71 env: process.env, 72 // optional, defaults to process.execPath 73 execPath: process.execPath, 74 // optional, defaults to process.platform 75 platform: process.platform, 76 // optional, defaults to process.cwd() 77 cwd: process.cwd(), 78}) 79 80// emits log events on the process object 81// see `proc-log` for more info 82process.on('log', (level, ...args) => { 83 console.log(level, ...args) 84}) 85 86// returns a promise that fails if config loading fails, and 87// resolves when the config object is ready for action 88conf.load().then(() => { 89 conf.validate() 90 console.log('loaded ok! some-key = ' + conf.get('some-key')) 91}).catch(er => { 92 console.error('error loading configs!', er) 93}) 94``` 95 96## API 97 98The `Config` class is the sole export. 99 100```js 101const Config = require('@npmcli/config') 102``` 103 104### static `Config.typeDefs` 105 106The type definitions passed to `nopt` for CLI option parsing and known 107configuration validation. 108 109### constructor `new Config(options)` 110 111Options: 112 113- `types` Types of all known config values. Note that some are effectively 114 given semantic value in the config loading process itself. 115- `shorthands` An object mapping a shorthand value to an array of CLI 116 arguments that replace it. 117- `defaults` Default values for each of the known configuration keys. 118 These should be defined for all configs given a type, and must be valid. 119- `npmPath` The path to the `npm` module, for loading the `builtin` config 120 file. 121- `cwd` Optional, defaults to `process.cwd()`, used for inferring the 122 `localPrefix` and loading the `project` config. 123- `platform` Optional, defaults to `process.platform`. Used when inferring 124 the `globalPrefix` from the `execPath`, since this is done diferently on 125 Windows. 126- `execPath` Optional, defaults to `process.execPath`. Used to infer the 127 `globalPrefix`. 128- `env` Optional, defaults to `process.env`. Source of the environment 129 variables for configuration. 130- `argv` Optional, defaults to `process.argv`. Source of the CLI options 131 used for configuration. 132 133Returns a `config` object, which is not yet loaded. 134 135Fields: 136 137- `config.globalPrefix` The prefix for `global` operations. Set by the 138 `prefix` config value, or defaults based on the location of the 139 `execPath` option. 140- `config.localPrefix` The prefix for `local` operations. Set by the 141 `prefix` config value on the CLI only, or defaults to either the `cwd` or 142 its nearest ancestor containing a `node_modules` folder or `package.json` 143 file. 144- `config.sources` A read-only `Map` of the file (or a comment, if no file 145 found, or relevant) to the config level loaded from that source. 146- `config.data` A `Map` of config level to `ConfigData` objects. These 147 objects should not be modified directly under any circumstances. 148 - `source` The source where this data was loaded from. 149 - `raw` The raw data used to generate this config data, as it was parsed 150 initially from the environment, config file, or CLI options. 151 - `data` The data object reflecting the inheritance of configs up to this 152 point in the chain. 153 - `loadError` Any errors encountered that prevented the loading of this 154 config data. 155- `config.list` A list sorted in priority of all the config data objects in 156 the prototype chain. `config.list[0]` is the `cli` level, 157 `config.list[1]` is the `env` level, and so on. 158- `cwd` The `cwd` param 159- `env` The `env` param 160- `argv` The `argv` param 161- `execPath` The `execPath` param 162- `platform` The `platform` param 163- `defaults` The `defaults` param 164- `shorthands` The `shorthands` param 165- `types` The `types` param 166- `npmPath` The `npmPath` param 167- `globalPrefix` The effective `globalPrefix` 168- `localPrefix` The effective `localPrefix` 169- `prefix` If `config.get('global')` is true, then `globalPrefix`, 170 otherwise `localPrefix` 171- `home` The user's home directory, found by looking at `env.HOME` or 172 calling `os.homedir()`. 173- `loaded` A boolean indicating whether or not configs are loaded 174- `valid` A getter that returns `true` if all the config objects are valid. 175 Any data objects that have been modified with `config.set(...)` will be 176 re-evaluated when `config.valid` is read. 177 178### `config.load()` 179 180Load configuration from the various sources of information. 181 182Returns a `Promise` that resolves when configuration is loaded, and fails 183if a fatal error is encountered. 184 185### `config.find(key)` 186 187Find the effective place in the configuration levels a given key is set. 188Returns one of: `cli`, `env`, `project`, `user`, `global`, `builtin`, or 189`default`. 190 191Returns `null` if the key is not set. 192 193### `config.get(key, where = 'cli')` 194 195Load the given key from the config stack. 196 197### `config.set(key, value, where = 'cli')` 198 199Set the key to the specified value, at the specified level in the config 200stack. 201 202### `config.delete(key, where = 'cli')` 203 204Delete the configuration key from the specified level in the config stack. 205 206### `config.validate(where)` 207 208Verify that all known configuration options are set to valid values, and 209log a warning if they are invalid. 210 211Invalid auth options will cause this method to throw an error with a `code` 212property of `ERR_INVALID_AUTH`, and a `problems` property listing the specific 213concerns with the current configuration. 214 215If `where` is not set, then all config objects are validated. 216 217Returns `true` if all configs are valid. 218 219Note that it's usually enough (and more efficient) to just check 220`config.valid`, since each data object is marked for re-evaluation on every 221`config.set()` operation. 222 223### `config.repair(problems)` 224 225Accept an optional array of problems (as thrown by `config.validate()`) and 226perform the necessary steps to resolve them. If no problems are provided, 227this method will call `config.validate()` internally to retrieve them. 228 229Note that you must `await config.save('user')` in order to persist the changes. 230 231### `config.isDefault(key)` 232 233Returns `true` if the value is coming directly from the 234default definitions, if the current value for the key config is 235coming from any other source, returns `false`. 236 237This method can be used for avoiding or tweaking default values, e.g: 238 239> Given a global default definition of foo='foo' it's possible to read that 240> value such as: 241> 242> ```js 243> const save = config.get('foo') 244> ``` 245> 246> Now in a different place of your app it's possible to avoid using the `foo` 247> default value, by checking to see if the current config value is currently 248> one that was defined by the default definitions: 249> 250> ```js 251> const save = config.isDefault('foo') ? 'bar' : config.get('foo') 252> ``` 253 254### `config.save(where)` 255 256Save the config file specified by the `where` param. Must be one of 257`project`, `user`, `global`, `builtin`. 258