UNPKG

ac-node

Version:

A common module for building Atlassian Connect add-ons

146 lines (130 loc) 3.94 kB
var rsvp = require('rsvp'); var Promise = rsvp.Promise; var redis = require('redis'); var redisScan = require('redisscan'); var urls = require('url'); function RedisStore(redisUrlOrClient, scope) { if (!(this instanceof RedisStore)) { return new RedisStore(redisUrlOrClient, scope); } if (redisUrlOrClient) { if (typeof redisUrlOrClient === 'object') { this._client = redisUrlOrClient; } else { this._client = createClient(redisUrlOrClient); } } else { this._client = createClient('redis://localhost:6379'); } this._scope = scope; }; RedisStore.prototype._get = function (key) { var self = this; return new Promise(function (resolve, reject) { self._client.get(key, function (err, value) { if (err) return reject(err); value = JSON.parse(value); resolve(value); }); }); }; RedisStore.prototype.get = function (key) { return this._get(this._key(key)); }; RedisStore.prototype._set = function (key, value, expiresIn) { var self = this; var args = [key, JSON.stringify(value)]; if (expiresIn) { args.push('EX', expiresIn); } return new Promise(function (resolve, reject) { self._client.set.apply(self._client, args.concat(function (err) { if (err) return reject(err); resolve(); })); }); }; RedisStore.prototype.set = function (key, value, expiresIn) { return this._set(this._key(key), value, expiresIn); }; RedisStore.prototype._del = function (key) { var self = this; return new Promise(function (resolve, reject) { self._client.del(key, function (err) { if (err) return reject(err); resolve(); }); }); }; RedisStore.prototype.del = function (key) { return this._del(this._key(key)); }; RedisStore.prototype._all = function (scope, limit, offset) { var self = this; scope = scope || ''; var prefix = scope + (scope ? ':' : ''); limit = limit >>> 0; offset = offset >>> 0; var args = [offset, 'match', prefix + '*']; if (limit) { args.push('count', limit); } return new Promise(function (resolve, reject) { self._client.scan.apply(self._client, args.concat([function (err, results) { if (err) return reject(err); var page = {}; var keys = results[1]; if (keys && keys.length > 0) { self._client.mget.apply(self._client, keys.concat([function (err, values) { if (err) return reject(err); values.forEach(function (value, i) { page[keys[i].slice(prefix.length)] = JSON.parse(values[i]); }); resolve(page); }])); return; } resolve(page); }])); }); }; RedisStore.prototype.all = function (limit, offset) { return this._all(this._scope, limit, offset); }; RedisStore.prototype.narrow = function (subscope) { return new RedisStore(this._client, this._key(subscope)); }; RedisStore.prototype.clear = function () { var self = this; return new Promise(function (resolve, reject) { var pattern = (self._scope ? self._scope + ':' : '') + '*'; redisScan({ redis: self._client, pattern: pattern, // _unknown is an arg not defined in the docs and unclear from the scan lib code each_callback: function (type, key, subkey, _unknown, value, next) { self._del(key).then(next, next); }, done_callback: function (err) { if (err) return reject(err); resolve(); } }); }); }; RedisStore.prototype._key = function (key) { return this._scope ? this._scope + ':' + key : key; } RedisStore.create = function (config, scope) { var url = config.REDIS_ENV && process.env[config.REDIS_ENV]; return RedisStore(url, scope); }; function createClient(redisUrl) { var parsed = urls.parse(redisUrl); var client = redis.createClient(parsed.port, parsed.hostname); if (parsed.auth) { client.auth(parsed.auth.split(':')[1]); } return client; } module.exports = RedisStore;