{"_id":"@conpago/ioredis-mock","name":"@conpago/ioredis-mock","dist-tags":{"latest":"8.10.0"},"versions":{"8.10.0":{"name":"@conpago/ioredis-mock","version":"8.10.0","description":"This library emulates ioredis by performing all operations in-memory.","keywords":["fakeredis","in-memory","ioredis","ioredis-mock","mock-ioredis","mock-redis","redis","redis fake","redis inmemory","redis js","redis memory","redis mock","redis standalone","redis test","redis testing","redis-js","redis-mock","redisjs"],"homepage":"https://github.com/stipsan/ioredis-mock#readme","bugs":{"url":"https://github.com/conpagoaus/ioredis-mock/issues"},"repository":{"type":"git","url":"git+https://github.com/conpagoaus/ioredis-mock.git"},"license":"MIT","author":{"name":"Cody Olsen","email":"stipsan@gmail.com"},"main":"./lib","unpkg":"./browser.js","browser":{"stream":"stream-browserify","crypto":"crypto-browserify","./lib":"./browser.js"},"scripts":{"build:browser.js":"esbuild src/index.js --bundle --format=esm --outfile=browser.js --define:process=undefined --define:global.process=undefined --define:process.env.FENGARICONF=undefined --define:global=window  --define:process.browser=true --define:process.nextTick=nextTickShim --define:process.hrtime=hrtimeShim --define:setImmediate=nextTickShim --inject:./browser-shims.js --minify-syntax --sourcemap --external:ioredis/built/command","build:lib":"npx rimraf lib && esbuild src/index.js --outfile=lib/index.js --platform=node --target=node12 --bundle --external:fengari --external:fengari-interop --external:@ioredis/commands --external:@ioredis/as-callback --external:ioredis --external:./data/*.json --sourcemap --minify-syntax","precoverage":"npx rimraf coverage && npx mkdirp coverage","coverage":"jest --coverage","coveralls":"cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js","lint":"prettier --check . && eslint .","lint:fix":"prettier --write . && eslint . --fix","prepublishOnly":"npm run build:lib && npm run build:browser.js -- --minify-whitespace --minify-identifiers","test":"jest","posttest":"npm run build:lib && npm run test:integration && npm run build:browser.js && npm run test:browser.js","test:browser.js":"IS_BROWSER=true jest --config jest.config.browser.js","test:e2e":"IS_E2E=true jest --config jest.config.redis.js --runInBand","test:integration":"jest --config jest.config.integration.js","update-compat":"node scripts/update-compat && npx prettier --write compat.md && git add compat.md README.md && git commit --quiet -m \"docs: Update feature compat table\" &> /dev/null || true","update-data":"node scripts/update-data","publish:npm":"np"},"prettier":{"arrowParens":"avoid","semi":false,"singleQuote":true,"trailingComma":"es5"},"dependencies":{"@ioredis/as-callback":"^3.0.0","@ioredis/commands":"^1.2.0","fengari":"^0.1.4","fengari-interop":"^0.1.3","semver":"^7.7.2"},"devDependencies":{"@babel/cli":"^7.28.0","@babel/core":"^7.28.0","@babel/eslint-parser":"^7.28.0","@babel/preset-env":"^7.28.0","@babel/register":"^7.27.1","@sanity/semantic-release-preset":"^4.1.4","browser-process-hrtime":"^1.0.0","buffer":"^6.0.3","chance":"^1.1.13","coveralls":"^3.1.1","crypto-browserify":"^3.12.1","esbuild":"^0.25.5","eslint":"^8.50.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.0.0","eslint-plugin-import":"^2.28.1","eslint-plugin-jest":"^27.4.0","eslint-plugin-simple-import-sort":"^10.0.0","events":"^3.3.0","ioredis":"^5.6.1","np":"^10.2.0","jest":"^29.7.0","jest-buffer-snapshot-serializer":"^1.0.0","jest-circus":"^29.7.0","jest-environment-jsdom":"^29.7.0","lodash.intersectionby":"^4.7.0","lodash.isplainobject":"^4.0.6","lodash.orderby":"^4.6.0","lodash.shuffle":"^4.2.0","lodash.sortby":"^4.7.0","lodash.zipobject":"^4.1.3","ls-engines":"^0.9.0","mkdirp":"^3.0.1","prettier":"^3.6.2","prettier-plugin-packagejson":"^2.5.18","stream-browserify":"^3.0.0","stream-mock":"^2.0.5","url":"^0.11.3","write-file-atomic":"^5.0.1"},"peerDependencies":{"@types/ioredis-mock":"^8","ioredis":"^5"},"engines":{"node":">=12.22"},"runkitExampleFilename":"example.js","publishConfig":{"access":"public"},"gitHead":"0c6cba6680e666c5350d649f752ef0c893844254","_id":"@conpago/ioredis-mock@8.10.0","_nodeVersion":"24.3.0","_npmVersion":"9.6.7","dist":{"integrity":"sha512-O8YjF7pvCEX/+FwXqQJxQi7dL/WoKEehWHAWeF7awM2fWsxa96+hk4mHSxZqZyd6vuKjwoe+Yvom8RuMZYUvAA==","shasum":"f5e2b53970f96f8ff08de51d1c6206e3f5d55375","tarball":"https://registry.npmjs.org/@conpago/ioredis-mock/-/ioredis-mock-8.10.0.tgz","fileCount":13,"unpackedSize":7050786,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDMSP5ULUwQSPG+p66l1xpAvW3VbUjEzQ6XrhL2rOK0tQIgfr9MfC7nh30OySkiZaO+DEWblR6VhKCtMCAvw0IMibI="}]},"_npmUser":{"name":"etonello_conpago","email":"emanuele@conpago.com.au","actor":{"name":"etonello_conpago","email":"emanuele@conpago.com.au","type":"user"}},"directories":{},"maintainers":[{"name":"alex_conpago","email":"alex@conpago.com.au"},{"name":"etonello_conpago","email":"emanuele@conpago.com.au"},{"name":"0xvlado","email":"vladimir@conpago.com.au"},{"name":"nihar27_conpago","email":"nihar@conpago.com.au"},{"name":"bishwoconpago","email":"bishwo@conpago.com.au"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ioredis-mock_8.10.0_1751852782870_0.25817626847115194"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-07T01:46:22.701Z","8.10.0":"2025-07-07T01:46:23.102Z","modified":"2025-07-07T01:46:23.497Z"},"maintainers":[{"name":"alex_conpago","email":"alex@conpago.com.au"},{"name":"etonello_conpago","email":"emanuele@conpago.com.au"},{"name":"0xvlado","email":"vladimir@conpago.com.au"},{"name":"nihar27_conpago","email":"nihar@conpago.com.au"},{"name":"bishwoconpago","email":"bishwo@conpago.com.au"}],"description":"This library emulates ioredis by performing all operations in-memory.","homepage":"https://github.com/stipsan/ioredis-mock#readme","keywords":["fakeredis","in-memory","ioredis","ioredis-mock","mock-ioredis","mock-redis","redis","redis fake","redis inmemory","redis js","redis memory","redis mock","redis standalone","redis test","redis testing","redis-js","redis-mock","redisjs"],"repository":{"type":"git","url":"git+https://github.com/conpagoaus/ioredis-mock.git"},"author":{"name":"Cody Olsen","email":"stipsan@gmail.com"},"bugs":{"url":"https://github.com/conpagoaus/ioredis-mock/issues"},"license":"MIT","readme":"# ioredis-mock &middot; [![npm](https://img.shields.io/npm/dm/ioredis-mock.svg?style=flat-square)](https://npm-stat.com/charts.html?package=ioredis-mock) [![npm version](https://img.shields.io/npm/v/ioredis-mock.svg?style=flat-square)](https://www.npmjs.com/package/ioredis-mock) [![Redis Compatibility: 63%](https://img.shields.io/badge/redis-63%25-orange.svg?style=flat-square)](compat.md) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)\n\nThis library emulates [ioredis](https://github.com/luin/ioredis) by performing\nall operations in-memory. The best way to do integration testing against redis\nand ioredis is on a real redis-server instance. However, there are cases where\nmocking the redis-server is a better option.\n\nCases like:\n\n- Your workflow already use a local redis-server instance for the dev server.\n- You're on a platform\n  [without an official redis release](https://github.com/MSOpenTech/redis),\n  that's even worse than using an emulator.\n- You're running tests on a CI, setting it up is complicated. If you combine it\n  with CI that also run selenium acceptance testing it's even more complicated,\n  as two redis-server instances on the same CI build is hard.\n- The GitHub repo have bots that run the testing suite and is limited through\n  npm package.json install scripts and can't fire up servers. (Having\n  [Renovatebot](https://renovatebot.com/) notifying you when a new release of\n  ioredis is out and wether your code breaks or not is awesome).\n\nCheck the [compatibility table](compat.md) for supported redis commands.\n\n## Usage ([try it in your browser with RunKit](https://runkit.com/npm/ioredis-mock))\n\n```js\nconst Redis = require('ioredis-mock')\nconst redis = new Redis({\n  // `options.data` does not exist in `ioredis`, only `ioredis-mock`\n  data: {\n    user_next: '3',\n    emails: {\n      'clark@daily.planet': '1',\n      'bruce@wayne.enterprises': '2',\n    },\n    'user:1': { id: '1', username: 'superman', email: 'clark@daily.planet' },\n    'user:2': { id: '2', username: 'batman', email: 'bruce@wayne.enterprises' },\n  },\n})\n// Basically use it just like ioredis\n```\n\n## Browser usage (Experimental)\n\nThere's a browser build available. You can import it directly (`import Redis from 'ioredis-mock/browser.js'`), or use it on unpkg.com:\n\n```js\nimport Redis from 'https://unpkg.com/ioredis-mock'\n\nconst redis = new Redis()\nredis.set('foo', 'bar')\nconsole.log(await redis.get('foo'))\n```\n\n## Breaking Changes\n\n### from v7 to v8\n\n#### `ioredis@v4` support dropped\n\n`ioredis@v5` is the new baseline. Stay on `ioredis-mock@v7` until you're ready to upgrade to `ioredis@v5`.\n\n#### `PromiseContainer` has been removed.\n\nSupport for third-party Promise libraries is dropped. The native Promise library\nwill always be used.\n\n### from v6 to v7\n\n#### `createConnectedClient` is removed\n\nReplace it with `.duplicate()` or use another `new Redis` instance.\n\n#### Dropped support for Node v10\n\n[It's been EOL since Apr, 2021 and it's recommended to upgrade to v14.x LTS.](https://twitter.com/nodejs/status/1388116425361874945)\n\n#### `ioredis-mock/jest.js` is removed\n\n`ioredis-mock` is no longer doing a `import { Command } from 'ioredis'` internally, it's now doing a direct import `import Command from 'ioredis/built/command'` and thus the `jest.js` [workaround](https://github.com/stipsan/ioredis-mock/issues/568) is no longer needed:\n\n```diff\n-jest.mock('ioredis', () => require('ioredis-mock/jest'))\n+jest.mock('ioredis', () => require('ioredis-mock'))\n```\n\n### from v5 to v6\n\nBefore v6, each instance of `ioredis-mock` lived in isolation:\n\n```js\nconst Redis = require('ioredis-mock')\nconst redis1 = new Redis()\nconst redis2 = new Redis()\n\nawait redis1.set('foo', 'bar')\nconsole.log(await redis1.get('foo'), await redis2.get('foo')) // 'bar', null\n```\n\nIn v6 the [internals were rewritten](https://github.com/stipsan/ioredis-mock/pull/1110) to behave more like real life redis, if the host and port is the same, the context is now shared:\n\n```js\nconst Redis = require('ioredis-mock')\nconst redis1 = new Redis()\nconst redis2 = new Redis()\nconst redis3 = new Redis(6380) // 6379 is the default port\n\nawait redis1.set('foo', 'bar')\nconsole.log(\n  await redis1.get('foo'), // 'bar'\n  await redis2.get('foo'), // 'bar'\n  await redis3.get('foo') // null\n)\n```\n\nAnd since `ioredis-mock` now persist data between instances, you'll [likely](https://github.com/luin/ioredis/blob/8278ec0a435756c54ba4f98587aec1a913e8b7d3/test/helpers/global.ts#L8) need to run `flushall` between testing suites:\n\n```js\nconst Redis = require('ioredis-mock')\n\nafterEach(done => {\n  new Redis().flushall().then(() => done())\n})\n```\n\n## Pub/Sub channels\n\nWe also support redis [publish/subscribe](https://redis.io/topics/pubsub) channels.\nLike [ioredis](https://github.com/luin/ioredis#pubsub), you need two clients:\n\n```js\nconst Redis = require('ioredis-mock')\nconst redisPub = new Redis()\nconst redisSub = new Redis()\n\nredisSub.on('message', (channel, message) => {\n  console.log(`Received ${message} from ${channel}`)\n})\nredisSub.subscribe('emails')\nredisPub.publish('emails', 'clark@daily.planet')\n```\n\n## Lua scripting\n\nYou can use the `defineCommand` to define custom commands using lua or `eval` to directly execute lua code.\n\nIn order to create custom commands, using [lua](http://lua.org) scripting, [ioredis exposes the defineCommand method](https://github.com/luin/ioredis#lua-scripting).\n\nYou could define a custom command `multiply` which accepts one\nkey and one argument. A redis key, where you can get the multiplicand, and an argument which will be the multiplicator:\n\n```js\nconst Redis = require('ioredis-mock')\nconst redis = new Redis({ data: { k1: 5 } })\nconst commandDefinition = {\n  numberOfKeys: 1,\n  lua: 'return redis.call(\"GET\", KEYS[1]) * ARGV[1]',\n}\nredis.defineCommand('multiply', commandDefinition) // defineCommand(name, definition)\n// now we can call our brand new multiply command as an ordinary command\nredis.multiply('k1', 10).then(result => {\n  expect(result).toBe(5 * 10)\n})\n```\n\nYou can also achieve the same effect by using the `eval` command:\n\n```js\nconst Redis = require('ioredis-mock')\nconst redis = new Redis({ data: { k1: 5 } })\nconst result = redis.eval(`return redis.call(\"GET\", \"k1\") * 10`)\nexpect(result).toBe(5 * 10)\n```\n\nnote we are calling the ordinary redis `GET` command by using the global `redis` object's `call` method.\n\nAs a difference from ioredis we currently don't support:\n\n- dynamic key number by passing the number of keys as the first argument of the command.\n- automatic definition of the custom command buffer companion (i.e. for the custom command `multiply` the `multiplyBuffer` which returns values using `Buffer.from(...)`)\n- the `evalsha` command\n- the `script` command\n\n## Cluster(Experimental)\n\nWork on Cluster support has started, the current implementation is minimal and PRs welcome #359\n\n```js\nconst Redis = require('ioredis-mock')\n\nconst cluster = new Redis.Cluster(['redis://localhost:7001'])\nconst nodes = cluster.nodes()\nexpect(nodes.length).toEqual(1)\n```\n\n## [Roadmap](https://github.com/users/stipsan/projects/1/views/4)\n\nYou can check the [roadmap project page](https://github.com/users/stipsan/projects/1/views/4), and [the compat table](compat.md), to see how close we are to feature parity with `ioredis`.\n\n## I need a feature not listed here\n\nJust create an issue and tell us all about it or submit a PR with it! 😄\n","readmeFilename":"README.md","_rev":"1-d38597717db3448857993f8421bad4ef"}