Updated eslint rules

This commit is contained in:
zneix 2020-08-28 04:39:03 +02:00
parent 4a583a52ce
commit e4eeec3d27
19 changed files with 1096 additions and 550 deletions

View File

@ -1,25 +1,23 @@
{ {
"env": { "env": {
"es6": true, "es2020": true,
"node": true "node": true
}, },
"extends": "eslint:recommended", "extends": "eslint:recommended",
"rules": { "parserOptions": {
"indent": [ "ecmaVersion": 11
"error", },
2 "rules": {
], "indent": [ "error", "tab" ],
"linebreak-style": [ "linebreak-style": [ "error", "unix" ],
"error", "quotes": [ "error", "single" ],
"unix" "semi": [ "error", "always" ],
], "no-console": "warn",
"quotes": [ "no-unused-vars": "warn",
"error", "max-len": ["warn", 150],
"single" "require-await": "warn"
], },
"semi": [ "globals": {
"error", "winston": "writable"
"always" }
]
}
} }

View File

@ -3,129 +3,129 @@ const Busboy = require('busboy');
// For handling serving stored documents // For handling serving stored documents
const DocumentHandler = function(options) { const DocumentHandler = function(options){
if (!options) options = new Object; if (!options) options = new Object;
this.keyLength = options.keyLength || DocumentHandler.defaultKeyLength; this.keyLength = options.keyLength || DocumentHandler.defaultKeyLength;
this.maxLength = options.maxLength; // none by default this.maxLength = options.maxLength; // none by default
this.store = options.store; this.store = options.store;
this.keyGenerator = options.keyGenerator; this.keyGenerator = options.keyGenerator;
}; };
DocumentHandler.defaultKeyLength = 10; DocumentHandler.defaultKeyLength = 10;
// Handle retrieving a document // Handle retrieving a document
DocumentHandler.prototype.handleGet = async function(key, res, skipExpire) { DocumentHandler.prototype.handleGet = async function(key, res, skipExpire){
await this.store.get(key, function(ret) { await this.store.get(key, function(ret){
if (ret) { if (ret){
winston.verbose('retrieved document', { key: key }); winston.verbose('retrieved document', { key: key });
res.writeHead(200, { 'content-type': 'application/json' }); res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify({ data: ret, key: key })); res.end(JSON.stringify({ data: ret, key: key }));
} }
else { else {
winston.warn('document not found', { key: key }); winston.warn('document not found', { key: key });
res.writeHead(404, { 'content-type': 'application/json' }); res.writeHead(404, { 'content-type': 'application/json' });
res.end(JSON.stringify({ message: 'Document not found.' })); res.end(JSON.stringify({ message: 'Document not found.' }));
} }
}, skipExpire); }, skipExpire);
}; };
// Handle retrieving the raw version of a document // Handle retrieving the raw version of a document
DocumentHandler.prototype.handleGetRaw = async function(key, res, skipExpire) { DocumentHandler.prototype.handleGetRaw = async function(key, res, skipExpire){
await this.store.get(key, function(ret) { await this.store.get(key, function(ret){
if (ret) { if (ret){
winston.verbose('retrieved raw document', { key: key }); winston.verbose('retrieved raw document', { key: key });
res.writeHead(200, { 'content-type': 'text/plain; charset=UTF-8' }); res.writeHead(200, { 'content-type': 'text/plain; charset=UTF-8' });
res.end(ret); res.end(ret);
} }
else { else {
winston.warn('raw document not found', { key: key }); winston.warn('raw document not found', { key: key });
res.writeHead(404, { 'content-type': 'application/json' }); res.writeHead(404, { 'content-type': 'application/json' });
res.end(JSON.stringify({ message: 'Document not found.' })); res.end(JSON.stringify({ message: 'Document not found.' }));
} }
}, skipExpire); }, skipExpire);
}; };
// Handle adding a new Document // Handle adding a new Document
DocumentHandler.prototype.handlePost = async function (req, res) { DocumentHandler.prototype.handlePost = function (req, res){
let _this = this; let _this = this;
let buffer = ''; let buffer = '';
let cancelled = false; let cancelled = false;
// What to do when done // What to do when done
let onSuccess = async function () { let onSuccess = async function (){
// Check length // Check length
if (_this.maxLength && buffer.length > _this.maxLength) { if (_this.maxLength && buffer.length > _this.maxLength){
cancelled = true; cancelled = true;
winston.warn('document >maxLength', { maxLength: _this.maxLength }); winston.warn('document >maxLength', { maxLength: _this.maxLength });
res.writeHead(400, { 'content-type': 'application/json' }); res.writeHead(400, { 'content-type': 'application/json' });
res.end( res.end(
JSON.stringify({ message: 'Document exceeds maximum length.' }) JSON.stringify({ message: 'Document exceeds maximum length.' })
); );
return; return;
} }
// And then save if we should // And then save if we should
await _this.chooseKey(async function (key) { await _this.chooseKey(async function (key){
await _this.store.set(key, buffer, function (resp) { await _this.store.set(key, buffer, function (resp){
if (resp) { if (resp){
winston.verbose('added document', { key: key }); winston.verbose('added document', { key: key });
res.writeHead(200, { 'content-type': 'application/json' }); res.writeHead(200, { 'content-type': 'application/json' });
res.end(JSON.stringify({ key: key })); res.end(JSON.stringify({ key: key }));
} }
else { else {
winston.verbose('error adding document'); winston.verbose('error adding document');
res.writeHead(500, { 'content-type': 'application/json' }); res.writeHead(500, { 'content-type': 'application/json' });
res.end(JSON.stringify({ message: 'Error adding document.' })); res.end(JSON.stringify({ message: 'Error adding document.' }));
} }
}); });
}); });
}; };
// If we should, parse a form to grab the data // If we should, parse a form to grab the data
let ct = req.headers['content-type']; let ct = req.headers['content-type'];
if (ct && ct.split(';')[0] == 'multipart/form-data') { if (ct && ct.split(';')[0] == 'multipart/form-data'){
let busboy = new Busboy({ headers: req.headers }); let busboy = new Busboy({ headers: req.headers });
busboy.on('field', function (fieldname, val) { busboy.on('field', function (fieldname, val){
if (fieldname == 'data') { if (fieldname == 'data'){
buffer = val; buffer = val;
} }
}); });
busboy.on('finish', async function () { busboy.on('finish', async function (){
await onSuccess(); await onSuccess();
}); });
req.pipe(busboy); req.pipe(busboy);
// Otherwise, use our own and just grab flat data from POST body // Otherwise, use our own and just grab flat data from POST body
} else { } else {
req.on('data', function (data) { req.on('data', function (data){
buffer += data.toString(); buffer += data.toString();
}); });
req.on('end', async function () { req.on('end', async function (){
if (cancelled) { return; } if (cancelled){ return; }
await onSuccess(); await onSuccess();
}); });
req.on('error', function (error) { req.on('error', function (error){
winston.error('connection error: ' + error.message); winston.error('connection error: ' + error.message);
res.writeHead(500, { 'content-type': 'application/json' }); res.writeHead(500, { 'content-type': 'application/json' });
res.end(JSON.stringify({ message: 'Connection error.' })); res.end(JSON.stringify({ message: 'Connection error.' }));
cancelled = true; cancelled = true;
}); });
} }
}; };
// Keep choosing keys until one isn't taken // Keep choosing keys until one isn't taken
DocumentHandler.prototype.chooseKey = async function(callback) { DocumentHandler.prototype.chooseKey = async function(callback){
let key = this.acceptableKey(); let key = this.acceptableKey();
let _this = this; let _this = this;
await this.store.get(key, function(ret) { await this.store.get(key, function(ret){
if (ret) { if (ret){
_this.chooseKey(callback); _this.chooseKey(callback);
} else { } else {
callback(key); callback(key);
} }
}, true); // Don't bump expirations when key searching }, true); // Don't bump expirations when key searching
}; };
DocumentHandler.prototype.acceptableKey = function() { DocumentHandler.prototype.acceptableKey = function(){
return this.keyGenerator.createKey(this.keyLength); return this.keyGenerator.createKey(this.keyLength);
}; };
module.exports = DocumentHandler; module.exports = DocumentHandler;

View File

@ -1,56 +1,54 @@
/*global require,module,process*/
const AWS = require('aws-sdk'); const AWS = require('aws-sdk');
const winston = require('winston'); const winston = require('winston');
const AmazonS3DocumentStore = function(options) { const AmazonS3DocumentStore = function(options){
this.expire = options.expire; this.expire = options.expire;
this.bucket = options.bucket; this.bucket = options.bucket;
this.client = new AWS.S3({region: options.region}); this.client = new AWS.S3({region: options.region});
}; };
AmazonS3DocumentStore.prototype.get = function(key, callback, skipExpire) { AmazonS3DocumentStore.prototype.get = function(key, callback, skipExpire){
const _this = this; const _this = this;
const req = { const req = {
Bucket: _this.bucket, Bucket: _this.bucket,
Key: key Key: key
}; };
_this.client.getObject(req, function(err, data) { _this.client.getObject(req, function(err, data){
if(err) { if(err){
callback(false); callback(false);
} }
else { else {
callback(data.Body.toString('utf-8')); callback(data.Body.toString('utf-8'));
if (_this.expire && !skipExpire) { if (_this.expire && !skipExpire){
winston.warn('amazon s3 store cannot set expirations on keys'); winston.warn('amazon s3 store cannot set expirations on keys');
} }
} }
}); });
} };
AmazonS3DocumentStore.prototype.set = function(key, data, callback, skipExpire) { AmazonS3DocumentStore.prototype.set = function(key, data, callback, skipExpire){
const _this = this; const _this = this;
const req = { const req = {
Bucket: _this.bucket, Bucket: _this.bucket,
Key: key, Key: key,
Body: data, Body: data,
ContentType: 'text/plain' ContentType: 'text/plain'
}; };
_this.client.putObject(req, function(err, data) { _this.client.putObject(req, function(err, data){
if (err) { if (err){
callback(false); callback(false);
} }
else { else {
callback(true); callback(true);
if (_this.expire && !skipExpire) { if (_this.expire && !skipExpire){
winston.warn('amazon s3 store cannot set expirations on keys'); winston.warn('amazon s3 store cannot set expirations on keys');
} }
} }
}); });
} };
module.exports = AmazonS3DocumentStore; module.exports = AmazonS3DocumentStore;

View File

@ -7,57 +7,57 @@ const winston = require('winston');
// options[type] = file // options[type] = file
// options[path] - Where to store // options[path] - Where to store
const FileDocumentStore = function(options) { const FileDocumentStore = function(options){
this.basePath = options.path || './data'; this.basePath = options.path || './data';
this.expire = options.expire; this.expire = options.expire;
}; };
// Generate md5 of a string // Generate md5 of a string
FileDocumentStore.md5 = function(str) { FileDocumentStore.md5 = function(str){
let md5sum = crypto.createHash('md5'); let md5sum = crypto.createHash('md5');
md5sum.update(str); md5sum.update(str);
return md5sum.digest('hex'); return md5sum.digest('hex');
}; };
// Save data in a file, key as md5 - since we don't know what we could // Save data in a file, key as md5 - since we don't know what we could
// be passed here // be passed here
FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) { FileDocumentStore.prototype.set = function(key, data, callback, skipExpire){
try { try {
const _this = this; const _this = this;
fs.mkdir(this.basePath, '700', function() { fs.mkdir(this.basePath, '700', function(){
const fn = _this.basePath + '/' + FileDocumentStore.md5(key); const fn = _this.basePath + '/' + FileDocumentStore.md5(key);
fs.writeFile(fn, data, 'utf8', function(err) { fs.writeFile(fn, data, 'utf8', function(err){
if (err) { if (err){
callback(false); callback(false);
} }
else { else {
callback(true); callback(true);
if (_this.expire && !skipExpire) { if (_this.expire && !skipExpire){
winston.warn('file store cannot set expirations on keys'); winston.warn('file store cannot set expirations on keys');
} }
} }
}); });
}); });
} catch(err) { } catch(err){
callback(false); callback(false);
} }
}; };
// Get data from a file from key // Get data from a file from key
FileDocumentStore.prototype.get = function(key, callback, skipExpire) { FileDocumentStore.prototype.get = function(key, callback, skipExpire){
const _this = this; const _this = this;
const fn = require('path').join(this.basePath, FileDocumentStore.md5(key)); const fn = require('path').join(this.basePath, FileDocumentStore.md5(key));
fs.readFile(fn, 'utf8', function(err, data) { fs.readFile(fn, 'utf8', function(err, data){
if (err) { if (err){
callback(false); callback(false);
} }
else { else {
callback(data); callback(data);
if (_this.expire && !skipExpire) { if (_this.expire && !skipExpire){
winston.warn('file store cannot set expirations on keys'); winston.warn('file store cannot set expirations on keys');
} }
} }
}); });
}; };
module.exports = FileDocumentStore; module.exports = FileDocumentStore;

View File

@ -3,49 +3,49 @@ const winston = require('winston');
class MemcachedDocumentStore { class MemcachedDocumentStore {
// Create a new store with options // Create a new store with options
constructor(options) { constructor(options){
this.expire = options.expire; this.expire = options.expire;
const host = options.host || '127.0.0.1'; const host = options.host || '127.0.0.1';
const port = options.port || 11211; const port = options.port || 11211;
const url = `${host}:${port}`; const url = `${host}:${port}`;
this.connect(url); this.connect(url);
} }
// Create a connection // Create a connection
connect(url) { connect(url){
this.client = new memcached(url); this.client = new memcached(url);
winston.info(`connecting to memcached on ${url}`); winston.info(`connecting to memcached on ${url}`);
this.client.on('failure', function(error) { this.client.on('failure', function(error){
winston.info('error connecting to memcached', {error}); winston.info('error connecting to memcached', {error});
}); });
} }
// Save file in a key // Save file in a key
set(key, data, callback, skipExpire) { set(key, data, callback, skipExpire){
this.client.set(key, data, skipExpire ? 0 : this.expire, (error) => { this.client.set(key, data, skipExpire ? 0 : this.expire, (error) => {
callback(!error); callback(!error);
}); });
} }
// Get a file from a key // Get a file from a key
get(key, callback, skipExpire) { get(key, callback, skipExpire){
this.client.get(key, (error, data) => { this.client.get(key, (error, data) => {
callback(error ? false : data); callback(error ? false : data);
// Update the key so that the expiration is pushed forward // Update the key so that the expiration is pushed forward
if (!skipExpire) { if (!skipExpire){
this.set(key, data, (updateSucceeded) => { this.set(key, data, (updateSucceeded) => {
if (!updateSucceeded) { if (!updateSucceeded){
winston.error('failed to update expiration on GET', {key}); winston.error('failed to update expiration on GET', {key});
} }
}, skipExpire); }, skipExpire);
} }
}); });
} }
} }

View File

@ -11,7 +11,7 @@ MongoDocumentStore.prototype.set = async function (key, data, callback, skipExpi
const now = Math.floor(Date.now() / 1000); const now = Math.floor(Date.now() / 1000);
const that = this; const that = this;
this.safeConnect(async ( {error} = {} ) => { await this.safeConnect(async ( {error} = {} ) => {
if (error) return callback(false); if (error) return callback(false);
await this.MongoClient.db().collection('entries').updateOne( await this.MongoClient.db().collection('entries').updateOne(
@ -32,13 +32,14 @@ MongoDocumentStore.prototype.set = async function (key, data, callback, skipExpi
{ {
upsert: true upsert: true
} }
).then((err, result) => { )
return callback(true); .then((err, result) => {
}) return callback(true);
.catch((err, result) => { })
winston.error('error updating mongodb document', { error: err }); .catch((err, result) => {
return callback(false); winston.error('error updating mongodb document', { error: err });
}); return callback(false);
});
}); });
}; };
@ -47,20 +48,20 @@ MongoDocumentStore.prototype.get = async function (key, callback, skipExpire){
const now = Math.floor(Date.now() / 1000); const now = Math.floor(Date.now() / 1000);
const that = this; const that = this;
this.safeConnect(async ( {error} = {} ) => { await this.safeConnect(async ( {error} = {} ) => {
if (error) return callback(false); if (error) return callback(false);
let document = await this.MongoClient.db().collection('entries').findOne({ let document = await this.MongoClient.db().collection('entries').findOne({
'entry_id': key, 'entry_id': key,
or: [ $or: [
{ expiration: -1 }, { expiration: -1 },
{ expiration: { $gt: now } } { expiration: { $gt: now } }
] ]
}) })
.catch(err => { .catch(err => {
winston.error('error finding mongodb document', { error: err }); winston.error('error finding mongodb document', { error: err });
return callback(false); return callback(false);
}); });
callback(document ? document.value : false); callback(document ? document.value : false);
@ -71,7 +72,7 @@ MongoDocumentStore.prototype.get = async function (key, callback, skipExpire){
).catch(err => { ).catch(err => {
return winston.warn('error extending expiry of mongodb document', { error: err }); return winston.warn('error extending expiry of mongodb document', { error: err });
}); });
winston.silly('extended expiry of mongodb document', { key: key, timestamp: that.expire + now }) winston.silly('extended expiry of mongodb document', { key: key, timestamp: that.expire + now });
} }
}); });
}; };

