cache-manager-redis-store
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -8,3 +8,7 @@ 'use strict'; | ||
var redisStore = function redisStore() { | ||
var redisCache = Redis.createClient.apply(Redis, arguments); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
var redisCache = Redis.createClient.apply(Redis, args); | ||
var storeArgs = redisCache.options; | ||
@@ -41,2 +45,63 @@ | ||
}, | ||
mset: function mset() { | ||
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
args[_key2] = arguments[_key2]; | ||
} | ||
var _this = this; | ||
return new Promise(function (resolve, reject) { | ||
var cb = void 0; | ||
var options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
cb = function cb(err, result) { | ||
return err ? reject(err) : resolve(result); | ||
}; | ||
} | ||
var ttl = options.ttl || options.ttl === 0 ? options.ttl : storeArgs.ttl; | ||
var multi = void 0; | ||
if (ttl) { | ||
multi = redisCache.multi(); | ||
} | ||
var key = void 0; | ||
var value = void 0; | ||
var parsed = []; | ||
for (var i = 0; i < args.length; i += 2) { | ||
key = args[i]; | ||
value = args[i + 1]; | ||
/** | ||
* Make sure the value is cacheable | ||
*/ | ||
if (!_this.isCacheableValue(value)) { | ||
return cb(new Error('value cannot be ' + value)); | ||
} | ||
value = JSON.stringify(value) || '"undefined"'; | ||
parsed.push.apply(parsed, [key, value]); | ||
if (ttl) { | ||
multi.setex(key, ttl, value); | ||
} | ||
} | ||
if (ttl) { | ||
multi.exec(handleResponse(cb)); | ||
} else { | ||
redisCache.mset.apply(redisCache, [].concat(parsed, [handleResponse(cb)])); | ||
} | ||
}); | ||
}, | ||
get: function get(key, options, cb) { | ||
@@ -57,8 +122,19 @@ return new Promise(function (resolve, reject) { | ||
}, | ||
del: function del(key, options, cb) { | ||
mget: function mget() { | ||
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
args[_key3] = arguments[_key3]; | ||
} | ||
return new Promise(function (resolve, reject) { | ||
if (typeof options === 'function') { | ||
cb = options; | ||
var cb = void 0; | ||
var options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
@@ -70,5 +146,31 @@ cb = function cb(err, result) { | ||
redisCache.del(key, handleResponse(cb)); | ||
redisCache.mget.apply(redisCache, [].concat(args, [handleResponse(cb, { parse: true })])); | ||
}); | ||
}, | ||
del: function del() { | ||
for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
args[_key4] = arguments[_key4]; | ||
} | ||
return new Promise(function (resolve, reject) { | ||
var cb = void 0; | ||
var options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
cb = function cb(err, result) { | ||
return err ? reject(err) : resolve(result); | ||
}; | ||
} | ||
redisCache.del.apply(redisCache, [].concat(args, [handleResponse(cb)])); | ||
}); | ||
}, | ||
reset: function reset(cb) { | ||
@@ -127,7 +229,17 @@ return new Promise(function (resolve, reject) { | ||
if (opts.parse) { | ||
try { | ||
result = JSON.parse(result); | ||
} catch (e) { | ||
return cb && cb(e); | ||
var isMultiple = Array.isArray(result); | ||
if (!isMultiple) { | ||
result = [result]; | ||
} | ||
result = result.map(function (_result) { | ||
try { | ||
_result = JSON.parse(_result); | ||
} catch (e) { | ||
return cb && cb(e); | ||
} | ||
return _result; | ||
}); | ||
result = isMultiple ? result : result[0]; | ||
} | ||
@@ -134,0 +246,0 @@ |
110
index.js
@@ -32,2 +32,57 @@ import Redis from 'redis'; | ||
), | ||
mset: function(...args) { | ||
const _this = this; | ||
return new Promise((resolve, reject) => { | ||
let cb; | ||
let options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
cb = (err, result) => (err ? reject(err) : resolve(result)); | ||
} | ||
const ttl = (options.ttl || options.ttl === 0) ? options.ttl : storeArgs.ttl; | ||
let multi; | ||
if (ttl) { | ||
multi = redisCache.multi(); | ||
} | ||
let key; | ||
let value; | ||
const parsed = []; | ||
for (let i = 0; i < args.length; i += 2) { | ||
key = args[i]; | ||
value = args[i + 1]; | ||
/** | ||
* Make sure the value is cacheable | ||
*/ | ||
if (!_this.isCacheableValue(value)) { | ||
return cb(new Error(`value cannot be ${value}`)); | ||
} | ||
value = JSON.stringify(value) || '"undefined"'; | ||
parsed.push(...[key, value]); | ||
if (ttl) { | ||
multi.setex(key, ttl, value); | ||
} | ||
} | ||
if (ttl) { | ||
multi.exec(handleResponse(cb)); | ||
} else { | ||
redisCache.mset.apply(redisCache, [...parsed, handleResponse(cb)]); | ||
} | ||
}); | ||
}, | ||
get: (key, options, cb) => ( | ||
@@ -46,15 +101,42 @@ new Promise((resolve, reject) => { | ||
), | ||
del: (key, options, cb) => ( | ||
mget: (...args) => ( | ||
new Promise((resolve, reject) => { | ||
if (typeof options === 'function') { | ||
cb = options; | ||
let cb; | ||
let options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
cb = (err, result) => (err ? reject(err) : resolve(result)); | ||
} | ||
redisCache.del(key, handleResponse(cb)); | ||
redisCache.mget.apply(redisCache, [...args, handleResponse(cb, { parse: true })]); | ||
}) | ||
), | ||
del: (...args) => ( | ||
new Promise((resolve, reject) => { | ||
let cb; | ||
let options = {}; | ||
if (typeof args[args.length - 1] === 'function') { | ||
cb = args.pop(); | ||
} | ||
if (args[args.length - 1] instanceof Object && args[args.length - 1].constructor === Object) { | ||
options = args.pop(); | ||
} | ||
if (!cb) { | ||
cb = (err, result) => (err ? reject(err) : resolve(result)); | ||
} | ||
redisCache.del.apply(redisCache, [...args, handleResponse(cb)]); | ||
}) | ||
), | ||
reset: cb => ( | ||
@@ -103,7 +185,17 @@ new Promise((resolve, reject) => { | ||
if (opts.parse) { | ||
try { | ||
result = JSON.parse(result); | ||
} catch (e) { | ||
return cb && cb(e); | ||
let isMultiple = Array.isArray(result); | ||
if (!isMultiple) { | ||
result = [result]; | ||
} | ||
result = result.map((_result) => { | ||
try { | ||
_result = JSON.parse(_result); | ||
} catch (e) { | ||
return cb && cb(e); | ||
} | ||
return _result; | ||
}); | ||
result = isMultiple ? result : result[0]; | ||
} | ||
@@ -110,0 +202,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"description": "Redis store for node-cache-manager", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"license": "MIT", | ||
@@ -29,3 +29,3 @@ "main": "dist/index.js", | ||
"babel-runtime": "^6.26.0", | ||
"cache-manager": "^2.4.0", | ||
"cache-manager": "^2.7.0", | ||
"coveralls": "^2.13.1", | ||
@@ -32,0 +32,0 @@ "jest": "^20.0.4", |
@@ -185,2 +185,110 @@ import cacheManager from 'cache-manager'; | ||
describe('mset', () => { | ||
it('should return a promise', (done) => { | ||
expect(redisCache.mset('foo', 'bar')).toBeInstanceOf(Promise); | ||
done(); | ||
}); | ||
it('should resolve promise on success', (done) => { | ||
redisCache.mset('foo', 'bar', 'foo2', 'bar2') | ||
.then(result => { | ||
expect(result[0]).toEqual('OK'); | ||
expect(result[1]).toEqual('OK'); | ||
done(); | ||
}); | ||
}); | ||
it('should reject promise on error', (done) => { | ||
redisCache.mset('foo') | ||
.then(() => done(new Error('Should reject'))) | ||
.catch((err) => done()); | ||
}); | ||
it('should store a value without ttl', (done) => { | ||
redisCache.mset('foo', 'bar', 'foo2', 'bar2', (err) => { | ||
expect(err).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
it('should store a value with a specific ttl', (done) => { | ||
redisCache.mset('foo', 'bar', 'foo2', 'bar2', { ttl: 60 }, (err) => { | ||
expect(err).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
it('should store a value with a infinite ttl', (done) => { | ||
redisCache.mset('foo', 'bar', { ttl: 0 }, (err) => { | ||
expect(err).toEqual(null); | ||
redisCache.ttl('foo', (err, ttl) => { | ||
expect(err).toEqual(null); | ||
expect(ttl).toEqual(-1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should not be able to store a null value (not cacheable)', (done) => { | ||
redisCache.mset('foo2', null, (err) => { | ||
if (err) { | ||
return done(); | ||
} | ||
}); | ||
}); | ||
it('should store a value without callback', (done) => { | ||
redisCache.mset('foo', 'baz', 'foo2', 'baz2'); | ||
redisCache.mget('foo', 'foo2', (err, values) => { | ||
expect(err).toEqual(null); | ||
expect(values[0]).toEqual('baz'); | ||
expect(values[1]).toEqual('baz2'); | ||
done(); | ||
}); | ||
}); | ||
it('should not store an invalid value', (done) => { | ||
redisCache.mset('foo1', undefined, (err) => { | ||
if (err !== null) { | ||
expect(err).not.toEqual(null); | ||
expect(err.message).toEqual('value cannot be undefined'); | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('should store an undefined value if permitted by isCacheableValue', (done) => { | ||
expect(customRedisCache.store.isCacheableValue(undefined)).toBe(true); | ||
customRedisCache.mset('foo3', undefined, 'foo4', undefined, (err) => { | ||
expect(err).toEqual(null); | ||
customRedisCache.mget('foo3', 'foo4', (err, data) => { | ||
expect(err).toEqual(null); | ||
// redis stored undefined as 'undefined' | ||
expect(data[0]).toEqual('undefined'); | ||
expect(data[1]).toEqual('undefined'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should not store a value disallowed by isCacheableValue', (done) => { | ||
expect(customRedisCache.store.isCacheableValue('FooBarString')).toBe(false); | ||
customRedisCache.mset('foobar', 'FooBarString', (err) => { | ||
expect(err).not.toEqual(null); | ||
expect(err.message).toEqual('value cannot be FooBarString'); | ||
if (err !== null) { | ||
done(); | ||
} | ||
}); | ||
}); | ||
it('should return an error if there is an error acquiring a connection', (done) => { | ||
redisCache.store.getClient().end(true); | ||
redisCache.mset('foo', 'bar', (err) => { | ||
expect(err).not.toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('get', () => { | ||
@@ -246,2 +354,69 @@ it('should return a promise', (done) => { | ||
describe('mget', () => { | ||
it('should return a promise', () => { | ||
expect(redisCache.mget('foo', 'foo2')).toBeInstanceOf(Promise); | ||
}); | ||
it('should resolve promise on success', (done) => { | ||
redisCache.mset('foo', 'bar') | ||
.then(() => redisCache.mget('foo')) | ||
.then(result => { | ||
expect(result).toEqual(['bar']); | ||
done(); | ||
}); | ||
}); | ||
it('should reject promise on error', (done) => { | ||
const client = redisCache.store.getClient(); | ||
client.mget = (key, cb) => cb(new Error('Something went wrong')); | ||
redisCache.mget('foo') | ||
.catch((err) => { | ||
expect(err.message).toEqual('Something went wrong'); | ||
done(); | ||
}) | ||
}); | ||
it('should retrieve a value for a given key', (done) => { | ||
const value = 'bar'; | ||
const value2 = 'bar2'; | ||
redisCache.mset('foo', value, 'foo2', value2, () => { | ||
redisCache.mget('foo', 'foo2', (err, result) => { | ||
expect(err).toEqual(null); | ||
expect(result[0]).toEqual(value); | ||
expect(result[1]).toEqual(value2); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should retrieve a value for a given key if options provided', (done) => { | ||
const value = 'bar'; | ||
redisCache.mset('foo', value, () => { | ||
redisCache.mget('foo', { someConfig: true }, (err, result) => { | ||
expect(err).toEqual(null); | ||
expect(result).toEqual([value]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should return null when the key is invalid', (done) => { | ||
redisCache.mget('invalidKey', 'otherInvalidKey', (err, result) => { | ||
expect(err).toEqual(null); | ||
expect(result[0]).toEqual(null); | ||
expect(result[1]).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
it('should return an error if there is an error acquiring a connection', (done) => { | ||
redisCache.store.getClient().end(true); | ||
redisCache.mget('foo', (err) => { | ||
expect(err).not.toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('del', () => { | ||
@@ -252,3 +427,3 @@ it('should return a promise', (done) => { | ||
}); | ||
it('should delete a value for a given key', (done) => { | ||
@@ -258,3 +433,6 @@ redisCache.set('foo', 'bar', () => { | ||
expect(err).toEqual(null); | ||
done(); | ||
redisCache.get('foo', (err, result) => { | ||
expect(result).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
@@ -264,2 +442,28 @@ }); | ||
it('should delete a unlimited number of keys', (done) => { | ||
redisCache.mset('foo', 'bar', 'foo2', 'bar2', () => { | ||
redisCache.del('foo', 'foo2', (err) => { | ||
expect(err).toEqual(null); | ||
redisCache.mget('foo', 'foo2', (err, result) => { | ||
expect(result[0]).toEqual(null); | ||
expect(result[1]).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should delete an Array of keys', (done) => { | ||
redisCache.mset('foo', 'bar', 'foo2', 'bar2', () => { | ||
redisCache.del(['foo', 'foo2'], (err) => { | ||
expect(err).toEqual(null); | ||
redisCache.mget('foo', 'foo2', (err, result) => { | ||
expect(result[0]).toEqual(null); | ||
expect(result[1]).toEqual(null); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should delete a value for a given key without callback', (done) => { | ||
@@ -266,0 +470,0 @@ redisCache.set('foo', 'bar', () => { |
Sorry, the diff of this file is not supported yet
38553
1019