Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Commit

Permalink
feat: add isDefault method (#27)
Browse files Browse the repository at this point in the history
Add a new method `isDefault(key)` that enables a way to know if the
value to be returned by a `config.get(key)` call is coming from the
default definitions or any other different source. In case it's coming
from the default values this method returns `true`, it returns `false`
otherwise.

This addition is going to allow for effectively managing different
default values in the npm cli on a command-basis, e.g:

The `save` config default value in the npm cli is `true`, so that in
`npm install` and other commands that value is always going to default
to true if no user config is provided. Now let's say we want to use a
different value in `npm update`, for example `save=false`. This change
enables us to have a conditional check to see if the `save` config value
is coming from the default source, thus providing a way to use a
different value instead of the default:

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

Relates to: npm/cli#4223
Relates to: npm/statusboard#324
  • Loading branch information
ruyadorno authored Jan 10, 2022
1 parent 170bb5c commit 30ca48d
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,29 @@ 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.isDefault(key)`

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

Can be useful 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:
>
> ```js
> 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:
>
> ```js
> 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
Expand Down
14 changes: 14 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,20 @@ class Config {
}
}

// Returns true if the value is coming directly from the source defined
// in default definitions, if the current value for the key config is
// coming from any other different source, returns false
isDefault (key) {
const [defaultType, ...types] = [...confTypes]
const defaultData = this.data.get(defaultType).data

return hasOwnProperty(defaultData, key)
&& types.every(type => {
const typeData = this.data.get(type).data
return !hasOwnProperty(typeData, key)
})
}

invalidHandler (k, val, type, source, where) {
this.log.warn(
'invalid config',
Expand Down
27 changes: 27 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,33 @@ loglevel = yolo
])
t.equal(config.valid, false)
logs.length = 0

// set a new value that defaults to cli source
config.set('cli-config', 1)

t.ok(config.isDefault('methane'),
'should return true if value is retrieved from default definitions')
t.notOk(config.isDefault('cli-config'),
'should return false for a cli-defined value')
t.notOk(config.isDefault('foo'),
'should return false for a env-defined value')
t.notOk(config.isDefault('project-config'),
'should return false for a project-defined value')
t.notOk(config.isDefault('default-user-config-in-home'),
'should return false for a user-defined value')
t.notOk(config.isDefault('global-config'),
'should return false for a global-defined value')
t.notOk(config.isDefault('builtin-config'),
'should return false for a builtin-defined value')

// make sure isDefault still works as intended after
// setting and deleting values in differente sources
config.set('methane', 'H2O', 'cli')
t.notOk(config.isDefault('methane'),
'should no longer return true now that a cli value was defined')
config.delete('methane', 'cli')
t.ok(config.isDefault('methane'),
'should return true once again now that values is retrieved from defaults')
})

t.test('do not double-load project/user config', async t => {
Expand Down

0 comments on commit 30ca48d

Please sign in to comment.