View File

@ -1,4 +1,4 @@
/*global require,module,process*/ // /*global require,module,process*/
const postgres = require('pg'); const postgres = require('pg');
const winston = require('winston'); const winston = require('winston');
@ -6,73 +6,74 @@ const winston = require('winston');
// create table entries (id serial primary key, key varchar(255) not null, value text not null, expiration int, unique(key)); // create table entries (id serial primary key, key varchar(255) not null, value text not null, expiration int, unique(key));
// A postgres document store // A postgres document store
const PostgresDocumentStore = function (options) { const PostgresDocumentStore = function (options){
this.expireJS = options.expire; this.expireJS = options.expire;
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl; this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl;
}; };
PostgresDocumentStore.prototype = { PostgresDocumentStore.prototype = {
// Set a given key // Set a given key
set: function (key, data, callback, skipExpire) { set: function (key, data, callback, skipExpire){
const now = Math.floor(Date.now() / 1000); const now = Math.floor(Date.now() / 1000);
const that = this; const that = this;
this.safeConnect(function (err, client, done) { this.safeConnect(function (err, client, done){
if (err) { return callback(false); } if (err){ return callback(false); }
client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [ client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [
key, key,
data, data,
that.expireJS && !skipExpire ? that.expireJS + now : null that.expireJS && !skipExpire ? that.expireJS + now : null
], function (err) { ], function (err){
if (err) { if (err){
winston.error('error persisting value to postgres', { error: err }); winston.error('error persisting value to postgres', { error: err });
return callback(false); return callback(false);
} }
callback(true); callback(true);
done(); done();
}); });
}); });
}, },
// Get a given key's data // Get a given key's data
get: function (key, callback, skipExpire) { get: function (key, callback, skipExpire){
const now = Math.floor(Date.now() / 1000); const now = Math.floor(Date.now() / 1000);
const that = this; const that = this;
this.safeConnect(function (err, client, done) { this.safeConnect(function (err, client, done){
if (err) { return callback(false); } if (err){ return callback(false); }
client.query('SELECT id,value,expiration from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now], function (err, result) { client.query('SELECT id,value,expiration from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now],
if (err) { function (err, result){
winston.error('error retrieving value from postgres', { error: err }); if (err){
return callback(false); winston.error('error retrieving value from postgres', { error: err });
} return callback(false);
callback(result.rows.length ? result.rows[0].value : false); }
if (result.rows.length && that.expireJS && !skipExpire) { callback(result.rows.length ? result.rows[0].value : false);
client.query('UPDATE entries SET expiration = $1 WHERE ID = $2', [ if (result.rows.length && that.expireJS && !skipExpire){
that.expireJS + now, client.query('UPDATE entries SET expiration = $1 WHERE ID = $2', [
result.rows[0].id that.expireJS + now,
], function (err) { result.rows[0].id
if (!err) { ], function (err){
done(); if (!err){
} done();
}); }
} else { });
done(); } else {
} done();
}); }
}); });
}, });
},
// A connection wrapper // A connection wrapper
safeConnect: function (callback) { safeConnect: function (callback){
postgres.connect(this.connectionUrl, function (err, client, done) { postgres.connect(this.connectionUrl, function (err, client, done){
if (err) { if (err){
winston.error('error connecting to postgres', { error: err }); winston.error('error connecting to postgres', { error: err });
callback(err); callback(err);
} else { } else {
callback(undefined, client, done); callback(undefined, client, done);
} }
}); });
} }
}; };

View File

@ -8,82 +8,82 @@ const winston = require('winston');
// options[db] - The db to use (default 0) // options[db] - The db to use (default 0)
// options[expire] - The time to live for each key set (default never) // options[expire] - The time to live for each key set (default never)
var RedisDocumentStore = function(options, client) { var RedisDocumentStore = function(options, client){
this.expire = options.expire; this.expire = options.expire;
if (client) { if (client){
winston.info('using predefined redis client'); winston.info('using predefined redis client');
RedisDocumentStore.client = client; RedisDocumentStore.client = client;
} else if (!RedisDocumentStore.client) { } else if (!RedisDocumentStore.client){
winston.info('configuring redis'); winston.info('configuring redis');
RedisDocumentStore.connect(options); RedisDocumentStore.connect(options);
} }
}; };
// Create a connection according to config // Create a connection according to config
RedisDocumentStore.connect = function(options) { RedisDocumentStore.connect = function(options){
var host = options.host || '127.0.0.1'; var host = options.host || '127.0.0.1';
var port = options.port || 6379; var port = options.port || 6379;
var index = options.db || 0; var index = options.db || 0;
RedisDocumentStore.client = redis.createClient(port, host); RedisDocumentStore.client = redis.createClient(port, host);
// authenticate if password is provided // authenticate if password is provided
if (options.password) { if (options.password){
RedisDocumentStore.client.auth(options.password); RedisDocumentStore.client.auth(options.password);
} }
RedisDocumentStore.client.on('error', function(err) { RedisDocumentStore.client.on('error', function(err){
winston.error('redis disconnected', err); winston.error('redis disconnected', err);
}); });
RedisDocumentStore.client.select(index, function(err) { RedisDocumentStore.client.select(index, function(err){
if (err) { if (err){
winston.error( winston.error(
'error connecting to redis index ' + index, 'error connecting to redis index ' + index,
{ error: err } { error: err }
); );
process.exit(1); process.exit(1);
} }
else { else {
winston.info('connected to redis on ' + host + ':' + port + '/' + index); winston.info('connected to redis on ' + host + ':' + port + '/' + index);
} }
}); });
}; };
// Save file in a key // Save file in a key
RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) { RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire){
var _this = this; var _this = this;
RedisDocumentStore.client.set(key, data, function(err) { RedisDocumentStore.client.set(key, data, function(err){
if (err) { if (err){
callback(false); callback(false);
} }
else { else {
if (!skipExpire) { if (!skipExpire){
_this.setExpiration(key); _this.setExpiration(key);
} }
callback(true); callback(true);
} }
}); });
}; };
// Expire a key in expire time if set // Expire a key in expire time if set
RedisDocumentStore.prototype.setExpiration = function(key) { RedisDocumentStore.prototype.setExpiration = function(key){
if (this.expire) { if (this.expire){
RedisDocumentStore.client.expire(key, this.expire, function(err) { RedisDocumentStore.client.expire(key, this.expire, function(err){
if (err) { if (err){
winston.error('failed to set expiry on key: ' + key); winston.error('failed to set expiry on key: ' + key);
} }
}); });
} }
}; };
// Get a file from a key // Get a file from a key
RedisDocumentStore.prototype.get = function(key, callback, skipExpire) { RedisDocumentStore.prototype.get = function(key, callback, skipExpire){
var _this = this; var _this = this;
RedisDocumentStore.client.get(key, function(err, reply) { RedisDocumentStore.client.get(key, function(err, reply){
if (!err && !skipExpire) { if (!err && !skipExpire){
_this.setExpiration(key); _this.setExpiration(key);
} }
callback(err ? false : reply); callback(err ? false : reply);
}); });
}; };
module.exports = RedisDocumentStore; module.exports = RedisDocumentStore;

View File

@ -3,44 +3,44 @@ const rethink = require('rethinkdbdash');
const winston = require('winston'); const winston = require('winston');
const md5 = (str) => { const md5 = (str) => {
const md5sum = crypto.createHash('md5'); const md5sum = crypto.createHash('md5');
md5sum.update(str); md5sum.update(str);
return md5sum.digest('hex'); return md5sum.digest('hex');
}; };
class RethinkDBStore { class RethinkDBStore {
constructor(options) { constructor(options){
this.client = rethink({ this.client = rethink({
silent: true, silent: true,
host: options.host || '127.0.0.1', host: options.host || '127.0.0.1',
port: options.port || 28015, port: options.port || 28015,
db: options.db || 'haste', db: options.db || 'haste',
user: options.user || 'admin', user: options.user || 'admin',
password: options.password || '' password: options.password || ''
}); });
} }
set(key, data, callback) { set(key, data, callback){
this.client.table('uploads').insert({ id: md5(key), data: data }).run((error) => { this.client.table('uploads').insert({ id: md5(key), data: data }).run((error) => {
if (error) { if (error){
callback(false); callback(false);
winston.error('failed to insert to table', error); winston.error('failed to insert to table', error);
return; return;
} }
callback(true); callback(true);
}); });
} }
get(key, callback) { get(key, callback){
this.client.table('uploads').get(md5(key)).run((error, result) => { this.client.table('uploads').get(md5(key)).run((error, result) => {
if (error || !result) { if (error || !result){
callback(false); callback(false);
if (error) winston.error('failed to insert to table', error); if (error) winston.error('failed to insert to table', error);
return; return;
} }
callback(result.data); callback(result.data);
}); });
} }
} }
module.exports = RethinkDBStore; module.exports = RethinkDBStore;

