diff --git a/axios-cache-adapter.d.ts b/axios-cache-adapter.d.ts index 0e8c8bf..8b23013 100644 --- a/axios-cache-adapter.d.ts +++ b/axios-cache-adapter.d.ts @@ -119,6 +119,7 @@ export declare function setup(options: AxiosRequestConfig): AxiosInstance; export declare function setupCache(options: IAxiosCacheAdapterOptions) : ISetupCache; export class RedisStore { constructor(client: any, HASH_KEY?: string); } +export class IoRedisStore { constructor(client: any, HASH_KEY?: string); } export interface IAxiosCacheAdapterRequest { diff --git a/package.json b/package.json index 54c1c54..d7861a9 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "codecov": "^3.0.0", "html-webpack-plugin": "^3.0.6", "husky": "^1.1.2", + "ioredis-mock": "^4.18.4", "istanbul-instrumenter-loader": "^3.0.0", "karma": "^2.0.0", "karma-chrome-launcher": "^3.1.0", diff --git a/src/index.node.js b/src/index.node.js index 42838f7..75332a1 100644 --- a/src/index.node.js +++ b/src/index.node.js @@ -1,5 +1,6 @@ import { setup, setupCache, serializeQuery } from './api' import RedisStore from './redis' +import IoRedisStore from './ioredis' -export { setup, setupCache, serializeQuery, RedisStore } -export default { setup, setupCache, serializeQuery, RedisStore } +export { setup, setupCache, serializeQuery, RedisStore, IoRedisStore } +export default { setup, setupCache, serializeQuery, RedisStore, IoRedisStore } diff --git a/src/ioredis.js b/src/ioredis.js new file mode 100644 index 0000000..33f3fef --- /dev/null +++ b/src/ioredis.js @@ -0,0 +1,38 @@ +import { mapObject } from './utilities' + +class IoRedisStore { + constructor (client, HASH_KEY = 'axios-cache') { + this.client = client + this.HASH_KEY = HASH_KEY + } + + async getItem (key) { + const item = (await this.client.hget(this.HASH_KEY, key)) || null + + return JSON.parse(item) + } + + async setItem (key, value) { + await this.client.hset(this.HASH_KEY, key, JSON.stringify(value)) + return value + } + + async removeItem (key) { + await this.client.hdel(this.HASH_KEY, key) + } + + async clear () { + await this.client.del(this.HASH_KEY) + } + + async length () { + return this.client.hlen(this.HASH_KEY) + } + + async iterate (fn) { + const hashData = await this.client.hgetall(this.HASH_KEY) + return Promise.all(mapObject(hashData, fn)) + } +} + +export default IoRedisStore diff --git a/test/spec/ioredis.spec.js b/test/spec/ioredis.spec.js new file mode 100644 index 0000000..ff944a8 --- /dev/null +++ b/test/spec/ioredis.spec.js @@ -0,0 +1,74 @@ +/* globals describe it beforeEach */ + +import assert from 'assert' +import Redis from 'ioredis-mock' +import RedisStore from 'src/ioredis' + +describe('Redis store', () => { + let store + const client = new Redis() + + beforeEach(() => { + store = new RedisStore(client) + }) + + it('Should accept custom HASH_KEY', async () => { + const expected = 'customHash' + store = new RedisStore(client, expected) + assert.equal(store.HASH_KEY, expected) + }) + + it('getItem(): Should retrieve an item', async () => { + const expected = 'bar' + + await store.setItem('foo', expected) + + const value = await store.getItem('foo') + + assert.equal(value, expected) + }) + + it('setItem(): Should set an item', async () => { + const expected = 'bar' + + await store.setItem('foo', expected) + + const value = await store.getItem('foo') + + assert.equal(value, expected) + }) + + it('removeItem(): Should remove an item', async () => { + await store.setItem('foo', 'bar') + + await store.removeItem('foo') + + const value = await store.getItem('foo') + assert.equal(value, null) + }) + + it('clear(): Should clear all set values', async () => { + await store.setItem('foo', 'bar') + await store.setItem('hello', 'hello') + + await store.clear() + + const length = await store.length() + + assert.equal(length, 0) + }) + + it('Should serialize stored data to prevent modification by reference', async () => { + const data = { + key: 'value' + } + + await store.setItem('key', data) + + data.key = 'other value' + + const storedData = await store.getItem('key') + + assert.notEqual(data.key, storedData.key) + }) +})