Comparing version 1.4.0 to 2.0.0
85
index.js
@@ -13,3 +13,3 @@ 'use strict'; | ||
const obj = () => Object.create(null); | ||
const plainObject = () => Object.create(null); | ||
@@ -21,32 +21,42 @@ // Prevent caching of this module so module.parent is always accurate | ||
class Conf { | ||
constructor(opts) { | ||
constructor(options) { | ||
const pkgPath = pkgUp.sync(parentDir); | ||
opts = Object.assign({ | ||
options = Object.assign({ | ||
// 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 | ||
}, opts); | ||
}, options); | ||
if (!opts.projectName && !opts.cwd) { | ||
if (!options.projectName && !options.cwd) { | ||
throw new Error('Project name could not be inferred. Please specify the `projectName` option.'); | ||
} | ||
opts = Object.assign({ | ||
configName: 'config' | ||
}, opts); | ||
options = Object.assign({ | ||
configName: 'config', | ||
fileExtension: 'json' | ||
}, options); | ||
if (!opts.cwd) { | ||
opts.cwd = envPaths(opts.projectName).config; | ||
if (!options.cwd) { | ||
options.cwd = envPaths(options.projectName).config; | ||
} | ||
this.events = new EventEmitter(); | ||
this.encryptionKey = opts.encryptionKey; | ||
this.path = path.resolve(opts.cwd, `${opts.configName}.json`); | ||
this.store = Object.assign(obj(), opts.defaults, this.store); | ||
this.encryptionKey = options.encryptionKey; | ||
this.path = path.resolve(options.cwd, `${options.configName}.${options.fileExtension}`); | ||
const fileStore = this.store; | ||
const store = Object.assign(plainObject(), options.defaults, fileStore); | ||
try { | ||
assert.deepEqual(fileStore, store); | ||
} catch (e) { | ||
this.store = store; | ||
} | ||
} | ||
get(key, defaultValue) { | ||
return dotProp.get(this.store, key, defaultValue); | ||
} | ||
set(key, val) { | ||
set(key, value) { | ||
if (typeof key !== 'string' && typeof key !== 'object') { | ||
@@ -56,4 +66,8 @@ throw new TypeError(`Expected \`key\` to be of type \`string\` or \`object\`, got ${typeof key}`); | ||
const store = this.store; | ||
if (typeof key !== 'object' && value === undefined) { | ||
throw new TypeError('Use `delete()` to clear values'); | ||
} | ||
const {store} = this; | ||
if (typeof key === 'object') { | ||
@@ -64,3 +78,3 @@ for (const k of Object.keys(key)) { | ||
} else { | ||
dotProp.set(store, key, val); | ||
dotProp.set(store, key, value); | ||
} | ||
@@ -70,13 +84,17 @@ | ||
} | ||
has(key) { | ||
return dotProp.has(this.store, key); | ||
} | ||
delete(key) { | ||
const store = this.store; | ||
const {store} = this; | ||
dotProp.delete(store, key); | ||
this.store = store; | ||
} | ||
clear() { | ||
this.store = obj(); | ||
this.store = plainObject(); | ||
} | ||
onDidChange(key, callback) { | ||
@@ -98,4 +116,5 @@ if (typeof key !== 'string') { | ||
try { | ||
// TODO: Use `util.isDeepStrictEqual` when targeting Node.js 10 | ||
assert.deepEqual(newValue, oldValue); | ||
} catch (err) { | ||
} catch (_) { | ||
currentValue = newValue; | ||
@@ -109,5 +128,7 @@ callback.call(this, newValue, oldValue); | ||
} | ||
get size() { | ||
return Object.keys(this.store).length; | ||
} | ||
get store() { | ||
@@ -121,24 +142,25 @@ try { | ||
data = Buffer.concat([decipher.update(data), decipher.final()]); | ||
} catch (err) {/* ignore */} | ||
} catch (_) {} | ||
} | ||
return Object.assign(obj(), JSON.parse(data)); | ||
} catch (err) { | ||
if (err.code === 'ENOENT') { | ||
return Object.assign(plainObject(), JSON.parse(data)); | ||
} catch (error) { | ||
if (error.code === 'ENOENT') { | ||
makeDir.sync(path.dirname(this.path)); | ||
return obj(); | ||
return plainObject(); | ||
} | ||
if (err.name === 'SyntaxError') { | ||
return obj(); | ||
if (error.name === 'SyntaxError') { | ||
return plainObject(); | ||
} | ||
throw err; | ||
throw error; | ||
} | ||
} | ||
set store(val) { | ||
set store(value) { | ||
// Ensure the directory exists as it could have been deleted in the meantime | ||
makeDir.sync(path.dirname(this.path)); | ||
let data = JSON.stringify(val, null, '\t'); | ||
let data = JSON.stringify(value, null, '\t'); | ||
@@ -153,5 +175,6 @@ if (this.encryptionKey) { | ||
} | ||
// TODO: Use `Object.entries()` here at some point | ||
// TODO: Use `Object.entries()` when targeting Node.js 8 | ||
* [Symbol.iterator]() { | ||
const store = this.store; | ||
const {store} = this; | ||
@@ -158,0 +181,0 @@ for (const key of Object.keys(store)) { |
{ | ||
"name": "conf", | ||
"version": "1.4.0", | ||
"version": "2.0.0", | ||
"description": "Simple config handling for your app or module", | ||
@@ -13,3 +13,3 @@ "license": "MIT", | ||
"engines": { | ||
"node": ">=4" | ||
"node": ">=6" | ||
}, | ||
@@ -16,0 +16,0 @@ "scripts": { |
@@ -16,3 +16,7 @@ # conf [![Build Status: Linux and macOS](https://travis-ci.org/sindresorhus/conf.svg?branch=master)](https://travis-ci.org/sindresorhus/conf) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/n88jwh3aju39i0p2/branch/master?svg=true)](https://ci.appveyor.com/project/sindresorhus/conf/branch/master) | ||
<a href="https://www.patreon.com/sindresorhus"> | ||
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160"> | ||
</a> | ||
## Usage | ||
@@ -97,2 +101,11 @@ | ||
#### fileExtension | ||
type: `string`<br> | ||
Default: `json` | ||
Extension of the config file. | ||
You would usually not need this, but could useful if you want to interact with a file with a custom file extension that can be associated with your app. These might be simple save/export/preference files that are intended to be shareable or saved outside of the app. | ||
### Instance | ||
@@ -99,0 +112,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
12192
141
183