View File

@ -2,31 +2,31 @@ const fs = require('fs');
module.exports = class DictionaryGenerator { module.exports = class DictionaryGenerator {
constructor(options, readyCallback) { constructor(options, readyCallback){
// Check options format // Check options format
if (!options) throw Error('No options passed to generator'); if (!options) throw Error('No options passed to generator');
if (!options.path) throw Error('No dictionary path specified in options'); if (!options.path) throw Error('No dictionary path specified in options');
// Load dictionary // Load dictionary
fs.readFile(options.path, 'utf8', (err, data) => { fs.readFile(options.path, 'utf8', (err, data) => {
if (err) throw err; if (err) throw err;
this.dictionary = data.split(/[\n\r]+/); this.dictionary = data.split(/[\n\r]+/);
if (readyCallback) readyCallback(); if (readyCallback) readyCallback();
}); });
} }
// Generates a dictionary-based key, of keyLength words // Generates a dictionary-based key, of keyLength words
createKey(keyLength) { createKey(keyLength){
let text = ''; let text = '';
for (let i = 0; i < keyLength; i++) { for (let i = 0; i < keyLength; i++){
const index = Math.floor(Math.random() * this.dictionary.length); const index = Math.floor(Math.random() * this.dictionary.length);
text += this.dictionary[index]; text += this.dictionary[index];
} }
return text; return text;
} }
}; };

View File

@ -1,9 +1,9 @@
// Draws inspiration from pwgen and http://tools.arantius.com/password // Draws inspiration from pwgen and http://tools.arantius.com/password
const randOf = (collection) => { const randOf = (collection) => {
return () => { return () => {
return collection[Math.floor(Math.random() * collection.length)]; return collection[Math.floor(Math.random() * collection.length)];
}; };
}; };
// Helper methods to get an random vowel or consonant // Helper methods to get an random vowel or consonant
@ -12,16 +12,16 @@ const randConsonant = randOf('bcdfghjklmnpqrstvwxyz');
module.exports = class PhoneticKeyGenerator { module.exports = class PhoneticKeyGenerator {
// Generate a phonetic key of alternating consonant & vowel // Generate a phonetic key of alternating consonant & vowel
createKey(keyLength) { createKey(keyLength){
let text = ''; let text = '';
const start = Math.floor(Math.random() * 2); const start = Math.floor(Math.random() * 2);
for (let i = 0; i < keyLength; i++) { for (let i = 0; i < keyLength; i++){
text += (i % 2 == start) ? randConsonant() : randVowel(); text += (i % 2 == start) ? randConsonant() : randVowel();
} }
return text; return text;
} }
}; };

View File

@ -1,20 +1,20 @@
module.exports = class RandomKeyGenerator { module.exports = class RandomKeyGenerator {
// Initialize a new generator with the given keySpace // Initialize a new generator with the given keySpace
constructor(options = {}) { constructor(options = {}){
this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; this.keyspace = options.keyspace || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
} }
// Generate a key of the given length // Generate a key of the given length
createKey(keyLength) { createKey(keyLength){
let text = ''; let text = '';
for (let i = 0; i < keyLength; i++) { for (let i = 0; i < keyLength; i++){
const index = Math.floor(Math.random() * this.keyspace.length); const index = Math.floor(Math.random() * this.keyspace.length);
text += this.keyspace.charAt(index); text += this.keyspace.charAt(index);
} }
return text; return text;
} }
}; };

View File

@ -1,13 +1,13 @@
module.exports = class HasteUtils { module.exports = class HasteUtils {
//init class //init class
constructor(options = {}){ constructor(options = {}){
//xd no options for now //xd no options for now
} }
//stringify json objects from winston message to cool "key=value" format //stringify json objects from winston message to cool "key=value" format
stringifyJSONMessagetoLogs(info){ stringifyJSONMessagetoLogs(info){
//really KKona solution, but works for now //really KKona solution, but works for now
let keys = Object.keys(info).filter(k => k != 'message' && k != 'level'); let keys = Object.keys(info).filter(k => k != 'message' && k != 'level');
return keys.map(k => `${k}=${info[k]}`).join(', '); return keys.map(k => `${k}=${info[k]}`).join(', ');
} }
} };

547
package-lock.json generated
View File

