GithubHelp home page GithubHelp logo

config's Introduction

NOTICE

The code for this module is now maintained inside a workspace of the npm cli itself:

https://github.com/npm/cli/blob/HEAD/workspaces/config

@npmcli/config

Configuration management for the npm cli.

This module is the spiritual descendant of npmconf, and the code that once lived in npm's lib/config/ folder.

It does the management of configuration files that npm uses, but importantly, does not define all the configuration defaults or types, as those parts make more sense to live within the npm CLI itself.

The only exceptions:

  • The prefix config value has some special semantics, setting the local prefix if specified on the CLI options and not in global mode, or the global prefix otherwise.
  • The project config file is loaded based on the local prefix (which can only be set by the CLI config options, and otherwise defaults to a walk up the folder tree to the first parent containing a node_modules folder, package.json file, or package-lock.json file.)
  • The userconfig value, as set by the environment and CLI (defaulting to ~/.npmrc, is used to load user configs.
  • The globalconfig value, as set by the environment, CLI, and userconfig file (defaulting to $PREFIX/etc/npmrc) is used to load global configs.
  • A builtin config, read from a npmrc file in the root of the npm project itself, overrides all defaults.

The resulting hierarchy of configs:

  • CLI switches. eg --some-key=some-value on the command line. These are parsed by nopt, which is not a great choice, but it's the one that npm has used forever, and changing it will be difficult.
  • Environment variables. eg npm_config_some_key=some_value in the environment. There is no way at this time to modify this prefix.
  • INI-formatted project configs. eg some-key = some-value in the localPrefix folder (ie, the cwd, or its nearest parent that contains either a node_modules folder or package.json file.)
  • INI-formatted userconfig file. eg some-key = some-value in ~/.npmrc. The userconfig config value can be overridden by the cli, env, or project configs to change this value.
  • INI-formatted globalconfig file. eg some-key = some-value in the globalPrefix folder, which is inferred by looking at the location of the node executable, or the prefix setting in the cli, env, project, or userconfig. The globalconfig value at any of those levels can override this.
  • INI-formatted builtin config file. eg some-key = some-value in /usr/local/lib/node_modules/npm/npmrc. This is not configurable, and is determined by looking in the npmPath folder.
  • Default values (passed in by npm when it loads this module).

USAGE

const Config = require('@npmcli/config')
// the types of all the configs we know about
const types = require('./config/types.js')
// default values for all the configs we know about
const defaults = require('./config/defaults.js')
// if you want -c to be short for --call and so on, define it here
const shorthands = require('./config/shorthands.js')

const conf = new Config({
  // path to the npm module being run
  npmPath: resolve(__dirname, '..'),
  types,
  shorthands,
  defaults,
  // optional, defaults to process.argv
  argv: process.argv,
  // optional, defaults to process.env
  env: process.env,
  // optional, defaults to process.execPath
  execPath: process.execPath,
  // optional, defaults to process.platform
  platform: process.platform,
  // optional, defaults to process.cwd()
  cwd: process.cwd(),
})

// emits log events on the process object
// see `proc-log` for more info
process.on('log', (level, ...args) => {
  console.log(level, ...args)
})

// returns a promise that fails if config loading fails, and
// resolves when the config object is ready for action
conf.load().then(() => {
  conf.validate()
  console.log('loaded ok! some-key = ' + conf.get('some-key'))
}).catch(er => {
  console.error('error loading configs!', er)
})

API

The Config class is the sole export.

const Config = require('@npmcli/config')

static Config.typeDefs

The type definitions passed to nopt for CLI option parsing and known configuration validation.

constructor new Config(options)

Options:

  • types Types of all known config values. Note that some are effectively given semantic value in the config loading process itself.
  • shorthands An object mapping a shorthand value to an array of CLI arguments that replace it.
  • defaults Default values for each of the known configuration keys. These should be defined for all configs given a type, and must be valid.
  • npmPath The path to the npm module, for loading the builtin config file.
  • cwd Optional, defaults to process.cwd(), used for inferring the localPrefix and loading the project config.
  • platform Optional, defaults to process.platform. Used when inferring the globalPrefix from the execPath, since this is done diferently on Windows.
  • execPath Optional, defaults to process.execPath. Used to infer the globalPrefix.
  • env Optional, defaults to process.env. Source of the environment variables for configuration.
  • argv Optional, defaults to process.argv. Source of the CLI options used for configuration.

Returns a config object, which is not yet loaded.

Fields:

  • config.globalPrefix The prefix for global operations. Set by the prefix config value, or defaults based on the location of the execPath option.
  • config.localPrefix The prefix for local operations. Set by the prefix config value on the CLI only, or defaults to either the cwd or its nearest ancestor containing a node_modules folder or package.json file.
  • config.sources A read-only Map of the file (or a comment, if no file found, or relevant) to the config level loaded from that source.
  • config.data A Map of config level to ConfigData objects. These objects should not be modified directly under any circumstances.
    • source The source where this data was loaded from.
    • raw The raw data used to generate this config data, as it was parsed initially from the environment, config file, or CLI options.
    • data The data object reflecting the inheritance of configs up to this point in the chain.
    • loadError Any errors encountered that prevented the loading of this config data.
  • config.list A list sorted in priority of all the config data objects in the prototype chain. config.list[0] is the cli level, config.list[1] is the env level, and so on.
  • cwd The cwd param
  • env The env param
  • argv The argv param
  • execPath The execPath param
  • platform The platform param
  • defaults The defaults param
  • shorthands The shorthands param
  • types The types param
  • npmPath The npmPath param
  • globalPrefix The effective globalPrefix
  • localPrefix The effective localPrefix
  • prefix If config.get('global') is true, then globalPrefix, otherwise localPrefix
  • home The user's home directory, found by looking at env.HOME or calling os.homedir().
  • loaded A boolean indicating whether or not configs are loaded
  • valid A getter that returns true if all the config objects are valid. Any data objects that have been modified with config.set(...) will be re-evaluated when config.valid is read.

config.load()

Load configuration from the various sources of information.

Returns a Promise that resolves when configuration is loaded, and fails if a fatal error is encountered.

config.find(key)

Find the effective place in the configuration levels a given key is set. Returns one of: cli, env, project, user, global, builtin, or default.

Returns null if the key is not set.

config.get(key, where = 'cli')

Load the given key from the config stack.

config.set(key, value, where = 'cli')

Set the key to the specified value, at the specified level in the config stack.

config.delete(key, where = 'cli')

Delete the configuration key from the specified level in the config stack.

config.validate(where)

Verify that all known configuration options are set to valid values, and log a warning if they are invalid.

Invalid auth options will cause this method to throw an error with a code property of ERR_INVALID_AUTH, and a problems property listing the specific concerns with the current configuration.

If where is not set, then all config objects are validated.

Returns true if all configs are valid.

Note that it's usually enough (and more efficient) to just check config.valid, since each data object is marked for re-evaluation on every config.set() operation.

config.repair(problems)

Accept an optional array of problems (as thrown by config.validate()) and perform the necessary steps to resolve them. If no problems are provided, this method will call config.validate() internally to retrieve them.

Note that you must await config.save('user') in order to persist the changes.

config.isDefault(key)

Returns true if the value is coming directly from the default definitions, if the current value for the key config is coming from any other source, returns false.

This method can be used for avoiding or tweaking default values, e.g:

Given a global default definition of foo='foo' it's possible to read that value such as:

   const save = config.get('foo')

Now in a different place of your app it's possible to avoid using the foo default value, by checking to see if the current config value is currently one that was defined by the default definitions:

   const save = config.isDefault('foo') ? 'bar' : config.get('foo')

config.save(where)

Save the config file specified by the where param. Must be one of project, user, global, builtin.

config's People

Contributors

avivahl avatar commanderroot avatar darcyclarke avatar dependabot[bot] avatar github-actions[bot] avatar isaacs avatar jameschensmith avatar jenseng avatar lukekarrys avatar nlf avatar ruyadorno avatar wraithgar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

config's Issues

[BUG] `npm_config_...` variables don't work for specifying a scoped registry password/auth/authToken

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

npm_config_... variables don't work for specifying a scoped registry _password/_auth/_authToken. The keys are downcased, and the underscore after the colon gets converted to a dash, so you end up with nerfed -password, -auth, and -authtoken keys, which npm-registry-fetch doesn't know how to handle. Although getCredentialsByURI does have some special handling for -authtoken, it's never actually used when doing registry fetches.

For example:

npm_config_username=foo -> { "username": "foo" } ๐Ÿ‘
npm_config__password=bar -> { "_password": "bar" } ๐Ÿ‘ underscore is preserved
npm_config_//my.registry.example/npm/:username=foo -> { "//my.registry.example/npm/:username": "foo" } ๐Ÿ‘
npm_config_//my.registry.example/npm/:_password=bar -> { "//my.registry.example/npm/:-password": "bar" } ๐Ÿ‘Ž (note the -password, it should be _password)
npm_config_//my.registry.example/npm/:_authToken=secret -> { "//my.registry.example/npm/:-authtoken": "secret" } ๐Ÿ‘Ž (note the -authtoken, it should be _authToken)

Expected Behavior

npm_config_//my.registry.example/npm/:_password=bar -> { "//my.registry.example/npm/:_password": "bar" } ๐Ÿ‘
npm_config_//my.registry.example/npm/:_authToken=secret -> { "//my.registry.example/npm/:_authToken": "secret" } ๐Ÿ‘

Granted, using env vars named this way is perhaps questionable and non-portable, but based on my limited testing the approach generally works (apart from this bug ๐Ÿ˜… ).

The value here is that env vars provide a reliable way to override local project config when you don't have a way to influence the command line args. If there were another mechanism to override project config WITHOUT using command-line args, that would also solve my current issue.

Steps To Reproduce

No response

Environment

No response

[BUG] env of `""` should be treated as null/unset

$ npm_config_only= npm config get only
npm WARN invalid config only="" set in environment
npm WARN invalid config Must be one of: null, dev, development, prod, production
null

Expect:

$ npm_config_only= node ../cli-v6 get only
null

[BUG] Environment variable DESTDIR is not honored if PREFIX is set via environment

What / Why

Environment variable DESTDIR is not honored if PREFIX is set via environment.

When

Whenever I run npm get prefix.

Where

  • n/a

How

Current Behavior

env DESTDIR=/tmp PREFIX="/opt" npm get prefix
/opt

Steps to Reproduce

  • Set DESTDIR and PREFIX environment variables and run npm get prefix.

Expected Behavior

env DESTDIR=/tmp PREFIX="/opt" npm get prefix
/tmp/opt

Who

  • n/a

References

  • n/a

[BUG] Crash when Node starts from ESM module

When

Use @npmcli/config from ESM Nodejs code.

How

Current Behavior

TypeError: Cannot read property 'filename' of undefined
    at setEnvs (C:\npm-config-issue\node_modules\@npmcli\config\lib\set-envs.js:95:35)

Steps to Reproduce

// test.mjs
import Config from '@npmcli/config';
new Config({ types:{}, npmPath:'', defaults: {} }).load();
npm i @npmcli/config semver
node ./test.mjs

Expected Behavior

No error

References

// @npmcli/config/lib/set-envs.js:95
// is
  env.npm_execpath = require.main.filename
// should be 
  env.npm_execpath = require.main?.filename
// because require.main is empty when Node start with ESM main module

[BUG] _auth not work for internal registry based off information (lack of?) found on docs.npmjs.com

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When using an internal registry as a repository and proxy publish fails due to auth errors because the registry in the .npmrc does not match the registry in the package.json publishConfig

Error:

user@rcampbe-mac WebContent % npm install
npm ERR! code E401
npm ERR! Unable to authenticate, need: BASIC realm="Sonatype Nexus Repository Manager"
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/user/.npm/_logs/2022-02-10T22_35_37_017Z-debug.log
user@user-mac dir %

Expected Behavior

the _auth property defined in .npmrc used for the repository where package will be published.

AND/OR

Documentation (https://docs.npmjs.com/cli/v8/using-npm/config) updated to reflect that if using an internal register and internal proxy register how the configuration for the different registries should be accomplished. This should probably include which properties are configurable for the different registries

Steps To Reproduce

Note the follow is assuming that you already have a private npm repository set up to both store internally created modules and a proxy to the global npm repository for modules not in the repository.

  1. config .npmrc:
init-author-name=Some Name
[email protected]
init-author-url=https://company.com
[email protected]
registry='http://company.com/interalRepoProxy'
_auth=${COMPANY_INTERNAL_REPO_AUTH}
fund=false
package-lock=true
  1. config package.json:
{
  "name": "the-package",
  "version": "1.0.0",
  "description": "Test package.json",
  "publishConfig": {
    "registry": "http://company.com/interalRepo"
  },
  "author": "company.com",
  "license": "ISC"
}
  1. run npm publish

Environment

  • npm: 8.5.1
  • Node: v16.13.1
  • OS: Mac
  • platform: Macbook pro

  • npm: 8.5.1
  • Node: v16.13.1
  • OS: Node v16.13.1 Docker image
  • platform: Gitlab Docker Image Runner

[BUG] config will no longer save registry-specific always-auth field

What / Why

As of #16, specifically commit 0ac3605c (remove registry-specific always-auth field) the npm config set command will no longer set a registry-specific always-auth field.

While the the npm CLI as of version 7 no longer makes use of the always-auth field then .npmrc file may be used by older versions of npm as well as other clients such as yarn. Since npm no longer uses always-auth there is no reason for the npm config set command to treat this field any different than any other field that npm does not use.

In particular this behavior breaks AWS CodeArtifact users that use yarn. The aws codeartifact login runs npm config set commands like the ones in the steps to reproduce below (plus another npm config set to set a registry-specific _authToken).

Steps to Reproduce

I've observed this behavior with npm CLI version 7.13.0 (other npm 7 versions may also be affected).

I've cleared my .npmrc.

rm ~/.npmrc

If I set the registry field:

npm config set registry https://example.com/npm/repo/

And then try to set always-auth for that registry:

npm config set //example.com/npm/repo/:always-auth true

Then npm ignores the attempt to set always-auth.

$ cat ~/.npmrc
registry=https://example.com/npm/repo/

If I set a different attribute, such as a miss-spelled always-oath it succeeds:

$ npm config set //example.com/npm/repo/:always-oath true
$ cat ~/.npmrc
registry=https://example.com/npm/repo/
//example.com/npm/repo/:always-oath=true

Also, if I set registry to a second registry then I can successfully set always-auth for the first registry:

$ npm config set registry https://example.com/npm/repo2/
$ npm config set //example.com/npm/repo/:always-auth true
$ cat ~/.npmrc
registry=https://example.com/npm/repo2/
//example.com/npm/repo/:always-oath=true
//example.com/npm/repo/:always-auth=true

Expected Behavior

I would expect npm config set //example.com/npm/repo/:always-auth true to set the field just as it would if I set an arbitrary field such as npm config set //example.com/npm/repo/:always-oath true.

I expect to use the npm config command to be able configure the .npmrc file even if I later using a different version of npm or a different client that reads my config from the .npmrc.

If the npm team agrees then I believe this can be fixed by removing lines 636 to 639 of lib/index.js

If not and there is a strong reason why this command should not succeed as I've requested then the command should fail with a non-zero exit code and should output a message informing the user why they can no longer set this field.

References

[BUG] npm 8 rewrites _auth field in config file

What / Why

While switching from former Node.js LTS 14.18.1 (npm 6.14.15) to new Node.js LTS 16.13.0 (npm 8.1.0) we've discovered that our authentication configuration in .npmrc for our ci/cd pipelines breaks.
With Node.js 14.x we did this:

npm config set _auth=XXXXXX
npm config set always-auth=true

which then added this to .npmrc:

_auth=XXXXXX
always-auth=true

But with Node.js 16.13.0 the second config set command will rewrite the _auth line in .npmrc file to this:

//nexus.acme.org/repository/npm-group/:username=yyyy
//nexus.acme.org/repository/npm-group/:_password="zzzz"

In the .npmrc file there is also a registry line specifying:

registry=https://nexus.acme.org/repository/npm-group/

So the _auth line is rewritten to registry specific username and _password config lines.

This breaks our pipelines as the _auth info applies to any registry (we publish to a different registry, but in the same Nexus instance and therefore with the same credentials) as it is now registry specific (for the wrong registry).

A workaround is to write a registry specific _auth line for the registry we publish to:

npm config set "//nexus.acme.org/repository/npm-releases/:_auth=XXXXXX"
npm config set "always-auth=true"

However, there could be use cases for a shared _auth config for any registry. Also, it's a breaking change between former Node.js LTS version and the new Node.js LTS version.

When

See steps above.

Where

See info provided above.

How

Current Behavior

See above.

Steps to Reproduce

See above.

Expected Behavior

I expected the same behavior as with Node.js 14.x/npm 6. See above.

Who

  • n/a

References

  • n/a

[BUG] [Improvement] Redirect a npmjs A package to npmjs B package from package.json config

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I have to change the entire sourcecode for the npmjs project or use an local alias to install a different package B instead of package A.

Expected Behavior

I should be able to redirect a npmjs A package to npmjs B package from package.json config.

Citing my repositories as an example to ensure not to make phpcgijs old versions unfindable. What I am wishing to do is redirect phpcgijs to cgijs

package.json


{
...
"repository": {
    "type": "git",
    "url": "https://github.com/ganeshkbhat/cgi-js.git",
    "redirect": "newpackagename_preferably--OR--differentrepository"
  }
}

OR

{
...
"redirect": "newpackagename_preferably"
"repository": {
    "type": "git",
    "url": "https://github.com/ganeshkbhat/cgi-js.git"
  }
}

Steps To Reproduce

NA

Environment

  • npm: current
  • Node: current
  • OS: Windows/ OS/ Linux
  • platform: Windows/ OS/ Linux

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.