Comparing version 2.2.0 to 3.0.0
62
index.js
@@ -20,2 +20,16 @@ /* eslint-disable node/no-deprecated-api */ | ||
const checkValueType = (key, value) => { | ||
const nonJsonTypes = [ | ||
'undefined', | ||
'symbol', | ||
'function' | ||
]; | ||
const type = typeof value; | ||
if (nonJsonTypes.includes(type)) { | ||
throw new TypeError(`Setting a value of type \`${type}\` for key \`${key}\` is not allowed as it's not supported by JSON`); | ||
} | ||
}; | ||
class Conf { | ||
@@ -25,7 +39,8 @@ constructor(options) { | ||
options = Object.assign({ | ||
options = { | ||
// Can't use `require` because of Webpack being annoying: | ||
// https://github.com/webpack/webpack/issues/196 | ||
projectName: pkgPath && JSON.parse(fs.readFileSync(pkgPath, 'utf8')).name | ||
}, options); | ||
projectName: pkgPath && JSON.parse(fs.readFileSync(pkgPath, 'utf8')).name, | ||
...options | ||
}; | ||
@@ -36,7 +51,11 @@ if (!options.projectName && !options.cwd) { | ||
options = Object.assign({ | ||
options = { | ||
configName: 'config', | ||
fileExtension: 'json', | ||
projectSuffix: 'nodejs' | ||
}, options); | ||
projectSuffix: 'nodejs', | ||
clearInvalidConfig: true, | ||
serialize: value => JSON.stringify(value, null, '\t'), | ||
deserialize: JSON.parse, | ||
...options | ||
}; | ||
@@ -47,4 +66,8 @@ if (!options.cwd) { | ||
this._options = options; | ||
this.events = new EventEmitter(); | ||
this.encryptionKey = options.encryptionKey; | ||
this.serialize = options.serialize; | ||
this.deserialize = options.deserialize; | ||
@@ -78,8 +101,14 @@ const fileExtension = options.fileExtension ? `.${options.fileExtension}` : ''; | ||
const set = (key, value) => { | ||
checkValueType(key, value); | ||
dotProp.set(store, key, value); | ||
}; | ||
if (typeof key === 'object') { | ||
for (const k of Object.keys(key)) { | ||
dotProp.set(store, k, key[k]); | ||
const object = key; | ||
for (const [key, value] of Object.entries(object)) { | ||
set(key, value); | ||
} | ||
} else { | ||
dotProp.set(store, key, value); | ||
set(key, value); | ||
} | ||
@@ -147,5 +176,6 @@ | ||
return Object.assign(plainObject(), JSON.parse(data)); | ||
return Object.assign(plainObject(), this.deserialize(data)); | ||
} catch (error) { | ||
if (error.code === 'ENOENT') { | ||
// TODO: Use `fs.mkdirSync` `recursive` option when targeting Node.js 12 | ||
makeDir.sync(path.dirname(this.path)); | ||
@@ -155,3 +185,3 @@ return plainObject(); | ||
if (error.name === 'SyntaxError') { | ||
if (this._options.clearInvalidConfig && error.name === 'SyntaxError') { | ||
return plainObject(); | ||
@@ -168,3 +198,3 @@ } | ||
let data = JSON.stringify(value, null, '\t'); | ||
let data = this.serialize(value); | ||
@@ -180,8 +210,5 @@ if (this.encryptionKey) { | ||
// TODO: Use `Object.entries()` when targeting Node.js 8 | ||
* [Symbol.iterator]() { | ||
const {store} = this; | ||
for (const key of Object.keys(store)) { | ||
yield [key, store[key]]; | ||
for (const [key, value] of Object.entries(this.store)) { | ||
yield [key, value]; | ||
} | ||
@@ -192,1 +219,2 @@ } | ||
module.exports = Conf; | ||
module.exports.default = Conf; |
{ | ||
"name": "conf", | ||
"version": "2.2.0", | ||
"version": "3.0.0", | ||
"description": "Simple config handling for your app or module", | ||
@@ -13,9 +13,10 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=6" | ||
"node": ">=8" | ||
}, | ||
"scripts": { | ||
"test": "xo && ava" | ||
"test": "xo && ava && tsd-check" | ||
}, | ||
"files": [ | ||
"index.js" | ||
"index.js", | ||
"index.d.ts" | ||
], | ||
@@ -44,13 +45,15 @@ "keywords": [ | ||
"env-paths": "^1.0.0", | ||
"make-dir": "^1.0.0", | ||
"make-dir": "^2.0.0", | ||
"pkg-up": "^2.0.0", | ||
"write-file-atomic": "^2.3.0" | ||
"write-file-atomic": "^2.4.2" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.25.0", | ||
"@types/node": "^11.10.4", | ||
"ava": "^1.2.0", | ||
"clear-module": "^3.0.0", | ||
"del": "^3.0.0", | ||
"del": "^4.0.0", | ||
"tempy": "^0.2.1", | ||
"xo": "^0.23.0" | ||
"tsd-check": "^0.3.0", | ||
"xo": "^0.24.0" | ||
} | ||
} |
@@ -59,3 +59,3 @@ # conf [![Build Status](https://travis-ci.org/sindresorhus/conf.svg?branch=master)](https://travis-ci.org/sindresorhus/conf) | ||
Default config. | ||
Config used if there are no existing config. | ||
@@ -104,3 +104,3 @@ #### configName | ||
type: `string`<br> | ||
Type: `string`<br> | ||
Default: `json` | ||
@@ -112,2 +112,27 @@ | ||
#### clearInvalidConfig | ||
Type: `boolean`<br> | ||
Default: `true` | ||
The config is cleared if reading the config file causes a `SyntaxError`. This is a good default, as the config file is not intended to be hand-edited, so it usually means the config is corrupt and there's nothing the user can do about it anyway. However, if you let the user edit the config file directly, mistakes might happen and it could be more useful to throw an error when the config is invalid instead of clearing. Disabling this option will make it throw a `SyntaxError` on invalid config instead of clearing. | ||
#### serialize | ||
Type: `Function`<br> | ||
Default: `value => JSON.stringify(value, null, '\t')` | ||
Function to serialize the config object to a UTF-8 string when writing the config file. | ||
You would usually not need this, but it could be useful if you want to use a format other than JSON. | ||
#### deserialize | ||
Type: `Function`<br> | ||
Default: `JSON.parse` | ||
Function to deserialize the config object from a UTF-8 string when reading the config file. | ||
You would usually not need this, but it could be useful if you want to use a format other than JSON. | ||
#### projectSuffix | ||
@@ -136,3 +161,3 @@ | ||
The `value` must be JSON serializable. | ||
The `value` must be JSON serializable. Trying to set the type `undefined`, `function`, or `symbol` will result in a TypeError. | ||
@@ -189,5 +214,21 @@ #### .set(object) | ||
I'm also the author of `configstore`. While it's pretty good, I did make some mistakes early on that are hard to change at this point. This module is the result of everything I learned from making `configstore`. Mainly where config is stored. In `configstore`, the config is stored in `~/.config` (which is mainly a Linux convention) on all systems, while `conf` stores config in the system default [user config directory](https://github.com/sindresorhus/env-paths#pathsconfig). The `~/.config` directory, it turns out, often have an incorrect permission on macOS and Windows, which has caused a lot of grief for users. | ||
I'm also the author of `configstore`. While it's pretty good, I did make some mistakes early on that are hard to change at this point. This module is the result of everything I learned from making `configstore`. Mainly where the config is stored. In `configstore`, the config is stored in `~/.config` (which is mainly a Linux convention) on all systems, while `conf` stores config in the system default [user config directory](https://github.com/sindresorhus/env-paths#pathsconfig). The `~/.config` directory, it turns out, often have an incorrect permission on macOS and Windows, which has caused a lot of grief for users. | ||
### Can I use YAML or another serialization format? | ||
The `serialize` and `deserialize` options can be used to customize the format of the config file, as long as the representation is compatible with `utf8` encoding. | ||
Example using YAML: | ||
```js | ||
const yaml = require('js-yaml'); | ||
const config = new Conf({ | ||
fileExtension: 'yaml', | ||
serialize: yaml.safeDump, | ||
deserialize: yaml.safeLoad | ||
}); | ||
``` | ||
## Related | ||
@@ -194,0 +235,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20659
5
302
238
7
+ Addedmake-dir@2.1.0(transitive)
+ Addedpify@4.0.1(transitive)
+ Addedsemver@5.7.2(transitive)
- Removedmake-dir@1.3.0(transitive)
- Removedpify@3.0.0(transitive)
Updatedmake-dir@^2.0.0
Updatedwrite-file-atomic@^2.4.2