electron-settings
Advanced tools
Comparing version 3.0.10 to 3.0.11
@@ -19,2 +19,37 @@ /** | ||
/** | ||
* A reference to the Electron app. If this framework is required within a | ||
* renderer processes, we need to load the app via `remote`. | ||
* | ||
* @type {string} | ||
*/ | ||
const app = electron.app || electron.remote.app; | ||
/** | ||
* The Electron app's user data path. | ||
* | ||
* @type {string} | ||
*/ | ||
const userDataPath = app.getPath('userData'); | ||
/** | ||
* The name of the settings file. | ||
* | ||
* @type {string} | ||
*/ | ||
const settingsFileName = 'Settings'; | ||
/** | ||
* The absolute path to th user settings file. | ||
* | ||
* @type {string} | ||
*/ | ||
const settingsFilePath = path.join(userDataPath, settingsFileName); | ||
/** | ||
* The electron-settings class. | ||
* | ||
* @extends EventEmitter | ||
* @class | ||
*/ | ||
class Settings extends EventEmitter { | ||
@@ -26,8 +61,8 @@ | ||
/** | ||
* Called when the settings file is changed or renamed. | ||
* The absolute path to the settings file on the disk. | ||
* | ||
* @type {Object} | ||
* @type {string} | ||
* @private | ||
*/ | ||
this._handleSettingsFileChange = this._onSettingsFileChange.bind(this); | ||
this._settingsFilePath = settingsFilePath; | ||
@@ -43,41 +78,71 @@ /** | ||
this._fsWatcher = null; | ||
/** | ||
* Called when the settings file is changed or renamed. | ||
* | ||
* @type {Object} | ||
* @private | ||
*/ | ||
this._handleSettingsFileChange = this._onSettingsFileChange.bind(this); | ||
} | ||
/** | ||
* Gets the absolute path to the user settings file. This is done | ||
* dynamically instead of being cached during instantiation because | ||
* it is possible to change the user data path programatically. | ||
* Watches the settings file for changes using the native `FSWatcher` | ||
* class in case the settings file is changed outside of | ||
* ElectronSettings' jursidiction. | ||
* | ||
* @returns {string} | ||
* @private | ||
*/ | ||
_getSettingsPath() { | ||
const app = electron.app || electron.remote.app; | ||
const userDataPath = app.getPath('userData'); | ||
const settingsFilePath = path.join(userDataPath, 'Settings'); | ||
_watchSettings() { | ||
if (!this._fsWatcher) { | ||
try { | ||
this._fsWatcher = fs.watch(this._settingsFilePath, this._handleSettingsFileChange); | ||
} catch (err) { | ||
// File may not exist yet or may not have appropriate permissions. | ||
} | ||
} | ||
} | ||
return settingsFilePath; | ||
/** | ||
* Unwatches the settings file by closing the FSWatcher and nullifying its | ||
* references. If the `reset` parameter is true, attempt to watch the | ||
* settings file again. | ||
* | ||
* @param {boolean} [reset=false] | ||
* @private | ||
*/ | ||
_unwatchSettings(reset = false) { | ||
if (this._fsWatcher) { | ||
this._fsWatcher.close(); | ||
this._fsWatcher = null; | ||
if (reset) { | ||
this._watchSettings(); | ||
} | ||
} | ||
} | ||
/** | ||
* Watches the settings file for changes using the native `FSWatcher` | ||
* class in case the settings file is changed outside of | ||
* ElectronSettings' jursidiction. | ||
* Ensures that the settings file exists, then initializes the FSWatcher. | ||
* | ||
* @private | ||
*/ | ||
_watchSettings() { | ||
if (!this._fsWatcher) { | ||
const settingsFilePath = this._getSettingsPath(); | ||
_ensureSettings() { | ||
try { | ||
fs.readJsonSync(this._settingsFilePath); | ||
} catch (err) { | ||
try { | ||
this._fsWatcher = fs.watch(settingsFilePath, this._handleSettingsFileChange); | ||
fs.writeJsonSync(this._settingsFilePath, {}); | ||
} catch (err) { | ||
// File may not exist yet or possible permissions error. | ||
// Cannot read or write file. This could be because the user does not | ||
// have the necessary permissions. Throw error. | ||
throw err; | ||
} | ||
} | ||
this._watchSettings(); | ||
} | ||
/** | ||
* Writes the given settings object to the disk. | ||
* Writes the settings to the disk. | ||
* | ||
@@ -89,18 +154,17 @@ * @param {Object} [obj={}] | ||
_writeSettings(obj = {}, opts = {}) { | ||
const settingsFilePath = this._getSettingsPath(); | ||
this._ensureSettings(); | ||
try { | ||
fs.outputJsonSync(settingsFilePath, obj, { | ||
fs.outputJsonSync(this._settingsFilePath, obj, { | ||
spaces: opts.prettify ? 2 : 0 | ||
}); | ||
} catch (err) { | ||
// Something went wrong. | ||
// Could not write the file. This could be because the user does not | ||
// have the necessary permissions. Throw error. | ||
throw err; | ||
} | ||
this._watchSettings(); | ||
} | ||
/** | ||
* Returns the settings from the settings file, or creates the file | ||
* if it does not yet exist. | ||
* Returns the parsed contents of the settings file. | ||
* | ||
@@ -111,11 +175,11 @@ * @returns {Object} | ||
_readSettings() { | ||
const settingsFilePath = this._getSettingsPath(); | ||
this._ensureSettings(); | ||
try { | ||
return fs.readJsonSync(settingsFilePath); | ||
return fs.readJsonSync(this._settingsFilePath); | ||
} catch (err) { | ||
this._writeSettings(); | ||
// Could not read the file. This could be because the user does not | ||
// have the necessary permissions. Throw error. | ||
throw err; | ||
} | ||
return {}; | ||
} | ||
@@ -133,8 +197,7 @@ | ||
case Settings.FSWatcherEvents.CHANGE: { | ||
this.emit(Settings.Events.CHANGE); | ||
this._emitChangeEvent(); | ||
break; | ||
} | ||
case Settings.FSWatcherEvents.RENAME: { | ||
this._fsWatcher.close(); | ||
this._fsWatcher = null; | ||
this._unwatchSettings(true); | ||
break; | ||
@@ -146,2 +209,12 @@ } | ||
/** | ||
* Broadcasts the internal "change" event. | ||
* | ||
* @emits ElectronSettings:change | ||
* @private | ||
*/ | ||
_emitChangeEvent() { | ||
this.emit(Settings.Events.CHANGE); | ||
} | ||
/** | ||
* Returns a boolean indicating whether the settings object contains | ||
@@ -261,3 +334,3 @@ * the given key path. | ||
has(keyPath) { | ||
assert.strictEqual(typeof keyPath, 'string', 'Key path parameter must be a string'); | ||
assert.strictEqual(typeof keyPath, 'string', 'First parameter must be a string'); | ||
@@ -277,4 +350,4 @@ return this._checkKeyPathExists(keyPath); | ||
set(keyPath, value, opts = {}) { | ||
assert.strictEqual(typeof keyPath, 'string', 'Key path parameter must be a string. Did you mean to use `setAll()` instead?'); | ||
assert.strictEqual(typeof opts, 'object', 'Options parameter must be an object'); | ||
assert.strictEqual(typeof keyPath, 'string', 'First parameter must be a string. Did you mean to use `setAll()` instead?'); | ||
assert.strictEqual(typeof opts, 'object', 'Second parameter must be an object'); | ||
@@ -293,4 +366,4 @@ this._setValueAtKeyPath(keyPath, value, opts); | ||
setAll(obj, opts = {}) { | ||
assert.strictEqual(typeof obj, 'object', 'Obj parameter must be an object'); | ||
assert.strictEqual(typeof opts, 'object', 'Options parameter must be an object'); | ||
assert.strictEqual(typeof obj, 'object', 'First parameter must be an object'); | ||
assert.strictEqual(typeof opts, 'object', 'Second parameter must be an object'); | ||
@@ -310,3 +383,3 @@ this._setValueAtKeyPath('', obj, opts); | ||
get(keyPath, defaultValue) { | ||
assert.strictEqual(typeof keyPath, 'string', 'Key path parameter must be a string. Did you mean to use `getAll()` instead?'); | ||
assert.strictEqual(typeof keyPath, 'string', 'First parameter must be a string. Did you mean to use `getAll()` instead?'); | ||
@@ -335,4 +408,4 @@ return this._getValueAtKeyPath(keyPath, defaultValue); | ||
delete(keyPath, opts = {}) { | ||
assert.strictEqual(typeof keyPath, 'string', 'Key path parameter must be a string. Did you mean to use `deleteAll()` instead?'); | ||
assert.strictEqual(typeof opts, 'object', 'Options parameter must be an object'); | ||
assert.strictEqual(typeof keyPath, 'string', 'First parameter must be a string. Did you mean to use `deleteAll()` instead?'); | ||
assert.strictEqual(typeof opts, 'object', 'Second parameter must be an object'); | ||
@@ -350,3 +423,3 @@ this._deleteValueAtKeyPath(keyPath, opts); | ||
deleteAll(opts = {}) { | ||
assert.strictEqual(typeof opts, 'object', 'Options parameter must be an object'); | ||
assert.strictEqual(typeof opts, 'object', 'First parameter must be an object'); | ||
@@ -367,4 +440,4 @@ this._deleteValueAtKeyPath('', opts); | ||
watch(keyPath, handler) { | ||
assert.strictEqual(typeof keyPath, 'string', 'Key path parameter must be a string'); | ||
assert.strictEqual(typeof handler, 'function', 'Handler parameter must be a function'); | ||
assert.strictEqual(typeof keyPath, 'string', 'First parameter must be a string'); | ||
assert.strictEqual(typeof handler, 'function', 'Second parameter must be a function'); | ||
@@ -381,3 +454,3 @@ return this._watchValueAtKeyPath(keyPath, handler); | ||
file() { | ||
return this._getSettingsPath(); | ||
return this._settingsFilePath; | ||
} | ||
@@ -384,0 +457,0 @@ } |
{ | ||
"name": "electron-settings", | ||
"version": "3.0.10", | ||
"version": "3.0.11", | ||
"description": "A simple persistent user settings framework for Electron.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -214,2 +214,15 @@ /* global it, describe, before, after, beforeEach, afterEach */ | ||
it('should watch for changes not made by electron-settings', done => { | ||
settings.watch('foo.bar', function handler(newValue, oldValue) { | ||
assert.deepEqual(oldValue, 'baz'); | ||
assert.deepEqual(newValue, 'qux'); | ||
this.dispose(); | ||
done(); | ||
}); | ||
fs.writeFileSync(settings.file(), JSON.stringify({ foo: { bar: 'qux' } })); | ||
}); | ||
it('should return undefined if the watched key path is deleted', done => { | ||
@@ -216,0 +229,0 @@ settings.watch('foo.bar', function handler(newValue, oldValue) { |
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
29616
849