UNPKG

@silverwind/ioredis-mock

Version:

This library emulates ioredis by performing all operations in-memory.

146 lines (115 loc) 4.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Command = void 0; exports.default = command; exports.isInSubscriberMode = isInSubscriberMode; exports.isNotConnected = isNotConnected; exports.processArguments = processArguments; exports.processReply = processReply; exports.safelyExecuteCommand = safelyExecuteCommand; exports.throwIfCommandIsNotAllowed = throwIfCommandIsNotAllowed; exports.throwIfInSubscriberMode = throwIfInSubscriberMode; exports.throwIfNotConnected = throwIfNotConnected; var _lodash = _interopRequireDefault(require("lodash")); var _standardAsCallback = _interopRequireDefault(require("standard-as-callback")); var _ioredis = require("ioredis"); var _promiseContainer = _interopRequireDefault(require("./promise-container")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function isInSubscriberMode(RedisMock) { if (RedisMock.channels === undefined) { return false; } return RedisMock.subscriberMode; } function isNotConnected(RedisMock) { if (RedisMock.connected === undefined) { return false; } return !RedisMock.connected; } function throwIfInSubscriberMode(commandName, RedisMock) { if (isInSubscriberMode(RedisMock)) { const allowedCommands = ['subscribe', 'psubscribe', 'unsubscribe', 'punsubscribe', 'ping', 'quit', 'disconnect']; if (allowedCommands.indexOf(commandName) > -1) {// command is allowed -> do not throw } else { throw new Error('Connection in subscriber mode, only subscriber commands may be used'); } } } function throwIfNotConnected(commandName, RedisMock) { if (isNotConnected(RedisMock)) { if (commandName !== 'connect' && commandName !== 'defineCommand') { throw new Error("Stream isn't writeable and enableOfflineQueue options is false"); } } } function throwIfCommandIsNotAllowed(commandName, RedisMock) { throwIfInSubscriberMode(commandName, RedisMock); throwIfNotConnected(commandName, RedisMock); } const Command = { // eslint-disable-next-line no-underscore-dangle transformers: _ioredis.Command._transformer, setArgumentTransformer: (name, func) => { Command.transformers.argument[name] = func; }, setReplyTransformer: (name, func) => { Command.transformers.reply[name] = func; } }; /** * Transform non-buffer arguments to strings to simulate real ioredis behavior * @param {any} arg the argument to transform */ exports.Command = Command; const argMapper = arg => { if (arg === null || arg === undefined) return ''; return arg instanceof Buffer ? arg : arg.toString(); }; function processArguments(args, commandName) { // fast return, the defineCommand command requires NO transformation of args if (commandName === 'defineCommand') return args; let commandArgs = args ? _lodash.default.flatten(args) : []; if (Command.transformers.argument[commandName]) { commandArgs = Command.transformers.argument[commandName](args); } commandArgs = commandArgs.map(argMapper); return commandArgs; } function processReply(result, commandName) { if (Command.transformers.reply[commandName]) { // ioredis' reply transformer seems to receive array of arrays for // the hgetall command, emulate this let newResult = result; if (commandName === 'hgetall') { newResult = _lodash.default.flatten(Object.entries(result)); } return Command.transformers.reply[commandName](newResult); } return result; } function safelyExecuteCommand(commandEmulator, commandName, RedisMock, ...commandArgs) { throwIfCommandIsNotAllowed(commandName, RedisMock); const result = commandEmulator(...commandArgs); return processReply(result, commandName); } function command(commandEmulator, commandName, RedisMock) { return (...args) => { const lastArgIndex = args.length - 1; let callback = args[lastArgIndex]; if (typeof callback !== 'function') { callback = undefined; } else { // eslint-disable-next-line no-param-reassign args.length = lastArgIndex; } const commandArgs = processArguments(args, commandName, RedisMock); if (commandName === 'defineCommand') { return safelyExecuteCommand(commandEmulator, commandName, RedisMock, ...commandArgs); } const Promise = _promiseContainer.default.get(); return (0, _standardAsCallback.default)(new Promise(resolve => resolve(safelyExecuteCommand(commandEmulator, commandName, RedisMock, ...commandArgs))), callback); }; }