@ -306,6 +306,30 @@
"negotiator": "0.6.2" "negotiator": "0.6.2"
} }
}, },
"acorn": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true
},
"acorn-jsx": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
"integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
"dev": true
},
"ajv": {
"version": "6.12.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-colors": { "ansi-colors": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
@ -364,6 +388,12 @@
"is-string": "^1.0.4" "is-string": "^1.0.4"
} }
}, },
"astral-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
"async": { "async": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
@ -718,6 +748,12 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
}, },
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"camelcase": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
@ -906,6 +942,17 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
}, },
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"debug": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@ -920,6 +967,12 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true "dev": true
}, },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@ -957,6 +1010,15 @@
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true "dev": true
}, },
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"ee-first": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -978,6 +1040,15 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
}, },
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1"
}
},
"es-abstract": { "es-abstract": {
"version": "1.17.6", "version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
@ -1046,12 +1117,177 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true "dev": true
}, },
"eslint": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz",
"integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.0",
"eslint-utils": "^2.1.0",
"eslint-visitor-keys": "^1.3.0",
"espree": "^7.2.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.19",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^3.1.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
"table": "^5.2.3",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
}
}
},
"eslint-scope": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
},
"espree": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
"integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
"dev": true,
"requires": {
"acorn": "^7.4.0",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.3.0"
}
},
"esprima": { "esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true "dev": true
}, },
"esquery": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"esrecurse": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"dev": true,
"requires": {
"estraverse": "^4.1.0"
}
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true
},
"esutils": { "esutils": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@ -1111,6 +1347,24 @@
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.1.3.tgz", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.1.3.tgz",
"integrity": "sha512-TINcxve5510pXj4n9/1AMupkj3iWxl3JuZaWhCdYDlZeoCPqweGZrxbrlqTCFb1CT5wli7s8e2SH/Qz2c9GorA==" "integrity": "sha512-TINcxve5510pXj4n9/1AMupkj3iWxl3JuZaWhCdYDlZeoCPqweGZrxbrlqTCFb1CT5wli7s8e2SH/Qz2c9GorA=="
}, },
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fast-safe-stringify": { "fast-safe-stringify": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
@ -1126,6 +1380,15 @@
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz", "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
"integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==" "integrity": "sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg=="
}, },
"file-entry-cache": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
"integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
"dev": true,
"requires": {
"flat-cache": "^2.0.1"
}
},
"fill-range": { "fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -1168,6 +1431,23 @@
"is-buffer": "~2.0.3" "is-buffer": "~2.0.3"
} }
}, },
"flat-cache": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
"integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
"dev": true,
"requires": {
"flatted": "^2.0.0",
"rimraf": "2.6.3",
"write": "1.0.3"
}
},
"flatted": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
"dev": true
},
"fn.name": { "fn.name": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
@ -1206,6 +1486,12 @@
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
}, },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
"gensync": { "gensync": {
"version": "1.0.0-beta.1", "version": "1.0.0-beta.1",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@ -1307,6 +1593,28 @@
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
}, },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"import-fresh": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"inflight": { "inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -1482,6 +1790,18 @@
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
}, },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"json5": { "json5": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
@ -1495,6 +1815,16 @@
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
}, },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"locate-path": { "locate-path": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -1656,6 +1986,12 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}, },
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"negotiator": { "negotiator": {
"version": "0.6.2", "version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
@ -1722,6 +2058,20 @@
"fn.name": "1.x.x" "fn.name": "1.x.x"
} }
}, },
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.3"
}
},
"p-limit": { "p-limit": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
@ -1751,6 +2101,15 @@
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
}, },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0"
}
},
"parseurl": { "parseurl": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -1768,6 +2127,12 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true "dev": true
}, },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"path-parse": { "path-parse": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
@ -1862,11 +2227,23 @@
"xtend": "^4.0.0" "xtend": "^4.0.0"
} }
}, },
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"process-nextick-args": { "process-nextick-args": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
}, },
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
"promise.allsettled": { "promise.allsettled": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz", "resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.2.tgz",
@ -1894,6 +2271,12 @@
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
}, },
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"qs": { "qs": {
"version": "6.7.0", "version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
@ -1980,6 +2363,12 @@
"redis": ">= 0.0.1" "redis": ">= 0.0.1"
} }
}, },
"regexpp": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
"require-directory": { "require-directory": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@ -2000,6 +2389,21 @@
"path-parse": "^1.0.6" "path-parse": "^1.0.6"
} }
}, },
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"safe-buffer": { "safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -2073,6 +2477,21 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
}, },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"simple-swizzle": { "simple-swizzle": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@ -2081,6 +2500,43 @@
"is-arrayish": "^0.3.1" "is-arrayish": "^0.3.1"
} }
}, },
"slice-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
"integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"astral-regex": "^1.0.0",
"is-fullwidth-code-point": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}
}
},
"source-map": { "source-map": {
"version": "0.5.7", "version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@ -2195,11 +2651,57 @@
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
} }
}, },
"table": {
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
"integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
"lodash": "^4.17.14",
"slice-ansi": "^2.1.0",
"string-width": "^3.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"text-hex": { "text-hex": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
}, },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"through": { "through": {
"version": "2.3.8", "version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@ -2229,6 +2731,21 @@
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
}, },
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
"type-is": { "type-is": {
"version": "1.6.18", "version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@ -2243,6 +2760,15 @@
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
}, },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -2264,6 +2790,12 @@
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
}, },
"v8-compile-cache": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
"dev": true
},
"vary": { "vary": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@ -2347,6 +2879,12 @@
} }
} }
}, },
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"workerpool": { "workerpool": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.0.tgz",
@ -2422,6 +2960,15 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true "dev": true
}, },
"write": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
"integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
"dev": true,
"requires": {
"mkdirp": "^0.5.1"
}
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

View File

@ -26,6 +26,7 @@
"winston": "^3.3.3" "winston": "^3.3.3"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.7.0",
"mocha": "^8.1.2" "mocha": "^8.1.2"
}, },
"bin": { "bin": {

View File

@ -18,7 +18,7 @@
// Handle pops // Handle pops
let handlePop = function(evt){ let handlePop = function(evt){
let path = evt.target.location.pathname; let path = evt.target.location.pathname;
if (path == '/') { app.newDocument(true); } if (path == '/'){ app.newDocument(true); }
else { app.loadDocument(path.substring(1, path.length)); } else { app.loadDocument(path.substring(1, path.length)); }
}; };
// Set up the pop state to handle loads, skipping the first load // Set up the pop state to handle loads, skipping the first load
@ -26,7 +26,7 @@
// http://code.google.com/p/chromium/issues/detail?id=63040 // http://code.google.com/p/chromium/issues/detail?id=63040
setTimeout(function(){ setTimeout(function(){
window.onpopstate = function(evt){ window.onpopstate = function(evt){
try { handlePop(evt); } catch(err) { /* not loaded yet */ } try { handlePop(evt); } catch(err){ /* not loaded yet */ }
}; };
}, 1000); }, 1000);
// Construct app and load initial path // Construct app and load initial path

View File

@ -5,22 +5,22 @@ const assert = require('assert');
const DocumentHandler = require('../lib/document_handler'); const DocumentHandler = require('../lib/document_handler');
const Generator = require('../lib/key_generators/random'); const Generator = require('../lib/key_generators/random');
describe('document_handler', function() { describe('document_handler', function(){
describe('randomKey', function() { describe('randomKey', function(){
it('should choose a key of the proper length', function() { it('should choose a key of the proper length', function(){
let gen = new Generator(); let gen = new Generator();
let dh = new DocumentHandler({ keyLength: 6, keyGenerator: gen }); let dh = new DocumentHandler({ keyLength: 6, keyGenerator: gen });
assert.equal(6, dh.acceptableKey().length); assert.equal(6, dh.acceptableKey().length);
}); });
it('should choose a default key length', function() { it('should choose a default key length', function(){
let gen = new Generator(); let gen = new Generator();
let dh = new DocumentHandler({ keyGenerator: gen }); let dh = new DocumentHandler({ keyGenerator: gen });
assert.equal(dh.keyLength, DocumentHandler.defaultKeyLength); assert.equal(dh.keyLength, DocumentHandler.defaultKeyLength);
}); });
}); });
}); });

View File

@ -6,28 +6,28 @@ const fs = require('fs');
const Generator = require('../../lib/key_generators/dictionary'); const Generator = require('../../lib/key_generators/dictionary');
describe('RandomKeyGenerator', function() { describe('RandomKeyGenerator', function(){
describe('randomKey', function() { describe('randomKey', function(){
it('should throw an error if given no options', () => { it('should throw an error if given no options', () => {
assert.throws(() => { assert.throws(() => {
new Generator(); new Generator();
}, Error); }, Error);
}); });
it('should throw an error if given no path', () => { it('should throw an error if given no path', () => {
assert.throws(() => { assert.throws(() => {
new Generator({}); new Generator({});
}, Error); }, Error);
}); });
it('should return a key of the proper number of words from the given dictionary', () => { it('should return a key of the proper number of words from the given dictionary', () => {
const path = '/tmp/haste-server-test-dictionary'; const path = '/tmp/haste-server-test-dictionary';
const words = ['cat']; const words = ['cat'];
fs.writeFileSync(path, words.join('\n')); fs.writeFileSync(path, words.join('\n'));
const gen = new Generator({path}, () => { const gen = new Generator({path}, () => {
assert.equal('catcatcat', gen.createKey(3)); assert.equal('catcatcat', gen.createKey(3));
}); });
}); });
}); });
}); });

View File

@ -7,48 +7,48 @@ winston.remove(winston.transports.Console);
const RedisDocumentStore = require('../lib/document_stores/redis'); const RedisDocumentStore = require('../lib/document_stores/redis');
describe('redis_document_store', function() { describe('redis_document_store', function(){
/* reconnect to redis on each test */ /* reconnect to redis on each test */
afterEach(function() { afterEach(function(){
if (RedisDocumentStore.client) { if (RedisDocumentStore.client){
RedisDocumentStore.client.quit(); RedisDocumentStore.client.quit();
RedisDocumentStore.client = false; RedisDocumentStore.client = false;
} }
}); });
describe('set', function() { describe('set', function(){
it('should be able to set a key and have an expiration set', function(done) { it('should be able to set a key and have an expiration set', function(done){
let store = new RedisDocumentStore({ expire: 10 }); let store = new RedisDocumentStore({ expire: 10 });
store.set('hello1', 'world', function() { store.set('hello1', 'world', function(){
RedisDocumentStore.client.ttl('hello1', function(err, res) { RedisDocumentStore.client.ttl('hello1', function(err, res){
assert.ok(res > 1); assert.ok(res > 1);
done(); done();
}); });
}); });
}); });
it('should not set an expiration when told not to', function(done) { it('should not set an expiration when told not to', function(done){
let store = new RedisDocumentStore({ expire: 10 }); let store = new RedisDocumentStore({ expire: 10 });
store.set('hello2', 'world', function() { store.set('hello2', 'world', function(){
RedisDocumentStore.client.ttl('hello2', function(err, res) { RedisDocumentStore.client.ttl('hello2', function(err, res){
assert.equal(-1, res); assert.equal(-1, res);
done(); done();
}); });
}, true); }, true);
}); });
it('should not set an expiration when expiration is off', function(done) { it('should not set an expiration when expiration is off', function(done){
let store = new RedisDocumentStore({ expire: false }); let store = new RedisDocumentStore({ expire: false });
store.set('hello3', 'world', function() { store.set('hello3', 'world', function(){
RedisDocumentStore.client.ttl('hello3', function(err, res) { RedisDocumentStore.client.ttl('hello3', function(err, res){
assert.equal(-1, res); assert.equal(-1, res);
done(); done();
}); });
}); });
}); });
}); });
}); });