-
-
Notifications
You must be signed in to change notification settings - Fork 57
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9c62976
commit 9ed0378
Showing
5 changed files
with
96 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
* text=auto | ||
*.js text eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,104 @@ | ||
'use strict'; | ||
var path = require('path'); | ||
var osTmpdir = require('os').tmpdir; | ||
var fs = require('graceful-fs'); | ||
var osenv = require('osenv'); | ||
var mkdirp = require('mkdirp'); | ||
var uuid = require('uuid'); | ||
var xdgBasedir = require('xdg-basedir'); | ||
var writeFileAtomic = require('write-file-atomic'); | ||
var dotProp = require('dot-prop'); | ||
|
||
var user = (osenv.user() || uuid.v4()).replace(/\\/g, ''); | ||
var configDir = xdgBasedir.config || path.join(osTmpdir(), user, '.config'); | ||
var permissionError = 'You don\'t have access to this file.'; | ||
var defaultPathMode = parseInt('0700', 8); | ||
var writeFileOptions = {mode: parseInt('0600', 8)}; | ||
|
||
function Configstore(id, defaults, opts) { | ||
opts = opts || {}; | ||
|
||
var pathPrefix = opts.globalConfigPath ? | ||
path.join(id, 'config.json') : | ||
path.join('configstore', id + '.json'); | ||
|
||
this.path = path.join(configDir, pathPrefix); | ||
|
||
this.all = Object.assign({}, defaults || {}, this.all || {}); | ||
} | ||
|
||
Configstore.prototype = Object.create(Object.prototype, { | ||
all: { | ||
get: function () { | ||
try { | ||
return JSON.parse(fs.readFileSync(this.path, 'utf8')); | ||
} catch (err) { | ||
// create dir if it doesn't exist | ||
if (err.code === 'ENOENT') { | ||
mkdirp.sync(path.dirname(this.path), defaultPathMode); | ||
return {}; | ||
} | ||
|
||
// improve the message of permission errors | ||
if (err.code === 'EACCES') { | ||
err.message = err.message + '\n' + permissionError + '\n'; | ||
} | ||
|
||
// empty the file if it encounters invalid JSON | ||
if (err.name === 'SyntaxError') { | ||
writeFileAtomic.sync(this.path, '', writeFileOptions); | ||
return {}; | ||
} | ||
|
||
throw err; | ||
} | ||
}, | ||
set: function (val) { | ||
try { | ||
// make sure the folder exists as it | ||
// could have been deleted in the meantime | ||
const path = require('path'); | ||
const osTmpdir = require('os').tmpdir; | ||
const fs = require('graceful-fs'); | ||
const osenv = require('osenv'); | ||
const mkdirp = require('mkdirp'); | ||
const uuid = require('uuid'); | ||
const xdgBasedir = require('xdg-basedir'); | ||
const writeFileAtomic = require('write-file-atomic'); | ||
const dotProp = require('dot-prop'); | ||
|
||
const user = (osenv.user() || uuid.v4()).replace(/\\/g, ''); | ||
const configDir = xdgBasedir.config || path.join(osTmpdir(), user, '.config'); | ||
const permissionError = 'You don\'t have access to this file.'; | ||
const defaultPathMode = 0o0700; | ||
const writeFileOptions = {mode: 0o0600}; | ||
|
||
class Configstore { | ||
constructor(id, defaults, opts) { | ||
opts = opts || {}; | ||
|
||
const pathPrefix = opts.globalConfigPath ? | ||
path.join(id, 'config.json') : | ||
path.join('configstore', `${id}.json`); | ||
|
||
this.path = path.join(configDir, pathPrefix); | ||
this.all = Object.assign({}, defaults, this.all); | ||
} | ||
get all() { | ||
try { | ||
return JSON.parse(fs.readFileSync(this.path, 'utf8')); | ||
} catch (err) { | ||
// Create dir if it doesn't exist | ||
if (err.code === 'ENOENT') { | ||
mkdirp.sync(path.dirname(this.path), defaultPathMode); | ||
return {}; | ||
} | ||
|
||
writeFileAtomic.sync(this.path, JSON.stringify(val, null, '\t'), writeFileOptions); | ||
} catch (err) { | ||
// improve the message of permission errors | ||
if (err.code === 'EACCES') { | ||
err.message = err.message + '\n' + permissionError + '\n'; | ||
} | ||
// Improve the message of permission errors | ||
if (err.code === 'EACCES') { | ||
err.message = `${err.message}\n${permissionError}\n`; | ||
} | ||
|
||
throw err; | ||
// Empty the file if it encounters invalid JSON | ||
if (err.name === 'SyntaxError') { | ||
writeFileAtomic.sync(this.path, '', writeFileOptions); | ||
return {}; | ||
} | ||
} | ||
}, | ||
size: { | ||
get: function () { | ||
return Object.keys(this.all || {}).length; | ||
|
||
throw err; | ||
} | ||
} | ||
}); | ||
|
||
Configstore.prototype.get = function (key) { | ||
return dotProp.get(this.all, key); | ||
}; | ||
set all(val) { | ||
try { | ||
// Make sure the folder exists as it could have been deleted in the meantime | ||
mkdirp.sync(path.dirname(this.path), defaultPathMode); | ||
|
||
writeFileAtomic.sync(this.path, JSON.stringify(val, null, '\t'), writeFileOptions); | ||
} catch (err) { | ||
// Improve the message of permission errors | ||
if (err.code === 'EACCES') { | ||
err.message = `${err.message}\n${permissionError}\n`; | ||
} | ||
|
||
Configstore.prototype.set = function (key, val) { | ||
var config = this.all; | ||
if (arguments.length === 1) { | ||
Object.keys(key).forEach(function (k) { | ||
dotProp.set(config, k, key[k]); | ||
}); | ||
} else { | ||
dotProp.set(config, key, val); | ||
throw err; | ||
} | ||
} | ||
this.all = config; | ||
}; | ||
|
||
Configstore.prototype.has = function (key) { | ||
return dotProp.has(this.all, key); | ||
}; | ||
get size() { | ||
return Object.keys(this.all || {}).length; | ||
} | ||
get(key) { | ||
return dotProp.get(this.all, key); | ||
} | ||
set(key, val) { | ||
const config = this.all; | ||
|
||
Configstore.prototype.delete = Configstore.prototype.del = function (key) { | ||
var config = this.all; | ||
dotProp.delete(config, key); | ||
this.all = config; | ||
}; | ||
if (arguments.length === 1) { | ||
for (const k of Object.keys(key)) { | ||
dotProp.set(config, k, key[k]); | ||
} | ||
} else { | ||
dotProp.set(config, key, val); | ||
} | ||
|
||
Configstore.prototype.clear = function () { | ||
this.all = {}; | ||
}; | ||
this.all = config; | ||
} | ||
has(key) { | ||
return dotProp.has(this.all, key); | ||
} | ||
delete(key) { | ||
const config = this.all; | ||
dotProp.delete(config, key); | ||
this.all = config; | ||
} | ||
clear() { | ||
this.all = {}; | ||
} | ||
// DEPRECATED | ||
del(key) { | ||
this.delete(key); | ||
} | ||
} | ||
|
||
module.exports = Configstore; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,6 @@ | |
}, | ||
"devDependencies": { | ||
"ava": "*", | ||
"path-exists": "^3.0.0", | ||
"xo": "*" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters