Socket
Socket
Sign inDemoInstall

handy-redis

Package Overview
Dependencies
3
Maintainers
1
Versions
37
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.8.3 to 2.0.0

dist/flatten.js.map

0

dist/flatten.d.ts
export declare const flattenDeep: (array: any[]) => any[];

12

dist/flatten.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.flattenDeep = void 0;
exports.flattenDeep = (array) => {
const flat = [];
for (const item of array) {
const values = Array.isArray(item) ? exports.flattenDeep(item) : [item];
for (const val of values) {
flat.push(val);
if (Array.isArray(item)) {
for (const val of exports.flattenDeep(item)) {
flat.push(val);
}
}
else {
flat.push(item);
}
}
return flat;
};
//# sourceMappingURL=flatten.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=interface.js.map

@@ -1,10 +0,1 @@

import { ClientOpts, RedisClient } from "redis";
import { IHandyRedis } from "./generated/interface";
export { IHandyRedis } from "./generated/interface";
export interface ICreateHandyClient {
(port_arg: number, host_arg?: string, options?: ClientOpts): IHandyRedis;
(unix_socket: string, options?: ClientOpts): IHandyRedis;
(options?: ClientOpts): IHandyRedis;
(redisClient: RedisClient): IHandyRedis;
}
export declare const createHandyClient: ICreateHandyClient;
export { addNodeRedisCommand, createNodeRedisClient, WrappedNodeRedisClient, CreateNodeRedisClient, createNodeRedisClient as createHandyClient, WrappedNodeRedisClient as IHandyRedis, } from "./node_redis";
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const redis_1 = require("redis");
const flatten_1 = require("./flatten");
const overrides_1 = require("./overrides");
exports.createHandyClient = (...clientArgs) => {
const nodeRedis = (typeof clientArgs[0] === "object" && typeof clientArgs[0].scan === "function")
? clientArgs[0]
: redis_1.createClient.apply(null, clientArgs);
const handyClient = { redis: nodeRedis };
Object.keys(nodeRedis.__proto__).forEach((key) => {
const func = nodeRedis[key];
if (overrides_1.useUnderlyingImpl.has(key)) {
handyClient[key] = func.bind(nodeRedis);
}
else {
const wrapped = (...args) => new Promise((resolve, reject) => {
const flattened = flatten_1.flattenDeep(args);
func.apply(nodeRedis, flattened.concat([(err, data) => err ? reject(err) : resolve(data)]));
});
handyClient[key] = wrapped;
}
});
Object.assign(handyClient, overrides_1.additionalFunctions);
return handyClient;
};
exports.createHandyClient = exports.createNodeRedisClient = exports.addNodeRedisCommand = void 0;
var node_redis_1 = require("./node_redis");
Object.defineProperty(exports, "addNodeRedisCommand", { enumerable: true, get: function () { return node_redis_1.addNodeRedisCommand; } });
Object.defineProperty(exports, "createNodeRedisClient", { enumerable: true, get: function () { return node_redis_1.createNodeRedisClient; } });
// for backwards-compatibility
Object.defineProperty(exports, "createHandyClient", { enumerable: true, get: function () { return node_redis_1.createNodeRedisClient; } });
//# sourceMappingURL=index.js.map
{
"name": "handy-redis",
"version": "1.8.3",
"description": "A wrapper around node_redis with Promise and TypeScript support.",
"version": "2.0.0",
"description": "A redis client with first-class Promise and TypeScript support, and extensive documentation.",
"keywords": [
"redis",
"typescript",
"promise"
],
"homepage": "https://github.com/mmkal/handy-redis#readme",
"bugs": {
"url": "https://github.com/mmkal/handy-redis/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/mmkal/handy-redis.git"
},
"license": "ISC",
"author": "mmkal",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"engines": {
"node": ">= 8.0.0"
},
"types": "dist/index.d.ts",
"scripts": {
"_": "echo \"these pass-through-to-docker scripts are mostly just as a hint for when I come back to this in a few weeks and forget what I'm supposed to do.\"",
"prebuild": "yarn codegen",
"build": "yarn typecheck && yarn compile",
"check-clean": "check-clean",
"ci": "run-s clean build coverage lint check-clean",
"preclean": "del-cli temp/backup-test-generated && mkdir -p temp && cp -r test/generated temp/backup-test-generated",
"clean": "del-cli 'dist' 'src/generated' 'test/generated'",
"codegen": "ts-node codegen/generate-schema && ts-node codegen/generate-client && ts-node codegen/generate-tests",
"compile": "tsc -p tsconfig.lib.json",
"coverage": "yarn test --coverage",
"coveralls": "yarn coverage --coverageReporters=text-lcov | coveralls",
"lint": "eslint --max-warnings 0 --ext .ts,.js,.md .",
"redis-cli": "docker-compose exec redis redis-cli",
"redis:down": "docker-compose down",
"redis:up": "docker-compose up",
"redis:down": "docker-compose down",
"redis-cli": "docker-compose exec redis redis-cli",
"clean": "del-cli 'dist' 'src/generated' 'test/generated/**/*.ts' '**/*.js' '**/*.js.map' '!node_modules/**/*'",
"compile": "tsc -p .",
"prebuild": "ts-node --transpile-only scripts/generate-types && ts-node scripts/generate-tests",
"build": "tsc -p .",
"prerelease": "yarn compile",
"release": "semantic-release",
"test": "jest --runInBand --forceExit --detectOpenHandles",
"lint": "tslint **/*.ts",
"check-clean": "check-clean",
"ci": "run-s clean build test lint check-clean",
"prerelease": "tsc -p src",
"release": "semantic-release",
"coverage": "yarn test --coverage",
"coveralls": "yarn coverage --coverageReporters=text-lcov | coveralls"
"tsn": "ts-node --transpile-only",
"typecheck": "tsc -p ."
},
"repository": {
"type": "git",
"url": "https://github.com/mmkal/handy-redis.git"
},
"keywords": [
"redis",
"typescript"
],
"author": "mmkal",
"license": "ISC",
"bugs": {
"url": "https://github.com/mmkal/handy-redis/issues"
},
"homepage": "https://github.com/mmkal/handy-redis#readme",
"jest": {
"globals": {
"ts-jest": {
"diagnostics": false
}
},
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"testRegex": ".*.test.ts$",
"testURL": "http://localhost",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json"
]
},
"prettier": {
"tabWidth": 4
},
"dependencies": {
"@types/redis": "^2.8.14",
"redis": "^3.0.2"
"@types/redis": "^2.8.27"
},
"devDependencies": {
"@types/cross-spawn": "^6.0.0",
"@types/eslint": "^7.2.0",
"@types/jest": "^24.0.18",

@@ -77,25 +57,30 @@ "@types/lodash": "^4.14.120",

"@types/redis-mock": "^0.17.0",
"@types/shelljs": "^0.8.5",
"@types/yamljs": "^0.2.30",
"@typescript-eslint/eslint-plugin": "^4.4.0",
"@typescript-eslint/parser": "^4.4.0",
"check-clean": "^0.1.0",
"coveralls": "^3.0.2",
"cross-spawn": "^7.0.1",
"del-cli": "^3.0.0",
"dotenv-extended": "^2.3.0",
"eslint": "^7.2.0",
"eslint-config-xo": "^0.31.0",
"eslint-config-xo-typescript": "^0.31.0",
"eslint-plugin-codegen": "^0.9.0",
"eslint-plugin-import": "^2.21.2",
"eslint-plugin-jest": "^23.13.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-unicorn": "^20.1.0",
"expect-type": "^0.7.4",
"jest": "^25.1.0",
"jest": "^26.0.1",
"lodash": "^4.17.14",
"npm-run-all": "^4.1.5",
"prettier": "^1.14.2",
"redis-commands": "^1.5.0",
"prettier": "^2.0.5",
"redis": "^3.0.2",
"redis-mock": "^0.49.0",
"semantic-release": "^15.13.16",
"shelljs": "^0.8.3",
"shx": "^0.3.2",
"ts-jest": "^25.0.0",
"string-argv": "^0.3.1",
"ts-jest": "^26.4.1",
"ts-node": "^8.3.0",
"tslint": "^6.0.0",
"typescript": "^3.8.3",
"yamljs": "^0.3.0"
"typescript": "^4.0.3"
},
"engines": {
"node": ">= 10.0.0"
}
}
# handy-redis
A wrapper around [node_redis](https://npmjs.com/package/redis) with Promise and TypeScript support.
[![Build Status](https://travis-ci.org/mmkal/handy-redis.svg?branch=master)](https://travis-ci.org/mmkal/handy-redis)
[![Coverage Status](https://coveralls.io/repos/github/mmkal/handy-redis/badge.svg)](https://coveralls.io/github/mmkal/handy-redis?branch=master)
[![Node CI](https://github.com/mmkal/handy-redis/workflows/CI/badge.svg)](https://github.com/mmkal/handy-redis/actions?query=workflow%3ACI)
[![codecov](https://codecov.io/gh/mmkal/handy-redis/branch/master/graph/badge.svg)](https://codecov.io/gh/mmkal/handy-redis)
[![npm version](https://badge.fury.io/js/handy-redis.svg)](https://www.npmjs.com/package/handy-redis)

@@ -22,8 +22,8 @@

```JavaScript
import { createHandyClient } from 'handy-redis';
import { createNodeRedisClient } from 'handy-redis';
(async function() {
const client = createHandyClient();
// or, call createHandyClient(opts) using opts for https://www.npmjs.com/package/redis#rediscreateclient
// or, call createHandyClient(oldClient) where oldClient is an existing node_redis client.
const client = createNodeRedisClient();
// or, call createNodeRedisClient(opts) using opts for https://www.npmjs.com/package/redis#rediscreateclient
// or, call createNodeRedisClient(oldClient) where oldClient is an existing node_redis client.

@@ -36,7 +36,8 @@ await client.set('foo', 'bar');

Vanilla JS:
Vanilla JS, no async/await:
```JavaScript
const handyRedis = require('handy-redis');
const { createNodeRedisClient } = require('handy-redis');
const client = handyRedis.createHandyClient();
const client = createNodeRedisClient();

@@ -52,22 +53,52 @@ client

Note: the [redis](https://npmjs.com/package/redis) package is listed as a peer dependency, so should be installed separately. If you need to use recent redis commands (e.g. `xadd` (recent at time of writing, at least)), you can run `npm install redis-commands` to tell the `redis` package to use more up-to-date commands than [redis](https://npmjs.com/package/redis) pulls in by default.
### Adding new commands
Note that the [`redis`](https://npmjs.com/package/redis) package should be installed separately. If you need to use recent redis commands (e.g. `lpos` (recent at time of writing, at least)), which is not included in the [`redis`](https://npmjs.com/package/redis) package by default, you can use `addNodeRedisCommand`:
```js
import { addNodeRedisCommand, createNodeRedisClient } from 'handy-redis'
addNodeRedisCommand('lpos')
const client = createNodeRedisClient(...)
```
If there's a command without a type, a new version of this library will need to be released - [raise an issue](https://github.com/mmkal/handy-redis/issues) if you come across one.
### Accessing the underlying client
Some features of node_redis are not duplicated in this library, such as `watch`, pubsub and events generally. To use them, get the underlying client via `.nodeRedis`:
```js
import { createNodeRedisClient } from 'handy-redis'
const client = createNodeRedisClient(...)
client.nodeRedis.on('error', err => console.error(err))
client.nodeRedis.publish('a_channel', 'a message')
```
### v1.x compatibility
Some aliases exist for backwards-compatibility with v1.x:
- `createNodeRedisClient` (preferred) is aliased to `createHandyClient`
- `WrappedNodeRedisClient` (preferred) is aliased to `IHandyRedis`
- `client.nodeRedis` (preferred) is aliased to `client.redis`
### Examples
See the [snapshot tests](https://github.com/mmkal/handy-redis/blob/master/test/generated/commands/__snapshots__) for tons of usage examples.
See the [snapshot tests](./test/generated/commands) for tons of usage examples.
### Multi
Most members of node_redis's `multi` type don't need to be promisified, because they execute synchronously. Only `exec` is async. For a promisified version of that, use `execMulti`:
Most members of node_redis's `multi` type don't need to be promisified, because they execute synchronously. Only `exec` is async. Usage example:
```JavaScript
import { createHandyClient } from 'handy-redis';
import { createNodeRedisClient } from 'handy-redis';
(async function() {
const client = createHandyClient();
const client = createNodeRedisClient();
const multi = client.multi().set("z:foo", "987").keys("z:*").get("z:foo");
const result = await client.multi().set("z:foo", "987").keys("z:*").get("z:foo").exec();
const result = await client.execMulti(multi);
console.log(result); // ["OK", ["z:foo"], "987"]

@@ -77,4 +108,14 @@ })();

`execMulti` is generic, so in TypeScript you can use something like `const strings = await client.execMulti<string>(multi)` if you know all results will be strings. Otherwise the type will default to `{}`.
The resolved value returned by `exec` is a tuple type, which keeps track of the commands that have been queued. In the above example, the type will be `[string, string[], string]`.
Note: `multi` results are strongly-typed only when using typescript 4.0 and above - for lower typescript versions they will gracefully fall back to a union type (for the example above, it'll be `Array<string | string[]>`).
`client.batch()` also works, with the same API. See [node_redis docs](https://www.npmjs.com/package/redis#clientbatchcommands) for details.
#### Migrating from v1.x
The client no longer has an `execMulti` function. Use the `.exec()` method on the multi instance.
___
## Development

@@ -84,10 +125,33 @@

<details>
<summary>How it works</summary>
The client is generated from the [redis-doc](https://github.com/redis/redis-doc) repo.
- `yarn codegen` generates code:
- `generate-schema`:
- [commands.json](./docs/redis-doc/commands.json) is used to output a commands file with json-schema arguments and return types.
- Argument lists are modeled as arrays, which are flattened when sent to the underlying client. e.g. `SET` might have args `['foo', 'bar', ['EX', 60]]` corresponding to the CLI command `SET foo bar EX 60`
- the markdown documentation for each command is parsed for the return type
- `generate-client`:
- the json-schema from the previous step is parsed and used to generate a [typescript interface of commands](./src/generated/interface.ts)
- `generate-tests`:
- the markdown docs for each command are parsed and transformed into typescript calls. e.g. `SET FOO BAR EX 60` is decoded into `client.set('foo', 'bar', ['EX', 60])`
- these typescript calls are put into jest tests and their outputs are snapshotted
- these tests are internal only and are not included in the published package
At each stage, there are some [patches](./codegen/patches) to plug gaps and inconsistencies in redis-doc and node_redis.
From all the code-generation only the [interface file](./src/generated/interface.ts) is exported. When a client is created, each command on the node_redis client prototype is added as a method on handy-redis's client, a wrapped and promisified version of the equivalent node_redis method.
</details>
```cli
git clone https://github.com/mmkal/handy-redis --recursive
git clone https://github.com/mmkal/handy-redis
cd handy-redis
npm install
yarn
```
Then in a separate terminal, make sure you have docker installed and `docker-compose` is on your path, and start up a redis server in the background with `yarn redis:up`.
Make sure you have docker installed and `docker-compose` is on your path, and start up a redis server in the background with `yarn redis:up -d`.
To fully test the package as it is on your machine, the same way travis does:
To fully test the package as it is on your machine, the same way CI does:

@@ -104,8 +168,12 @@ ```cli

If you cloned without `--recursive` you'll need to run `git submodule update --init` to get the redis-doc repo locally.
Redis doc was added via `git subtree add --prefix docs/redis-doc https://github.com/redis/redis-doc master --squash` following [this guide](https://www.atlassian.com/git/tutorials/git-subtree). Here's how they say it can be updated:
```
git subtree pull --prefix docs/redis-doc https://github.com/redis/redis-doc master --squash
```
### Testing
If a snapshot test fails, it's possible it just needs to be updated. Make sure your git status is clean and run `npm test -- -u`.
If a snapshot test fails, it's possible it just needs to be updated. Make sure your git status is clean and run `yarn test -u`.
Types are tested using [expect-type](https://npmjs.com/package/expect-type).

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc