diff --git a/.github/release-drafter-config.yml b/.github/release-drafter-config.yml
index f17a2992fa..9a98b1c08a 100644
--- a/.github/release-drafter-config.yml
+++ b/.github/release-drafter-config.yml
@@ -41,4 +41,3 @@ template: |
We'd like to thank all the contributors who worked on this release!
$CONTRIBUTORS
-
diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml
deleted file mode 100644
index 2df438eb19..0000000000
--- a/.github/workflows/benchmark.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-name: Benchmark
-
-on:
- push:
- branches:
- - master
- - v4.0
-
-jobs:
- benchmark:
- name: Benchmark
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- node-version: [16.x]
- redis-version: [6.x]
-
- steps:
- - uses: actions/checkout@v2.3.4
- with:
- fetch-depth: 1
-
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v2.3.0
- with:
- node-version: ${{ matrix.node-version }}
-
- - name: Setup Redis
- uses: shogo82148/actions-setup-redis@v1.12.0
- with:
- redis-version: ${{ matrix.redis-version }}
-
- - name: Install Packages
- run: npm ci
-
- - name: Build
- run: npm run build
-
- - name: Install Benchmark Packages
- run: npm ci
- working-directory: ./benchmark
-
- - name: Benchmark
- run: npm run start
- working-directory: ./benchmark
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b6b2dd050e..5942120839 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -28,6 +28,9 @@ jobs:
- name: Install Packages
run: npm ci
+ - name: Build tests tools
+ run: npm run build:tests-tools
+
- name: Run Tests
run: npm run test -- --forbid-only --redis-version=${{ matrix.redis-version }}
diff --git a/.gitignore b/.gitignore
index 8d752019aa..9ee58bfbd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,8 @@
-.vscode/
.idea/
-node_modules/
-dist/
.nyc_output/
+.vscode/
coverage/
-dump.rdb
-documentation/
+dist/
+node_modules/
.DS_Store
+dump.rdb
diff --git a/.npmignore b/.npmignore
deleted file mode 100644
index 115395e3fb..0000000000
--- a/.npmignore
+++ /dev/null
@@ -1,20 +0,0 @@
-.vscode/
-.idea/
-node_modules/
-.nyc_output/
-coverage/
-dump.rdb
-documentation/
-CONTRIBUTING.md
-tsconfig.json
-.deepsource.toml
-.nycrc.json
-benchmark/
-.github/
-scripts/
-lib/
-index.ts
-*.spec.*
-dist/lib/test-utils.*
-.DS_Store
-examples/
diff --git a/.nycrc.json b/.nycrc.json
deleted file mode 100644
index 918b308a89..0000000000
--- a/.nycrc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "extends": "@istanbuljs/nyc-config-typescript",
- "exclude": ["**/*.spec.ts", "lib/test-utils/**/*.ts"]
-}
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fbad520508..a041584e6f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -47,10 +47,7 @@ Node Redis has a full test suite with coverage setup.
To run the tests, run `npm install` to install dependencies, then run `npm test`.
-Note that the test suite assumes that a few tools are installed in your environment, such as:
-
-- redis (make sure redis-server is not running when starting the tests, it's part of the test-suite to start it and you'll end up with a "port already in use" error)
-- stunnel (for TLS tests)
+Note that the test suite assumes that [`docker`](https://www.docker.com/) is installed in your environment.
### Submitting Code for Review
diff --git a/README.md b/README.md
index 9fe9e70a25..35648bd72e 100644
--- a/README.md
+++ b/README.md
@@ -1,296 +1,18 @@
-
-
-
-
-
Node Redis
-
+# Node-Redis monorpo
-
+### Clients
----
+| Name | Description |
+|------------------------------------|-------------|
+| [redis](./packages/all-in-one) | |
+| [@redis/client](./packages/client) | |
-## Installation
+### [Modules](https://redis.io/modules)
-```bash
-npm install redis@next
-```
-
-> :warning: The new interface is clean and cool, but if you have an existing code base, you'll want to read the [migration guide](./docs/v3-to-v4.md).
-
-## Usage
-
-### Basic Example
-
-```typescript
-import { createClient } from 'redis';
-
-(async () => {
- const client = createClient();
-
- client.on('error', (err) => console.log('Redis Client Error', err));
-
- await client.connect();
-
- await client.set('key', 'value');
- const value = await client.get('key');
-})();
-```
-
-The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in the format `redis[s]://[[username][:password]@][host][:port][/db-number]`:
-
-```typescript
-createClient({
- url: 'redis://alice:foobared@awesome.redis.server:6380'
-});
-```
-
-You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in the [client configuration guide](./docs/client-configuration.md).
-
-### Redis Commands
-
-There is built-in support for all of the [out-of-the-box Redis commands](https://redis.io/commands). They are exposed using the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`, etc.):
-
-```typescript
-// raw Redis commands
-await client.HSET('key', 'field', 'value');
-await client.HGETALL('key');
-
-// friendly JavaScript commands
-await client.hSet('key', 'field', 'value');
-await client.hGetAll('key');
-```
-
-Modifiers to commands are specified using a JavaScript object:
-
-```typescript
-await client.set('key', 'value', {
- EX: 10,
- NX: true
-});
-```
-
-Replies will be transformed into useful data structures:
-
-```typescript
-await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
-await client.hVals('key'); // ['value1', 'value2']
-```
-
-### Unsupported Redis Commands
-
-If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
-
-```typescript
-await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
-
-await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
-```
-
-### Transactions (Multi/Exec)
-
-Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When you're done, call `.exec()` and you'll get an array back with your results:
-
-```typescript
-await client.set('another-key', 'another-value');
-
-const [setKeyReply, otherKeyValue] = await client
- .multi()
- .set('key', 'value')
- .get('another-key')
- .exec(); // ['OK', 'another-value']
-```
-
-You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
-
-To dig deeper into transactions, check out the [Isolated Execution Guide](./docs/isolated-execution.md).
-
-### Blocking Commands
-
-Any command can be run on a new connection by specifying the `isolated` option. The newly created connection is closed when the command's `Promise` is fulfilled.
-
-This pattern works especially well for blocking commands—such as `BLPOP` and `BLMOVE`:
-
-```typescript
-import { commandOptions } from 'redis';
-
-const blPopPromise = client.blPop(commandOptions({ isolated: true }), 'key', 0);
-
-await client.lPush('key', ['1', '2']);
-
-await blPopPromise; // '2'
-```
-
-To learn more about isolated execution, check out the [guide](./docs/isolated-execution.md).
-
-### Pub/Sub
-
-Subscribing to a channel requires a dedicated stand-alone connection. You can easily get one by `.duplicate()`ing an existing Redis connection.
-
-```typescript
-const subscriber = client.duplicate();
-
-await subscriber.connect();
-```
-
-Once you have one, simply subscribe and unsubscribe as needed:
-
-```typescript
-await subscriber.subscribe('channel', (message) => {
- console.log(message); // 'message'
-});
-
-await subscriber.pSubscribe('channe*', (message, channel) => {
- console.log(message, channel); // 'message', 'channel'
-});
-
-await subscriber.unsubscribe('channel');
-
-await subscriber.pUnsubscribe('channe*');
-```
-
-Publish a message on a channel:
-
-```typescript
-await publisher.publish('channel', 'message');
-```
-
-### Scan Iterator
-
-[`SCAN`](https://redis.io/commands/scan) results can be looped over using [async iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator):
-
-```typescript
-for await (const key of client.scanIterator()) {
- // use the key!
- await client.get(key);
-}
-```
-
-This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
-
-```typescript
-for await (const { field, value } of client.hScanIterator('hash')) {}
-for await (const member of client.sScanIterator('set')) {}
-for await (const { score, member } of client.zScanIterator('sorted-set')) {}
-```
-
-You can override the default options by providing a configuration object:
-
-```typescript
-client.scanIterator({
- TYPE: 'string', // `SCAN` only
- MATCH: 'patter*',
- COUNT: 100
-});
-```
-
-### Lua Scripts
-
-Define new functions using [Lua scripts](https://redis.io/commands/eval) which execute on the Redis server:
-
-```typescript
-import { createClient, defineScript } from 'redis';
-
-(async () => {
- const client = createClient({
- scripts: {
- add: defineScript({
- NUMBER_OF_KEYS: 1,
- SCRIPT:
- "local val = redis.pcall('GET', KEYS[1]);" + "return val + ARGV[1];",
- transformArguments(key: string, toAdd: number): Array {
- return [key, toAdd.toString()];
- },
- transformReply(reply: number): number {
- return reply;
- }
- })
- }
- });
-
- await client.connect();
-
- await client.set('key', '1');
- await client.add('key', 2); // 3
-})();
-```
-
-### Disconnecting
-
-There are two functions that disconnect a client from the Redis server. In most scenarios you should use `.quit()` to ensure that pending commands are sent to Redis before closing a connection.
-
-#### `.QUIT()`/`.quit()`
-
-Gracefully close a client's connection to Redis, by sending the [`QUIT`](https://redis.io/commands/quit) command to the server. Before quitting, the client executes any remaining commands in its queue, and will receive replies from Redis for each of them.
-
-```typescript
-const [ping, get, quit] = await Promise.all([
- client.ping(),
- client.get('key'),
- client.quit()
-]); // ['PONG', null, 'OK']
-
-try {
- await client.get('key');
-} catch (err) {
- // ClosedClient Error
-}
-```
-
-#### `.disconnect()`
-
-Forcibly close a client's connection to Redis immediately. Calling `disconnect` will not send further pending commands to the Redis server, or wait for or parse outstanding responses.
-
-```typescript
-await client.disconnect();
-```
-
-### Auto-Pipelining
-
-Node Redis will automatically pipeline requests that are made during the same "tick".
-
-```typescript
-client.set('Tm9kZSBSZWRpcw==', 'users:1');
-client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
-```
-
-Of course, if you don't do something with your Promises you're certain to get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
-
-```typescript
-await Promise.all([
- client.set('Tm9kZSBSZWRpcw==', 'users:1'),
- client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
-]);
-```
-
-### Clustering
-
-Check out the [Clustering Guide](./docs/clustering.md) when using Node Redis to connect to a Redis Cluster.
-
-## Supported Redis versions
-
-Node Redis is supported with the following versions of Redis:
-
-| Version | Supported |
-|---------|--------------------|
-| 6.2.z | :heavy_check_mark: |
-| 6.0.z | :heavy_check_mark: |
-| 5.y.z | :heavy_check_mark: |
-| < 5.0 | :x: |
-
-> Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.
+| Name | Description |
+|------------------------------------|------------------------------------------------------------|
+| [@redis/json](./packages/json) | [Redis JSON](https://oss.redis.com/redisjson/) commands |
+| [@redis/search](./packages/search) | [Redis Search](https://oss.redis.com/redisearch/) commands |
## Contributing
diff --git a/benchmark/.gitignore b/benchmark/.gitignore
deleted file mode 100644
index 3c3629e647..0000000000
--- a/benchmark/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/benchmark/index.js b/benchmark/index.js
deleted file mode 100644
index 37f8817665..0000000000
--- a/benchmark/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { add, suite, cycle, complete } from 'benny';
-import v4 from 'v4';
-import v3 from 'v3';
-import { once } from 'events';
-
-const v4Client = v4.createClient(),
- v4LegacyClient = v4.createClient({
- legacyMode: true
- }),
- v3Client = v3.createClient();
-
-await Promise.all([
- v4Client.connect(),
- v4LegacyClient.connect(),
- once(v3Client, 'connect')
-]);
-
-const key = random(100),
- value = random(100);
-
-function random(size) {
- const result = [];
-
- for (let i = 0; i < size; i++) {
- result.push(Math.floor(Math.random() * 10));
- }
-
- return result.join('');
-}
-
-suite(
- 'SET GET',
- add('v4', async () => {
- await Promise.all([
- v4Client.set(key, value),
- v4Client.get(key)
- ]);
- }),
- add('v4 - legacy mode', () => {
- return new Promise((resolve, reject) => {
- v4LegacyClient.set(key, value);
- v4LegacyClient.get(key, (err, reply) => {
- if (err) {
- reject(err);
- } else {
- resolve(reply);
- }
- });
- });
- }),
- add('v3', () => {
- return new Promise((resolve, reject) => {
- v3Client.set(key, value);
- v3Client.get(key, (err, reply) => {
- if (err) {
- reject(err);
- } else {
- resolve(reply);
- }
- });
- });
- }),
- cycle(),
- complete(),
- complete(() => {
- return Promise.all([
- v4Client.disconnect(),
- v4LegacyClient.disconnect(),
- new Promise((resolve, reject) => {
- v3Client.quit((err) => {
- if (err) {
- reject(err);
- } else {
- resolve(err);
- }
- });
- })
- ]);
- })
-);
-
diff --git a/benchmark/package-lock.json b/benchmark/package-lock.json
deleted file mode 100644
index 4afaf8c305..0000000000
--- a/benchmark/package-lock.json
+++ /dev/null
@@ -1,849 +0,0 @@
-{
- "name": "benchmark",
- "lockfileVersion": 2,
- "requires": true,
- "packages": {
- "": {
- "name": "benchmark",
- "license": "ISC",
- "dependencies": {
- "benny": "3.6.15",
- "v3": "npm:redis@3.1.2",
- "v4": "file:../"
- }
- },
- "..": {
- "name": "redis",
- "version": "4.0.0-rc.2",
- "license": "MIT",
- "dependencies": {
- "cluster-key-slot": "1.1.0",
- "generic-pool": "3.8.2",
- "redis-parser": "3.0.0",
- "yallist": "4.0.0"
- },
- "devDependencies": {
- "@istanbuljs/nyc-config-typescript": "^1.0.1",
- "@tsconfig/node12": "^1.0.9",
- "@types/mocha": "^9.0.0",
- "@types/node": "^16.10.3",
- "@types/sinon": "^10.0.4",
- "@types/which": "^2.0.1",
- "@types/yallist": "^4.0.1",
- "mocha": "^9.1.2",
- "nyc": "^15.1.0",
- "release-it": "^14.11.6",
- "sinon": "^11.1.2",
- "source-map-support": "^0.5.20",
- "ts-node": "^10.3.0",
- "typedoc": "^0.22.5",
- "typedoc-github-wiki-theme": "^0.6.0",
- "typedoc-plugin-markdown": "^3.11.3",
- "typescript": "^4.4.3",
- "which": "^2.0.2"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@arrows/array": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@arrows/array/-/array-1.4.1.tgz",
- "integrity": "sha512-MGYS8xi3c4tTy1ivhrVntFvufoNzje0PchjEz6G/SsWRgUKxL4tKwS6iPdO8vsaJYldagAeWMd5KRD0aX3Q39g==",
- "dependencies": {
- "@arrows/composition": "^1.2.2"
- }
- },
- "node_modules/@arrows/composition": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@arrows/composition/-/composition-1.2.2.tgz",
- "integrity": "sha512-9fh1yHwrx32lundiB3SlZ/VwuStPB4QakPsSLrGJFH6rCXvdrd060ivAZ7/2vlqPnEjBkPRRXOcG1YOu19p2GQ=="
- },
- "node_modules/@arrows/dispatch": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@arrows/dispatch/-/dispatch-1.0.3.tgz",
- "integrity": "sha512-v/HwvrFonitYZM2PmBlAlCqVqxrkIIoiEuy5bQgn0BdfvlL0ooSBzcPzTMrtzY8eYktPyYcHg8fLbSgyybXEqw==",
- "dependencies": {
- "@arrows/composition": "^1.2.2"
- }
- },
- "node_modules/@arrows/error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@arrows/error/-/error-1.0.2.tgz",
- "integrity": "sha512-yvkiv1ay4Z3+Z6oQsUkedsQm5aFdyPpkBUQs8vejazU/RmANABx6bMMcBPPHI4aW43VPQmXFfBzr/4FExwWTEA=="
- },
- "node_modules/@arrows/multimethod": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@arrows/multimethod/-/multimethod-1.1.7.tgz",
- "integrity": "sha512-EjHD3XuGAV4G28rm7mu8k7zQJh/EOizh104/p9i2ofGcnL5mgKONFH/Bq6H3SJjM+WDAlKcR9WBpNhaAKCnH2g==",
- "dependencies": {
- "@arrows/array": "^1.4.0",
- "@arrows/composition": "^1.2.2",
- "@arrows/error": "^1.0.2",
- "fast-deep-equal": "^3.1.1"
- }
- },
- "node_modules/ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/at-least-node": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
- "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
- "node_modules/benchmark": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
- "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=",
- "dependencies": {
- "lodash": "^4.17.4",
- "platform": "^1.3.3"
- }
- },
- "node_modules/benny": {
- "version": "3.6.15",
- "resolved": "https://registry.npmjs.org/benny/-/benny-3.6.15.tgz",
- "integrity": "sha512-kq6XVGGYVou3Y8KNPs3SEF881vi5fJ8sIf9w69D2rreiNfRicWVWK6u6/mObMw6BiexoHHumtipn5gcu0Tngng==",
- "dependencies": {
- "@arrows/composition": "^1.0.0",
- "@arrows/dispatch": "^1.0.2",
- "@arrows/multimethod": "^1.1.6",
- "benchmark": "^2.1.4",
- "fs-extra": "^9.0.1",
- "json2csv": "^5.0.4",
- "kleur": "^4.1.3",
- "log-update": "^4.0.0",
- "prettier": "^2.1.2",
- "stats-median": "^1.0.1"
- }
- },
- "node_modules/cli-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
- "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "dependencies": {
- "restore-cursor": "^3.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/commander": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
- "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/denque": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
- "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "node_modules/fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "dependencies": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.8",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
- "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/json2csv": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.6.tgz",
- "integrity": "sha512-0/4Lv6IenJV0qj2oBdgPIAmFiKKnh8qh7bmLFJ+/ZZHLjSeiL3fKKGX3UryvKPbxFbhV+JcYo9KUC19GJ/Z/4A==",
- "dependencies": {
- "commander": "^6.1.0",
- "jsonparse": "^1.3.1",
- "lodash.get": "^4.4.2"
- },
- "bin": {
- "json2csv": "bin/json2csv.js"
- },
- "engines": {
- "node": ">= 10",
- "npm": ">= 6.13.0"
- }
- },
- "node_modules/jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dependencies": {
- "universalify": "^2.0.0"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/jsonparse": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
- "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
- "engines": [
- "node >= 0.2.0"
- ]
- },
- "node_modules/kleur": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
- "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "node_modules/lodash.get": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
- },
- "node_modules/log-update": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
- "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
- "dependencies": {
- "ansi-escapes": "^4.3.0",
- "cli-cursor": "^3.1.0",
- "slice-ansi": "^4.0.0",
- "wrap-ansi": "^6.2.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/platform": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
- "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
- },
- "node_modules/prettier": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz",
- "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==",
- "bin": {
- "prettier": "bin-prettier.js"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/redis-commands": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
- "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
- },
- "node_modules/redis-errors": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
- "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/redis-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
- "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
- "dependencies": {
- "redis-errors": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/restore-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
- "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "dependencies": {
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/signal-exit": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz",
- "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ=="
- },
- "node_modules/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
- "node_modules/stats-median": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stats-median/-/stats-median-1.0.1.tgz",
- "integrity": "sha512-IYsheLg6dasD3zT/w9+8Iq9tcIQqqu91ZIpJOnIEM25C3X/g4Tl8mhXwW2ZQpbrsJISr9+wizEYgsibN5/b32Q=="
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/universalify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
- "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/v3": {
- "name": "redis",
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
- "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
- "dependencies": {
- "denque": "^1.5.0",
- "redis-commands": "^1.7.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-redis"
- }
- },
- "node_modules/v4": {
- "resolved": "..",
- "link": true
- },
- "node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- }
- },
- "dependencies": {
- "@arrows/array": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@arrows/array/-/array-1.4.1.tgz",
- "integrity": "sha512-MGYS8xi3c4tTy1ivhrVntFvufoNzje0PchjEz6G/SsWRgUKxL4tKwS6iPdO8vsaJYldagAeWMd5KRD0aX3Q39g==",
- "requires": {
- "@arrows/composition": "^1.2.2"
- }
- },
- "@arrows/composition": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@arrows/composition/-/composition-1.2.2.tgz",
- "integrity": "sha512-9fh1yHwrx32lundiB3SlZ/VwuStPB4QakPsSLrGJFH6rCXvdrd060ivAZ7/2vlqPnEjBkPRRXOcG1YOu19p2GQ=="
- },
- "@arrows/dispatch": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@arrows/dispatch/-/dispatch-1.0.3.tgz",
- "integrity": "sha512-v/HwvrFonitYZM2PmBlAlCqVqxrkIIoiEuy5bQgn0BdfvlL0ooSBzcPzTMrtzY8eYktPyYcHg8fLbSgyybXEqw==",
- "requires": {
- "@arrows/composition": "^1.2.2"
- }
- },
- "@arrows/error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@arrows/error/-/error-1.0.2.tgz",
- "integrity": "sha512-yvkiv1ay4Z3+Z6oQsUkedsQm5aFdyPpkBUQs8vejazU/RmANABx6bMMcBPPHI4aW43VPQmXFfBzr/4FExwWTEA=="
- },
- "@arrows/multimethod": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@arrows/multimethod/-/multimethod-1.1.7.tgz",
- "integrity": "sha512-EjHD3XuGAV4G28rm7mu8k7zQJh/EOizh104/p9i2ofGcnL5mgKONFH/Bq6H3SJjM+WDAlKcR9WBpNhaAKCnH2g==",
- "requires": {
- "@arrows/array": "^1.4.0",
- "@arrows/composition": "^1.2.2",
- "@arrows/error": "^1.0.2",
- "fast-deep-equal": "^3.1.1"
- }
- },
- "ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "requires": {
- "type-fest": "^0.21.3"
- }
- },
- "ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
- },
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
- },
- "at-least-node": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
- "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
- },
- "benchmark": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz",
- "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=",
- "requires": {
- "lodash": "^4.17.4",
- "platform": "^1.3.3"
- }
- },
- "benny": {
- "version": "3.6.15",
- "resolved": "https://registry.npmjs.org/benny/-/benny-3.6.15.tgz",
- "integrity": "sha512-kq6XVGGYVou3Y8KNPs3SEF881vi5fJ8sIf9w69D2rreiNfRicWVWK6u6/mObMw6BiexoHHumtipn5gcu0Tngng==",
- "requires": {
- "@arrows/composition": "^1.0.0",
- "@arrows/dispatch": "^1.0.2",
- "@arrows/multimethod": "^1.1.6",
- "benchmark": "^2.1.4",
- "fs-extra": "^9.0.1",
- "json2csv": "^5.0.4",
- "kleur": "^4.1.3",
- "log-update": "^4.0.0",
- "prettier": "^2.1.2",
- "stats-median": "^1.0.1"
- }
- },
- "cli-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
- "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
- "requires": {
- "restore-cursor": "^3.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "commander": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
- "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="
- },
- "denque": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
- "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw=="
- },
- "emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
- },
- "fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
- },
- "fs-extra": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
- "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
- "requires": {
- "at-least-node": "^1.0.0",
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- }
- },
- "graceful-fs": {
- "version": "4.2.8",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
- "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
- },
- "json2csv": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.6.tgz",
- "integrity": "sha512-0/4Lv6IenJV0qj2oBdgPIAmFiKKnh8qh7bmLFJ+/ZZHLjSeiL3fKKGX3UryvKPbxFbhV+JcYo9KUC19GJ/Z/4A==",
- "requires": {
- "commander": "^6.1.0",
- "jsonparse": "^1.3.1",
- "lodash.get": "^4.4.2"
- }
- },
- "jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "requires": {
- "graceful-fs": "^4.1.6",
- "universalify": "^2.0.0"
- }
- },
- "jsonparse": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
- "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
- },
- "kleur": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.4.tgz",
- "integrity": "sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA=="
- },
- "lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "lodash.get": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
- },
- "log-update": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
- "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
- "requires": {
- "ansi-escapes": "^4.3.0",
- "cli-cursor": "^3.1.0",
- "slice-ansi": "^4.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "mimic-fn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
- "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
- },
- "onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "requires": {
- "mimic-fn": "^2.1.0"
- }
- },
- "platform": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz",
- "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg=="
- },
- "prettier": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz",
- "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA=="
- },
- "redis-commands": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
- "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
- },
- "redis-errors": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
- "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60="
- },
- "redis-parser": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
- "integrity": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
- "requires": {
- "redis-errors": "^1.0.0"
- }
- },
- "restore-cursor": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
- "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
- "requires": {
- "onetime": "^5.1.0",
- "signal-exit": "^3.0.2"
- }
- },
- "signal-exit": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz",
- "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ=="
- },
- "slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- }
- },
- "stats-median": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stats-median/-/stats-median-1.0.1.tgz",
- "integrity": "sha512-IYsheLg6dasD3zT/w9+8Iq9tcIQqqu91ZIpJOnIEM25C3X/g4Tl8mhXwW2ZQpbrsJISr9+wizEYgsibN5/b32Q=="
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="
- },
- "universalify": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
- "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
- },
- "v3": {
- "version": "npm:redis@3.1.2",
- "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
- "integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
- "requires": {
- "denque": "^1.5.0",
- "redis-commands": "^1.7.0",
- "redis-errors": "^1.2.0",
- "redis-parser": "^3.0.0"
- }
- },
- "v4": {
- "version": "file:..",
- "requires": {
- "@istanbuljs/nyc-config-typescript": "^1.0.1",
- "@tsconfig/node12": "^1.0.9",
- "@types/mocha": "^9.0.0",
- "@types/node": "^16.10.3",
- "@types/sinon": "^10.0.4",
- "@types/which": "^2.0.1",
- "@types/yallist": "^4.0.1",
- "cluster-key-slot": "1.1.0",
- "generic-pool": "3.8.2",
- "mocha": "^9.1.2",
- "nyc": "^15.1.0",
- "redis-parser": "3.0.0",
- "release-it": "^14.11.6",
- "sinon": "^11.1.2",
- "source-map-support": "^0.5.20",
- "ts-node": "^10.3.0",
- "typedoc": "^0.22.5",
- "typedoc-github-wiki-theme": "^0.6.0",
- "typedoc-plugin-markdown": "^3.11.3",
- "typescript": "^4.4.3",
- "which": "^2.0.2",
- "yallist": "4.0.0"
- }
- },
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- }
- }
-}
diff --git a/benchmark/package.json b/benchmark/package.json
deleted file mode 100644
index ab874090c4..0000000000
--- a/benchmark/package.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "benchmark",
- "private": true,
- "description": "",
- "main": "index.js",
- "type": "module",
- "scripts": {
- "start": "node ./"
- },
- "author": "",
- "license": "ISC",
- "dependencies": {
- "benny": "3.6.15",
- "v3": "npm:redis@3.1.2",
- "v4": "file:../"
- }
-}
diff --git a/package-lock.json b/package-lock.json
index ff1b2e6e56..87ae980524 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,44 +1,15 @@
{
- "name": "redis",
- "version": "4.0.0-rc.3",
+ "name": "redis-monorepo",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "name": "redis",
- "version": "4.0.0-rc.3",
- "license": "MIT",
- "dependencies": {
- "cluster-key-slot": "1.1.0",
- "generic-pool": "3.8.2",
- "redis-parser": "3.0.0",
- "yallist": "4.0.0"
- },
+ "name": "redis-monorepo",
+ "workspaces": [
+ "./packages/*"
+ ],
"devDependencies": {
- "@istanbuljs/nyc-config-typescript": "^1.0.1",
- "@tsconfig/node12": "^1.0.9",
- "@types/mocha": "^9.0.0",
- "@types/node": "^16.11.6",
- "@types/sinon": "^10.0.6",
- "@types/yallist": "^4.0.1",
- "@types/yargs": "^17.0.5",
- "@typescript-eslint/eslint-plugin": "^5.2.0",
- "@typescript-eslint/parser": "^5.2.0",
- "eslint": "^8.1.0",
- "mocha": "^9.1.3",
- "nyc": "^15.1.0",
- "release-it": "^14.11.6",
- "sinon": "^11.1.2",
- "source-map-support": "^0.5.20",
- "ts-node": "^10.4.0",
- "typedoc": "^0.22.7",
- "typedoc-github-wiki-theme": "^0.6.0",
- "typedoc-plugin-markdown": "^3.11.3",
- "typescript": "^4.4.4",
- "yargs": "^17.2.1"
- },
- "engines": {
- "node": ">=12"
+ "@tsconfig/node12": "^1.0.9"
}
},
"node_modules/@babel/code-frame": {
@@ -392,9 +363,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.0.tgz",
- "integrity": "sha512-TEHWXf0xxpi9wKVyBCmRcSSDjbJ/cl6LUdlbYUHEaNQUJGhreJbZrXT6sR4+fZLxVUJqNRB4KyOvjuy/D9009A==",
+ "version": "7.16.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
+ "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -481,9 +452,9 @@
}
},
"node_modules/@eslint/eslintrc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz",
- "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz",
+ "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
@@ -492,7 +463,7 @@
"globals": "^13.9.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
- "js-yaml": "^3.13.1",
+ "js-yaml": "^4.1.0",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
@@ -500,15 +471,6 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
- "node_modules/@eslint/eslintrc/node_modules/argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "dependencies": {
- "sprintf-js": "~1.0.2"
- }
- },
"node_modules/@eslint/eslintrc/node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -518,19 +480,6 @@
"node": ">= 4"
}
},
- "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/@humanwhocodes/config-array": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.6.0.tgz",
@@ -546,9 +495,9 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
- "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
"node_modules/@iarna/toml": {
@@ -849,6 +798,26 @@
"@octokit/openapi-types": "^11.2.0"
}
},
+ "node_modules/@redis/client": {
+ "resolved": "packages/client",
+ "link": true
+ },
+ "node_modules/@redis/json": {
+ "resolved": "packages/json",
+ "link": true
+ },
+ "node_modules/@redis/search": {
+ "resolved": "packages/search",
+ "link": true
+ },
+ "node_modules/@redis/test-utils": {
+ "resolved": "packages/test-utils",
+ "link": true
+ },
+ "node_modules/@redis/time-series": {
+ "resolved": "packages/time-series",
+ "link": true
+ },
"node_modules/@sindresorhus/is": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
@@ -972,9 +941,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "16.11.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
- "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==",
+ "version": "16.11.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
+ "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
"dev": true
},
"node_modules/@types/parse-json": {
@@ -1023,13 +992,13 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz",
- "integrity": "sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz",
+ "integrity": "sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/experimental-utils": "5.2.0",
- "@typescript-eslint/scope-manager": "5.2.0",
+ "@typescript-eslint/experimental-utils": "5.3.1",
+ "@typescript-eslint/scope-manager": "5.3.1",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@@ -1055,15 +1024,15 @@
}
},
"node_modules/@typescript-eslint/experimental-utils": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz",
- "integrity": "sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz",
+ "integrity": "sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.2.0",
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/typescript-estree": "5.2.0",
+ "@typescript-eslint/scope-manager": "5.3.1",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/typescript-estree": "5.3.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
},
@@ -1079,14 +1048,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.2.0.tgz",
- "integrity": "sha512-Uyy4TjJBlh3NuA8/4yIQptyJb95Qz5PX//6p8n7zG0QnN4o3NF9Je3JHbVU7fxf5ncSXTmnvMtd/LDQWDk0YqA==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.3.1.tgz",
+ "integrity": "sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.2.0",
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/typescript-estree": "5.2.0",
+ "@typescript-eslint/scope-manager": "5.3.1",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/typescript-estree": "5.3.1",
"debug": "^4.3.2"
},
"engines": {
@@ -1106,13 +1075,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz",
- "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz",
+ "integrity": "sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/visitor-keys": "5.2.0"
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/visitor-keys": "5.3.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1123,9 +1092,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz",
- "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.1.tgz",
+ "integrity": "sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1136,13 +1105,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz",
- "integrity": "sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz",
+ "integrity": "sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/visitor-keys": "5.2.0",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/visitor-keys": "5.3.1",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@@ -1163,12 +1132,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz",
- "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz",
+ "integrity": "sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.2.0",
+ "@typescript-eslint/types": "5.3.1",
"eslint-visitor-keys": "^3.0.0"
},
"engines": {
@@ -1495,13 +1464,13 @@
"dev": true
},
"node_modules/browserslist": {
- "version": "4.17.5",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz",
- "integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==",
+ "version": "4.17.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz",
+ "integrity": "sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==",
"dev": true,
"dependencies": {
- "caniuse-lite": "^1.0.30001271",
- "electron-to-chromium": "^1.3.878",
+ "caniuse-lite": "^1.0.30001274",
+ "electron-to-chromium": "^1.3.886",
"escalade": "^3.1.1",
"node-releases": "^2.0.1",
"picocolors": "^1.0.0"
@@ -1636,9 +1605,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001274",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz",
- "integrity": "sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==",
+ "version": "1.0.30001278",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz",
+ "integrity": "sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==",
"dev": true,
"funding": {
"type": "opencollective",
@@ -2097,9 +2066,9 @@
"dev": true
},
"node_modules/electron-to-chromium": {
- "version": "1.3.885",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.885.tgz",
- "integrity": "sha512-JXKFJcVWrdHa09n4CNZYfYaK6EW5aAew7/wr3L1OnsD1L+JHL+RCtd7QgIsxUbFPeTwPlvnpqNNTOLkoefmtXg==",
+ "version": "1.3.891",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.891.tgz",
+ "integrity": "sha512-3cpwR82QkIS01CN/dup/4Yr3BiOiRLlZlcAFn/5FbNCunMO9ojqDgEP9JEo1QNLflu3pEnPWve50gHOEKc7r6w==",
"dev": true
},
"node_modules/emoji-regex": {
@@ -2175,12 +2144,12 @@
}
},
"node_modules/eslint": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz",
- "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz",
+ "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==",
"dev": true,
"dependencies": {
- "@eslint/eslintrc": "^1.0.3",
+ "@eslint/eslintrc": "^1.0.4",
"@humanwhocodes/config-array": "^0.6.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@@ -2214,7 +2183,7 @@
"progress": "^2.0.0",
"regexpp": "^3.2.0",
"semver": "^7.2.1",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
@@ -2270,9 +2239,9 @@
}
},
"node_modules/eslint-visitor-keys": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz",
- "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz",
+ "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -3060,9 +3029,9 @@
]
},
"node_modules/ignore": {
- "version": "5.1.8",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
- "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
+ "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -5096,6 +5065,10 @@
"node": ">= 0.10"
}
},
+ "node_modules/redis": {
+ "resolved": "packages/all-in-one",
+ "link": true
+ },
"node_modules/redis-errors": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
@@ -5883,9 +5856,9 @@
}
},
"node_modules/typedoc": {
- "version": "0.22.7",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.7.tgz",
- "integrity": "sha512-ndxxp+tU1Wczvdxp4u2/PvT1qjD6hdFdSdehpORHjE+JXmMkl2bftXCR0upHmsnesBG7VCcr8vfgloGHIH8glQ==",
+ "version": "0.22.8",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.8.tgz",
+ "integrity": "sha512-92S+YzyhospdXN5rnkYUTgirdTYqNWY7NP9vco+IqQQoiSXzVSUsawVro+tMyEEsWUS7EMaJ2YOjB9uE0CBi6A==",
"dev": true,
"dependencies": {
"glob": "^7.2.0",
@@ -5960,9 +5933,9 @@
}
},
"node_modules/uglify-js": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz",
- "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==",
+ "version": "3.14.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz",
+ "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==",
"dev": true,
"optional": true,
"bin": {
@@ -6385,6 +6358,124 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "packages/all-in-one": {
+ "name": "redis",
+ "version": "4.0.0-rc.3",
+ "license": "MIT",
+ "dependencies": {
+ "@redis/client": "^4.0.0-rc",
+ "@redis/json": "^1.0.0-rc",
+ "@redis/search": "^1.0.0-rc"
+ },
+ "devDependencies": {
+ "release-it": "^14.11.6",
+ "typescript": "^4.4.4"
+ }
+ },
+ "packages/client": {
+ "name": "@redis/client",
+ "version": "4.0.0-rc.3",
+ "license": "MIT",
+ "dependencies": {
+ "cluster-key-slot": "1.1.0",
+ "generic-pool": "3.8.2",
+ "redis-parser": "3.0.0",
+ "yallist": "4.0.0"
+ },
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "@types/sinon": "^10.0.6",
+ "@types/yallist": "^4.0.1",
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
+ "@typescript-eslint/parser": "^5.2.0",
+ "eslint": "^8.1.0",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "sinon": "^11.1.2",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typedoc": "^0.22.7",
+ "typedoc-github-wiki-theme": "^0.6.0",
+ "typedoc-plugin-markdown": "^3.11.3",
+ "typescript": "^4.4.4"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "packages/json": {
+ "name": "@redis/json",
+ "version": "1.0.0-rc.0",
+ "license": "MIT",
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ }
+ },
+ "packages/search": {
+ "name": "@redis/search",
+ "version": "1.0.0-rc.0",
+ "license": "MIT",
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ }
+ },
+ "packages/test-utils": {
+ "name": "@redis/test-utils",
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@tsconfig/node12": "^1.0.9",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.11.6",
+ "@types/yargs": "^17.0.5",
+ "mocha": "^9.1.3",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4",
+ "yargs": "^17.2.1"
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ }
+ },
+ "packages/time-series": {
+ "name": "@redis/time-series",
+ "version": "1.0.0",
+ "license": "ISC",
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
}
},
"dependencies": {
@@ -6660,9 +6751,9 @@
}
},
"@babel/parser": {
- "version": "7.16.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.0.tgz",
- "integrity": "sha512-TEHWXf0xxpi9wKVyBCmRcSSDjbJ/cl6LUdlbYUHEaNQUJGhreJbZrXT6sR4+fZLxVUJqNRB4KyOvjuy/D9009A==",
+ "version": "7.16.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz",
+ "integrity": "sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==",
"dev": true
},
"@babel/template": {
@@ -6727,9 +6818,9 @@
}
},
"@eslint/eslintrc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.3.tgz",
- "integrity": "sha512-DHI1wDPoKCBPoLZA3qDR91+3te/wDSc1YhKg3jR8NxKKRJq2hwHwcWv31cSwSYvIBrmbENoYMWcenW8uproQqg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.4.tgz",
+ "integrity": "sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@@ -6738,35 +6829,16 @@
"globals": "^13.9.0",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
- "js-yaml": "^3.13.1",
+ "js-yaml": "^4.1.0",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
- "argparse": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
- "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
- "dev": true,
- "requires": {
- "sprintf-js": "~1.0.2"
- }
- },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
- },
- "js-yaml": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
- "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
}
}
},
@@ -6782,9 +6854,9 @@
}
},
"@humanwhocodes/object-schema": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
- "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
"@iarna/toml": {
@@ -7035,6 +7107,88 @@
"@octokit/openapi-types": "^11.2.0"
}
},
+ "@redis/client": {
+ "version": "file:packages/client",
+ "requires": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "@types/sinon": "^10.0.6",
+ "@types/yallist": "^4.0.1",
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
+ "@typescript-eslint/parser": "^5.2.0",
+ "cluster-key-slot": "1.1.0",
+ "eslint": "^8.1.0",
+ "generic-pool": "3.8.2",
+ "nyc": "^15.1.0",
+ "redis-parser": "3.0.0",
+ "release-it": "^14.11.6",
+ "sinon": "^11.1.2",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typedoc": "^0.22.7",
+ "typedoc-github-wiki-theme": "^0.6.0",
+ "typedoc-plugin-markdown": "^3.11.3",
+ "typescript": "^4.4.4",
+ "yallist": "4.0.0"
+ }
+ },
+ "@redis/json": {
+ "version": "file:packages/json",
+ "requires": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
+ },
+ "@redis/search": {
+ "version": "file:packages/search",
+ "requires": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
+ },
+ "@redis/test-utils": {
+ "version": "file:packages/test-utils",
+ "requires": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@tsconfig/node12": "^1.0.9",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.11.6",
+ "@types/yargs": "^17.0.5",
+ "mocha": "^9.1.3",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4",
+ "yargs": "^17.2.1"
+ }
+ },
+ "@redis/time-series": {
+ "version": "file:packages/time-series",
+ "requires": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
+ },
"@sindresorhus/is": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
@@ -7149,9 +7303,9 @@
"dev": true
},
"@types/node": {
- "version": "16.11.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz",
- "integrity": "sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==",
+ "version": "16.11.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
+ "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
"dev": true
},
"@types/parse-json": {
@@ -7200,13 +7354,13 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.2.0.tgz",
- "integrity": "sha512-qQwg7sqYkBF4CIQSyRQyqsYvP+g/J0To9ZPVNJpfxfekl5RmdvQnFFTVVwpRtaUDFNvjfe/34TgY/dpc3MgNTw==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.1.tgz",
+ "integrity": "sha512-cFImaoIr5Ojj358xI/SDhjog57OK2NqlpxwdcgyxDA3bJlZcJq5CPzUXtpD7CxI2Hm6ATU7w5fQnnkVnmwpHqw==",
"dev": true,
"requires": {
- "@typescript-eslint/experimental-utils": "5.2.0",
- "@typescript-eslint/scope-manager": "5.2.0",
+ "@typescript-eslint/experimental-utils": "5.3.1",
+ "@typescript-eslint/scope-manager": "5.3.1",
"debug": "^4.3.2",
"functional-red-black-tree": "^1.0.1",
"ignore": "^5.1.8",
@@ -7216,55 +7370,55 @@
}
},
"@typescript-eslint/experimental-utils": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.2.0.tgz",
- "integrity": "sha512-fWyT3Agf7n7HuZZRpvUYdFYbPk3iDCq6fgu3ulia4c7yxmPnwVBovdSOX7RL+k8u6hLbrXcdAehlWUVpGh6IEw==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.1.tgz",
+ "integrity": "sha512-RgFn5asjZ5daUhbK5Sp0peq0SSMytqcrkNfU4pnDma2D8P3ElZ6JbYjY8IMSFfZAJ0f3x3tnO3vXHweYg0g59w==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
- "@typescript-eslint/scope-manager": "5.2.0",
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/typescript-estree": "5.2.0",
+ "@typescript-eslint/scope-manager": "5.3.1",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/typescript-estree": "5.3.1",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
}
},
"@typescript-eslint/parser": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.2.0.tgz",
- "integrity": "sha512-Uyy4TjJBlh3NuA8/4yIQptyJb95Qz5PX//6p8n7zG0QnN4o3NF9Je3JHbVU7fxf5ncSXTmnvMtd/LDQWDk0YqA==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.3.1.tgz",
+ "integrity": "sha512-TD+ONlx5c+Qhk21x9gsJAMRohWAUMavSOmJgv3JGy9dgPhuBd5Wok0lmMClZDyJNLLZK1JRKiATzCKZNUmoyfw==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.2.0",
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/typescript-estree": "5.2.0",
+ "@typescript-eslint/scope-manager": "5.3.1",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/typescript-estree": "5.3.1",
"debug": "^4.3.2"
}
},
"@typescript-eslint/scope-manager": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.2.0.tgz",
- "integrity": "sha512-RW+wowZqPzQw8MUFltfKYZfKXqA2qgyi6oi/31J1zfXJRpOn6tCaZtd9b5u9ubnDG2n/EMvQLeZrsLNPpaUiFQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.3.1.tgz",
+ "integrity": "sha512-XksFVBgAq0Y9H40BDbuPOTUIp7dn4u8oOuhcgGq7EoDP50eqcafkMVGrypyVGvDYHzjhdUCUwuwVUK4JhkMAMg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/visitor-keys": "5.2.0"
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/visitor-keys": "5.3.1"
}
},
"@typescript-eslint/types": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.2.0.tgz",
- "integrity": "sha512-cTk6x08qqosps6sPyP2j7NxyFPlCNsJwSDasqPNjEQ8JMD5xxj2NHxcLin5AJQ8pAVwpQ8BMI3bTxR0zxmK9qQ==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.3.1.tgz",
+ "integrity": "sha512-bG7HeBLolxKHtdHG54Uac750eXuQQPpdJfCYuw4ZI3bZ7+GgKClMWM8jExBtp7NSP4m8PmLRM8+lhzkYnSmSxQ==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.2.0.tgz",
- "integrity": "sha512-RsdXq2XmVgKbm9nLsE3mjNUM7BTr/K4DYR9WfFVMUuozHWtH5gMpiNZmtrMG8GR385EOSQ3kC9HiEMJWimxd/g==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.1.tgz",
+ "integrity": "sha512-PwFbh/PKDVo/Wct6N3w+E4rLZxUDgsoII/GrWM2A62ETOzJd4M6s0Mu7w4CWsZraTbaC5UQI+dLeyOIFF1PquQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.2.0",
- "@typescript-eslint/visitor-keys": "5.2.0",
+ "@typescript-eslint/types": "5.3.1",
+ "@typescript-eslint/visitor-keys": "5.3.1",
"debug": "^4.3.2",
"globby": "^11.0.4",
"is-glob": "^4.0.3",
@@ -7273,12 +7427,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.2.0.tgz",
- "integrity": "sha512-Nk7HizaXWWCUBfLA/rPNKMzXzWS8Wg9qHMuGtT+v2/YpPij4nVXrVJc24N/r5WrrmqK31jCrZxeHqIgqRzs0Xg==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.1.tgz",
+ "integrity": "sha512-3cHUzUuVTuNHx0Gjjt5pEHa87+lzyqOiHXy/Gz+SJOCW1mpw9xQHIIEwnKn+Thph1mgWyZ90nboOcSuZr/jTTQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.2.0",
+ "@typescript-eslint/types": "5.3.1",
"eslint-visitor-keys": "^3.0.0"
}
},
@@ -7519,13 +7673,13 @@
"dev": true
},
"browserslist": {
- "version": "4.17.5",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.5.tgz",
- "integrity": "sha512-I3ekeB92mmpctWBoLXe0d5wPS2cBuRvvW0JyyJHMrk9/HmP2ZjrTboNAZ8iuGqaEIlKguljbQY32OkOJIRrgoA==",
+ "version": "4.17.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz",
+ "integrity": "sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001271",
- "electron-to-chromium": "^1.3.878",
+ "caniuse-lite": "^1.0.30001274",
+ "electron-to-chromium": "^1.3.886",
"escalade": "^3.1.1",
"node-releases": "^2.0.1",
"picocolors": "^1.0.0"
@@ -7614,9 +7768,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001274",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001274.tgz",
- "integrity": "sha512-+Nkvv0fHyhISkiMIjnyjmf5YJcQ1IQHZN6U9TLUMroWR38FNwpsC51Gb68yueafX1V6ifOisInSgP9WJFS13ew==",
+ "version": "1.0.30001278",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz",
+ "integrity": "sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==",
"dev": true
},
"chalk": {
@@ -7963,9 +8117,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.885",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.885.tgz",
- "integrity": "sha512-JXKFJcVWrdHa09n4CNZYfYaK6EW5aAew7/wr3L1OnsD1L+JHL+RCtd7QgIsxUbFPeTwPlvnpqNNTOLkoefmtXg==",
+ "version": "1.3.891",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.891.tgz",
+ "integrity": "sha512-3cpwR82QkIS01CN/dup/4Yr3BiOiRLlZlcAFn/5FbNCunMO9ojqDgEP9JEo1QNLflu3pEnPWve50gHOEKc7r6w==",
"dev": true
},
"emoji-regex": {
@@ -8026,12 +8180,12 @@
"dev": true
},
"eslint": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz",
- "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.2.0.tgz",
+ "integrity": "sha512-erw7XmM+CLxTOickrimJ1SiF55jiNlVSp2qqm0NuBWPtHYQCegD5ZMaW0c3i5ytPqL+SSLaCxdvQXFPLJn+ABw==",
"dev": true,
"requires": {
- "@eslint/eslintrc": "^1.0.3",
+ "@eslint/eslintrc": "^1.0.4",
"@humanwhocodes/config-array": "^0.6.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@@ -8065,7 +8219,7 @@
"progress": "^2.0.0",
"regexpp": "^3.2.0",
"semver": "^7.2.1",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"strip-json-comments": "^3.1.0",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
@@ -8123,9 +8277,9 @@
}
},
"eslint-visitor-keys": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz",
- "integrity": "sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz",
+ "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==",
"dev": true
},
"espree": {
@@ -8667,9 +8821,9 @@
"dev": true
},
"ignore": {
- "version": "5.1.8",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
- "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
+ "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"dev": true
},
"import-cwd": {
@@ -10220,6 +10374,16 @@
"resolve": "^1.1.6"
}
},
+ "redis": {
+ "version": "file:packages/all-in-one",
+ "requires": {
+ "@redis/client": "^4.0.0-rc",
+ "@redis/json": "^1.0.0-rc",
+ "@redis/search": "^1.0.0-rc",
+ "release-it": "^14.11.6",
+ "typescript": "^4.4.4"
+ }
+ },
"redis-errors": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
@@ -10803,9 +10967,9 @@
}
},
"typedoc": {
- "version": "0.22.7",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.7.tgz",
- "integrity": "sha512-ndxxp+tU1Wczvdxp4u2/PvT1qjD6hdFdSdehpORHjE+JXmMkl2bftXCR0upHmsnesBG7VCcr8vfgloGHIH8glQ==",
+ "version": "0.22.8",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.8.tgz",
+ "integrity": "sha512-92S+YzyhospdXN5rnkYUTgirdTYqNWY7NP9vco+IqQQoiSXzVSUsawVro+tMyEEsWUS7EMaJ2YOjB9uE0CBi6A==",
"dev": true,
"requires": {
"glob": "^7.2.0",
@@ -10854,9 +11018,9 @@
"dev": true
},
"uglify-js": {
- "version": "3.14.2",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz",
- "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==",
+ "version": "3.14.3",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz",
+ "integrity": "sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==",
"dev": true,
"optional": true
},
diff --git a/package.json b/package.json
index f252e4a0fa..e7de3fc867 100644
--- a/package.json
+++ b/package.json
@@ -1,60 +1,19 @@
{
- "name": "redis",
- "version": "4.0.0-rc.3",
- "description": "A high performance Redis client.",
- "keywords": [
- "database",
- "redis",
- "pubsub"
+ "name": "redis-monorepo",
+ "private": true,
+ "workspaces": [
+ "./packages/*"
],
- "author": "Matt Ranney ",
- "license": "MIT",
- "main": "./dist/index.js",
- "types": "./dist/index.d.ts",
"scripts": {
- "test": "nyc -r text-summary -r html mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'",
- "build": "tsc",
- "lint": "eslint ./*.ts ./lib/**/*.ts",
- "documentation": "typedoc"
- },
- "dependencies": {
- "cluster-key-slot": "1.1.0",
- "generic-pool": "3.8.2",
- "redis-parser": "3.0.0",
- "yallist": "4.0.0"
+ "test": "npm run test -ws --if-present",
+ "build:client": "npm run build -w ./packages/client",
+ "build:test-utils": "npm run build -w ./packages/test-utils",
+ "build:tests-tools": "npm run build:client && npm run build:test-utils",
+ "build:modules": "find ./packages -mindepth 1 -maxdepth 1 -type d ! -name 'client' ! -name 'test-utils' ! -name 'all-in-one' -exec npm run build -w {} \\;",
+ "build:all-in-one": "npm run build -w ./packages/all-in-one",
+ "build": "npm run build:client && npm run build:test-utils && npm run build:modules && npm run build:all-in-one"
},
"devDependencies": {
- "@istanbuljs/nyc-config-typescript": "^1.0.1",
- "@tsconfig/node12": "^1.0.9",
- "@types/mocha": "^9.0.0",
- "@types/node": "^16.11.6",
- "@types/sinon": "^10.0.6",
- "@types/yallist": "^4.0.1",
- "@types/yargs": "^17.0.5",
- "@typescript-eslint/eslint-plugin": "^5.2.0",
- "@typescript-eslint/parser": "^5.2.0",
- "eslint": "^8.1.0",
- "mocha": "^9.1.3",
- "nyc": "^15.1.0",
- "release-it": "^14.11.6",
- "sinon": "^11.1.2",
- "source-map-support": "^0.5.20",
- "ts-node": "^10.4.0",
- "typedoc": "^0.22.7",
- "typedoc-github-wiki-theme": "^0.6.0",
- "typedoc-plugin-markdown": "^3.11.3",
- "typescript": "^4.4.4",
- "yargs": "^17.2.1"
- },
- "engines": {
- "node": ">=12"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/redis/node-redis.git"
- },
- "bugs": {
- "url": "https://github.com/redis/node-redis/issues"
- },
- "homepage": "https://github.com/redis/node-redis"
+ "@tsconfig/node12": "^1.0.9"
+ }
}
diff --git a/packages/all-in-one/index.ts b/packages/all-in-one/index.ts
new file mode 100644
index 0000000000..b0cd5c1f8f
--- /dev/null
+++ b/packages/all-in-one/index.ts
@@ -0,0 +1,19 @@
+import { createClient as _createClient } from '@redis/client';
+import { RedisScripts } from '@redis/client/dist/lib/commands';
+import { RedisClientOptions, RedisClientType } from '@redis/client/dist/lib/client';
+import RedisJSON from '@redis/json';
+import RediSearch from '@redis/search';
+
+const modules = {
+ json: RedisJSON,
+ ft: RediSearch
+};
+
+export function createClient>(
+ options?: Omit, 'modules'>
+): RedisClientType {
+ return _createClient({
+ ...options,
+ modules
+ });
+}
diff --git a/packages/all-in-one/package.json b/packages/all-in-one/package.json
new file mode 100644
index 0000000000..8fdb714971
--- /dev/null
+++ b/packages/all-in-one/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "redis",
+ "version": "4.0.0-rc.3",
+ "license": "MIT",
+ "main": "./dist/index.js",
+ "types": "./dist/index.ts",
+ "scripts": {
+ "build": "tsc"
+ },
+ "dependencies": {
+ "@redis/client": "^4.0.0-rc",
+ "@redis/json": "^1.0.0-rc",
+ "@redis/search": "^1.0.0-rc"
+ },
+ "devDependencies": {
+ "release-it": "^14.11.6",
+ "typescript": "^4.4.4"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/redis/node-redis.git"
+ },
+ "bugs": {
+ "url": "https://github.com/redis/node-redis/issues"
+ },
+ "homepage": "https://github.com/redis/node-redis"
+}
diff --git a/packages/all-in-one/tsconfig.json b/packages/all-in-one/tsconfig.json
new file mode 100644
index 0000000000..103760b874
--- /dev/null
+++ b/packages/all-in-one/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "./dist"
+ },
+ "include": [
+ "./index.ts"
+ ]
+ }
diff --git a/.eslintrc.json b/packages/client/.eslintrc.json
similarity index 100%
rename from .eslintrc.json
rename to packages/client/.eslintrc.json
diff --git a/packages/client/.gitignore b/packages/client/.gitignore
new file mode 100644
index 0000000000..2d7ddbc106
--- /dev/null
+++ b/packages/client/.gitignore
@@ -0,0 +1 @@
+documentation/
diff --git a/packages/client/.npmignore b/packages/client/.npmignore
new file mode 100644
index 0000000000..b7310e1576
--- /dev/null
+++ b/packages/client/.npmignore
@@ -0,0 +1,9 @@
+.nyc_output/
+coverage/
+documentation/
+examples/
+lib/
+.nycrc.json
+dump.rdb
+index.ts
+tsconfig.json
diff --git a/packages/client/.nycrc.json b/packages/client/.nycrc.json
new file mode 100644
index 0000000000..b4e671e178
--- /dev/null
+++ b/packages/client/.nycrc.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@istanbuljs/nyc-config-typescript",
+ "exclude": ["**/*.spec.ts", "lib/test-utils.ts"]
+}
diff --git a/CHANGELOG.md b/packages/client/CHANGELOG.md
similarity index 100%
rename from CHANGELOG.md
rename to packages/client/CHANGELOG.md
diff --git a/packages/client/LICENSE b/packages/client/LICENSE
new file mode 100644
index 0000000000..db86cc4de7
--- /dev/null
+++ b/packages/client/LICENSE
@@ -0,0 +1,24 @@
+MIT License
+
+Copyright (c) 2016-present Node Redis contributors.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/client/README.md b/packages/client/README.md
new file mode 100644
index 0000000000..813f9830ef
--- /dev/null
+++ b/packages/client/README.md
@@ -0,0 +1,294 @@
+
+
+
+
+
Node Redis
+
+
+
+
+---
+
+## Installation
+
+```bash
+npm install redis@next
+```
+
+> :warning: The new interface is clean and cool, but if you have an existing code base, you'll want to read the [migration guide](./docs/v3-to-v4.md).
+
+## Usage
+
+### Basic Example
+
+```typescript
+import { createClient } from 'redis';
+
+(async () => {
+ const client = createClient();
+
+ client.on('error', (err) => console.log('Redis Client Error', err));
+
+ await client.connect();
+
+ await client.set('key', 'value');
+ const value = await client.get('key');
+})();
+```
+
+The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in the format `redis[s]://[[username][:password]@][host][:port][/db-number]`:
+
+```typescript
+createClient({
+ url: 'redis://alice:foobared@awesome.redis.server:6380'
+});
+```
+
+You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in the [client configuration guide](./docs/client-configuration.md).
+
+### Redis Commands
+
+There is built-in support for all of the [out-of-the-box Redis commands](https://redis.io/commands). They are exposed using the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`, etc.):
+
+```typescript
+// raw Redis commands
+await client.HSET('key', 'field', 'value');
+await client.HGETALL('key');
+
+// friendly JavaScript commands
+await client.hSet('key', 'field', 'value');
+await client.hGetAll('key');
+```
+
+Modifiers to commands are specified using a JavaScript object:
+
+```typescript
+await client.set('key', 'value', {
+ EX: 10,
+ NX: true
+});
+```
+
+Replies will be transformed into useful data structures:
+
+```typescript
+await client.hGetAll('key'); // { field1: 'value1', field2: 'value2' }
+await client.hVals('key'); // ['value1', 'value2']
+```
+
+### Unsupported Redis Commands
+
+If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:
+
+```typescript
+await client.sendCommand(['SET', 'key', 'value', 'NX']); // 'OK'
+
+await client.sendCommand(['HGETALL', 'key']); // ['key1', 'field1', 'key2', 'field2']
+```
+
+### Transactions (Multi/Exec)
+
+Start a [transaction](https://redis.io/topics/transactions) by calling `.multi()`, then chaining your commands. When you're done, call `.exec()` and you'll get an array back with your results:
+
+```typescript
+await client.set('another-key', 'another-value');
+
+const [setKeyReply, otherKeyValue] = await client
+ .multi()
+ .set('key', 'value')
+ .get('another-key')
+ .exec(); // ['OK', 'another-value']
+```
+
+You can also [watch](https://redis.io/topics/transactions#optimistic-locking-using-check-and-set) keys by calling `.watch()`. Your transaction will abort if any of the watched keys change.
+
+To dig deeper into transactions, check out the [Isolated Execution Guide](./docs/isolated-execution.md).
+
+### Blocking Commands
+
+Any command can be run on a new connection by specifying the `isolated` option. The newly created connection is closed when the command's `Promise` is fulfilled.
+
+This pattern works especially well for blocking commands—such as `BLPOP` and `BLMOVE`:
+
+```typescript
+import { commandOptions } from 'redis';
+
+const blPopPromise = client.blPop(commandOptions({ isolated: true }), 'key', 0);
+
+await client.lPush('key', ['1', '2']);
+
+await blPopPromise; // '2'
+```
+
+To learn more about isolated execution, check out the [guide](./docs/isolated-execution.md).
+
+### Pub/Sub
+
+Subscribing to a channel requires a dedicated stand-alone connection. You can easily get one by `.duplicate()`ing an existing Redis connection.
+
+```typescript
+const subscriber = client.duplicate();
+
+await subscriber.connect();
+```
+
+Once you have one, simply subscribe and unsubscribe as needed:
+
+```typescript
+await subscriber.subscribe('channel', (message) => {
+ console.log(message); // 'message'
+});
+
+await subscriber.pSubscribe('channe*', (message, channel) => {
+ console.log(message, channel); // 'message', 'channel'
+});
+
+await subscriber.unsubscribe('channel');
+
+await subscriber.pUnsubscribe('channe*');
+```
+
+Publish a message on a channel:
+
+```typescript
+await publisher.publish('channel', 'message');
+```
+
+### Scan Iterator
+
+[`SCAN`](https://redis.io/commands/scan) results can be looped over using [async iterators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator):
+
+```typescript
+for await (const key of client.scanIterator()) {
+ // use the key!
+ await client.get(key);
+}
+```
+
+This works with `HSCAN`, `SSCAN`, and `ZSCAN` too:
+
+```typescript
+for await (const { field, value } of client.hScanIterator('hash')) {}
+for await (const member of client.sScanIterator('set')) {}
+for await (const { score, member } of client.zScanIterator('sorted-set')) {}
+```
+
+You can override the default options by providing a configuration object:
+
+```typescript
+client.scanIterator({
+ TYPE: 'string', // `SCAN` only
+ MATCH: 'patter*',
+ COUNT: 100
+});
+```
+
+### Lua Scripts
+
+Define new functions using [Lua scripts](https://redis.io/commands/eval) which execute on the Redis server:
+
+```typescript
+import { createClient, defineScript } from 'redis';
+
+(async () => {
+ const client = createClient({
+ scripts: {
+ add: defineScript({
+ NUMBER_OF_KEYS: 1,
+ SCRIPT:
+ 'local val = redis.pcall("GET", KEYS[1]);' +
+ 'return val + ARGV[1];',
+ transformArguments(key: string, toAdd: number): Array {
+ return [key, toAdd.toString()];
+ },
+ transformReply(reply: number): number {
+ return reply;
+ }
+ })
+ }
+ });
+
+ await client.connect();
+
+ await client.set('key', '1');
+ await client.add('key', 2); // 3
+})();
+```
+
+### Disconnecting
+
+There are two functions that disconnect a client from the Redis server. In most scenarios you should use `.quit()` to ensure that pending commands are sent to Redis before closing a connection.
+
+#### `.QUIT()`/`.quit()`
+
+Gracefully close a client's connection to Redis, by sending the [`QUIT`](https://redis.io/commands/quit) command to the server. Before quitting, the client executes any remaining commands in its queue, and will receive replies from Redis for each of them.
+
+```typescript
+const [ping, get, quit] = await Promise.all([
+ client.ping(),
+ client.get('key'),
+ client.quit()
+]); // ['PONG', null, 'OK']
+
+try {
+ await client.get('key');
+} catch (err) {
+ // ClosedClient Error
+}
+```
+
+#### `.disconnect()`
+
+Forcibly close a client's connection to Redis immediately. Calling `disconnect` will not send further pending commands to the Redis server, or wait for or parse outstanding responses.
+
+```typescript
+await client.disconnect();
+```
+
+### Auto-Pipelining
+
+Node Redis will automatically pipeline requests that are made during the same "tick".
+
+```typescript
+client.set('Tm9kZSBSZWRpcw==', 'users:1');
+client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==');
+```
+
+Of course, if you don't do something with your Promises you're certain to get [unhandled Promise exceptions](https://nodejs.org/api/process.html#process_event_unhandledrejection). To take advantage of auto-pipelining and handle your Promises, use `Promise.all()`.
+
+```typescript
+await Promise.all([
+ client.set('Tm9kZSBSZWRpcw==', 'users:1'),
+ client.sAdd('users:1:tokens', 'Tm9kZSBSZWRpcw==')
+]);
+```
+
+### Clustering
+
+Check out the [Clustering Guide](./docs/clustering.md) when using Node Redis to connect to a Redis Cluster.
+
+## Supported Redis versions
+
+Node Redis is supported with the following versions of Redis:
+
+| Version | Supported |
+|---------|--------------------|
+| 6.2.z | :heavy_check_mark: |
+| 6.0.z | :heavy_check_mark: |
+| 5.y.z | :heavy_check_mark: |
+| < 5.0 | :x: |
+
+> Node Redis should work with older versions of Redis, but it is not fully tested and we cannot offer support.
diff --git a/docs/FAQ.md b/packages/client/docs/FAQ.md
similarity index 100%
rename from docs/FAQ.md
rename to packages/client/docs/FAQ.md
diff --git a/docs/client-configuration.md b/packages/client/docs/client-configuration.md
similarity index 98%
rename from docs/client-configuration.md
rename to packages/client/docs/client-configuration.md
index 11fdb0a681..3b6b7dcad7 100644
--- a/docs/client-configuration.md
+++ b/packages/client/docs/client-configuration.md
@@ -15,7 +15,7 @@
| username | | ACL username ([see ACL guide](https://redis.io/topics/acl)) |
| password | | ACL password or the old "--requirepass" password |
| database | | Database number to connect to (see [`SELECT`](https://redis.io/commands/select) command) |
-| modules | | Object defining which [Redis Modules](https://redis.io/modules) to include (TODO - document) |
+| modules | | Object defining which [Redis Modules](../../README.md#modules) to include |
| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
| commandsQueueMaxLength | | Maximum length of the client's internal command queue |
| readonly | `false` | Connect in [`READONLY`](https://redis.io/commands/readonly) mode |
diff --git a/docs/clustering.md b/packages/client/docs/clustering.md
similarity index 82%
rename from docs/clustering.md
rename to packages/client/docs/clustering.md
index a84dc3b1aa..3b5ef94a5c 100644
--- a/docs/clustering.md
+++ b/packages/client/docs/clustering.md
@@ -37,7 +37,9 @@ import { createCluster } from 'redis';
| rootNodes | | An array of root nodes that are part of the cluster, which will be used to get the cluster topology. Each element in the array is a client configuration object. There is no need to specify every node in the cluster, 3 should be enough to reliably connect and obtain the cluster configuration from the server |
| defaults | | The default configuration values for every client in the cluster. Use this for example when specifying an ACL user to connect with |
| useReplicas | `false` | When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes |
-| maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors | |
+| maxCommandRedirections | `16` | The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors |
+| modules | | Object defining which [Redis Modules](../../README.md#modules) to include |
+| scripts | | Object defining Lua Scripts to use with this client (see [Lua Scripts](../README.md#lua-scripts)) |
## Command Routing
diff --git a/docs/isolated-execution.md b/packages/client/docs/isolated-execution.md
similarity index 100%
rename from docs/isolated-execution.md
rename to packages/client/docs/isolated-execution.md
diff --git a/docs/v3-to-v4.md b/packages/client/docs/v3-to-v4.md
similarity index 100%
rename from docs/v3-to-v4.md
rename to packages/client/docs/v3-to-v4.md
diff --git a/examples/README.md b/packages/client/examples/README.md
similarity index 100%
rename from examples/README.md
rename to packages/client/examples/README.md
diff --git a/examples/blocking-list-pop.js b/packages/client/examples/blocking-list-pop.js
similarity index 100%
rename from examples/blocking-list-pop.js
rename to packages/client/examples/blocking-list-pop.js
diff --git a/examples/command-with-modifiers.js b/packages/client/examples/command-with-modifiers.js
similarity index 100%
rename from examples/command-with-modifiers.js
rename to packages/client/examples/command-with-modifiers.js
diff --git a/examples/connect-as-acl-user.js b/packages/client/examples/connect-as-acl-user.js
similarity index 100%
rename from examples/connect-as-acl-user.js
rename to packages/client/examples/connect-as-acl-user.js
diff --git a/examples/lua-multi-incr.js b/packages/client/examples/lua-multi-incr.js
similarity index 100%
rename from examples/lua-multi-incr.js
rename to packages/client/examples/lua-multi-incr.js
diff --git a/examples/package-lock.json b/packages/client/examples/package-lock.json
similarity index 100%
rename from examples/package-lock.json
rename to packages/client/examples/package-lock.json
diff --git a/examples/package.json b/packages/client/examples/package.json
similarity index 64%
rename from examples/package.json
rename to packages/client/examples/package.json
index 4963094b0b..edb8cdacdb 100644
--- a/examples/package.json
+++ b/packages/client/examples/package.json
@@ -4,11 +4,6 @@
"description": "node-redis 4 example script",
"main": "index.js",
"private": true,
- "scripts": {
- },
- "type": "module",
- "dependencies": {
- "redis": "../"
- }
+ "type": "module"
}
diff --git a/examples/set-scan.js b/packages/client/examples/set-scan.js
similarity index 100%
rename from examples/set-scan.js
rename to packages/client/examples/set-scan.js
diff --git a/index.ts b/packages/client/index.ts
similarity index 100%
rename from index.ts
rename to packages/client/index.ts
diff --git a/lib/client/commands-queue.ts b/packages/client/lib/client/commands-queue.ts
similarity index 100%
rename from lib/client/commands-queue.ts
rename to packages/client/lib/client/commands-queue.ts
diff --git a/lib/client/commands.ts b/packages/client/lib/client/commands.ts
similarity index 100%
rename from lib/client/commands.ts
rename to packages/client/lib/client/commands.ts
diff --git a/lib/client/index.spec.ts b/packages/client/lib/client/index.spec.ts
similarity index 98%
rename from lib/client/index.spec.ts
rename to packages/client/lib/client/index.spec.ts
index 51dded18b1..21abe8a25f 100644
--- a/lib/client/index.spec.ts
+++ b/packages/client/lib/client/index.spec.ts
@@ -444,16 +444,16 @@ describe('Client', () => {
}
});
- testUtils.testWithClient('executeIsolated', async client => {
- await client.sendCommand(['CLIENT', 'SETNAME', 'client']);
+ // testUtils.testWithClient('executeIsolated', async client => {
+ // await client.sendCommand(['CLIENT', 'SETNAME', 'client']);
- assert.equal(
- await client.executeIsolated(isolatedClient =>
- isolatedClient.sendCommand(['CLIENT', 'GETNAME'])
- ),
- null
- );
- }, GLOBAL.SERVERS.OPEN);
+ // assert.equal(
+ // await client.executeIsolated(isolatedClient =>
+ // isolatedClient.sendCommand(['CLIENT', 'GETNAME'])
+ // ),
+ // null
+ // );
+ // }, GLOBAL.SERVERS.OPEN);
async function killClient(client: RedisClientType): Promise {
const onceErrorPromise = once(client, 'error');
diff --git a/lib/client/index.ts b/packages/client/lib/client/index.ts
similarity index 100%
rename from lib/client/index.ts
rename to packages/client/lib/client/index.ts
diff --git a/lib/client/multi-command.ts b/packages/client/lib/client/multi-command.ts
similarity index 100%
rename from lib/client/multi-command.ts
rename to packages/client/lib/client/multi-command.ts
diff --git a/lib/client/socket.spec.ts b/packages/client/lib/client/socket.spec.ts
similarity index 100%
rename from lib/client/socket.spec.ts
rename to packages/client/lib/client/socket.spec.ts
diff --git a/lib/client/socket.ts b/packages/client/lib/client/socket.ts
similarity index 100%
rename from lib/client/socket.ts
rename to packages/client/lib/client/socket.ts
diff --git a/lib/cluster/cluster-slots.ts b/packages/client/lib/cluster/cluster-slots.ts
similarity index 100%
rename from lib/cluster/cluster-slots.ts
rename to packages/client/lib/cluster/cluster-slots.ts
diff --git a/lib/cluster/commands.ts b/packages/client/lib/cluster/commands.ts
similarity index 100%
rename from lib/cluster/commands.ts
rename to packages/client/lib/cluster/commands.ts
diff --git a/lib/cluster/index.spec.ts b/packages/client/lib/cluster/index.spec.ts
similarity index 51%
rename from lib/cluster/index.spec.ts
rename to packages/client/lib/cluster/index.spec.ts
index 66319460f6..43492a6500 100644
--- a/lib/cluster/index.spec.ts
+++ b/packages/client/lib/cluster/index.spec.ts
@@ -47,47 +47,47 @@ describe('Cluster', () => {
}
});
- testUtils.testWithCluster('should handle live resharding', async cluster => {
- const key = 'key',
- value = 'value';
- await cluster.set(key, value);
+ // testUtils.testWithCluster('should handle live resharding', async cluster => {
+ // const key = 'key',
+ // value = 'value';
+ // await cluster.set(key, value);
- const slot = calculateSlot(key),
- from = cluster.getSlotMaster(slot),
- to = cluster.getMasters().find(node => node.id !== from.id);
+ // const slot = calculateSlot(key),
+ // from = cluster.getSlotMaster(slot),
+ // to = cluster.getMasters().find(node => node.id !== from.id);
- await to!.client.clusterSetSlot(slot, ClusterSlotStates.IMPORTING, from.id);
+ // await to!.client.clusterSetSlot(slot, ClusterSlotStates.IMPORTING, from.id);
- // should be able to get the key from the original node before it was migrated
- assert.equal(
- await cluster.get(key),
- value
- );
+ // // should be able to get the key from the original node before it was migrated
+ // assert.equal(
+ // await cluster.get(key),
+ // value
+ // );
- await from.client.clusterSetSlot(slot, ClusterSlotStates.MIGRATING, to!.id);
+ // await from.client.clusterSetSlot(slot, ClusterSlotStates.MIGRATING, to!.id);
- // should be able to get the key from the original node using the "ASKING" command
- assert.equal(
- await cluster.get(key),
- value
- );
+ // // should be able to get the key from the original node using the "ASKING" command
+ // assert.equal(
+ // await cluster.get(key),
+ // value
+ // );
- const { port: toPort } = to!.client.options!.socket;
+ // const { port: toPort } = to!.client.options!.socket;
- await from.client.migrate(
- '127.0.0.1',
- toPort,
- key,
- 0,
- 10
- );
+ // await from.client.migrate(
+ // '127.0.0.1',
+ // toPort,
+ // key,
+ // 0,
+ // 10
+ // );
- // should be able to get the key from the new node
- assert.equal(
- await cluster.get(key),
- value
- );
- }, {
- serverArguments: []
- });
+ // // should be able to get the key from the new node
+ // assert.equal(
+ // await cluster.get(key),
+ // value
+ // );
+ // }, {
+ // serverArguments: []
+ // });
});
diff --git a/lib/cluster/index.ts b/packages/client/lib/cluster/index.ts
similarity index 100%
rename from lib/cluster/index.ts
rename to packages/client/lib/cluster/index.ts
diff --git a/lib/cluster/multi-command.ts b/packages/client/lib/cluster/multi-command.ts
similarity index 100%
rename from lib/cluster/multi-command.ts
rename to packages/client/lib/cluster/multi-command.ts
diff --git a/lib/command-options.ts b/packages/client/lib/command-options.ts
similarity index 100%
rename from lib/command-options.ts
rename to packages/client/lib/command-options.ts
diff --git a/lib/commander.spec.ts b/packages/client/lib/commander.spec.ts
similarity index 100%
rename from lib/commander.spec.ts
rename to packages/client/lib/commander.spec.ts
diff --git a/lib/commander.ts b/packages/client/lib/commander.ts
similarity index 100%
rename from lib/commander.ts
rename to packages/client/lib/commander.ts
diff --git a/lib/commands/ACL_CAT.spec.ts b/packages/client/lib/commands/ACL_CAT.spec.ts
similarity index 100%
rename from lib/commands/ACL_CAT.spec.ts
rename to packages/client/lib/commands/ACL_CAT.spec.ts
diff --git a/lib/commands/ACL_CAT.ts b/packages/client/lib/commands/ACL_CAT.ts
similarity index 100%
rename from lib/commands/ACL_CAT.ts
rename to packages/client/lib/commands/ACL_CAT.ts
diff --git a/lib/commands/ACL_DELUSER.spec.ts b/packages/client/lib/commands/ACL_DELUSER.spec.ts
similarity index 100%
rename from lib/commands/ACL_DELUSER.spec.ts
rename to packages/client/lib/commands/ACL_DELUSER.spec.ts
diff --git a/lib/commands/ACL_DELUSER.ts b/packages/client/lib/commands/ACL_DELUSER.ts
similarity index 100%
rename from lib/commands/ACL_DELUSER.ts
rename to packages/client/lib/commands/ACL_DELUSER.ts
diff --git a/lib/commands/ACL_GENPASS.spec.ts b/packages/client/lib/commands/ACL_GENPASS.spec.ts
similarity index 100%
rename from lib/commands/ACL_GENPASS.spec.ts
rename to packages/client/lib/commands/ACL_GENPASS.spec.ts
diff --git a/lib/commands/ACL_GENPASS.ts b/packages/client/lib/commands/ACL_GENPASS.ts
similarity index 100%
rename from lib/commands/ACL_GENPASS.ts
rename to packages/client/lib/commands/ACL_GENPASS.ts
diff --git a/lib/commands/ACL_GETUSER.spec.ts b/packages/client/lib/commands/ACL_GETUSER.spec.ts
similarity index 100%
rename from lib/commands/ACL_GETUSER.spec.ts
rename to packages/client/lib/commands/ACL_GETUSER.spec.ts
diff --git a/lib/commands/ACL_GETUSER.ts b/packages/client/lib/commands/ACL_GETUSER.ts
similarity index 100%
rename from lib/commands/ACL_GETUSER.ts
rename to packages/client/lib/commands/ACL_GETUSER.ts
diff --git a/lib/commands/ACL_LIST.spec.ts b/packages/client/lib/commands/ACL_LIST.spec.ts
similarity index 100%
rename from lib/commands/ACL_LIST.spec.ts
rename to packages/client/lib/commands/ACL_LIST.spec.ts
diff --git a/lib/commands/ACL_LIST.ts b/packages/client/lib/commands/ACL_LIST.ts
similarity index 100%
rename from lib/commands/ACL_LIST.ts
rename to packages/client/lib/commands/ACL_LIST.ts
diff --git a/lib/commands/ACL_LOAD.spec.ts b/packages/client/lib/commands/ACL_LOAD.spec.ts
similarity index 100%
rename from lib/commands/ACL_LOAD.spec.ts
rename to packages/client/lib/commands/ACL_LOAD.spec.ts
diff --git a/lib/commands/ACL_LOAD.ts b/packages/client/lib/commands/ACL_LOAD.ts
similarity index 100%
rename from lib/commands/ACL_LOAD.ts
rename to packages/client/lib/commands/ACL_LOAD.ts
diff --git a/lib/commands/ACL_LOG.spec.ts b/packages/client/lib/commands/ACL_LOG.spec.ts
similarity index 100%
rename from lib/commands/ACL_LOG.spec.ts
rename to packages/client/lib/commands/ACL_LOG.spec.ts
diff --git a/lib/commands/ACL_LOG.ts b/packages/client/lib/commands/ACL_LOG.ts
similarity index 100%
rename from lib/commands/ACL_LOG.ts
rename to packages/client/lib/commands/ACL_LOG.ts
diff --git a/lib/commands/ACL_LOG_RESET.spec.ts b/packages/client/lib/commands/ACL_LOG_RESET.spec.ts
similarity index 100%
rename from lib/commands/ACL_LOG_RESET.spec.ts
rename to packages/client/lib/commands/ACL_LOG_RESET.spec.ts
diff --git a/lib/commands/ACL_LOG_RESET.ts b/packages/client/lib/commands/ACL_LOG_RESET.ts
similarity index 100%
rename from lib/commands/ACL_LOG_RESET.ts
rename to packages/client/lib/commands/ACL_LOG_RESET.ts
diff --git a/lib/commands/ACL_SAVE.spec.ts b/packages/client/lib/commands/ACL_SAVE.spec.ts
similarity index 100%
rename from lib/commands/ACL_SAVE.spec.ts
rename to packages/client/lib/commands/ACL_SAVE.spec.ts
diff --git a/lib/commands/ACL_SAVE.ts b/packages/client/lib/commands/ACL_SAVE.ts
similarity index 100%
rename from lib/commands/ACL_SAVE.ts
rename to packages/client/lib/commands/ACL_SAVE.ts
diff --git a/lib/commands/ACL_SETUSER.spec.ts b/packages/client/lib/commands/ACL_SETUSER.spec.ts
similarity index 100%
rename from lib/commands/ACL_SETUSER.spec.ts
rename to packages/client/lib/commands/ACL_SETUSER.spec.ts
diff --git a/lib/commands/ACL_SETUSER.ts b/packages/client/lib/commands/ACL_SETUSER.ts
similarity index 100%
rename from lib/commands/ACL_SETUSER.ts
rename to packages/client/lib/commands/ACL_SETUSER.ts
diff --git a/lib/commands/ACL_USERS.spec.ts b/packages/client/lib/commands/ACL_USERS.spec.ts
similarity index 100%
rename from lib/commands/ACL_USERS.spec.ts
rename to packages/client/lib/commands/ACL_USERS.spec.ts
diff --git a/lib/commands/ACL_USERS.ts b/packages/client/lib/commands/ACL_USERS.ts
similarity index 100%
rename from lib/commands/ACL_USERS.ts
rename to packages/client/lib/commands/ACL_USERS.ts
diff --git a/lib/commands/ACL_WHOAMI.spec.ts b/packages/client/lib/commands/ACL_WHOAMI.spec.ts
similarity index 100%
rename from lib/commands/ACL_WHOAMI.spec.ts
rename to packages/client/lib/commands/ACL_WHOAMI.spec.ts
diff --git a/lib/commands/ACL_WHOAMI.ts b/packages/client/lib/commands/ACL_WHOAMI.ts
similarity index 100%
rename from lib/commands/ACL_WHOAMI.ts
rename to packages/client/lib/commands/ACL_WHOAMI.ts
diff --git a/lib/commands/APPEND.spec.ts b/packages/client/lib/commands/APPEND.spec.ts
similarity index 100%
rename from lib/commands/APPEND.spec.ts
rename to packages/client/lib/commands/APPEND.spec.ts
diff --git a/lib/commands/APPEND.ts b/packages/client/lib/commands/APPEND.ts
similarity index 100%
rename from lib/commands/APPEND.ts
rename to packages/client/lib/commands/APPEND.ts
diff --git a/lib/commands/ASKING.spec.ts b/packages/client/lib/commands/ASKING.spec.ts
similarity index 100%
rename from lib/commands/ASKING.spec.ts
rename to packages/client/lib/commands/ASKING.spec.ts
diff --git a/lib/commands/ASKING.ts b/packages/client/lib/commands/ASKING.ts
similarity index 100%
rename from lib/commands/ASKING.ts
rename to packages/client/lib/commands/ASKING.ts
diff --git a/lib/commands/AUTH.spec.ts b/packages/client/lib/commands/AUTH.spec.ts
similarity index 100%
rename from lib/commands/AUTH.spec.ts
rename to packages/client/lib/commands/AUTH.spec.ts
diff --git a/lib/commands/AUTH.ts b/packages/client/lib/commands/AUTH.ts
similarity index 100%
rename from lib/commands/AUTH.ts
rename to packages/client/lib/commands/AUTH.ts
diff --git a/lib/commands/BGREWRITEAOF.spec.ts b/packages/client/lib/commands/BGREWRITEAOF.spec.ts
similarity index 100%
rename from lib/commands/BGREWRITEAOF.spec.ts
rename to packages/client/lib/commands/BGREWRITEAOF.spec.ts
diff --git a/lib/commands/BGREWRITEAOF.ts b/packages/client/lib/commands/BGREWRITEAOF.ts
similarity index 100%
rename from lib/commands/BGREWRITEAOF.ts
rename to packages/client/lib/commands/BGREWRITEAOF.ts
diff --git a/lib/commands/BGSAVE.spec.ts b/packages/client/lib/commands/BGSAVE.spec.ts
similarity index 100%
rename from lib/commands/BGSAVE.spec.ts
rename to packages/client/lib/commands/BGSAVE.spec.ts
diff --git a/lib/commands/BGSAVE.ts b/packages/client/lib/commands/BGSAVE.ts
similarity index 100%
rename from lib/commands/BGSAVE.ts
rename to packages/client/lib/commands/BGSAVE.ts
diff --git a/lib/commands/BITCOUNT.spec.ts b/packages/client/lib/commands/BITCOUNT.spec.ts
similarity index 100%
rename from lib/commands/BITCOUNT.spec.ts
rename to packages/client/lib/commands/BITCOUNT.spec.ts
diff --git a/lib/commands/BITCOUNT.ts b/packages/client/lib/commands/BITCOUNT.ts
similarity index 100%
rename from lib/commands/BITCOUNT.ts
rename to packages/client/lib/commands/BITCOUNT.ts
diff --git a/lib/commands/BITFIELD.spec.ts b/packages/client/lib/commands/BITFIELD.spec.ts
similarity index 100%
rename from lib/commands/BITFIELD.spec.ts
rename to packages/client/lib/commands/BITFIELD.spec.ts
diff --git a/lib/commands/BITFIELD.ts b/packages/client/lib/commands/BITFIELD.ts
similarity index 100%
rename from lib/commands/BITFIELD.ts
rename to packages/client/lib/commands/BITFIELD.ts
diff --git a/lib/commands/BITOP.spec.ts b/packages/client/lib/commands/BITOP.spec.ts
similarity index 100%
rename from lib/commands/BITOP.spec.ts
rename to packages/client/lib/commands/BITOP.spec.ts
diff --git a/lib/commands/BITOP.ts b/packages/client/lib/commands/BITOP.ts
similarity index 100%
rename from lib/commands/BITOP.ts
rename to packages/client/lib/commands/BITOP.ts
diff --git a/lib/commands/BITPOS.spec.ts b/packages/client/lib/commands/BITPOS.spec.ts
similarity index 100%
rename from lib/commands/BITPOS.spec.ts
rename to packages/client/lib/commands/BITPOS.spec.ts
diff --git a/lib/commands/BITPOS.ts b/packages/client/lib/commands/BITPOS.ts
similarity index 100%
rename from lib/commands/BITPOS.ts
rename to packages/client/lib/commands/BITPOS.ts
diff --git a/lib/commands/BLMOVE.spec.ts b/packages/client/lib/commands/BLMOVE.spec.ts
similarity index 100%
rename from lib/commands/BLMOVE.spec.ts
rename to packages/client/lib/commands/BLMOVE.spec.ts
diff --git a/lib/commands/BLMOVE.ts b/packages/client/lib/commands/BLMOVE.ts
similarity index 100%
rename from lib/commands/BLMOVE.ts
rename to packages/client/lib/commands/BLMOVE.ts
diff --git a/lib/commands/BLPOP.spec.ts b/packages/client/lib/commands/BLPOP.spec.ts
similarity index 100%
rename from lib/commands/BLPOP.spec.ts
rename to packages/client/lib/commands/BLPOP.spec.ts
diff --git a/lib/commands/BLPOP.ts b/packages/client/lib/commands/BLPOP.ts
similarity index 100%
rename from lib/commands/BLPOP.ts
rename to packages/client/lib/commands/BLPOP.ts
diff --git a/lib/commands/BRPOP.spec.ts b/packages/client/lib/commands/BRPOP.spec.ts
similarity index 100%
rename from lib/commands/BRPOP.spec.ts
rename to packages/client/lib/commands/BRPOP.spec.ts
diff --git a/lib/commands/BRPOP.ts b/packages/client/lib/commands/BRPOP.ts
similarity index 100%
rename from lib/commands/BRPOP.ts
rename to packages/client/lib/commands/BRPOP.ts
diff --git a/lib/commands/BRPOPLPUSH.spec.ts b/packages/client/lib/commands/BRPOPLPUSH.spec.ts
similarity index 100%
rename from lib/commands/BRPOPLPUSH.spec.ts
rename to packages/client/lib/commands/BRPOPLPUSH.spec.ts
diff --git a/lib/commands/BRPOPLPUSH.ts b/packages/client/lib/commands/BRPOPLPUSH.ts
similarity index 100%
rename from lib/commands/BRPOPLPUSH.ts
rename to packages/client/lib/commands/BRPOPLPUSH.ts
diff --git a/lib/commands/BZPOPMAX.spec.ts b/packages/client/lib/commands/BZPOPMAX.spec.ts
similarity index 100%
rename from lib/commands/BZPOPMAX.spec.ts
rename to packages/client/lib/commands/BZPOPMAX.spec.ts
diff --git a/lib/commands/BZPOPMAX.ts b/packages/client/lib/commands/BZPOPMAX.ts
similarity index 100%
rename from lib/commands/BZPOPMAX.ts
rename to packages/client/lib/commands/BZPOPMAX.ts
diff --git a/lib/commands/BZPOPMIN.spec.ts b/packages/client/lib/commands/BZPOPMIN.spec.ts
similarity index 100%
rename from lib/commands/BZPOPMIN.spec.ts
rename to packages/client/lib/commands/BZPOPMIN.spec.ts
diff --git a/lib/commands/BZPOPMIN.ts b/packages/client/lib/commands/BZPOPMIN.ts
similarity index 100%
rename from lib/commands/BZPOPMIN.ts
rename to packages/client/lib/commands/BZPOPMIN.ts
diff --git a/lib/commands/CLIENT_ID.spec.ts b/packages/client/lib/commands/CLIENT_ID.spec.ts
similarity index 100%
rename from lib/commands/CLIENT_ID.spec.ts
rename to packages/client/lib/commands/CLIENT_ID.spec.ts
diff --git a/lib/commands/CLIENT_ID.ts b/packages/client/lib/commands/CLIENT_ID.ts
similarity index 100%
rename from lib/commands/CLIENT_ID.ts
rename to packages/client/lib/commands/CLIENT_ID.ts
diff --git a/lib/commands/CLIENT_INFO.spec.ts b/packages/client/lib/commands/CLIENT_INFO.spec.ts
similarity index 100%
rename from lib/commands/CLIENT_INFO.spec.ts
rename to packages/client/lib/commands/CLIENT_INFO.spec.ts
diff --git a/lib/commands/CLIENT_INFO.ts b/packages/client/lib/commands/CLIENT_INFO.ts
similarity index 100%
rename from lib/commands/CLIENT_INFO.ts
rename to packages/client/lib/commands/CLIENT_INFO.ts
diff --git a/lib/commands/CLUSTER_ADDSLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_ADDSLOTS.spec.ts
rename to packages/client/lib/commands/CLUSTER_ADDSLOTS.spec.ts
diff --git a/lib/commands/CLUSTER_ADDSLOTS.ts b/packages/client/lib/commands/CLUSTER_ADDSLOTS.ts
similarity index 100%
rename from lib/commands/CLUSTER_ADDSLOTS.ts
rename to packages/client/lib/commands/CLUSTER_ADDSLOTS.ts
diff --git a/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_FLUSHSLOTS.spec.ts
rename to packages/client/lib/commands/CLUSTER_FLUSHSLOTS.spec.ts
diff --git a/lib/commands/CLUSTER_FLUSHSLOTS.ts b/packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts
similarity index 100%
rename from lib/commands/CLUSTER_FLUSHSLOTS.ts
rename to packages/client/lib/commands/CLUSTER_FLUSHSLOTS.ts
diff --git a/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts
rename to packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.spec.ts
diff --git a/lib/commands/CLUSTER_GETKEYSINSLOT.ts b/packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts
similarity index 100%
rename from lib/commands/CLUSTER_GETKEYSINSLOT.ts
rename to packages/client/lib/commands/CLUSTER_GETKEYSINSLOT.ts
diff --git a/lib/commands/CLUSTER_INFO.spec.ts b/packages/client/lib/commands/CLUSTER_INFO.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_INFO.spec.ts
rename to packages/client/lib/commands/CLUSTER_INFO.spec.ts
diff --git a/lib/commands/CLUSTER_INFO.ts b/packages/client/lib/commands/CLUSTER_INFO.ts
similarity index 100%
rename from lib/commands/CLUSTER_INFO.ts
rename to packages/client/lib/commands/CLUSTER_INFO.ts
diff --git a/lib/commands/CLUSTER_MEET.spec.ts b/packages/client/lib/commands/CLUSTER_MEET.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_MEET.spec.ts
rename to packages/client/lib/commands/CLUSTER_MEET.spec.ts
diff --git a/lib/commands/CLUSTER_MEET.ts b/packages/client/lib/commands/CLUSTER_MEET.ts
similarity index 100%
rename from lib/commands/CLUSTER_MEET.ts
rename to packages/client/lib/commands/CLUSTER_MEET.ts
diff --git a/lib/commands/CLUSTER_NODES.spec.ts b/packages/client/lib/commands/CLUSTER_NODES.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_NODES.spec.ts
rename to packages/client/lib/commands/CLUSTER_NODES.spec.ts
diff --git a/lib/commands/CLUSTER_NODES.ts b/packages/client/lib/commands/CLUSTER_NODES.ts
similarity index 100%
rename from lib/commands/CLUSTER_NODES.ts
rename to packages/client/lib/commands/CLUSTER_NODES.ts
diff --git a/lib/commands/CLUSTER_RESET.spec.ts b/packages/client/lib/commands/CLUSTER_RESET.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_RESET.spec.ts
rename to packages/client/lib/commands/CLUSTER_RESET.spec.ts
diff --git a/lib/commands/CLUSTER_RESET.ts b/packages/client/lib/commands/CLUSTER_RESET.ts
similarity index 100%
rename from lib/commands/CLUSTER_RESET.ts
rename to packages/client/lib/commands/CLUSTER_RESET.ts
diff --git a/lib/commands/CLUSTER_SETSLOT.spec.ts b/packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_SETSLOT.spec.ts
rename to packages/client/lib/commands/CLUSTER_SETSLOT.spec.ts
diff --git a/lib/commands/CLUSTER_SETSLOT.ts b/packages/client/lib/commands/CLUSTER_SETSLOT.ts
similarity index 100%
rename from lib/commands/CLUSTER_SETSLOT.ts
rename to packages/client/lib/commands/CLUSTER_SETSLOT.ts
diff --git a/lib/commands/CLUSTER_SLOTS.spec.ts b/packages/client/lib/commands/CLUSTER_SLOTS.spec.ts
similarity index 100%
rename from lib/commands/CLUSTER_SLOTS.spec.ts
rename to packages/client/lib/commands/CLUSTER_SLOTS.spec.ts
diff --git a/lib/commands/CLUSTER_SLOTS.ts b/packages/client/lib/commands/CLUSTER_SLOTS.ts
similarity index 100%
rename from lib/commands/CLUSTER_SLOTS.ts
rename to packages/client/lib/commands/CLUSTER_SLOTS.ts
diff --git a/lib/commands/COMMAND.spec.ts b/packages/client/lib/commands/COMMAND.spec.ts
similarity index 65%
rename from lib/commands/COMMAND.spec.ts
rename to packages/client/lib/commands/COMMAND.spec.ts
index baad79845a..04ceab2a07 100644
--- a/lib/commands/COMMAND.spec.ts
+++ b/packages/client/lib/commands/COMMAND.spec.ts
@@ -11,7 +11,7 @@ describe('COMMAND', () => {
);
});
- testUtils.testWithClient('client.command', async client => {
- assertPingCommand((await client.command()).find(command => command.name === 'ping'));
- }, GLOBAL.SERVERS.OPEN);
+ // testUtils.testWithClient('client.command', async client => {
+ // assertPingCommand((await client.command()).find(command => command.name === 'ping'));
+ // }, GLOBAL.SERVERS.OPEN);
});
diff --git a/lib/commands/COMMAND.ts b/packages/client/lib/commands/COMMAND.ts
similarity index 100%
rename from lib/commands/COMMAND.ts
rename to packages/client/lib/commands/COMMAND.ts
diff --git a/lib/commands/COMMAND_COUNT.spec.ts b/packages/client/lib/commands/COMMAND_COUNT.spec.ts
similarity index 100%
rename from lib/commands/COMMAND_COUNT.spec.ts
rename to packages/client/lib/commands/COMMAND_COUNT.spec.ts
diff --git a/lib/commands/COMMAND_COUNT.ts b/packages/client/lib/commands/COMMAND_COUNT.ts
similarity index 100%
rename from lib/commands/COMMAND_COUNT.ts
rename to packages/client/lib/commands/COMMAND_COUNT.ts
diff --git a/lib/commands/COMMAND_GETKEYS.spec.ts b/packages/client/lib/commands/COMMAND_GETKEYS.spec.ts
similarity index 100%
rename from lib/commands/COMMAND_GETKEYS.spec.ts
rename to packages/client/lib/commands/COMMAND_GETKEYS.spec.ts
diff --git a/lib/commands/COMMAND_GETKEYS.ts b/packages/client/lib/commands/COMMAND_GETKEYS.ts
similarity index 100%
rename from lib/commands/COMMAND_GETKEYS.ts
rename to packages/client/lib/commands/COMMAND_GETKEYS.ts
diff --git a/lib/commands/COMMAND_INFO.spec.ts b/packages/client/lib/commands/COMMAND_INFO.spec.ts
similarity index 100%
rename from lib/commands/COMMAND_INFO.spec.ts
rename to packages/client/lib/commands/COMMAND_INFO.spec.ts
diff --git a/lib/commands/COMMAND_INFO.ts b/packages/client/lib/commands/COMMAND_INFO.ts
similarity index 100%
rename from lib/commands/COMMAND_INFO.ts
rename to packages/client/lib/commands/COMMAND_INFO.ts
diff --git a/lib/commands/CONFIG_GET.spec.ts b/packages/client/lib/commands/CONFIG_GET.spec.ts
similarity index 100%
rename from lib/commands/CONFIG_GET.spec.ts
rename to packages/client/lib/commands/CONFIG_GET.spec.ts
diff --git a/lib/commands/CONFIG_GET.ts b/packages/client/lib/commands/CONFIG_GET.ts
similarity index 100%
rename from lib/commands/CONFIG_GET.ts
rename to packages/client/lib/commands/CONFIG_GET.ts
diff --git a/lib/commands/CONFIG_RESETSTAT.spec.ts b/packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts
similarity index 100%
rename from lib/commands/CONFIG_RESETSTAT.spec.ts
rename to packages/client/lib/commands/CONFIG_RESETSTAT.spec.ts
diff --git a/lib/commands/CONFIG_RESETSTAT.ts b/packages/client/lib/commands/CONFIG_RESETSTAT.ts
similarity index 100%
rename from lib/commands/CONFIG_RESETSTAT.ts
rename to packages/client/lib/commands/CONFIG_RESETSTAT.ts
diff --git a/lib/commands/CONFIG_REWRITE.spec.ts b/packages/client/lib/commands/CONFIG_REWRITE.spec.ts
similarity index 100%
rename from lib/commands/CONFIG_REWRITE.spec.ts
rename to packages/client/lib/commands/CONFIG_REWRITE.spec.ts
diff --git a/lib/commands/CONFIG_REWRITE.ts b/packages/client/lib/commands/CONFIG_REWRITE.ts
similarity index 100%
rename from lib/commands/CONFIG_REWRITE.ts
rename to packages/client/lib/commands/CONFIG_REWRITE.ts
diff --git a/lib/commands/CONFIG_SET.spec.ts b/packages/client/lib/commands/CONFIG_SET.spec.ts
similarity index 100%
rename from lib/commands/CONFIG_SET.spec.ts
rename to packages/client/lib/commands/CONFIG_SET.spec.ts
diff --git a/lib/commands/CONFIG_SET.ts b/packages/client/lib/commands/CONFIG_SET.ts
similarity index 100%
rename from lib/commands/CONFIG_SET.ts
rename to packages/client/lib/commands/CONFIG_SET.ts
diff --git a/lib/commands/COPY.spec.ts b/packages/client/lib/commands/COPY.spec.ts
similarity index 100%
rename from lib/commands/COPY.spec.ts
rename to packages/client/lib/commands/COPY.spec.ts
diff --git a/lib/commands/COPY.ts b/packages/client/lib/commands/COPY.ts
similarity index 100%
rename from lib/commands/COPY.ts
rename to packages/client/lib/commands/COPY.ts
diff --git a/lib/commands/DBSIZE.spec.ts b/packages/client/lib/commands/DBSIZE.spec.ts
similarity index 100%
rename from lib/commands/DBSIZE.spec.ts
rename to packages/client/lib/commands/DBSIZE.spec.ts
diff --git a/lib/commands/DBSIZE.ts b/packages/client/lib/commands/DBSIZE.ts
similarity index 100%
rename from lib/commands/DBSIZE.ts
rename to packages/client/lib/commands/DBSIZE.ts
diff --git a/lib/commands/DECR.spec.ts b/packages/client/lib/commands/DECR.spec.ts
similarity index 100%
rename from lib/commands/DECR.spec.ts
rename to packages/client/lib/commands/DECR.spec.ts
diff --git a/lib/commands/DECR.ts b/packages/client/lib/commands/DECR.ts
similarity index 100%
rename from lib/commands/DECR.ts
rename to packages/client/lib/commands/DECR.ts
diff --git a/lib/commands/DECRBY.spec.ts b/packages/client/lib/commands/DECRBY.spec.ts
similarity index 100%
rename from lib/commands/DECRBY.spec.ts
rename to packages/client/lib/commands/DECRBY.spec.ts
diff --git a/lib/commands/DECRBY.ts b/packages/client/lib/commands/DECRBY.ts
similarity index 100%
rename from lib/commands/DECRBY.ts
rename to packages/client/lib/commands/DECRBY.ts
diff --git a/lib/commands/DEL.spec.ts b/packages/client/lib/commands/DEL.spec.ts
similarity index 100%
rename from lib/commands/DEL.spec.ts
rename to packages/client/lib/commands/DEL.spec.ts
diff --git a/lib/commands/DEL.ts b/packages/client/lib/commands/DEL.ts
similarity index 100%
rename from lib/commands/DEL.ts
rename to packages/client/lib/commands/DEL.ts
diff --git a/lib/commands/DISCARD.spec.ts b/packages/client/lib/commands/DISCARD.spec.ts
similarity index 100%
rename from lib/commands/DISCARD.spec.ts
rename to packages/client/lib/commands/DISCARD.spec.ts
diff --git a/lib/commands/DISCARD.ts b/packages/client/lib/commands/DISCARD.ts
similarity index 100%
rename from lib/commands/DISCARD.ts
rename to packages/client/lib/commands/DISCARD.ts
diff --git a/lib/commands/DUMP.spec.ts b/packages/client/lib/commands/DUMP.spec.ts
similarity index 100%
rename from lib/commands/DUMP.spec.ts
rename to packages/client/lib/commands/DUMP.spec.ts
diff --git a/lib/commands/DUMP.ts b/packages/client/lib/commands/DUMP.ts
similarity index 100%
rename from lib/commands/DUMP.ts
rename to packages/client/lib/commands/DUMP.ts
diff --git a/lib/commands/ECHO.spec.ts b/packages/client/lib/commands/ECHO.spec.ts
similarity index 100%
rename from lib/commands/ECHO.spec.ts
rename to packages/client/lib/commands/ECHO.spec.ts
diff --git a/lib/commands/ECHO.ts b/packages/client/lib/commands/ECHO.ts
similarity index 100%
rename from lib/commands/ECHO.ts
rename to packages/client/lib/commands/ECHO.ts
diff --git a/lib/commands/EVAL.spec.ts b/packages/client/lib/commands/EVAL.spec.ts
similarity index 100%
rename from lib/commands/EVAL.spec.ts
rename to packages/client/lib/commands/EVAL.spec.ts
diff --git a/lib/commands/EVAL.ts b/packages/client/lib/commands/EVAL.ts
similarity index 100%
rename from lib/commands/EVAL.ts
rename to packages/client/lib/commands/EVAL.ts
diff --git a/lib/commands/EVALSHA.spec.ts b/packages/client/lib/commands/EVALSHA.spec.ts
similarity index 100%
rename from lib/commands/EVALSHA.spec.ts
rename to packages/client/lib/commands/EVALSHA.spec.ts
diff --git a/lib/commands/EVALSHA.ts b/packages/client/lib/commands/EVALSHA.ts
similarity index 100%
rename from lib/commands/EVALSHA.ts
rename to packages/client/lib/commands/EVALSHA.ts
diff --git a/lib/commands/EXISTS.spec.ts b/packages/client/lib/commands/EXISTS.spec.ts
similarity index 100%
rename from lib/commands/EXISTS.spec.ts
rename to packages/client/lib/commands/EXISTS.spec.ts
diff --git a/lib/commands/EXISTS.ts b/packages/client/lib/commands/EXISTS.ts
similarity index 100%
rename from lib/commands/EXISTS.ts
rename to packages/client/lib/commands/EXISTS.ts
diff --git a/lib/commands/EXPIRE.spec.ts b/packages/client/lib/commands/EXPIRE.spec.ts
similarity index 100%
rename from lib/commands/EXPIRE.spec.ts
rename to packages/client/lib/commands/EXPIRE.spec.ts
diff --git a/lib/commands/EXPIRE.ts b/packages/client/lib/commands/EXPIRE.ts
similarity index 100%
rename from lib/commands/EXPIRE.ts
rename to packages/client/lib/commands/EXPIRE.ts
diff --git a/lib/commands/EXPIREAT.spec.ts b/packages/client/lib/commands/EXPIREAT.spec.ts
similarity index 100%
rename from lib/commands/EXPIREAT.spec.ts
rename to packages/client/lib/commands/EXPIREAT.spec.ts
diff --git a/lib/commands/EXPIREAT.ts b/packages/client/lib/commands/EXPIREAT.ts
similarity index 100%
rename from lib/commands/EXPIREAT.ts
rename to packages/client/lib/commands/EXPIREAT.ts
diff --git a/lib/commands/FAILOVER.spec.ts b/packages/client/lib/commands/FAILOVER.spec.ts
similarity index 100%
rename from lib/commands/FAILOVER.spec.ts
rename to packages/client/lib/commands/FAILOVER.spec.ts
diff --git a/lib/commands/FAILOVER.ts b/packages/client/lib/commands/FAILOVER.ts
similarity index 100%
rename from lib/commands/FAILOVER.ts
rename to packages/client/lib/commands/FAILOVER.ts
diff --git a/lib/commands/FLUSHALL.spec.ts b/packages/client/lib/commands/FLUSHALL.spec.ts
similarity index 100%
rename from lib/commands/FLUSHALL.spec.ts
rename to packages/client/lib/commands/FLUSHALL.spec.ts
diff --git a/lib/commands/FLUSHALL.ts b/packages/client/lib/commands/FLUSHALL.ts
similarity index 100%
rename from lib/commands/FLUSHALL.ts
rename to packages/client/lib/commands/FLUSHALL.ts
diff --git a/lib/commands/FLUSHDB.spec.ts b/packages/client/lib/commands/FLUSHDB.spec.ts
similarity index 100%
rename from lib/commands/FLUSHDB.spec.ts
rename to packages/client/lib/commands/FLUSHDB.spec.ts
diff --git a/lib/commands/FLUSHDB.ts b/packages/client/lib/commands/FLUSHDB.ts
similarity index 100%
rename from lib/commands/FLUSHDB.ts
rename to packages/client/lib/commands/FLUSHDB.ts
diff --git a/lib/commands/GEOADD.spec.ts b/packages/client/lib/commands/GEOADD.spec.ts
similarity index 100%
rename from lib/commands/GEOADD.spec.ts
rename to packages/client/lib/commands/GEOADD.spec.ts
diff --git a/lib/commands/GEOADD.ts b/packages/client/lib/commands/GEOADD.ts
similarity index 100%
rename from lib/commands/GEOADD.ts
rename to packages/client/lib/commands/GEOADD.ts
diff --git a/lib/commands/GEODIST.spec.ts b/packages/client/lib/commands/GEODIST.spec.ts
similarity index 100%
rename from lib/commands/GEODIST.spec.ts
rename to packages/client/lib/commands/GEODIST.spec.ts
diff --git a/lib/commands/GEODIST.ts b/packages/client/lib/commands/GEODIST.ts
similarity index 100%
rename from lib/commands/GEODIST.ts
rename to packages/client/lib/commands/GEODIST.ts
diff --git a/lib/commands/GEOHASH.spec.ts b/packages/client/lib/commands/GEOHASH.spec.ts
similarity index 100%
rename from lib/commands/GEOHASH.spec.ts
rename to packages/client/lib/commands/GEOHASH.spec.ts
diff --git a/lib/commands/GEOHASH.ts b/packages/client/lib/commands/GEOHASH.ts
similarity index 100%
rename from lib/commands/GEOHASH.ts
rename to packages/client/lib/commands/GEOHASH.ts
diff --git a/lib/commands/GEOPOS.spec.ts b/packages/client/lib/commands/GEOPOS.spec.ts
similarity index 100%
rename from lib/commands/GEOPOS.spec.ts
rename to packages/client/lib/commands/GEOPOS.spec.ts
diff --git a/lib/commands/GEOPOS.ts b/packages/client/lib/commands/GEOPOS.ts
similarity index 100%
rename from lib/commands/GEOPOS.ts
rename to packages/client/lib/commands/GEOPOS.ts
diff --git a/lib/commands/GEOSEARCH.spec.ts b/packages/client/lib/commands/GEOSEARCH.spec.ts
similarity index 100%
rename from lib/commands/GEOSEARCH.spec.ts
rename to packages/client/lib/commands/GEOSEARCH.spec.ts
diff --git a/lib/commands/GEOSEARCH.ts b/packages/client/lib/commands/GEOSEARCH.ts
similarity index 100%
rename from lib/commands/GEOSEARCH.ts
rename to packages/client/lib/commands/GEOSEARCH.ts
diff --git a/lib/commands/GEOSEARCHSTORE.spec.ts b/packages/client/lib/commands/GEOSEARCHSTORE.spec.ts
similarity index 100%
rename from lib/commands/GEOSEARCHSTORE.spec.ts
rename to packages/client/lib/commands/GEOSEARCHSTORE.spec.ts
diff --git a/lib/commands/GEOSEARCHSTORE.ts b/packages/client/lib/commands/GEOSEARCHSTORE.ts
similarity index 100%
rename from lib/commands/GEOSEARCHSTORE.ts
rename to packages/client/lib/commands/GEOSEARCHSTORE.ts
diff --git a/lib/commands/GEOSEARCH_WITH.spec.ts b/packages/client/lib/commands/GEOSEARCH_WITH.spec.ts
similarity index 100%
rename from lib/commands/GEOSEARCH_WITH.spec.ts
rename to packages/client/lib/commands/GEOSEARCH_WITH.spec.ts
diff --git a/lib/commands/GEOSEARCH_WITH.ts b/packages/client/lib/commands/GEOSEARCH_WITH.ts
similarity index 100%
rename from lib/commands/GEOSEARCH_WITH.ts
rename to packages/client/lib/commands/GEOSEARCH_WITH.ts
diff --git a/lib/commands/GET.spec.ts b/packages/client/lib/commands/GET.spec.ts
similarity index 100%
rename from lib/commands/GET.spec.ts
rename to packages/client/lib/commands/GET.spec.ts
diff --git a/lib/commands/GET.ts b/packages/client/lib/commands/GET.ts
similarity index 100%
rename from lib/commands/GET.ts
rename to packages/client/lib/commands/GET.ts
diff --git a/lib/commands/GETBIT.spec.ts b/packages/client/lib/commands/GETBIT.spec.ts
similarity index 100%
rename from lib/commands/GETBIT.spec.ts
rename to packages/client/lib/commands/GETBIT.spec.ts
diff --git a/lib/commands/GETBIT.ts b/packages/client/lib/commands/GETBIT.ts
similarity index 100%
rename from lib/commands/GETBIT.ts
rename to packages/client/lib/commands/GETBIT.ts
diff --git a/lib/commands/GETDEL.spec.ts b/packages/client/lib/commands/GETDEL.spec.ts
similarity index 100%
rename from lib/commands/GETDEL.spec.ts
rename to packages/client/lib/commands/GETDEL.spec.ts
diff --git a/lib/commands/GETDEL.ts b/packages/client/lib/commands/GETDEL.ts
similarity index 100%
rename from lib/commands/GETDEL.ts
rename to packages/client/lib/commands/GETDEL.ts
diff --git a/lib/commands/GETEX.spec.ts b/packages/client/lib/commands/GETEX.spec.ts
similarity index 100%
rename from lib/commands/GETEX.spec.ts
rename to packages/client/lib/commands/GETEX.spec.ts
diff --git a/lib/commands/GETEX.ts b/packages/client/lib/commands/GETEX.ts
similarity index 100%
rename from lib/commands/GETEX.ts
rename to packages/client/lib/commands/GETEX.ts
diff --git a/lib/commands/GETRANGE.spec.ts b/packages/client/lib/commands/GETRANGE.spec.ts
similarity index 100%
rename from lib/commands/GETRANGE.spec.ts
rename to packages/client/lib/commands/GETRANGE.spec.ts
diff --git a/lib/commands/GETRANGE.ts b/packages/client/lib/commands/GETRANGE.ts
similarity index 100%
rename from lib/commands/GETRANGE.ts
rename to packages/client/lib/commands/GETRANGE.ts
diff --git a/lib/commands/GETSET.spec.ts b/packages/client/lib/commands/GETSET.spec.ts
similarity index 100%
rename from lib/commands/GETSET.spec.ts
rename to packages/client/lib/commands/GETSET.spec.ts
diff --git a/lib/commands/GETSET.ts b/packages/client/lib/commands/GETSET.ts
similarity index 100%
rename from lib/commands/GETSET.ts
rename to packages/client/lib/commands/GETSET.ts
diff --git a/lib/commands/GET_BUFFER.spec.ts b/packages/client/lib/commands/GET_BUFFER.spec.ts
similarity index 100%
rename from lib/commands/GET_BUFFER.spec.ts
rename to packages/client/lib/commands/GET_BUFFER.spec.ts
diff --git a/lib/commands/GET_BUFFER.ts b/packages/client/lib/commands/GET_BUFFER.ts
similarity index 100%
rename from lib/commands/GET_BUFFER.ts
rename to packages/client/lib/commands/GET_BUFFER.ts
diff --git a/lib/commands/HDEL.spec.ts b/packages/client/lib/commands/HDEL.spec.ts
similarity index 100%
rename from lib/commands/HDEL.spec.ts
rename to packages/client/lib/commands/HDEL.spec.ts
diff --git a/lib/commands/HDEL.ts b/packages/client/lib/commands/HDEL.ts
similarity index 100%
rename from lib/commands/HDEL.ts
rename to packages/client/lib/commands/HDEL.ts
diff --git a/lib/commands/HELLO.spec.ts b/packages/client/lib/commands/HELLO.spec.ts
similarity index 100%
rename from lib/commands/HELLO.spec.ts
rename to packages/client/lib/commands/HELLO.spec.ts
diff --git a/lib/commands/HELLO.ts b/packages/client/lib/commands/HELLO.ts
similarity index 100%
rename from lib/commands/HELLO.ts
rename to packages/client/lib/commands/HELLO.ts
diff --git a/lib/commands/HEXISTS.spec.ts b/packages/client/lib/commands/HEXISTS.spec.ts
similarity index 100%
rename from lib/commands/HEXISTS.spec.ts
rename to packages/client/lib/commands/HEXISTS.spec.ts
diff --git a/lib/commands/HEXISTS.ts b/packages/client/lib/commands/HEXISTS.ts
similarity index 100%
rename from lib/commands/HEXISTS.ts
rename to packages/client/lib/commands/HEXISTS.ts
diff --git a/lib/commands/HGET.spec.ts b/packages/client/lib/commands/HGET.spec.ts
similarity index 100%
rename from lib/commands/HGET.spec.ts
rename to packages/client/lib/commands/HGET.spec.ts
diff --git a/lib/commands/HGET.ts b/packages/client/lib/commands/HGET.ts
similarity index 100%
rename from lib/commands/HGET.ts
rename to packages/client/lib/commands/HGET.ts
diff --git a/lib/commands/HGETALL.spec.ts b/packages/client/lib/commands/HGETALL.spec.ts
similarity index 100%
rename from lib/commands/HGETALL.spec.ts
rename to packages/client/lib/commands/HGETALL.spec.ts
diff --git a/lib/commands/HGETALL.ts b/packages/client/lib/commands/HGETALL.ts
similarity index 100%
rename from lib/commands/HGETALL.ts
rename to packages/client/lib/commands/HGETALL.ts
diff --git a/lib/commands/HINCRBY.spec.ts b/packages/client/lib/commands/HINCRBY.spec.ts
similarity index 100%
rename from lib/commands/HINCRBY.spec.ts
rename to packages/client/lib/commands/HINCRBY.spec.ts
diff --git a/lib/commands/HINCRBY.ts b/packages/client/lib/commands/HINCRBY.ts
similarity index 100%
rename from lib/commands/HINCRBY.ts
rename to packages/client/lib/commands/HINCRBY.ts
diff --git a/lib/commands/HINCRBYFLOAT.spec.ts b/packages/client/lib/commands/HINCRBYFLOAT.spec.ts
similarity index 100%
rename from lib/commands/HINCRBYFLOAT.spec.ts
rename to packages/client/lib/commands/HINCRBYFLOAT.spec.ts
diff --git a/lib/commands/HINCRBYFLOAT.ts b/packages/client/lib/commands/HINCRBYFLOAT.ts
similarity index 100%
rename from lib/commands/HINCRBYFLOAT.ts
rename to packages/client/lib/commands/HINCRBYFLOAT.ts
diff --git a/lib/commands/HKEYS.spec.ts b/packages/client/lib/commands/HKEYS.spec.ts
similarity index 100%
rename from lib/commands/HKEYS.spec.ts
rename to packages/client/lib/commands/HKEYS.spec.ts
diff --git a/lib/commands/HKEYS.ts b/packages/client/lib/commands/HKEYS.ts
similarity index 100%
rename from lib/commands/HKEYS.ts
rename to packages/client/lib/commands/HKEYS.ts
diff --git a/lib/commands/HLEN.spec.ts b/packages/client/lib/commands/HLEN.spec.ts
similarity index 100%
rename from lib/commands/HLEN.spec.ts
rename to packages/client/lib/commands/HLEN.spec.ts
diff --git a/lib/commands/HLEN.ts b/packages/client/lib/commands/HLEN.ts
similarity index 100%
rename from lib/commands/HLEN.ts
rename to packages/client/lib/commands/HLEN.ts
diff --git a/lib/commands/HMGET.spec.ts b/packages/client/lib/commands/HMGET.spec.ts
similarity index 100%
rename from lib/commands/HMGET.spec.ts
rename to packages/client/lib/commands/HMGET.spec.ts
diff --git a/lib/commands/HMGET.ts b/packages/client/lib/commands/HMGET.ts
similarity index 100%
rename from lib/commands/HMGET.ts
rename to packages/client/lib/commands/HMGET.ts
diff --git a/lib/commands/HRANDFIELD.spec.ts b/packages/client/lib/commands/HRANDFIELD.spec.ts
similarity index 100%
rename from lib/commands/HRANDFIELD.spec.ts
rename to packages/client/lib/commands/HRANDFIELD.spec.ts
diff --git a/lib/commands/HRANDFIELD.ts b/packages/client/lib/commands/HRANDFIELD.ts
similarity index 100%
rename from lib/commands/HRANDFIELD.ts
rename to packages/client/lib/commands/HRANDFIELD.ts
diff --git a/lib/commands/HRANDFIELD_COUNT.spec.ts b/packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts
similarity index 100%
rename from lib/commands/HRANDFIELD_COUNT.spec.ts
rename to packages/client/lib/commands/HRANDFIELD_COUNT.spec.ts
diff --git a/lib/commands/HRANDFIELD_COUNT.ts b/packages/client/lib/commands/HRANDFIELD_COUNT.ts
similarity index 100%
rename from lib/commands/HRANDFIELD_COUNT.ts
rename to packages/client/lib/commands/HRANDFIELD_COUNT.ts
diff --git a/lib/commands/HRANDFIELD_COUNT_WITHVALUES.spec.ts b/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.spec.ts
similarity index 100%
rename from lib/commands/HRANDFIELD_COUNT_WITHVALUES.spec.ts
rename to packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.spec.ts
diff --git a/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts b/packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts
similarity index 100%
rename from lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts
rename to packages/client/lib/commands/HRANDFIELD_COUNT_WITHVALUES.ts
diff --git a/lib/commands/HSCAN.spec.ts b/packages/client/lib/commands/HSCAN.spec.ts
similarity index 100%
rename from lib/commands/HSCAN.spec.ts
rename to packages/client/lib/commands/HSCAN.spec.ts
diff --git a/lib/commands/HSCAN.ts b/packages/client/lib/commands/HSCAN.ts
similarity index 100%
rename from lib/commands/HSCAN.ts
rename to packages/client/lib/commands/HSCAN.ts
diff --git a/lib/commands/HSET.spec.ts b/packages/client/lib/commands/HSET.spec.ts
similarity index 100%
rename from lib/commands/HSET.spec.ts
rename to packages/client/lib/commands/HSET.spec.ts
diff --git a/lib/commands/HSET.ts b/packages/client/lib/commands/HSET.ts
similarity index 100%
rename from lib/commands/HSET.ts
rename to packages/client/lib/commands/HSET.ts
diff --git a/lib/commands/HSETNX.spec.ts b/packages/client/lib/commands/HSETNX.spec.ts
similarity index 100%
rename from lib/commands/HSETNX.spec.ts
rename to packages/client/lib/commands/HSETNX.spec.ts
diff --git a/lib/commands/HSETNX.ts b/packages/client/lib/commands/HSETNX.ts
similarity index 100%
rename from lib/commands/HSETNX.ts
rename to packages/client/lib/commands/HSETNX.ts
diff --git a/lib/commands/HSTRLEN.spec.ts b/packages/client/lib/commands/HSTRLEN.spec.ts
similarity index 100%
rename from lib/commands/HSTRLEN.spec.ts
rename to packages/client/lib/commands/HSTRLEN.spec.ts
diff --git a/lib/commands/HSTRLEN.ts b/packages/client/lib/commands/HSTRLEN.ts
similarity index 100%
rename from lib/commands/HSTRLEN.ts
rename to packages/client/lib/commands/HSTRLEN.ts
diff --git a/lib/commands/HVALS.spec.ts b/packages/client/lib/commands/HVALS.spec.ts
similarity index 100%
rename from lib/commands/HVALS.spec.ts
rename to packages/client/lib/commands/HVALS.spec.ts
diff --git a/lib/commands/HVALS.ts b/packages/client/lib/commands/HVALS.ts
similarity index 100%
rename from lib/commands/HVALS.ts
rename to packages/client/lib/commands/HVALS.ts
diff --git a/lib/commands/INCR.spec.ts b/packages/client/lib/commands/INCR.spec.ts
similarity index 100%
rename from lib/commands/INCR.spec.ts
rename to packages/client/lib/commands/INCR.spec.ts
diff --git a/lib/commands/INCR.ts b/packages/client/lib/commands/INCR.ts
similarity index 100%
rename from lib/commands/INCR.ts
rename to packages/client/lib/commands/INCR.ts
diff --git a/lib/commands/INCRBY.spec.ts b/packages/client/lib/commands/INCRBY.spec.ts
similarity index 100%
rename from lib/commands/INCRBY.spec.ts
rename to packages/client/lib/commands/INCRBY.spec.ts
diff --git a/lib/commands/INCRBY.ts b/packages/client/lib/commands/INCRBY.ts
similarity index 100%
rename from lib/commands/INCRBY.ts
rename to packages/client/lib/commands/INCRBY.ts
diff --git a/lib/commands/INCRBYFLOAT.spec.ts b/packages/client/lib/commands/INCRBYFLOAT.spec.ts
similarity index 100%
rename from lib/commands/INCRBYFLOAT.spec.ts
rename to packages/client/lib/commands/INCRBYFLOAT.spec.ts
diff --git a/lib/commands/INCRBYFLOAT.ts b/packages/client/lib/commands/INCRBYFLOAT.ts
similarity index 100%
rename from lib/commands/INCRBYFLOAT.ts
rename to packages/client/lib/commands/INCRBYFLOAT.ts
diff --git a/lib/commands/INFO.spec.ts b/packages/client/lib/commands/INFO.spec.ts
similarity index 100%
rename from lib/commands/INFO.spec.ts
rename to packages/client/lib/commands/INFO.spec.ts
diff --git a/lib/commands/INFO.ts b/packages/client/lib/commands/INFO.ts
similarity index 100%
rename from lib/commands/INFO.ts
rename to packages/client/lib/commands/INFO.ts
diff --git a/lib/commands/KEYS.spec.ts b/packages/client/lib/commands/KEYS.spec.ts
similarity index 100%
rename from lib/commands/KEYS.spec.ts
rename to packages/client/lib/commands/KEYS.spec.ts
diff --git a/lib/commands/KEYS.ts b/packages/client/lib/commands/KEYS.ts
similarity index 100%
rename from lib/commands/KEYS.ts
rename to packages/client/lib/commands/KEYS.ts
diff --git a/lib/commands/LASTSAVE.spec.ts b/packages/client/lib/commands/LASTSAVE.spec.ts
similarity index 100%
rename from lib/commands/LASTSAVE.spec.ts
rename to packages/client/lib/commands/LASTSAVE.spec.ts
diff --git a/lib/commands/LASTSAVE.ts b/packages/client/lib/commands/LASTSAVE.ts
similarity index 100%
rename from lib/commands/LASTSAVE.ts
rename to packages/client/lib/commands/LASTSAVE.ts
diff --git a/lib/commands/LINDEX.spec.ts b/packages/client/lib/commands/LINDEX.spec.ts
similarity index 100%
rename from lib/commands/LINDEX.spec.ts
rename to packages/client/lib/commands/LINDEX.spec.ts
diff --git a/lib/commands/LINDEX.ts b/packages/client/lib/commands/LINDEX.ts
similarity index 100%
rename from lib/commands/LINDEX.ts
rename to packages/client/lib/commands/LINDEX.ts
diff --git a/lib/commands/LINSERT.spec.ts b/packages/client/lib/commands/LINSERT.spec.ts
similarity index 100%
rename from lib/commands/LINSERT.spec.ts
rename to packages/client/lib/commands/LINSERT.spec.ts
diff --git a/lib/commands/LINSERT.ts b/packages/client/lib/commands/LINSERT.ts
similarity index 100%
rename from lib/commands/LINSERT.ts
rename to packages/client/lib/commands/LINSERT.ts
diff --git a/lib/commands/LLEN.spec.ts b/packages/client/lib/commands/LLEN.spec.ts
similarity index 100%
rename from lib/commands/LLEN.spec.ts
rename to packages/client/lib/commands/LLEN.spec.ts
diff --git a/lib/commands/LLEN.ts b/packages/client/lib/commands/LLEN.ts
similarity index 100%
rename from lib/commands/LLEN.ts
rename to packages/client/lib/commands/LLEN.ts
diff --git a/lib/commands/LMOVE.spec.ts b/packages/client/lib/commands/LMOVE.spec.ts
similarity index 100%
rename from lib/commands/LMOVE.spec.ts
rename to packages/client/lib/commands/LMOVE.spec.ts
diff --git a/lib/commands/LMOVE.ts b/packages/client/lib/commands/LMOVE.ts
similarity index 100%
rename from lib/commands/LMOVE.ts
rename to packages/client/lib/commands/LMOVE.ts
diff --git a/lib/commands/LOLWUT.spec.ts b/packages/client/lib/commands/LOLWUT.spec.ts
similarity index 100%
rename from lib/commands/LOLWUT.spec.ts
rename to packages/client/lib/commands/LOLWUT.spec.ts
diff --git a/lib/commands/LOLWUT.ts b/packages/client/lib/commands/LOLWUT.ts
similarity index 100%
rename from lib/commands/LOLWUT.ts
rename to packages/client/lib/commands/LOLWUT.ts
diff --git a/lib/commands/LPOP.spec.ts b/packages/client/lib/commands/LPOP.spec.ts
similarity index 100%
rename from lib/commands/LPOP.spec.ts
rename to packages/client/lib/commands/LPOP.spec.ts
diff --git a/lib/commands/LPOP.ts b/packages/client/lib/commands/LPOP.ts
similarity index 100%
rename from lib/commands/LPOP.ts
rename to packages/client/lib/commands/LPOP.ts
diff --git a/lib/commands/LPOP_COUNT.spec.ts b/packages/client/lib/commands/LPOP_COUNT.spec.ts
similarity index 100%
rename from lib/commands/LPOP_COUNT.spec.ts
rename to packages/client/lib/commands/LPOP_COUNT.spec.ts
diff --git a/lib/commands/LPOP_COUNT.ts b/packages/client/lib/commands/LPOP_COUNT.ts
similarity index 100%
rename from lib/commands/LPOP_COUNT.ts
rename to packages/client/lib/commands/LPOP_COUNT.ts
diff --git a/lib/commands/LPOS.spec.ts b/packages/client/lib/commands/LPOS.spec.ts
similarity index 100%
rename from lib/commands/LPOS.spec.ts
rename to packages/client/lib/commands/LPOS.spec.ts
diff --git a/lib/commands/LPOS.ts b/packages/client/lib/commands/LPOS.ts
similarity index 100%
rename from lib/commands/LPOS.ts
rename to packages/client/lib/commands/LPOS.ts
diff --git a/lib/commands/LPOS_COUNT.spec.ts b/packages/client/lib/commands/LPOS_COUNT.spec.ts
similarity index 100%
rename from lib/commands/LPOS_COUNT.spec.ts
rename to packages/client/lib/commands/LPOS_COUNT.spec.ts
diff --git a/lib/commands/LPOS_COUNT.ts b/packages/client/lib/commands/LPOS_COUNT.ts
similarity index 100%
rename from lib/commands/LPOS_COUNT.ts
rename to packages/client/lib/commands/LPOS_COUNT.ts
diff --git a/lib/commands/LPUSH.spec.ts b/packages/client/lib/commands/LPUSH.spec.ts
similarity index 100%
rename from lib/commands/LPUSH.spec.ts
rename to packages/client/lib/commands/LPUSH.spec.ts
diff --git a/lib/commands/LPUSH.ts b/packages/client/lib/commands/LPUSH.ts
similarity index 100%
rename from lib/commands/LPUSH.ts
rename to packages/client/lib/commands/LPUSH.ts
diff --git a/lib/commands/LPUSHX.spec.ts b/packages/client/lib/commands/LPUSHX.spec.ts
similarity index 100%
rename from lib/commands/LPUSHX.spec.ts
rename to packages/client/lib/commands/LPUSHX.spec.ts
diff --git a/lib/commands/LPUSHX.ts b/packages/client/lib/commands/LPUSHX.ts
similarity index 100%
rename from lib/commands/LPUSHX.ts
rename to packages/client/lib/commands/LPUSHX.ts
diff --git a/lib/commands/LRANGE.spec.ts b/packages/client/lib/commands/LRANGE.spec.ts
similarity index 100%
rename from lib/commands/LRANGE.spec.ts
rename to packages/client/lib/commands/LRANGE.spec.ts
diff --git a/lib/commands/LRANGE.ts b/packages/client/lib/commands/LRANGE.ts
similarity index 100%
rename from lib/commands/LRANGE.ts
rename to packages/client/lib/commands/LRANGE.ts
diff --git a/lib/commands/LREM.spec.ts b/packages/client/lib/commands/LREM.spec.ts
similarity index 100%
rename from lib/commands/LREM.spec.ts
rename to packages/client/lib/commands/LREM.spec.ts
diff --git a/lib/commands/LREM.ts b/packages/client/lib/commands/LREM.ts
similarity index 100%
rename from lib/commands/LREM.ts
rename to packages/client/lib/commands/LREM.ts
diff --git a/lib/commands/LSET.spec.ts b/packages/client/lib/commands/LSET.spec.ts
similarity index 100%
rename from lib/commands/LSET.spec.ts
rename to packages/client/lib/commands/LSET.spec.ts
diff --git a/lib/commands/LSET.ts b/packages/client/lib/commands/LSET.ts
similarity index 100%
rename from lib/commands/LSET.ts
rename to packages/client/lib/commands/LSET.ts
diff --git a/lib/commands/LTRIM.spec.ts b/packages/client/lib/commands/LTRIM.spec.ts
similarity index 100%
rename from lib/commands/LTRIM.spec.ts
rename to packages/client/lib/commands/LTRIM.spec.ts
diff --git a/lib/commands/LTRIM.ts b/packages/client/lib/commands/LTRIM.ts
similarity index 100%
rename from lib/commands/LTRIM.ts
rename to packages/client/lib/commands/LTRIM.ts
diff --git a/lib/commands/MEMORY_DOCTOR.spec.ts b/packages/client/lib/commands/MEMORY_DOCTOR.spec.ts
similarity index 100%
rename from lib/commands/MEMORY_DOCTOR.spec.ts
rename to packages/client/lib/commands/MEMORY_DOCTOR.spec.ts
diff --git a/lib/commands/MEMORY_DOCTOR.ts b/packages/client/lib/commands/MEMORY_DOCTOR.ts
similarity index 100%
rename from lib/commands/MEMORY_DOCTOR.ts
rename to packages/client/lib/commands/MEMORY_DOCTOR.ts
diff --git a/lib/commands/MEMORY_MALLOC-STATS.spec.ts b/packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts
similarity index 100%
rename from lib/commands/MEMORY_MALLOC-STATS.spec.ts
rename to packages/client/lib/commands/MEMORY_MALLOC-STATS.spec.ts
diff --git a/lib/commands/MEMORY_MALLOC-STATS.ts b/packages/client/lib/commands/MEMORY_MALLOC-STATS.ts
similarity index 100%
rename from lib/commands/MEMORY_MALLOC-STATS.ts
rename to packages/client/lib/commands/MEMORY_MALLOC-STATS.ts
diff --git a/lib/commands/MEMORY_PURGE.spec.ts b/packages/client/lib/commands/MEMORY_PURGE.spec.ts
similarity index 100%
rename from lib/commands/MEMORY_PURGE.spec.ts
rename to packages/client/lib/commands/MEMORY_PURGE.spec.ts
diff --git a/lib/commands/MEMORY_PURGE.ts b/packages/client/lib/commands/MEMORY_PURGE.ts
similarity index 100%
rename from lib/commands/MEMORY_PURGE.ts
rename to packages/client/lib/commands/MEMORY_PURGE.ts
diff --git a/lib/commands/MEMORY_STATS.spec.ts b/packages/client/lib/commands/MEMORY_STATS.spec.ts
similarity index 100%
rename from lib/commands/MEMORY_STATS.spec.ts
rename to packages/client/lib/commands/MEMORY_STATS.spec.ts
diff --git a/lib/commands/MEMORY_STATS.ts b/packages/client/lib/commands/MEMORY_STATS.ts
similarity index 100%
rename from lib/commands/MEMORY_STATS.ts
rename to packages/client/lib/commands/MEMORY_STATS.ts
diff --git a/lib/commands/MEMORY_USAGE.spec.ts b/packages/client/lib/commands/MEMORY_USAGE.spec.ts
similarity index 100%
rename from lib/commands/MEMORY_USAGE.spec.ts
rename to packages/client/lib/commands/MEMORY_USAGE.spec.ts
diff --git a/lib/commands/MEMORY_USAGE.ts b/packages/client/lib/commands/MEMORY_USAGE.ts
similarity index 100%
rename from lib/commands/MEMORY_USAGE.ts
rename to packages/client/lib/commands/MEMORY_USAGE.ts
diff --git a/lib/commands/MGET.spec.ts b/packages/client/lib/commands/MGET.spec.ts
similarity index 100%
rename from lib/commands/MGET.spec.ts
rename to packages/client/lib/commands/MGET.spec.ts
diff --git a/lib/commands/MGET.ts b/packages/client/lib/commands/MGET.ts
similarity index 100%
rename from lib/commands/MGET.ts
rename to packages/client/lib/commands/MGET.ts
diff --git a/lib/commands/MIGRATE.spec.ts b/packages/client/lib/commands/MIGRATE.spec.ts
similarity index 100%
rename from lib/commands/MIGRATE.spec.ts
rename to packages/client/lib/commands/MIGRATE.spec.ts
diff --git a/lib/commands/MIGRATE.ts b/packages/client/lib/commands/MIGRATE.ts
similarity index 100%
rename from lib/commands/MIGRATE.ts
rename to packages/client/lib/commands/MIGRATE.ts
diff --git a/lib/commands/MODULE_LIST.spec.ts b/packages/client/lib/commands/MODULE_LIST.spec.ts
similarity index 100%
rename from lib/commands/MODULE_LIST.spec.ts
rename to packages/client/lib/commands/MODULE_LIST.spec.ts
diff --git a/lib/commands/MODULE_LIST.ts b/packages/client/lib/commands/MODULE_LIST.ts
similarity index 100%
rename from lib/commands/MODULE_LIST.ts
rename to packages/client/lib/commands/MODULE_LIST.ts
diff --git a/lib/commands/MODULE_LOAD.spec.ts b/packages/client/lib/commands/MODULE_LOAD.spec.ts
similarity index 100%
rename from lib/commands/MODULE_LOAD.spec.ts
rename to packages/client/lib/commands/MODULE_LOAD.spec.ts
diff --git a/lib/commands/MODULE_LOAD.ts b/packages/client/lib/commands/MODULE_LOAD.ts
similarity index 100%
rename from lib/commands/MODULE_LOAD.ts
rename to packages/client/lib/commands/MODULE_LOAD.ts
diff --git a/lib/commands/MODULE_UNLOAD.spec.ts b/packages/client/lib/commands/MODULE_UNLOAD.spec.ts
similarity index 100%
rename from lib/commands/MODULE_UNLOAD.spec.ts
rename to packages/client/lib/commands/MODULE_UNLOAD.spec.ts
diff --git a/lib/commands/MODULE_UNLOAD.ts b/packages/client/lib/commands/MODULE_UNLOAD.ts
similarity index 100%
rename from lib/commands/MODULE_UNLOAD.ts
rename to packages/client/lib/commands/MODULE_UNLOAD.ts
diff --git a/lib/commands/MOVE.spec.ts b/packages/client/lib/commands/MOVE.spec.ts
similarity index 100%
rename from lib/commands/MOVE.spec.ts
rename to packages/client/lib/commands/MOVE.spec.ts
diff --git a/lib/commands/MOVE.ts b/packages/client/lib/commands/MOVE.ts
similarity index 100%
rename from lib/commands/MOVE.ts
rename to packages/client/lib/commands/MOVE.ts
diff --git a/lib/commands/MSET.spec.ts b/packages/client/lib/commands/MSET.spec.ts
similarity index 100%
rename from lib/commands/MSET.spec.ts
rename to packages/client/lib/commands/MSET.spec.ts
diff --git a/lib/commands/MSET.ts b/packages/client/lib/commands/MSET.ts
similarity index 100%
rename from lib/commands/MSET.ts
rename to packages/client/lib/commands/MSET.ts
diff --git a/lib/commands/MSETNX.spec.ts b/packages/client/lib/commands/MSETNX.spec.ts
similarity index 100%
rename from lib/commands/MSETNX.spec.ts
rename to packages/client/lib/commands/MSETNX.spec.ts
diff --git a/lib/commands/MSETNX.ts b/packages/client/lib/commands/MSETNX.ts
similarity index 100%
rename from lib/commands/MSETNX.ts
rename to packages/client/lib/commands/MSETNX.ts
diff --git a/lib/commands/PERSIST.spec.ts b/packages/client/lib/commands/PERSIST.spec.ts
similarity index 100%
rename from lib/commands/PERSIST.spec.ts
rename to packages/client/lib/commands/PERSIST.spec.ts
diff --git a/lib/commands/PERSIST.ts b/packages/client/lib/commands/PERSIST.ts
similarity index 100%
rename from lib/commands/PERSIST.ts
rename to packages/client/lib/commands/PERSIST.ts
diff --git a/lib/commands/PEXPIRE.spec.ts b/packages/client/lib/commands/PEXPIRE.spec.ts
similarity index 100%
rename from lib/commands/PEXPIRE.spec.ts
rename to packages/client/lib/commands/PEXPIRE.spec.ts
diff --git a/lib/commands/PEXPIRE.ts b/packages/client/lib/commands/PEXPIRE.ts
similarity index 100%
rename from lib/commands/PEXPIRE.ts
rename to packages/client/lib/commands/PEXPIRE.ts
diff --git a/lib/commands/PEXPIREAT.spec.ts b/packages/client/lib/commands/PEXPIREAT.spec.ts
similarity index 100%
rename from lib/commands/PEXPIREAT.spec.ts
rename to packages/client/lib/commands/PEXPIREAT.spec.ts
diff --git a/lib/commands/PEXPIREAT.ts b/packages/client/lib/commands/PEXPIREAT.ts
similarity index 100%
rename from lib/commands/PEXPIREAT.ts
rename to packages/client/lib/commands/PEXPIREAT.ts
diff --git a/lib/commands/PFADD.spec.ts b/packages/client/lib/commands/PFADD.spec.ts
similarity index 100%
rename from lib/commands/PFADD.spec.ts
rename to packages/client/lib/commands/PFADD.spec.ts
diff --git a/lib/commands/PFADD.ts b/packages/client/lib/commands/PFADD.ts
similarity index 100%
rename from lib/commands/PFADD.ts
rename to packages/client/lib/commands/PFADD.ts
diff --git a/lib/commands/PFCOUNT.spec.ts b/packages/client/lib/commands/PFCOUNT.spec.ts
similarity index 100%
rename from lib/commands/PFCOUNT.spec.ts
rename to packages/client/lib/commands/PFCOUNT.spec.ts
diff --git a/lib/commands/PFCOUNT.ts b/packages/client/lib/commands/PFCOUNT.ts
similarity index 100%
rename from lib/commands/PFCOUNT.ts
rename to packages/client/lib/commands/PFCOUNT.ts
diff --git a/lib/commands/PFMERGE.spec.ts b/packages/client/lib/commands/PFMERGE.spec.ts
similarity index 100%
rename from lib/commands/PFMERGE.spec.ts
rename to packages/client/lib/commands/PFMERGE.spec.ts
diff --git a/lib/commands/PFMERGE.ts b/packages/client/lib/commands/PFMERGE.ts
similarity index 100%
rename from lib/commands/PFMERGE.ts
rename to packages/client/lib/commands/PFMERGE.ts
diff --git a/lib/commands/PING.spec.ts b/packages/client/lib/commands/PING.spec.ts
similarity index 100%
rename from lib/commands/PING.spec.ts
rename to packages/client/lib/commands/PING.spec.ts
diff --git a/lib/commands/PING.ts b/packages/client/lib/commands/PING.ts
similarity index 100%
rename from lib/commands/PING.ts
rename to packages/client/lib/commands/PING.ts
diff --git a/lib/commands/PSETEX.spec.ts b/packages/client/lib/commands/PSETEX.spec.ts
similarity index 100%
rename from lib/commands/PSETEX.spec.ts
rename to packages/client/lib/commands/PSETEX.spec.ts
diff --git a/lib/commands/PSETEX.ts b/packages/client/lib/commands/PSETEX.ts
similarity index 100%
rename from lib/commands/PSETEX.ts
rename to packages/client/lib/commands/PSETEX.ts
diff --git a/lib/commands/PTTL.spec.ts b/packages/client/lib/commands/PTTL.spec.ts
similarity index 100%
rename from lib/commands/PTTL.spec.ts
rename to packages/client/lib/commands/PTTL.spec.ts
diff --git a/lib/commands/PTTL.ts b/packages/client/lib/commands/PTTL.ts
similarity index 100%
rename from lib/commands/PTTL.ts
rename to packages/client/lib/commands/PTTL.ts
diff --git a/lib/commands/PUBLISH.spec.ts b/packages/client/lib/commands/PUBLISH.spec.ts
similarity index 100%
rename from lib/commands/PUBLISH.spec.ts
rename to packages/client/lib/commands/PUBLISH.spec.ts
diff --git a/lib/commands/PUBLISH.ts b/packages/client/lib/commands/PUBLISH.ts
similarity index 100%
rename from lib/commands/PUBLISH.ts
rename to packages/client/lib/commands/PUBLISH.ts
diff --git a/lib/commands/PUBSUB_CHANNELS.spec.ts b/packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts
similarity index 100%
rename from lib/commands/PUBSUB_CHANNELS.spec.ts
rename to packages/client/lib/commands/PUBSUB_CHANNELS.spec.ts
diff --git a/lib/commands/PUBSUB_CHANNELS.ts b/packages/client/lib/commands/PUBSUB_CHANNELS.ts
similarity index 100%
rename from lib/commands/PUBSUB_CHANNELS.ts
rename to packages/client/lib/commands/PUBSUB_CHANNELS.ts
diff --git a/lib/commands/PUBSUB_NUMPAT.spec.ts b/packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts
similarity index 100%
rename from lib/commands/PUBSUB_NUMPAT.spec.ts
rename to packages/client/lib/commands/PUBSUB_NUMPAT.spec.ts
diff --git a/lib/commands/PUBSUB_NUMPAT.ts b/packages/client/lib/commands/PUBSUB_NUMPAT.ts
similarity index 100%
rename from lib/commands/PUBSUB_NUMPAT.ts
rename to packages/client/lib/commands/PUBSUB_NUMPAT.ts
diff --git a/lib/commands/PUBSUB_NUMSUB.spec.ts b/packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts
similarity index 100%
rename from lib/commands/PUBSUB_NUMSUB.spec.ts
rename to packages/client/lib/commands/PUBSUB_NUMSUB.spec.ts
diff --git a/lib/commands/PUBSUB_NUMSUB.ts b/packages/client/lib/commands/PUBSUB_NUMSUB.ts
similarity index 100%
rename from lib/commands/PUBSUB_NUMSUB.ts
rename to packages/client/lib/commands/PUBSUB_NUMSUB.ts
diff --git a/lib/commands/RANDOMKEY.spec.ts b/packages/client/lib/commands/RANDOMKEY.spec.ts
similarity index 100%
rename from lib/commands/RANDOMKEY.spec.ts
rename to packages/client/lib/commands/RANDOMKEY.spec.ts
diff --git a/lib/commands/RANDOMKEY.ts b/packages/client/lib/commands/RANDOMKEY.ts
similarity index 100%
rename from lib/commands/RANDOMKEY.ts
rename to packages/client/lib/commands/RANDOMKEY.ts
diff --git a/lib/commands/READONLY.spec.ts b/packages/client/lib/commands/READONLY.spec.ts
similarity index 100%
rename from lib/commands/READONLY.spec.ts
rename to packages/client/lib/commands/READONLY.spec.ts
diff --git a/lib/commands/READONLY.ts b/packages/client/lib/commands/READONLY.ts
similarity index 100%
rename from lib/commands/READONLY.ts
rename to packages/client/lib/commands/READONLY.ts
diff --git a/lib/commands/READWRITE.spec.ts b/packages/client/lib/commands/READWRITE.spec.ts
similarity index 100%
rename from lib/commands/READWRITE.spec.ts
rename to packages/client/lib/commands/READWRITE.spec.ts
diff --git a/lib/commands/READWRITE.ts b/packages/client/lib/commands/READWRITE.ts
similarity index 100%
rename from lib/commands/READWRITE.ts
rename to packages/client/lib/commands/READWRITE.ts
diff --git a/lib/commands/RENAME.spec.ts b/packages/client/lib/commands/RENAME.spec.ts
similarity index 100%
rename from lib/commands/RENAME.spec.ts
rename to packages/client/lib/commands/RENAME.spec.ts
diff --git a/lib/commands/RENAME.ts b/packages/client/lib/commands/RENAME.ts
similarity index 100%
rename from lib/commands/RENAME.ts
rename to packages/client/lib/commands/RENAME.ts
diff --git a/lib/commands/RENAMENX.spec.ts b/packages/client/lib/commands/RENAMENX.spec.ts
similarity index 100%
rename from lib/commands/RENAMENX.spec.ts
rename to packages/client/lib/commands/RENAMENX.spec.ts
diff --git a/lib/commands/RENAMENX.ts b/packages/client/lib/commands/RENAMENX.ts
similarity index 100%
rename from lib/commands/RENAMENX.ts
rename to packages/client/lib/commands/RENAMENX.ts
diff --git a/lib/commands/REPLICAOF.spec.ts b/packages/client/lib/commands/REPLICAOF.spec.ts
similarity index 100%
rename from lib/commands/REPLICAOF.spec.ts
rename to packages/client/lib/commands/REPLICAOF.spec.ts
diff --git a/lib/commands/REPLICAOF.ts b/packages/client/lib/commands/REPLICAOF.ts
similarity index 100%
rename from lib/commands/REPLICAOF.ts
rename to packages/client/lib/commands/REPLICAOF.ts
diff --git a/lib/commands/RESTORE-ASKING.spec.ts b/packages/client/lib/commands/RESTORE-ASKING.spec.ts
similarity index 100%
rename from lib/commands/RESTORE-ASKING.spec.ts
rename to packages/client/lib/commands/RESTORE-ASKING.spec.ts
diff --git a/lib/commands/RESTORE-ASKING.ts b/packages/client/lib/commands/RESTORE-ASKING.ts
similarity index 100%
rename from lib/commands/RESTORE-ASKING.ts
rename to packages/client/lib/commands/RESTORE-ASKING.ts
diff --git a/lib/commands/ROLE.spec.ts b/packages/client/lib/commands/ROLE.spec.ts
similarity index 100%
rename from lib/commands/ROLE.spec.ts
rename to packages/client/lib/commands/ROLE.spec.ts
diff --git a/lib/commands/ROLE.ts b/packages/client/lib/commands/ROLE.ts
similarity index 100%
rename from lib/commands/ROLE.ts
rename to packages/client/lib/commands/ROLE.ts
diff --git a/lib/commands/RPOP.spec.ts b/packages/client/lib/commands/RPOP.spec.ts
similarity index 100%
rename from lib/commands/RPOP.spec.ts
rename to packages/client/lib/commands/RPOP.spec.ts
diff --git a/lib/commands/RPOP.ts b/packages/client/lib/commands/RPOP.ts
similarity index 100%
rename from lib/commands/RPOP.ts
rename to packages/client/lib/commands/RPOP.ts
diff --git a/lib/commands/RPOPLPUSH.spec.ts b/packages/client/lib/commands/RPOPLPUSH.spec.ts
similarity index 100%
rename from lib/commands/RPOPLPUSH.spec.ts
rename to packages/client/lib/commands/RPOPLPUSH.spec.ts
diff --git a/lib/commands/RPOPLPUSH.ts b/packages/client/lib/commands/RPOPLPUSH.ts
similarity index 100%
rename from lib/commands/RPOPLPUSH.ts
rename to packages/client/lib/commands/RPOPLPUSH.ts
diff --git a/lib/commands/RPOP_COUNT.spec.ts b/packages/client/lib/commands/RPOP_COUNT.spec.ts
similarity index 100%
rename from lib/commands/RPOP_COUNT.spec.ts
rename to packages/client/lib/commands/RPOP_COUNT.spec.ts
diff --git a/lib/commands/RPOP_COUNT.ts b/packages/client/lib/commands/RPOP_COUNT.ts
similarity index 100%
rename from lib/commands/RPOP_COUNT.ts
rename to packages/client/lib/commands/RPOP_COUNT.ts
diff --git a/lib/commands/RPUSH.spec.ts b/packages/client/lib/commands/RPUSH.spec.ts
similarity index 100%
rename from lib/commands/RPUSH.spec.ts
rename to packages/client/lib/commands/RPUSH.spec.ts
diff --git a/lib/commands/RPUSH.ts b/packages/client/lib/commands/RPUSH.ts
similarity index 100%
rename from lib/commands/RPUSH.ts
rename to packages/client/lib/commands/RPUSH.ts
diff --git a/lib/commands/RPUSHX.spec.ts b/packages/client/lib/commands/RPUSHX.spec.ts
similarity index 100%
rename from lib/commands/RPUSHX.spec.ts
rename to packages/client/lib/commands/RPUSHX.spec.ts
diff --git a/lib/commands/RPUSHX.ts b/packages/client/lib/commands/RPUSHX.ts
similarity index 100%
rename from lib/commands/RPUSHX.ts
rename to packages/client/lib/commands/RPUSHX.ts
diff --git a/lib/commands/SADD.spec.ts b/packages/client/lib/commands/SADD.spec.ts
similarity index 100%
rename from lib/commands/SADD.spec.ts
rename to packages/client/lib/commands/SADD.spec.ts
diff --git a/lib/commands/SADD.ts b/packages/client/lib/commands/SADD.ts
similarity index 100%
rename from lib/commands/SADD.ts
rename to packages/client/lib/commands/SADD.ts
diff --git a/lib/commands/SAVE.spec.ts b/packages/client/lib/commands/SAVE.spec.ts
similarity index 100%
rename from lib/commands/SAVE.spec.ts
rename to packages/client/lib/commands/SAVE.spec.ts
diff --git a/lib/commands/SAVE.ts b/packages/client/lib/commands/SAVE.ts
similarity index 100%
rename from lib/commands/SAVE.ts
rename to packages/client/lib/commands/SAVE.ts
diff --git a/lib/commands/SCAN.spec.ts b/packages/client/lib/commands/SCAN.spec.ts
similarity index 100%
rename from lib/commands/SCAN.spec.ts
rename to packages/client/lib/commands/SCAN.spec.ts
diff --git a/lib/commands/SCAN.ts b/packages/client/lib/commands/SCAN.ts
similarity index 100%
rename from lib/commands/SCAN.ts
rename to packages/client/lib/commands/SCAN.ts
diff --git a/lib/commands/SCARD.spec.ts b/packages/client/lib/commands/SCARD.spec.ts
similarity index 100%
rename from lib/commands/SCARD.spec.ts
rename to packages/client/lib/commands/SCARD.spec.ts
diff --git a/lib/commands/SCARD.ts b/packages/client/lib/commands/SCARD.ts
similarity index 100%
rename from lib/commands/SCARD.ts
rename to packages/client/lib/commands/SCARD.ts
diff --git a/lib/commands/SCRIPT_DEBUG.spec.ts b/packages/client/lib/commands/SCRIPT_DEBUG.spec.ts
similarity index 100%
rename from lib/commands/SCRIPT_DEBUG.spec.ts
rename to packages/client/lib/commands/SCRIPT_DEBUG.spec.ts
diff --git a/lib/commands/SCRIPT_DEBUG.ts b/packages/client/lib/commands/SCRIPT_DEBUG.ts
similarity index 100%
rename from lib/commands/SCRIPT_DEBUG.ts
rename to packages/client/lib/commands/SCRIPT_DEBUG.ts
diff --git a/lib/commands/SCRIPT_EXISTS.spec.ts b/packages/client/lib/commands/SCRIPT_EXISTS.spec.ts
similarity index 100%
rename from lib/commands/SCRIPT_EXISTS.spec.ts
rename to packages/client/lib/commands/SCRIPT_EXISTS.spec.ts
diff --git a/lib/commands/SCRIPT_EXISTS.ts b/packages/client/lib/commands/SCRIPT_EXISTS.ts
similarity index 100%
rename from lib/commands/SCRIPT_EXISTS.ts
rename to packages/client/lib/commands/SCRIPT_EXISTS.ts
diff --git a/lib/commands/SCRIPT_FLUSH.spec.ts b/packages/client/lib/commands/SCRIPT_FLUSH.spec.ts
similarity index 100%
rename from lib/commands/SCRIPT_FLUSH.spec.ts
rename to packages/client/lib/commands/SCRIPT_FLUSH.spec.ts
diff --git a/lib/commands/SCRIPT_FLUSH.ts b/packages/client/lib/commands/SCRIPT_FLUSH.ts
similarity index 100%
rename from lib/commands/SCRIPT_FLUSH.ts
rename to packages/client/lib/commands/SCRIPT_FLUSH.ts
diff --git a/lib/commands/SCRIPT_KILL.spec.ts b/packages/client/lib/commands/SCRIPT_KILL.spec.ts
similarity index 100%
rename from lib/commands/SCRIPT_KILL.spec.ts
rename to packages/client/lib/commands/SCRIPT_KILL.spec.ts
diff --git a/lib/commands/SCRIPT_KILL.ts b/packages/client/lib/commands/SCRIPT_KILL.ts
similarity index 100%
rename from lib/commands/SCRIPT_KILL.ts
rename to packages/client/lib/commands/SCRIPT_KILL.ts
diff --git a/lib/commands/SCRIPT_LOAD.spec.ts b/packages/client/lib/commands/SCRIPT_LOAD.spec.ts
similarity index 100%
rename from lib/commands/SCRIPT_LOAD.spec.ts
rename to packages/client/lib/commands/SCRIPT_LOAD.spec.ts
diff --git a/lib/commands/SCRIPT_LOAD.ts b/packages/client/lib/commands/SCRIPT_LOAD.ts
similarity index 100%
rename from lib/commands/SCRIPT_LOAD.ts
rename to packages/client/lib/commands/SCRIPT_LOAD.ts
diff --git a/lib/commands/SDIFF.spec.ts b/packages/client/lib/commands/SDIFF.spec.ts
similarity index 100%
rename from lib/commands/SDIFF.spec.ts
rename to packages/client/lib/commands/SDIFF.spec.ts
diff --git a/lib/commands/SDIFF.ts b/packages/client/lib/commands/SDIFF.ts
similarity index 100%
rename from lib/commands/SDIFF.ts
rename to packages/client/lib/commands/SDIFF.ts
diff --git a/lib/commands/SDIFFSTORE.spec.ts b/packages/client/lib/commands/SDIFFSTORE.spec.ts
similarity index 100%
rename from lib/commands/SDIFFSTORE.spec.ts
rename to packages/client/lib/commands/SDIFFSTORE.spec.ts
diff --git a/lib/commands/SDIFFSTORE.ts b/packages/client/lib/commands/SDIFFSTORE.ts
similarity index 100%
rename from lib/commands/SDIFFSTORE.ts
rename to packages/client/lib/commands/SDIFFSTORE.ts
diff --git a/lib/commands/SET.spec.ts b/packages/client/lib/commands/SET.spec.ts
similarity index 100%
rename from lib/commands/SET.spec.ts
rename to packages/client/lib/commands/SET.spec.ts
diff --git a/lib/commands/SET.ts b/packages/client/lib/commands/SET.ts
similarity index 100%
rename from lib/commands/SET.ts
rename to packages/client/lib/commands/SET.ts
diff --git a/lib/commands/SETBIT.spec.ts b/packages/client/lib/commands/SETBIT.spec.ts
similarity index 100%
rename from lib/commands/SETBIT.spec.ts
rename to packages/client/lib/commands/SETBIT.spec.ts
diff --git a/lib/commands/SETBIT.ts b/packages/client/lib/commands/SETBIT.ts
similarity index 100%
rename from lib/commands/SETBIT.ts
rename to packages/client/lib/commands/SETBIT.ts
diff --git a/lib/commands/SETEX.spec.ts b/packages/client/lib/commands/SETEX.spec.ts
similarity index 100%
rename from lib/commands/SETEX.spec.ts
rename to packages/client/lib/commands/SETEX.spec.ts
diff --git a/lib/commands/SETEX.ts b/packages/client/lib/commands/SETEX.ts
similarity index 100%
rename from lib/commands/SETEX.ts
rename to packages/client/lib/commands/SETEX.ts
diff --git a/lib/commands/SETNX .spec.ts b/packages/client/lib/commands/SETNX .spec.ts
similarity index 100%
rename from lib/commands/SETNX .spec.ts
rename to packages/client/lib/commands/SETNX .spec.ts
diff --git a/lib/commands/SETNX.ts b/packages/client/lib/commands/SETNX.ts
similarity index 100%
rename from lib/commands/SETNX.ts
rename to packages/client/lib/commands/SETNX.ts
diff --git a/lib/commands/SETRANGE.spec.ts b/packages/client/lib/commands/SETRANGE.spec.ts
similarity index 100%
rename from lib/commands/SETRANGE.spec.ts
rename to packages/client/lib/commands/SETRANGE.spec.ts
diff --git a/lib/commands/SETRANGE.ts b/packages/client/lib/commands/SETRANGE.ts
similarity index 100%
rename from lib/commands/SETRANGE.ts
rename to packages/client/lib/commands/SETRANGE.ts
diff --git a/lib/commands/SHUTDOWN.spec.ts b/packages/client/lib/commands/SHUTDOWN.spec.ts
similarity index 100%
rename from lib/commands/SHUTDOWN.spec.ts
rename to packages/client/lib/commands/SHUTDOWN.spec.ts
diff --git a/lib/commands/SHUTDOWN.ts b/packages/client/lib/commands/SHUTDOWN.ts
similarity index 100%
rename from lib/commands/SHUTDOWN.ts
rename to packages/client/lib/commands/SHUTDOWN.ts
diff --git a/lib/commands/SINTER.spec.ts b/packages/client/lib/commands/SINTER.spec.ts
similarity index 100%
rename from lib/commands/SINTER.spec.ts
rename to packages/client/lib/commands/SINTER.spec.ts
diff --git a/lib/commands/SINTER.ts b/packages/client/lib/commands/SINTER.ts
similarity index 100%
rename from lib/commands/SINTER.ts
rename to packages/client/lib/commands/SINTER.ts
diff --git a/lib/commands/SINTERSTORE.spec.ts b/packages/client/lib/commands/SINTERSTORE.spec.ts
similarity index 100%
rename from lib/commands/SINTERSTORE.spec.ts
rename to packages/client/lib/commands/SINTERSTORE.spec.ts
diff --git a/lib/commands/SINTERSTORE.ts b/packages/client/lib/commands/SINTERSTORE.ts
similarity index 100%
rename from lib/commands/SINTERSTORE.ts
rename to packages/client/lib/commands/SINTERSTORE.ts
diff --git a/lib/commands/SISMEMBER.spec.ts b/packages/client/lib/commands/SISMEMBER.spec.ts
similarity index 100%
rename from lib/commands/SISMEMBER.spec.ts
rename to packages/client/lib/commands/SISMEMBER.spec.ts
diff --git a/lib/commands/SISMEMBER.ts b/packages/client/lib/commands/SISMEMBER.ts
similarity index 100%
rename from lib/commands/SISMEMBER.ts
rename to packages/client/lib/commands/SISMEMBER.ts
diff --git a/lib/commands/SMEMBERS.spec.ts b/packages/client/lib/commands/SMEMBERS.spec.ts
similarity index 100%
rename from lib/commands/SMEMBERS.spec.ts
rename to packages/client/lib/commands/SMEMBERS.spec.ts
diff --git a/lib/commands/SMEMBERS.ts b/packages/client/lib/commands/SMEMBERS.ts
similarity index 100%
rename from lib/commands/SMEMBERS.ts
rename to packages/client/lib/commands/SMEMBERS.ts
diff --git a/lib/commands/SMISMEMBER.spec.ts b/packages/client/lib/commands/SMISMEMBER.spec.ts
similarity index 100%
rename from lib/commands/SMISMEMBER.spec.ts
rename to packages/client/lib/commands/SMISMEMBER.spec.ts
diff --git a/lib/commands/SMISMEMBER.ts b/packages/client/lib/commands/SMISMEMBER.ts
similarity index 100%
rename from lib/commands/SMISMEMBER.ts
rename to packages/client/lib/commands/SMISMEMBER.ts
diff --git a/lib/commands/SMOVE.spec.ts b/packages/client/lib/commands/SMOVE.spec.ts
similarity index 100%
rename from lib/commands/SMOVE.spec.ts
rename to packages/client/lib/commands/SMOVE.spec.ts
diff --git a/lib/commands/SMOVE.ts b/packages/client/lib/commands/SMOVE.ts
similarity index 100%
rename from lib/commands/SMOVE.ts
rename to packages/client/lib/commands/SMOVE.ts
diff --git a/lib/commands/SORT.spec.ts b/packages/client/lib/commands/SORT.spec.ts
similarity index 100%
rename from lib/commands/SORT.spec.ts
rename to packages/client/lib/commands/SORT.spec.ts
diff --git a/lib/commands/SORT.ts b/packages/client/lib/commands/SORT.ts
similarity index 100%
rename from lib/commands/SORT.ts
rename to packages/client/lib/commands/SORT.ts
diff --git a/lib/commands/SPOP.spec.ts b/packages/client/lib/commands/SPOP.spec.ts
similarity index 100%
rename from lib/commands/SPOP.spec.ts
rename to packages/client/lib/commands/SPOP.spec.ts
diff --git a/lib/commands/SPOP.ts b/packages/client/lib/commands/SPOP.ts
similarity index 100%
rename from lib/commands/SPOP.ts
rename to packages/client/lib/commands/SPOP.ts
diff --git a/lib/commands/SRANDMEMBER.spec.ts b/packages/client/lib/commands/SRANDMEMBER.spec.ts
similarity index 100%
rename from lib/commands/SRANDMEMBER.spec.ts
rename to packages/client/lib/commands/SRANDMEMBER.spec.ts
diff --git a/lib/commands/SRANDMEMBER.ts b/packages/client/lib/commands/SRANDMEMBER.ts
similarity index 100%
rename from lib/commands/SRANDMEMBER.ts
rename to packages/client/lib/commands/SRANDMEMBER.ts
diff --git a/lib/commands/SRANDMEMBER_COUNT.spec.ts b/packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts
similarity index 100%
rename from lib/commands/SRANDMEMBER_COUNT.spec.ts
rename to packages/client/lib/commands/SRANDMEMBER_COUNT.spec.ts
diff --git a/lib/commands/SRANDMEMBER_COUNT.ts b/packages/client/lib/commands/SRANDMEMBER_COUNT.ts
similarity index 100%
rename from lib/commands/SRANDMEMBER_COUNT.ts
rename to packages/client/lib/commands/SRANDMEMBER_COUNT.ts
diff --git a/lib/commands/SREM.spec.ts b/packages/client/lib/commands/SREM.spec.ts
similarity index 100%
rename from lib/commands/SREM.spec.ts
rename to packages/client/lib/commands/SREM.spec.ts
diff --git a/lib/commands/SREM.ts b/packages/client/lib/commands/SREM.ts
similarity index 100%
rename from lib/commands/SREM.ts
rename to packages/client/lib/commands/SREM.ts
diff --git a/lib/commands/SSCAN.spec.ts b/packages/client/lib/commands/SSCAN.spec.ts
similarity index 100%
rename from lib/commands/SSCAN.spec.ts
rename to packages/client/lib/commands/SSCAN.spec.ts
diff --git a/lib/commands/SSCAN.ts b/packages/client/lib/commands/SSCAN.ts
similarity index 100%
rename from lib/commands/SSCAN.ts
rename to packages/client/lib/commands/SSCAN.ts
diff --git a/lib/commands/STRLEN.spec.ts b/packages/client/lib/commands/STRLEN.spec.ts
similarity index 100%
rename from lib/commands/STRLEN.spec.ts
rename to packages/client/lib/commands/STRLEN.spec.ts
diff --git a/lib/commands/STRLEN.ts b/packages/client/lib/commands/STRLEN.ts
similarity index 100%
rename from lib/commands/STRLEN.ts
rename to packages/client/lib/commands/STRLEN.ts
diff --git a/lib/commands/SUNION.spec.ts b/packages/client/lib/commands/SUNION.spec.ts
similarity index 100%
rename from lib/commands/SUNION.spec.ts
rename to packages/client/lib/commands/SUNION.spec.ts
diff --git a/lib/commands/SUNION.ts b/packages/client/lib/commands/SUNION.ts
similarity index 100%
rename from lib/commands/SUNION.ts
rename to packages/client/lib/commands/SUNION.ts
diff --git a/lib/commands/SUNIONSTORE.spec.ts b/packages/client/lib/commands/SUNIONSTORE.spec.ts
similarity index 100%
rename from lib/commands/SUNIONSTORE.spec.ts
rename to packages/client/lib/commands/SUNIONSTORE.spec.ts
diff --git a/lib/commands/SUNIONSTORE.ts b/packages/client/lib/commands/SUNIONSTORE.ts
similarity index 100%
rename from lib/commands/SUNIONSTORE.ts
rename to packages/client/lib/commands/SUNIONSTORE.ts
diff --git a/lib/commands/SWAPDB.spec.ts b/packages/client/lib/commands/SWAPDB.spec.ts
similarity index 100%
rename from lib/commands/SWAPDB.spec.ts
rename to packages/client/lib/commands/SWAPDB.spec.ts
diff --git a/lib/commands/SWAPDB.ts b/packages/client/lib/commands/SWAPDB.ts
similarity index 100%
rename from lib/commands/SWAPDB.ts
rename to packages/client/lib/commands/SWAPDB.ts
diff --git a/lib/commands/TIME.spec.ts b/packages/client/lib/commands/TIME.spec.ts
similarity index 55%
rename from lib/commands/TIME.spec.ts
rename to packages/client/lib/commands/TIME.spec.ts
index bbaa7942db..1139d18d53 100644
--- a/lib/commands/TIME.spec.ts
+++ b/packages/client/lib/commands/TIME.spec.ts
@@ -10,9 +10,9 @@ describe('TIME', () => {
);
});
- testUtils.testWithClient('client.time', async client => {
- const reply = await client.time();
- assert.ok(reply instanceof Date);
- assert.ok(typeof reply.microseconds === 'number');
- }, GLOBAL.SERVERS.OPEN);
+ // testUtils.testWithClient('client.time', async client => {
+ // const reply = await client.time();
+ // assert.ok(reply instanceof Date);
+ // assert.ok(typeof reply.microseconds === 'number');
+ // }, GLOBAL.SERVERS.OPEN);
});
diff --git a/lib/commands/TIME.ts b/packages/client/lib/commands/TIME.ts
similarity index 100%
rename from lib/commands/TIME.ts
rename to packages/client/lib/commands/TIME.ts
diff --git a/lib/commands/TOUCH.spec.ts b/packages/client/lib/commands/TOUCH.spec.ts
similarity index 100%
rename from lib/commands/TOUCH.spec.ts
rename to packages/client/lib/commands/TOUCH.spec.ts
diff --git a/lib/commands/TOUCH.ts b/packages/client/lib/commands/TOUCH.ts
similarity index 100%
rename from lib/commands/TOUCH.ts
rename to packages/client/lib/commands/TOUCH.ts
diff --git a/lib/commands/TTL.spec.ts b/packages/client/lib/commands/TTL.spec.ts
similarity index 100%
rename from lib/commands/TTL.spec.ts
rename to packages/client/lib/commands/TTL.spec.ts
diff --git a/lib/commands/TTL.ts b/packages/client/lib/commands/TTL.ts
similarity index 100%
rename from lib/commands/TTL.ts
rename to packages/client/lib/commands/TTL.ts
diff --git a/lib/commands/TYPE.spec.ts b/packages/client/lib/commands/TYPE.spec.ts
similarity index 100%
rename from lib/commands/TYPE.spec.ts
rename to packages/client/lib/commands/TYPE.spec.ts
diff --git a/lib/commands/TYPE.ts b/packages/client/lib/commands/TYPE.ts
similarity index 100%
rename from lib/commands/TYPE.ts
rename to packages/client/lib/commands/TYPE.ts
diff --git a/lib/commands/UNLINK.spec.ts b/packages/client/lib/commands/UNLINK.spec.ts
similarity index 100%
rename from lib/commands/UNLINK.spec.ts
rename to packages/client/lib/commands/UNLINK.spec.ts
diff --git a/lib/commands/UNLINK.ts b/packages/client/lib/commands/UNLINK.ts
similarity index 100%
rename from lib/commands/UNLINK.ts
rename to packages/client/lib/commands/UNLINK.ts
diff --git a/lib/commands/UNWATCH.spec.ts b/packages/client/lib/commands/UNWATCH.spec.ts
similarity index 100%
rename from lib/commands/UNWATCH.spec.ts
rename to packages/client/lib/commands/UNWATCH.spec.ts
diff --git a/lib/commands/UNWATCH.ts b/packages/client/lib/commands/UNWATCH.ts
similarity index 100%
rename from lib/commands/UNWATCH.ts
rename to packages/client/lib/commands/UNWATCH.ts
diff --git a/lib/commands/WAIT.spec.ts b/packages/client/lib/commands/WAIT.spec.ts
similarity index 100%
rename from lib/commands/WAIT.spec.ts
rename to packages/client/lib/commands/WAIT.spec.ts
diff --git a/lib/commands/WAIT.ts b/packages/client/lib/commands/WAIT.ts
similarity index 100%
rename from lib/commands/WAIT.ts
rename to packages/client/lib/commands/WAIT.ts
diff --git a/lib/commands/WATCH.spec.ts b/packages/client/lib/commands/WATCH.spec.ts
similarity index 100%
rename from lib/commands/WATCH.spec.ts
rename to packages/client/lib/commands/WATCH.spec.ts
diff --git a/lib/commands/WATCH.ts b/packages/client/lib/commands/WATCH.ts
similarity index 100%
rename from lib/commands/WATCH.ts
rename to packages/client/lib/commands/WATCH.ts
diff --git a/lib/commands/XACK.spec.ts b/packages/client/lib/commands/XACK.spec.ts
similarity index 100%
rename from lib/commands/XACK.spec.ts
rename to packages/client/lib/commands/XACK.spec.ts
diff --git a/lib/commands/XACK.ts b/packages/client/lib/commands/XACK.ts
similarity index 100%
rename from lib/commands/XACK.ts
rename to packages/client/lib/commands/XACK.ts
diff --git a/lib/commands/XADD.spec.ts b/packages/client/lib/commands/XADD.spec.ts
similarity index 100%
rename from lib/commands/XADD.spec.ts
rename to packages/client/lib/commands/XADD.spec.ts
diff --git a/lib/commands/XADD.ts b/packages/client/lib/commands/XADD.ts
similarity index 100%
rename from lib/commands/XADD.ts
rename to packages/client/lib/commands/XADD.ts
diff --git a/lib/commands/XAUTOCLAIM.spec.ts b/packages/client/lib/commands/XAUTOCLAIM.spec.ts
similarity index 100%
rename from lib/commands/XAUTOCLAIM.spec.ts
rename to packages/client/lib/commands/XAUTOCLAIM.spec.ts
diff --git a/lib/commands/XAUTOCLAIM.ts b/packages/client/lib/commands/XAUTOCLAIM.ts
similarity index 100%
rename from lib/commands/XAUTOCLAIM.ts
rename to packages/client/lib/commands/XAUTOCLAIM.ts
diff --git a/lib/commands/XAUTOCLAIM_JUSTID.spec.ts b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts
similarity index 100%
rename from lib/commands/XAUTOCLAIM_JUSTID.spec.ts
rename to packages/client/lib/commands/XAUTOCLAIM_JUSTID.spec.ts
diff --git a/lib/commands/XAUTOCLAIM_JUSTID.ts b/packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts
similarity index 100%
rename from lib/commands/XAUTOCLAIM_JUSTID.ts
rename to packages/client/lib/commands/XAUTOCLAIM_JUSTID.ts
diff --git a/lib/commands/XCLAIM.spec.ts b/packages/client/lib/commands/XCLAIM.spec.ts
similarity index 100%
rename from lib/commands/XCLAIM.spec.ts
rename to packages/client/lib/commands/XCLAIM.spec.ts
diff --git a/lib/commands/XCLAIM.ts b/packages/client/lib/commands/XCLAIM.ts
similarity index 100%
rename from lib/commands/XCLAIM.ts
rename to packages/client/lib/commands/XCLAIM.ts
diff --git a/lib/commands/XCLAIM_JUSTID.spec.ts b/packages/client/lib/commands/XCLAIM_JUSTID.spec.ts
similarity index 100%
rename from lib/commands/XCLAIM_JUSTID.spec.ts
rename to packages/client/lib/commands/XCLAIM_JUSTID.spec.ts
diff --git a/lib/commands/XCLAIM_JUSTID.ts b/packages/client/lib/commands/XCLAIM_JUSTID.ts
similarity index 100%
rename from lib/commands/XCLAIM_JUSTID.ts
rename to packages/client/lib/commands/XCLAIM_JUSTID.ts
diff --git a/lib/commands/XDEL.spec.ts b/packages/client/lib/commands/XDEL.spec.ts
similarity index 100%
rename from lib/commands/XDEL.spec.ts
rename to packages/client/lib/commands/XDEL.spec.ts
diff --git a/lib/commands/XDEL.ts b/packages/client/lib/commands/XDEL.ts
similarity index 100%
rename from lib/commands/XDEL.ts
rename to packages/client/lib/commands/XDEL.ts
diff --git a/lib/commands/XGROUP_CREATE.spec.ts b/packages/client/lib/commands/XGROUP_CREATE.spec.ts
similarity index 100%
rename from lib/commands/XGROUP_CREATE.spec.ts
rename to packages/client/lib/commands/XGROUP_CREATE.spec.ts
diff --git a/lib/commands/XGROUP_CREATE.ts b/packages/client/lib/commands/XGROUP_CREATE.ts
similarity index 100%
rename from lib/commands/XGROUP_CREATE.ts
rename to packages/client/lib/commands/XGROUP_CREATE.ts
diff --git a/lib/commands/XGROUP_CREATECONSUMER.spec.ts b/packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts
similarity index 100%
rename from lib/commands/XGROUP_CREATECONSUMER.spec.ts
rename to packages/client/lib/commands/XGROUP_CREATECONSUMER.spec.ts
diff --git a/lib/commands/XGROUP_CREATECONSUMER.ts b/packages/client/lib/commands/XGROUP_CREATECONSUMER.ts
similarity index 100%
rename from lib/commands/XGROUP_CREATECONSUMER.ts
rename to packages/client/lib/commands/XGROUP_CREATECONSUMER.ts
diff --git a/lib/commands/XGROUP_DELCONSUMER.spec.ts b/packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts
similarity index 100%
rename from lib/commands/XGROUP_DELCONSUMER.spec.ts
rename to packages/client/lib/commands/XGROUP_DELCONSUMER.spec.ts
diff --git a/lib/commands/XGROUP_DELCONSUMER.ts b/packages/client/lib/commands/XGROUP_DELCONSUMER.ts
similarity index 100%
rename from lib/commands/XGROUP_DELCONSUMER.ts
rename to packages/client/lib/commands/XGROUP_DELCONSUMER.ts
diff --git a/lib/commands/XGROUP_DESTROY.spec.ts b/packages/client/lib/commands/XGROUP_DESTROY.spec.ts
similarity index 100%
rename from lib/commands/XGROUP_DESTROY.spec.ts
rename to packages/client/lib/commands/XGROUP_DESTROY.spec.ts
diff --git a/lib/commands/XGROUP_DESTROY.ts b/packages/client/lib/commands/XGROUP_DESTROY.ts
similarity index 100%
rename from lib/commands/XGROUP_DESTROY.ts
rename to packages/client/lib/commands/XGROUP_DESTROY.ts
diff --git a/lib/commands/XGROUP_SETID.spec.ts b/packages/client/lib/commands/XGROUP_SETID.spec.ts
similarity index 100%
rename from lib/commands/XGROUP_SETID.spec.ts
rename to packages/client/lib/commands/XGROUP_SETID.spec.ts
diff --git a/lib/commands/XGROUP_SETID.ts b/packages/client/lib/commands/XGROUP_SETID.ts
similarity index 100%
rename from lib/commands/XGROUP_SETID.ts
rename to packages/client/lib/commands/XGROUP_SETID.ts
diff --git a/lib/commands/XINFO_CONSUMERS.spec.ts b/packages/client/lib/commands/XINFO_CONSUMERS.spec.ts
similarity index 100%
rename from lib/commands/XINFO_CONSUMERS.spec.ts
rename to packages/client/lib/commands/XINFO_CONSUMERS.spec.ts
diff --git a/lib/commands/XINFO_CONSUMERS.ts b/packages/client/lib/commands/XINFO_CONSUMERS.ts
similarity index 100%
rename from lib/commands/XINFO_CONSUMERS.ts
rename to packages/client/lib/commands/XINFO_CONSUMERS.ts
diff --git a/lib/commands/XINFO_GROUPS.spec.ts b/packages/client/lib/commands/XINFO_GROUPS.spec.ts
similarity index 100%
rename from lib/commands/XINFO_GROUPS.spec.ts
rename to packages/client/lib/commands/XINFO_GROUPS.spec.ts
diff --git a/lib/commands/XINFO_GROUPS.ts b/packages/client/lib/commands/XINFO_GROUPS.ts
similarity index 100%
rename from lib/commands/XINFO_GROUPS.ts
rename to packages/client/lib/commands/XINFO_GROUPS.ts
diff --git a/lib/commands/XINFO_STREAM.spec.ts b/packages/client/lib/commands/XINFO_STREAM.spec.ts
similarity index 100%
rename from lib/commands/XINFO_STREAM.spec.ts
rename to packages/client/lib/commands/XINFO_STREAM.spec.ts
diff --git a/lib/commands/XINFO_STREAM.ts b/packages/client/lib/commands/XINFO_STREAM.ts
similarity index 100%
rename from lib/commands/XINFO_STREAM.ts
rename to packages/client/lib/commands/XINFO_STREAM.ts
diff --git a/lib/commands/XLEN.spec.ts b/packages/client/lib/commands/XLEN.spec.ts
similarity index 100%
rename from lib/commands/XLEN.spec.ts
rename to packages/client/lib/commands/XLEN.spec.ts
diff --git a/lib/commands/XLEN.ts b/packages/client/lib/commands/XLEN.ts
similarity index 100%
rename from lib/commands/XLEN.ts
rename to packages/client/lib/commands/XLEN.ts
diff --git a/lib/commands/XPENDING.spec.ts b/packages/client/lib/commands/XPENDING.spec.ts
similarity index 100%
rename from lib/commands/XPENDING.spec.ts
rename to packages/client/lib/commands/XPENDING.spec.ts
diff --git a/lib/commands/XPENDING.ts b/packages/client/lib/commands/XPENDING.ts
similarity index 100%
rename from lib/commands/XPENDING.ts
rename to packages/client/lib/commands/XPENDING.ts
diff --git a/lib/commands/XPENDING_RANGE.spec.ts b/packages/client/lib/commands/XPENDING_RANGE.spec.ts
similarity index 100%
rename from lib/commands/XPENDING_RANGE.spec.ts
rename to packages/client/lib/commands/XPENDING_RANGE.spec.ts
diff --git a/lib/commands/XPENDING_RANGE.ts b/packages/client/lib/commands/XPENDING_RANGE.ts
similarity index 100%
rename from lib/commands/XPENDING_RANGE.ts
rename to packages/client/lib/commands/XPENDING_RANGE.ts
diff --git a/lib/commands/XRANGE.spec.ts b/packages/client/lib/commands/XRANGE.spec.ts
similarity index 100%
rename from lib/commands/XRANGE.spec.ts
rename to packages/client/lib/commands/XRANGE.spec.ts
diff --git a/lib/commands/XRANGE.ts b/packages/client/lib/commands/XRANGE.ts
similarity index 100%
rename from lib/commands/XRANGE.ts
rename to packages/client/lib/commands/XRANGE.ts
diff --git a/lib/commands/XREAD.spec.ts b/packages/client/lib/commands/XREAD.spec.ts
similarity index 100%
rename from lib/commands/XREAD.spec.ts
rename to packages/client/lib/commands/XREAD.spec.ts
diff --git a/lib/commands/XREAD.ts b/packages/client/lib/commands/XREAD.ts
similarity index 100%
rename from lib/commands/XREAD.ts
rename to packages/client/lib/commands/XREAD.ts
diff --git a/lib/commands/XREADGROUP.spec.ts b/packages/client/lib/commands/XREADGROUP.spec.ts
similarity index 100%
rename from lib/commands/XREADGROUP.spec.ts
rename to packages/client/lib/commands/XREADGROUP.spec.ts
diff --git a/lib/commands/XREADGROUP.ts b/packages/client/lib/commands/XREADGROUP.ts
similarity index 100%
rename from lib/commands/XREADGROUP.ts
rename to packages/client/lib/commands/XREADGROUP.ts
diff --git a/lib/commands/XREVRANGE.spec.ts b/packages/client/lib/commands/XREVRANGE.spec.ts
similarity index 100%
rename from lib/commands/XREVRANGE.spec.ts
rename to packages/client/lib/commands/XREVRANGE.spec.ts
diff --git a/lib/commands/XREVRANGE.ts b/packages/client/lib/commands/XREVRANGE.ts
similarity index 100%
rename from lib/commands/XREVRANGE.ts
rename to packages/client/lib/commands/XREVRANGE.ts
diff --git a/lib/commands/XTRIM.spec.ts b/packages/client/lib/commands/XTRIM.spec.ts
similarity index 100%
rename from lib/commands/XTRIM.spec.ts
rename to packages/client/lib/commands/XTRIM.spec.ts
diff --git a/lib/commands/XTRIM.ts b/packages/client/lib/commands/XTRIM.ts
similarity index 100%
rename from lib/commands/XTRIM.ts
rename to packages/client/lib/commands/XTRIM.ts
diff --git a/lib/commands/ZADD.spec.ts b/packages/client/lib/commands/ZADD.spec.ts
similarity index 100%
rename from lib/commands/ZADD.spec.ts
rename to packages/client/lib/commands/ZADD.spec.ts
diff --git a/lib/commands/ZADD.ts b/packages/client/lib/commands/ZADD.ts
similarity index 100%
rename from lib/commands/ZADD.ts
rename to packages/client/lib/commands/ZADD.ts
diff --git a/lib/commands/ZCARD.spec.ts b/packages/client/lib/commands/ZCARD.spec.ts
similarity index 100%
rename from lib/commands/ZCARD.spec.ts
rename to packages/client/lib/commands/ZCARD.spec.ts
diff --git a/lib/commands/ZCARD.ts b/packages/client/lib/commands/ZCARD.ts
similarity index 100%
rename from lib/commands/ZCARD.ts
rename to packages/client/lib/commands/ZCARD.ts
diff --git a/lib/commands/ZCOUNT.spec.ts b/packages/client/lib/commands/ZCOUNT.spec.ts
similarity index 100%
rename from lib/commands/ZCOUNT.spec.ts
rename to packages/client/lib/commands/ZCOUNT.spec.ts
diff --git a/lib/commands/ZCOUNT.ts b/packages/client/lib/commands/ZCOUNT.ts
similarity index 100%
rename from lib/commands/ZCOUNT.ts
rename to packages/client/lib/commands/ZCOUNT.ts
diff --git a/lib/commands/ZDIFF.spec.ts b/packages/client/lib/commands/ZDIFF.spec.ts
similarity index 100%
rename from lib/commands/ZDIFF.spec.ts
rename to packages/client/lib/commands/ZDIFF.spec.ts
diff --git a/lib/commands/ZDIFF.ts b/packages/client/lib/commands/ZDIFF.ts
similarity index 100%
rename from lib/commands/ZDIFF.ts
rename to packages/client/lib/commands/ZDIFF.ts
diff --git a/lib/commands/ZDIFFSTORE.spec.ts b/packages/client/lib/commands/ZDIFFSTORE.spec.ts
similarity index 100%
rename from lib/commands/ZDIFFSTORE.spec.ts
rename to packages/client/lib/commands/ZDIFFSTORE.spec.ts
diff --git a/lib/commands/ZDIFFSTORE.ts b/packages/client/lib/commands/ZDIFFSTORE.ts
similarity index 100%
rename from lib/commands/ZDIFFSTORE.ts
rename to packages/client/lib/commands/ZDIFFSTORE.ts
diff --git a/lib/commands/ZDIFF_WITHSCORES.spec.ts b/packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZDIFF_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZDIFF_WITHSCORES.spec.ts
diff --git a/lib/commands/ZDIFF_WITHSCORES.ts b/packages/client/lib/commands/ZDIFF_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZDIFF_WITHSCORES.ts
rename to packages/client/lib/commands/ZDIFF_WITHSCORES.ts
diff --git a/lib/commands/ZINCRBY.spec.ts b/packages/client/lib/commands/ZINCRBY.spec.ts
similarity index 100%
rename from lib/commands/ZINCRBY.spec.ts
rename to packages/client/lib/commands/ZINCRBY.spec.ts
diff --git a/lib/commands/ZINCRBY.ts b/packages/client/lib/commands/ZINCRBY.ts
similarity index 100%
rename from lib/commands/ZINCRBY.ts
rename to packages/client/lib/commands/ZINCRBY.ts
diff --git a/lib/commands/ZINTER.spec.ts b/packages/client/lib/commands/ZINTER.spec.ts
similarity index 100%
rename from lib/commands/ZINTER.spec.ts
rename to packages/client/lib/commands/ZINTER.spec.ts
diff --git a/lib/commands/ZINTER.ts b/packages/client/lib/commands/ZINTER.ts
similarity index 100%
rename from lib/commands/ZINTER.ts
rename to packages/client/lib/commands/ZINTER.ts
diff --git a/lib/commands/ZINTERSTORE.spec.ts b/packages/client/lib/commands/ZINTERSTORE.spec.ts
similarity index 100%
rename from lib/commands/ZINTERSTORE.spec.ts
rename to packages/client/lib/commands/ZINTERSTORE.spec.ts
diff --git a/lib/commands/ZINTERSTORE.ts b/packages/client/lib/commands/ZINTERSTORE.ts
similarity index 100%
rename from lib/commands/ZINTERSTORE.ts
rename to packages/client/lib/commands/ZINTERSTORE.ts
diff --git a/lib/commands/ZINTER_WITHSCORES.spec.ts b/packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZINTER_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZINTER_WITHSCORES.spec.ts
diff --git a/lib/commands/ZINTER_WITHSCORES.ts b/packages/client/lib/commands/ZINTER_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZINTER_WITHSCORES.ts
rename to packages/client/lib/commands/ZINTER_WITHSCORES.ts
diff --git a/lib/commands/ZLEXCOUNT.spec.ts b/packages/client/lib/commands/ZLEXCOUNT.spec.ts
similarity index 100%
rename from lib/commands/ZLEXCOUNT.spec.ts
rename to packages/client/lib/commands/ZLEXCOUNT.spec.ts
diff --git a/lib/commands/ZLEXCOUNT.ts b/packages/client/lib/commands/ZLEXCOUNT.ts
similarity index 100%
rename from lib/commands/ZLEXCOUNT.ts
rename to packages/client/lib/commands/ZLEXCOUNT.ts
diff --git a/lib/commands/ZMSCORE.spec.ts b/packages/client/lib/commands/ZMSCORE.spec.ts
similarity index 100%
rename from lib/commands/ZMSCORE.spec.ts
rename to packages/client/lib/commands/ZMSCORE.spec.ts
diff --git a/lib/commands/ZMSCORE.ts b/packages/client/lib/commands/ZMSCORE.ts
similarity index 100%
rename from lib/commands/ZMSCORE.ts
rename to packages/client/lib/commands/ZMSCORE.ts
diff --git a/lib/commands/ZPOPMAX.spec.ts b/packages/client/lib/commands/ZPOPMAX.spec.ts
similarity index 100%
rename from lib/commands/ZPOPMAX.spec.ts
rename to packages/client/lib/commands/ZPOPMAX.spec.ts
diff --git a/lib/commands/ZPOPMAX.ts b/packages/client/lib/commands/ZPOPMAX.ts
similarity index 100%
rename from lib/commands/ZPOPMAX.ts
rename to packages/client/lib/commands/ZPOPMAX.ts
diff --git a/lib/commands/ZPOPMAX_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts
similarity index 100%
rename from lib/commands/ZPOPMAX_COUNT.spec.ts
rename to packages/client/lib/commands/ZPOPMAX_COUNT.spec.ts
diff --git a/lib/commands/ZPOPMAX_COUNT.ts b/packages/client/lib/commands/ZPOPMAX_COUNT.ts
similarity index 100%
rename from lib/commands/ZPOPMAX_COUNT.ts
rename to packages/client/lib/commands/ZPOPMAX_COUNT.ts
diff --git a/lib/commands/ZPOPMIN.spec.ts b/packages/client/lib/commands/ZPOPMIN.spec.ts
similarity index 100%
rename from lib/commands/ZPOPMIN.spec.ts
rename to packages/client/lib/commands/ZPOPMIN.spec.ts
diff --git a/lib/commands/ZPOPMIN.ts b/packages/client/lib/commands/ZPOPMIN.ts
similarity index 100%
rename from lib/commands/ZPOPMIN.ts
rename to packages/client/lib/commands/ZPOPMIN.ts
diff --git a/lib/commands/ZPOPMIN_COUNT.spec.ts b/packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts
similarity index 100%
rename from lib/commands/ZPOPMIN_COUNT.spec.ts
rename to packages/client/lib/commands/ZPOPMIN_COUNT.spec.ts
diff --git a/lib/commands/ZPOPMIN_COUNT.ts b/packages/client/lib/commands/ZPOPMIN_COUNT.ts
similarity index 100%
rename from lib/commands/ZPOPMIN_COUNT.ts
rename to packages/client/lib/commands/ZPOPMIN_COUNT.ts
diff --git a/lib/commands/ZRANDMEMBER.spec.ts b/packages/client/lib/commands/ZRANDMEMBER.spec.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER.spec.ts
rename to packages/client/lib/commands/ZRANDMEMBER.spec.ts
diff --git a/lib/commands/ZRANDMEMBER.ts b/packages/client/lib/commands/ZRANDMEMBER.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER.ts
rename to packages/client/lib/commands/ZRANDMEMBER.ts
diff --git a/lib/commands/ZRANDMEMBER_COUNT.spec.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER_COUNT.spec.ts
rename to packages/client/lib/commands/ZRANDMEMBER_COUNT.spec.ts
diff --git a/lib/commands/ZRANDMEMBER_COUNT.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER_COUNT.ts
rename to packages/client/lib/commands/ZRANDMEMBER_COUNT.ts
diff --git a/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.spec.ts
diff --git a/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts b/packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts
rename to packages/client/lib/commands/ZRANDMEMBER_COUNT_WITHSCORES.ts
diff --git a/lib/commands/ZRANGE.spec.ts b/packages/client/lib/commands/ZRANGE.spec.ts
similarity index 100%
rename from lib/commands/ZRANGE.spec.ts
rename to packages/client/lib/commands/ZRANGE.spec.ts
diff --git a/lib/commands/ZRANGE.ts b/packages/client/lib/commands/ZRANGE.ts
similarity index 100%
rename from lib/commands/ZRANGE.ts
rename to packages/client/lib/commands/ZRANGE.ts
diff --git a/lib/commands/ZRANGEBYLEX.spec.ts b/packages/client/lib/commands/ZRANGEBYLEX.spec.ts
similarity index 100%
rename from lib/commands/ZRANGEBYLEX.spec.ts
rename to packages/client/lib/commands/ZRANGEBYLEX.spec.ts
diff --git a/lib/commands/ZRANGEBYLEX.ts b/packages/client/lib/commands/ZRANGEBYLEX.ts
similarity index 100%
rename from lib/commands/ZRANGEBYLEX.ts
rename to packages/client/lib/commands/ZRANGEBYLEX.ts
diff --git a/lib/commands/ZRANGEBYSCORE.spec.ts b/packages/client/lib/commands/ZRANGEBYSCORE.spec.ts
similarity index 100%
rename from lib/commands/ZRANGEBYSCORE.spec.ts
rename to packages/client/lib/commands/ZRANGEBYSCORE.spec.ts
diff --git a/lib/commands/ZRANGEBYSCORE.ts b/packages/client/lib/commands/ZRANGEBYSCORE.ts
similarity index 100%
rename from lib/commands/ZRANGEBYSCORE.ts
rename to packages/client/lib/commands/ZRANGEBYSCORE.ts
diff --git a/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.spec.ts
diff --git a/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts b/packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZRANGEBYSCORE_WITHSCORES.ts
rename to packages/client/lib/commands/ZRANGEBYSCORE_WITHSCORES.ts
diff --git a/lib/commands/ZRANGESTORE.spec.ts b/packages/client/lib/commands/ZRANGESTORE.spec.ts
similarity index 100%
rename from lib/commands/ZRANGESTORE.spec.ts
rename to packages/client/lib/commands/ZRANGESTORE.spec.ts
diff --git a/lib/commands/ZRANGESTORE.ts b/packages/client/lib/commands/ZRANGESTORE.ts
similarity index 100%
rename from lib/commands/ZRANGESTORE.ts
rename to packages/client/lib/commands/ZRANGESTORE.ts
diff --git a/lib/commands/ZRANGE_WITHSCORES.spec.ts b/packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZRANGE_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZRANGE_WITHSCORES.spec.ts
diff --git a/lib/commands/ZRANGE_WITHSCORES.ts b/packages/client/lib/commands/ZRANGE_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZRANGE_WITHSCORES.ts
rename to packages/client/lib/commands/ZRANGE_WITHSCORES.ts
diff --git a/lib/commands/ZRANK.spec.ts b/packages/client/lib/commands/ZRANK.spec.ts
similarity index 100%
rename from lib/commands/ZRANK.spec.ts
rename to packages/client/lib/commands/ZRANK.spec.ts
diff --git a/lib/commands/ZRANK.ts b/packages/client/lib/commands/ZRANK.ts
similarity index 100%
rename from lib/commands/ZRANK.ts
rename to packages/client/lib/commands/ZRANK.ts
diff --git a/lib/commands/ZREM.spec.ts b/packages/client/lib/commands/ZREM.spec.ts
similarity index 100%
rename from lib/commands/ZREM.spec.ts
rename to packages/client/lib/commands/ZREM.spec.ts
diff --git a/lib/commands/ZREM.ts b/packages/client/lib/commands/ZREM.ts
similarity index 100%
rename from lib/commands/ZREM.ts
rename to packages/client/lib/commands/ZREM.ts
diff --git a/lib/commands/ZREMRANGEBYLEX.spec.ts b/packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYLEX.spec.ts
rename to packages/client/lib/commands/ZREMRANGEBYLEX.spec.ts
diff --git a/lib/commands/ZREMRANGEBYLEX.ts b/packages/client/lib/commands/ZREMRANGEBYLEX.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYLEX.ts
rename to packages/client/lib/commands/ZREMRANGEBYLEX.ts
diff --git a/lib/commands/ZREMRANGEBYRANK.spec.ts b/packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYRANK.spec.ts
rename to packages/client/lib/commands/ZREMRANGEBYRANK.spec.ts
diff --git a/lib/commands/ZREMRANGEBYRANK.ts b/packages/client/lib/commands/ZREMRANGEBYRANK.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYRANK.ts
rename to packages/client/lib/commands/ZREMRANGEBYRANK.ts
diff --git a/lib/commands/ZREMRANGEBYSCORE.spec.ts b/packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYSCORE.spec.ts
rename to packages/client/lib/commands/ZREMRANGEBYSCORE.spec.ts
diff --git a/lib/commands/ZREMRANGEBYSCORE.ts b/packages/client/lib/commands/ZREMRANGEBYSCORE.ts
similarity index 100%
rename from lib/commands/ZREMRANGEBYSCORE.ts
rename to packages/client/lib/commands/ZREMRANGEBYSCORE.ts
diff --git a/lib/commands/ZREVRANK.spec.ts b/packages/client/lib/commands/ZREVRANK.spec.ts
similarity index 100%
rename from lib/commands/ZREVRANK.spec.ts
rename to packages/client/lib/commands/ZREVRANK.spec.ts
diff --git a/lib/commands/ZREVRANK.ts b/packages/client/lib/commands/ZREVRANK.ts
similarity index 100%
rename from lib/commands/ZREVRANK.ts
rename to packages/client/lib/commands/ZREVRANK.ts
diff --git a/lib/commands/ZSCAN.spec.ts b/packages/client/lib/commands/ZSCAN.spec.ts
similarity index 100%
rename from lib/commands/ZSCAN.spec.ts
rename to packages/client/lib/commands/ZSCAN.spec.ts
diff --git a/lib/commands/ZSCAN.ts b/packages/client/lib/commands/ZSCAN.ts
similarity index 100%
rename from lib/commands/ZSCAN.ts
rename to packages/client/lib/commands/ZSCAN.ts
diff --git a/lib/commands/ZSCORE.spec.ts b/packages/client/lib/commands/ZSCORE.spec.ts
similarity index 100%
rename from lib/commands/ZSCORE.spec.ts
rename to packages/client/lib/commands/ZSCORE.spec.ts
diff --git a/lib/commands/ZSCORE.ts b/packages/client/lib/commands/ZSCORE.ts
similarity index 100%
rename from lib/commands/ZSCORE.ts
rename to packages/client/lib/commands/ZSCORE.ts
diff --git a/lib/commands/ZUNION.spec.ts b/packages/client/lib/commands/ZUNION.spec.ts
similarity index 100%
rename from lib/commands/ZUNION.spec.ts
rename to packages/client/lib/commands/ZUNION.spec.ts
diff --git a/lib/commands/ZUNION.ts b/packages/client/lib/commands/ZUNION.ts
similarity index 100%
rename from lib/commands/ZUNION.ts
rename to packages/client/lib/commands/ZUNION.ts
diff --git a/lib/commands/ZUNIONSTORE.spec.ts b/packages/client/lib/commands/ZUNIONSTORE.spec.ts
similarity index 100%
rename from lib/commands/ZUNIONSTORE.spec.ts
rename to packages/client/lib/commands/ZUNIONSTORE.spec.ts
diff --git a/lib/commands/ZUNIONSTORE.ts b/packages/client/lib/commands/ZUNIONSTORE.ts
similarity index 100%
rename from lib/commands/ZUNIONSTORE.ts
rename to packages/client/lib/commands/ZUNIONSTORE.ts
diff --git a/lib/commands/ZUNION_WITHSCORES.spec.ts b/packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts
similarity index 100%
rename from lib/commands/ZUNION_WITHSCORES.spec.ts
rename to packages/client/lib/commands/ZUNION_WITHSCORES.spec.ts
diff --git a/lib/commands/ZUNION_WITHSCORES.ts b/packages/client/lib/commands/ZUNION_WITHSCORES.ts
similarity index 100%
rename from lib/commands/ZUNION_WITHSCORES.ts
rename to packages/client/lib/commands/ZUNION_WITHSCORES.ts
diff --git a/lib/commands/generic-transformers.spec.ts b/packages/client/lib/commands/generic-transformers.spec.ts
similarity index 100%
rename from lib/commands/generic-transformers.spec.ts
rename to packages/client/lib/commands/generic-transformers.spec.ts
diff --git a/lib/commands/generic-transformers.ts b/packages/client/lib/commands/generic-transformers.ts
similarity index 100%
rename from lib/commands/generic-transformers.ts
rename to packages/client/lib/commands/generic-transformers.ts
diff --git a/lib/commands/index.ts b/packages/client/lib/commands/index.ts
similarity index 100%
rename from lib/commands/index.ts
rename to packages/client/lib/commands/index.ts
diff --git a/lib/errors.ts b/packages/client/lib/errors.ts
similarity index 100%
rename from lib/errors.ts
rename to packages/client/lib/errors.ts
diff --git a/lib/lua-script.ts b/packages/client/lib/lua-script.ts
similarity index 100%
rename from lib/lua-script.ts
rename to packages/client/lib/lua-script.ts
diff --git a/lib/multi-command.spec.ts b/packages/client/lib/multi-command.spec.ts
similarity index 100%
rename from lib/multi-command.spec.ts
rename to packages/client/lib/multi-command.spec.ts
diff --git a/lib/multi-command.ts b/packages/client/lib/multi-command.ts
similarity index 100%
rename from lib/multi-command.ts
rename to packages/client/lib/multi-command.ts
diff --git a/lib/test-utils/index.ts b/packages/client/lib/test-utils.ts
similarity index 93%
rename from lib/test-utils/index.ts
rename to packages/client/lib/test-utils.ts
index 69bfc440c9..85057da841 100644
--- a/lib/test-utils/index.ts
+++ b/packages/client/lib/test-utils.ts
@@ -1,6 +1,6 @@
-import TestUtils from './test-utils';
+import TestUtils from '@redis/test-utils';
import { SinonSpy } from 'sinon';
-import { promiseTimeout } from '../utils';
+import { promiseTimeout } from './utils';
export default new TestUtils({
defaultDockerVersion: '6.2',
diff --git a/lib/ts-declarations/cluster-key-slot.d.ts b/packages/client/lib/ts-declarations/cluster-key-slot.d.ts
similarity index 100%
rename from lib/ts-declarations/cluster-key-slot.d.ts
rename to packages/client/lib/ts-declarations/cluster-key-slot.d.ts
diff --git a/lib/ts-declarations/redis-parser.d.ts b/packages/client/lib/ts-declarations/redis-parser.d.ts
similarity index 100%
rename from lib/ts-declarations/redis-parser.d.ts
rename to packages/client/lib/ts-declarations/redis-parser.d.ts
diff --git a/lib/utils.ts b/packages/client/lib/utils.ts
similarity index 100%
rename from lib/utils.ts
rename to packages/client/lib/utils.ts
diff --git a/packages/client/package.json b/packages/client/package.json
new file mode 100644
index 0000000000..30be25d26a
--- /dev/null
+++ b/packages/client/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "@redis/client",
+ "version": "4.0.0-rc.3",
+ "license": "MIT",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "test": "nyc -r text-summary -r html mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'",
+ "build": "tsc",
+ "lint": "eslint ./*.ts ./lib/**/*.ts",
+ "documentation": "typedoc"
+ },
+ "dependencies": {
+ "cluster-key-slot": "1.1.0",
+ "generic-pool": "3.8.2",
+ "redis-parser": "3.0.0",
+ "yallist": "4.0.0"
+ },
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "@types/sinon": "^10.0.6",
+ "@types/yallist": "^4.0.1",
+ "@typescript-eslint/eslint-plugin": "^5.2.0",
+ "@typescript-eslint/parser": "^5.2.0",
+ "eslint": "^8.1.0",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "sinon": "^11.1.2",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typedoc": "^0.22.7",
+ "typedoc-github-wiki-theme": "^0.6.0",
+ "typedoc-plugin-markdown": "^3.11.3",
+ "typescript": "^4.4.4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/redis/node-redis.git"
+ },
+ "bugs": {
+ "url": "https://github.com/redis/node-redis/issues"
+ },
+ "homepage": "https://github.com/redis/node-redis"
+}
diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json
new file mode 100644
index 0000000000..1700c9097b
--- /dev/null
+++ b/packages/client/tsconfig.json
@@ -0,0 +1,27 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist"
+ },
+ "include": [
+ "./index.ts",
+ "./lib/**/*.ts"
+ ],
+ "exclude": [
+ "./lib/test-utils.ts",
+ "./lib/**/*.spec.ts"
+ ],
+ "typedocOptions": {
+ "entryPoints": [
+ "./index.ts",
+ "./lib"
+ ],
+ "entryPointStrategy": "expand",
+ "exclude": [
+ "./lib/ts-declarations",
+ "./lib/test-utils.ts"
+ ],
+ "theme": "./node_modules/typedoc-github-wiki-theme/dist",
+ "out": "documentation"
+ }
+}
diff --git a/packages/json/.nycrc.json b/packages/json/.nycrc.json
new file mode 100644
index 0000000000..b4e671e178
--- /dev/null
+++ b/packages/json/.nycrc.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@istanbuljs/nyc-config-typescript",
+ "exclude": ["**/*.spec.ts", "lib/test-utils.ts"]
+}
diff --git a/packages/json/lib/commands/ARRAPPEND.spec.ts b/packages/json/lib/commands/ARRAPPEND.spec.ts
new file mode 100644
index 0000000000..ab53837a00
--- /dev/null
+++ b/packages/json/lib/commands/ARRAPPEND.spec.ts
@@ -0,0 +1,30 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRAPPEND';
+
+describe('ARRAPPEND', () => {
+ describe('transformArguments', () => {
+ it('single JSON', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 1),
+ ['JSON.ARRAPPEND', 'key', '$', '1']
+ );
+ });
+
+ it('multiple JSONs', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 1, 2),
+ ['JSON.ARRAPPEND', 'key', '$', '1', '2']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrAppend', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrAppend('key', '$', 1),
+ [1]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRAPPEND.ts b/packages/json/lib/commands/ARRAPPEND.ts
new file mode 100644
index 0000000000..2935d19299
--- /dev/null
+++ b/packages/json/lib/commands/ARRAPPEND.ts
@@ -0,0 +1,15 @@
+import { RedisJSON, transformRedisJsonArgument } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path: string, ...jsons: Array): Array {
+ const args = ['JSON.ARRAPPEND', key, path];
+
+ for (const json of jsons) {
+ args.push(transformRedisJsonArgument(json));
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/ARRINDEX.spec.ts b/packages/json/lib/commands/ARRINDEX.spec.ts
new file mode 100644
index 0000000000..7a47d67126
--- /dev/null
+++ b/packages/json/lib/commands/ARRINDEX.spec.ts
@@ -0,0 +1,37 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRINDEX';
+
+describe('ARRINDEX', () => {
+ describe('transformArguments', () => {
+ it('simple', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json'),
+ ['JSON.ARRINDEX', 'key', '$', '"json"']
+ );
+ });
+
+ it('with start', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json', 1),
+ ['JSON.ARRINDEX', 'key', '$', '"json"', '1']
+ );
+ });
+
+ it('with start, end', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json', 1, 2),
+ ['JSON.ARRINDEX', 'key', '$', '"json"', '1', '2']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrIndex', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrIndex('key', '$', 'json'),
+ [-1]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRINDEX.ts b/packages/json/lib/commands/ARRINDEX.ts
new file mode 100644
index 0000000000..5860b59cb3
--- /dev/null
+++ b/packages/json/lib/commands/ARRINDEX.ts
@@ -0,0 +1,21 @@
+import { RedisJSON, transformRedisJsonArgument } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+export const IS_READ_ONLY = true;
+
+export function transformArguments(key: string, path: string, json: RedisJSON, start?: number, stop?: number): Array {
+ const args = ['JSON.ARRINDEX', key, path, transformRedisJsonArgument(json)];
+
+ if (start !== undefined && start !== null) {
+ args.push(start.toString());
+
+ if (stop !== undefined && stop !== null) {
+ args.push(stop.toString());
+ }
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/ARRINSERT.spec.ts b/packages/json/lib/commands/ARRINSERT.spec.ts
new file mode 100644
index 0000000000..4b9d58b2ca
--- /dev/null
+++ b/packages/json/lib/commands/ARRINSERT.spec.ts
@@ -0,0 +1,30 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRINSERT';
+
+describe('ARRINSERT', () => {
+ describe('transformArguments', () => {
+ it('single JSON', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 0, 'json'),
+ ['JSON.ARRINSERT', 'key', '$', '0', '"json"']
+ );
+ });
+
+ it('multiple JSONs', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 0, '1', '2'),
+ ['JSON.ARRINSERT', 'key', '$', '0', '"1"', '"2"']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrInsert', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrInsert('key', '$', 0, 'json'),
+ [1]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRINSERT.ts b/packages/json/lib/commands/ARRINSERT.ts
new file mode 100644
index 0000000000..8585765701
--- /dev/null
+++ b/packages/json/lib/commands/ARRINSERT.ts
@@ -0,0 +1,15 @@
+import { RedisJSON, transformRedisJsonArgument } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path: string, index: number, ...jsons: Array): Array {
+ const args = ['JSON.ARRINSERT', key, path, index.toString()];
+
+ for (const json of jsons) {
+ args.push(transformRedisJsonArgument(json));
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/ARRLEN.spec.ts b/packages/json/lib/commands/ARRLEN.spec.ts
new file mode 100644
index 0000000000..f0a3ec40a4
--- /dev/null
+++ b/packages/json/lib/commands/ARRLEN.spec.ts
@@ -0,0 +1,30 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRLEN';
+
+describe('ARRLEN', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.ARRLEN', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.ARRLEN', 'key', '$']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrLen', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrLen('key', '$'),
+ [0]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRLEN.ts b/packages/json/lib/commands/ARRLEN.ts
new file mode 100644
index 0000000000..818397b7f8
--- /dev/null
+++ b/packages/json/lib/commands/ARRLEN.ts
@@ -0,0 +1,15 @@
+export const FIRST_KEY_INDEX = 1;
+
+export const IS_READ_ONLY = true;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.ARRLEN', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/ARRPOP.spec.ts b/packages/json/lib/commands/ARRPOP.spec.ts
new file mode 100644
index 0000000000..a80b8c3cbc
--- /dev/null
+++ b/packages/json/lib/commands/ARRPOP.spec.ts
@@ -0,0 +1,37 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRPOP';
+
+describe('ARRPOP', () => {
+ describe('transformArguments', () => {
+ it('key', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.ARRPOP', 'key']
+ );
+ });
+
+ it('key, path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.ARRPOP', 'key', '$']
+ );
+ });
+
+ it('key, path, index', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 0),
+ ['JSON.ARRPOP', 'key', '$', '0']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrPop', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrPop('key', '$'),
+ [null]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRPOP.ts b/packages/json/lib/commands/ARRPOP.ts
new file mode 100644
index 0000000000..5d8785a8d9
--- /dev/null
+++ b/packages/json/lib/commands/ARRPOP.ts
@@ -0,0 +1,17 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string, index?: number): Array {
+ const args = ['JSON.ARRPOP', key];
+
+ if (path) {
+ args.push(path);
+
+ if (index !== undefined && index !== null) {
+ args.push(index.toString());
+ }
+ }
+
+ return args;
+}
+
+export { transformRedisJsonNullArrayReply as transformReply } from '.';
diff --git a/packages/json/lib/commands/ARRTRIM.spec.ts b/packages/json/lib/commands/ARRTRIM.spec.ts
new file mode 100644
index 0000000000..c254e1b6a0
--- /dev/null
+++ b/packages/json/lib/commands/ARRTRIM.spec.ts
@@ -0,0 +1,21 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './ARRTRIM';
+
+describe('ARRTRIM', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 0, 1),
+ ['JSON.ARRTRIM', 'key', '$', '0', '1']
+ );
+ });
+
+ testUtils.testWithClient('client.json.arrTrim', async client => {
+ await client.json.set('key', '$', []);
+
+ assert.deepEqual(
+ await client.json.arrTrim('key', '$', 0, 1),
+ [0]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/ARRTRIM.ts b/packages/json/lib/commands/ARRTRIM.ts
new file mode 100644
index 0000000000..2de444eeeb
--- /dev/null
+++ b/packages/json/lib/commands/ARRTRIM.ts
@@ -0,0 +1,7 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path: string, start: number, stop: number): Array {
+ return ['JSON.ARRTRIM', key, path, start.toString(), stop.toString()];
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/DEBUG_MEMORY.spec.ts b/packages/json/lib/commands/DEBUG_MEMORY.spec.ts
new file mode 100644
index 0000000000..468c994f2f
--- /dev/null
+++ b/packages/json/lib/commands/DEBUG_MEMORY.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './DEBUG_MEMORY';
+
+describe('DEBUG MEMORY', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.DEBUG', 'MEMORY', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.DEBUG', 'MEMORY', 'key', '$']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.arrTrim', async client => {
+ assert.deepEqual(
+ await client.json.debugMemory('key', '$'),
+ []
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/DEBUG_MEMORY.ts b/packages/json/lib/commands/DEBUG_MEMORY.ts
new file mode 100644
index 0000000000..da60b1d952
--- /dev/null
+++ b/packages/json/lib/commands/DEBUG_MEMORY.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 2;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.DEBUG', 'MEMORY', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number;
diff --git a/packages/json/lib/commands/DEL.spec.ts b/packages/json/lib/commands/DEL.spec.ts
new file mode 100644
index 0000000000..a957b9584a
--- /dev/null
+++ b/packages/json/lib/commands/DEL.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './DEL';
+
+describe('DEL', () => {
+ describe('transformArguments', () => {
+ it('key', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.DEL', 'key']
+ );
+ });
+
+ it('key, path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$.path'),
+ ['JSON.DEL', 'key', '$.path']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.del', async client => {
+ assert.deepEqual(
+ await client.json.del('key'),
+ 0
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/DEL.ts b/packages/json/lib/commands/DEL.ts
new file mode 100644
index 0000000000..090d4dbe85
--- /dev/null
+++ b/packages/json/lib/commands/DEL.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.DEL', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number;
diff --git a/packages/json/lib/commands/FORGET.spec.ts b/packages/json/lib/commands/FORGET.spec.ts
new file mode 100644
index 0000000000..923bb997fc
--- /dev/null
+++ b/packages/json/lib/commands/FORGET.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './FORGET';
+
+describe('FORGET', () => {
+ describe('transformArguments', () => {
+ it('key', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.FORGET', 'key']
+ );
+ });
+
+ it('key, path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$.path'),
+ ['JSON.FORGET', 'key', '$.path']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.forget', async client => {
+ assert.deepEqual(
+ await client.json.forget('key'),
+ 0
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/FORGET.ts b/packages/json/lib/commands/FORGET.ts
new file mode 100644
index 0000000000..cb2df3d605
--- /dev/null
+++ b/packages/json/lib/commands/FORGET.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.FORGET', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number;
diff --git a/packages/json/lib/commands/GET.spec.ts b/packages/json/lib/commands/GET.spec.ts
new file mode 100644
index 0000000000..ed831689a9
--- /dev/null
+++ b/packages/json/lib/commands/GET.spec.ts
@@ -0,0 +1,78 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './GET';
+
+describe('GET', () => {
+ describe('transformArguments', () => {
+ describe('path', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('key', { path: '$' }),
+ ['JSON.GET', 'key', '$']
+ );
+ });
+
+ it('array', () => {
+ assert.deepEqual(
+ transformArguments('key', { path: ['$.1', '$.2'] }),
+ ['JSON.GET', 'key', '$.1', '$.2']
+ );
+ });
+ });
+
+ it('key', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.GET', 'key']
+ );
+ });
+
+ it('INDENT', () => {
+ assert.deepEqual(
+ transformArguments('key', { INDENT: 'indent' }),
+ ['JSON.GET', 'key', 'INDENT', 'indent']
+ );
+ });
+
+ it('NEWLINE', () => {
+ assert.deepEqual(
+ transformArguments('key', { NEWLINE: 'newline' }),
+ ['JSON.GET', 'key', 'NEWLINE', 'newline']
+ );
+ });
+
+ it('SPACE', () => {
+ assert.deepEqual(
+ transformArguments('key', { SPACE: 'space' }),
+ ['JSON.GET', 'key', 'SPACE', 'space']
+ );
+ });
+
+ it('NOESCAPE', () => {
+ assert.deepEqual(
+ transformArguments('key', { NOESCAPE: true }),
+ ['JSON.GET', 'key', 'NOESCAPE']
+ );
+ });
+
+ it('INDENT, NEWLINE, SPACE, NOESCAPE, path', () => {
+ assert.deepEqual(
+ transformArguments('key', {
+ path: '$.path',
+ INDENT: 'indent',
+ NEWLINE: 'newline',
+ SPACE: 'space',
+ NOESCAPE: true
+ }),
+ ['JSON.GET', 'key', '$.path', 'INDENT', 'indent', 'NEWLINE', 'newline', 'SPACE', 'space', 'NOESCAPE']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.get', async client => {
+ assert.equal(
+ await client.json.get('key'),
+ null
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/GET.ts b/packages/json/lib/commands/GET.ts
new file mode 100644
index 0000000000..8b69dc8053
--- /dev/null
+++ b/packages/json/lib/commands/GET.ts
@@ -0,0 +1,41 @@
+import { pushVerdictArguments } from '@redis/client/lib/commands/generic-transformers';
+
+export const FIRST_KEY_INDEX = 1;
+
+export const IS_READ_ONLY = true;
+
+interface GetOptions {
+ path?: string | Array;
+ INDENT?: string;
+ NEWLINE?: string;
+ SPACE?: string;
+ NOESCAPE?: true;
+}
+
+export function transformArguments(key: string, options?: GetOptions): Array {
+ const args = ['JSON.GET', key];
+
+ if (options?.path) {
+ pushVerdictArguments(args, options.path);
+ }
+
+ if (options?.INDENT) {
+ args.push('INDENT', options.INDENT);
+ }
+
+ if (options?.NEWLINE) {
+ args.push('NEWLINE', options.NEWLINE);
+ }
+
+ if (options?.SPACE) {
+ args.push('SPACE', options.SPACE);
+ }
+
+ if (options?.NOESCAPE) {
+ args.push('NOESCAPE');
+ }
+
+ return args;
+}
+
+export { transformRedisJsonNullReply as transformReply } from '.';
diff --git a/packages/json/lib/commands/MGET.spec.ts b/packages/json/lib/commands/MGET.spec.ts
new file mode 100644
index 0000000000..456e160dd5
--- /dev/null
+++ b/packages/json/lib/commands/MGET.spec.ts
@@ -0,0 +1,19 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './MGET';
+
+describe('MGET', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments(['1', '2'], '$'),
+ ['JSON.MGET', '1', '2', '$']
+ );
+ });
+
+ testUtils.testWithClient('client.json.mGet', async client => {
+ assert.deepEqual(
+ await client.json.mGet(['1', '2'], '$'),
+ [null, null]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/MGET.ts b/packages/json/lib/commands/MGET.ts
new file mode 100644
index 0000000000..582b73bf85
--- /dev/null
+++ b/packages/json/lib/commands/MGET.ts
@@ -0,0 +1,15 @@
+import { RedisJSON, transformRedisJsonNullReply } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(keys: Array, path: string): Array {
+ return [
+ 'JSON.MGET',
+ ...keys,
+ path
+ ];
+}
+
+export function transformReply(reply: Array): Array {
+ return reply.map(transformRedisJsonNullReply);
+}
diff --git a/packages/json/lib/commands/NUMINCRBY.spec.ts b/packages/json/lib/commands/NUMINCRBY.spec.ts
new file mode 100644
index 0000000000..56dede68bd
--- /dev/null
+++ b/packages/json/lib/commands/NUMINCRBY.spec.ts
@@ -0,0 +1,21 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './NUMINCRBY';
+
+describe('NUMINCRBY', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 1),
+ ['JSON.NUMINCRBY', 'key', '$', '1']
+ );
+ });
+
+ testUtils.testWithClient('client.json.numIncrBy', async client => {
+ await client.json.set('key', '$', 0);
+
+ assert.deepEqual(
+ await client.json.numIncrBy('key', '$', 1),
+ [1]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/NUMINCRBY.ts b/packages/json/lib/commands/NUMINCRBY.ts
new file mode 100644
index 0000000000..e3d8887ea3
--- /dev/null
+++ b/packages/json/lib/commands/NUMINCRBY.ts
@@ -0,0 +1,7 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path: string, by: number): Array {
+ return ['JSON.NUMINCRBY', key, path, by.toString()];
+}
+
+export { transformNumbersReply as transformReply } from '.';
diff --git a/packages/json/lib/commands/NUMMULTBY.spec.ts b/packages/json/lib/commands/NUMMULTBY.spec.ts
new file mode 100644
index 0000000000..3e2581a3cd
--- /dev/null
+++ b/packages/json/lib/commands/NUMMULTBY.spec.ts
@@ -0,0 +1,21 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './NUMMULTBY';
+
+describe('NUMMULTBY', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 2),
+ ['JSON.NUMMULTBY', 'key', '$', '2']
+ );
+ });
+
+ testUtils.testWithClient('client.json.numMultBy', async client => {
+ await client.json.set('key', '$', 1);
+
+ assert.deepEqual(
+ await client.json.numMultBy('key', '$', 2),
+ [2]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/NUMMULTBY.ts b/packages/json/lib/commands/NUMMULTBY.ts
new file mode 100644
index 0000000000..2082916619
--- /dev/null
+++ b/packages/json/lib/commands/NUMMULTBY.ts
@@ -0,0 +1,7 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path: string, by: number): Array {
+ return ['JSON.NUMMULTBY', key, path, by.toString()];
+}
+
+export { transformNumbersReply as transformReply } from '.';
diff --git a/packages/json/lib/commands/OBJKEYS.spec.ts b/packages/json/lib/commands/OBJKEYS.spec.ts
new file mode 100644
index 0000000000..6288c11239
--- /dev/null
+++ b/packages/json/lib/commands/OBJKEYS.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './OBJKEYS';
+
+describe('OBJKEYS', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.OBJKEYS', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.OBJKEYS', 'key', '$']
+ );
+ });
+ });
+
+ // testUtils.testWithClient('client.json.objKeys', async client => {
+ // assert.deepEqual(
+ // await client.json.objKeys('key', '$'),
+ // [null]
+ // );
+ // }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/OBJKEYS.ts b/packages/json/lib/commands/OBJKEYS.ts
new file mode 100644
index 0000000000..a9465c9160
--- /dev/null
+++ b/packages/json/lib/commands/OBJKEYS.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.OBJKEYS', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): Array | null | Array | null>;
diff --git a/packages/json/lib/commands/OBJLEN.spec.ts b/packages/json/lib/commands/OBJLEN.spec.ts
new file mode 100644
index 0000000000..35b6589c87
--- /dev/null
+++ b/packages/json/lib/commands/OBJLEN.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './OBJLEN';
+
+describe('OBJLEN', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.OBJLEN', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.OBJLEN', 'key', '$']
+ );
+ });
+ });
+
+ // testUtils.testWithClient('client.json.objLen', async client => {
+ // assert.equal(
+ // await client.json.objLen('key', '$'),
+ // [null]
+ // );
+ // }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/OBJLEN.ts b/packages/json/lib/commands/OBJLEN.ts
new file mode 100644
index 0000000000..aa800e97f7
--- /dev/null
+++ b/packages/json/lib/commands/OBJLEN.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.OBJLEN', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | null | Array;
diff --git a/packages/json/lib/commands/RESP.spec.ts b/packages/json/lib/commands/RESP.spec.ts
new file mode 100644
index 0000000000..8b70962d1c
--- /dev/null
+++ b/packages/json/lib/commands/RESP.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './RESP';
+
+describe('RESP', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.RESP', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.RESP', 'key', '$']
+ );
+ });
+ });
+
+ // testUtils.testWithClient('client.json.resp', async client => {
+ // assert.deepEqual(
+ // await client.json.resp('key', '$'),
+ // [null]
+ // );
+ // }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/RESP.ts b/packages/json/lib/commands/RESP.ts
new file mode 100644
index 0000000000..2b56bf1f05
--- /dev/null
+++ b/packages/json/lib/commands/RESP.ts
@@ -0,0 +1,15 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.RESP', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+type RESPReply = Array;
+
+export declare function transfromReply(): RESPReply;
diff --git a/packages/json/lib/commands/SET.spec.ts b/packages/json/lib/commands/SET.spec.ts
new file mode 100644
index 0000000000..8f8586a204
--- /dev/null
+++ b/packages/json/lib/commands/SET.spec.ts
@@ -0,0 +1,35 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SET';
+
+describe('SET', () => {
+ describe('transformArguments', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json'),
+ ['JSON.SET', 'key', '$', '"json"']
+ );
+ });
+
+ it('NX', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json', { NX: true }),
+ ['JSON.SET', 'key', '$', '"json"', 'NX']
+ );
+ });
+
+ it('XX', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'json', { XX: true }),
+ ['JSON.SET', 'key', '$', '"json"', 'XX']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.mGet', async client => {
+ assert.equal(
+ await client.json.set('key', '$', 'json'),
+ 'OK'
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/SET.ts b/packages/json/lib/commands/SET.ts
new file mode 100644
index 0000000000..f50a42bf5d
--- /dev/null
+++ b/packages/json/lib/commands/SET.ts
@@ -0,0 +1,25 @@
+import { RedisJSON, transformRedisJsonArgument } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+interface NX {
+ NX: true;
+}
+
+interface XX {
+ XX: true;
+}
+
+export function transformArguments(key: string, path: string, json: RedisJSON, options?: NX | XX): Array {
+ const args = ['JSON.SET', key, path, transformRedisJsonArgument(json)];
+
+ if ((options)?.NX) {
+ args.push('NX');
+ } else if ((options)?.XX) {
+ args.push('XX');
+ }
+
+ return args;
+}
+
+export declare function transformReply(): 'OK' | null;
diff --git a/packages/json/lib/commands/STRAPPEND.spec.ts b/packages/json/lib/commands/STRAPPEND.spec.ts
new file mode 100644
index 0000000000..a37eaa1d91
--- /dev/null
+++ b/packages/json/lib/commands/STRAPPEND.spec.ts
@@ -0,0 +1,30 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './STRAPPEND';
+
+describe('STRAPPEND', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key', 'append'),
+ ['JSON.STRAPPEND', 'key', '"append"']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$', 'append'),
+ ['JSON.STRAPPEND', 'key', '$', '"append"']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.strAppend', async client => {
+ await client.json.set('key', '$', '');
+
+ assert.deepEqual(
+ await client.json.strAppend('key', '$', 'append'),
+ [6]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/STRAPPEND.ts b/packages/json/lib/commands/STRAPPEND.ts
new file mode 100644
index 0000000000..eea384c93f
--- /dev/null
+++ b/packages/json/lib/commands/STRAPPEND.ts
@@ -0,0 +1,21 @@
+import { transformRedisJsonArgument } from '.';
+
+export const FIRST_KEY_INDEX = 1;
+
+type AppendArguments = [key: string, append: string];
+
+type AppendWithPathArguments = [key: string, path: string, append: string];
+
+export function transformArguments(...[key, pathOrAppend, append]: AppendArguments | AppendWithPathArguments): Array {
+ const args = ['JSON.STRAPPEND', key];
+
+ if (append !== undefined && append !== null) {
+ args.push(pathOrAppend, transformRedisJsonArgument(append));
+ } else {
+ args.push(transformRedisJsonArgument(pathOrAppend));
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number | Array;
diff --git a/packages/json/lib/commands/STRLEN.spec.ts b/packages/json/lib/commands/STRLEN.spec.ts
new file mode 100644
index 0000000000..cf163d3c19
--- /dev/null
+++ b/packages/json/lib/commands/STRLEN.spec.ts
@@ -0,0 +1,30 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './STRLEN';
+
+describe('STRLEN', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.STRLEN', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.STRLEN', 'key', '$']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.json.strLen', async client => {
+ await client.json.set('key', '$', '');
+
+ assert.deepEqual(
+ await client.json.strLen('key', '$'),
+ [0]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/STRLEN.ts b/packages/json/lib/commands/STRLEN.ts
new file mode 100644
index 0000000000..93f5d563ba
--- /dev/null
+++ b/packages/json/lib/commands/STRLEN.ts
@@ -0,0 +1,15 @@
+export const FIRST_KEY_INDEX = 1;
+
+export const IS_READ_ONLY = true;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.STRLEN', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number;
diff --git a/packages/json/lib/commands/TYPE.spec.ts b/packages/json/lib/commands/TYPE.spec.ts
new file mode 100644
index 0000000000..5cecfb827a
--- /dev/null
+++ b/packages/json/lib/commands/TYPE.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './TYPE';
+
+describe('TYPE', () => {
+ describe('transformArguments', () => {
+ it('without path', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['JSON.TYPE', 'key']
+ );
+ });
+
+ it('with path', () => {
+ assert.deepEqual(
+ transformArguments('key', '$'),
+ ['JSON.TYPE', 'key', '$']
+ );
+ });
+ });
+
+ // testUtils.testWithClient('client.json.type', async client => {
+ // assert.deepEqual(
+ // await client.json.type('key', '$'),
+ // [null]
+ // );
+ // }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/json/lib/commands/TYPE.ts b/packages/json/lib/commands/TYPE.ts
new file mode 100644
index 0000000000..7fd55f625d
--- /dev/null
+++ b/packages/json/lib/commands/TYPE.ts
@@ -0,0 +1,13 @@
+export const FIRST_KEY_INDEX = 1;
+
+export function transformArguments(key: string, path?: string): Array {
+ const args = ['JSON.TYPE', key];
+
+ if (path) {
+ args.push(path);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): string | null | Array;
diff --git a/packages/json/lib/commands/index.ts b/packages/json/lib/commands/index.ts
new file mode 100644
index 0000000000..91b4f7dc4b
--- /dev/null
+++ b/packages/json/lib/commands/index.ts
@@ -0,0 +1,94 @@
+import * as ARRAPPEND from './ARRAPPEND';
+import * as ARRINDEX from './ARRINDEX';
+import * as ARRINSERT from './ARRINSERT';
+import * as ARRLEN from './ARRLEN';
+import * as ARRPOP from './ARRPOP';
+import * as ARRTRIM from './ARRTRIM';
+import * as DEBUG_MEMORY from './DEBUG_MEMORY';
+import * as DEL from './DEL';
+import * as FORGET from './FORGET';
+import * as GET from './GET';
+import * as MGET from './MGET';
+import * as NUMINCRBY from './NUMINCRBY';
+import * as NUMMULTBY from './NUMMULTBY';
+import * as OBJKEYS from './OBJKEYS';
+import * as OBJLEN from './OBJLEN';
+import * as RESP from './RESP';
+import * as SET from './SET';
+import * as STRAPPEND from './STRAPPEND';
+import * as STRLEN from './STRLEN';
+import * as TYPE from './TYPE';
+
+export default {
+ ARRAPPEND,
+ arrAppend: ARRAPPEND,
+ ARRINDEX,
+ arrIndex: ARRINDEX,
+ ARRINSERT,
+ arrInsert: ARRINSERT,
+ ARRLEN,
+ arrLen: ARRLEN,
+ ARRPOP,
+ arrPop: ARRPOP,
+ ARRTRIM,
+ arrTrim: ARRTRIM,
+ DEBUG_MEMORY,
+ debugMemory: DEBUG_MEMORY,
+ DEL,
+ del: DEL,
+ FORGET,
+ forget: FORGET,
+ GET,
+ get: GET,
+ MGET,
+ mGet: MGET,
+ NUMINCRBY,
+ numIncrBy: NUMINCRBY,
+ NUMMULTBY,
+ numMultBy: NUMMULTBY,
+ OBJKEYS,
+ objKeys: OBJKEYS,
+ OBJLEN,
+ objLen: OBJLEN,
+ RESP,
+ resp: RESP,
+ SET,
+ set: SET,
+ STRAPPEND,
+ strAppend: STRAPPEND,
+ STRLEN,
+ strLen: STRLEN,
+ TYPE,
+ type: TYPE
+};
+
+// using two "objects" and not `Record` cause of:
+// https://github.com/microsoft/TypeScript/issues/14174
+export type RedisJSON = null | boolean | number | string | Date | Array | { [key: string]: RedisJSON } | { [key: number]: RedisJSON };
+
+export function transformRedisJsonArgument(json: RedisJSON): string {
+ return JSON.stringify(json);
+}
+
+export function transformRedisJsonReply(json: string): RedisJSON {
+ return JSON.parse(json);
+}
+
+export function transformRedisJsonArrayReply(jsons: Array): Array {
+ return jsons.map(transformRedisJsonReply)
+}
+
+export function transformRedisJsonNullReply(json: string | null): RedisJSON | null {
+ if (json === null) return null;
+
+ return transformRedisJsonReply(json);
+}
+
+
+export function transformRedisJsonNullArrayReply(jsons: Array): Array {
+ return jsons.map(transformRedisJsonNullReply);
+}
+
+export function transformNumbersReply(reply: string): number | Array {
+ return JSON.parse(reply);
+}
diff --git a/packages/json/lib/index.ts b/packages/json/lib/index.ts
new file mode 100644
index 0000000000..bc0e103e8c
--- /dev/null
+++ b/packages/json/lib/index.ts
@@ -0,0 +1 @@
+export { default } from './commands';
diff --git a/packages/json/lib/test-utils.ts b/packages/json/lib/test-utils.ts
new file mode 100644
index 0000000000..140e781d91
--- /dev/null
+++ b/packages/json/lib/test-utils.ts
@@ -0,0 +1,21 @@
+import TestUtils from '@redis/test-utils';
+import RedisJSON from '.';
+
+export default new TestUtils({
+ dockerImageName: 'redislabs/rejson',
+ dockerImageVersionArgument: 'rejson-version',
+ defaultDockerVersion: '2.0.2'
+});
+
+export const GLOBAL = {
+ SERVERS: {
+ OPEN: {
+ serverArguments: ['--loadmodule /usr/lib/redis/modules/rejson.so'],
+ clientOptions: {
+ modules: {
+ json: RedisJSON
+ }
+ }
+ }
+ }
+};
diff --git a/packages/json/package.json b/packages/json/package.json
new file mode 100644
index 0000000000..ebd7f8f76f
--- /dev/null
+++ b/packages/json/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "@redis/json",
+ "version": "1.0.0-rc.0",
+ "license": "MIT",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "test": "nyc -r text-summary -r html mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'",
+ "build": "tsc"
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ },
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
+}
diff --git a/packages/json/tsconfig.json b/packages/json/tsconfig.json
new file mode 100644
index 0000000000..fdb86c004c
--- /dev/null
+++ b/packages/json/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "./dist"
+ },
+ "include": [
+ "./lib/**/*.ts"
+ ]
+}
diff --git a/packages/search/.nycrc.json b/packages/search/.nycrc.json
new file mode 100644
index 0000000000..b4e671e178
--- /dev/null
+++ b/packages/search/.nycrc.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@istanbuljs/nyc-config-typescript",
+ "exclude": ["**/*.spec.ts", "lib/test-utils.ts"]
+}
diff --git a/packages/search/lib/commands/AGGREGATE.spec.ts b/packages/search/lib/commands/AGGREGATE.spec.ts
new file mode 100644
index 0000000000..2a6647c97a
--- /dev/null
+++ b/packages/search/lib/commands/AGGREGATE.spec.ts
@@ -0,0 +1,482 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { AggregateGroupByReducers, AggregateSteps, transformArguments } from './AGGREGATE';
+import { SchemaFieldTypes } from './CREATE';
+
+describe('AGGREGATE', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('index', '*'),
+ ['FT.AGGREGATE', 'index', '*']
+ );
+ });
+
+ it('with VERBATIM', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', { VERBATIM: true }),
+ ['FT.AGGREGATE', 'index', '*', 'VERBATIM']
+ );
+ });
+
+ describe('with LOAD', () => {
+ describe('single', () => {
+ describe('without alias', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', { LOAD: '@property' }),
+ ['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
+ );
+ });
+
+ it('{ identifier: string }', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ LOAD: {
+ identifier: '@property'
+ }
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'LOAD', '1', '@property']
+ );
+ });
+ });
+
+ it('with alias', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ LOAD: {
+ identifier: '@property',
+ AS: 'alias'
+ }
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'LOAD', '3', '@property', 'AS', 'alias']
+ );
+ });
+ });
+
+ it('multiple', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', { LOAD: ['@1', '@2'] }),
+ ['FT.AGGREGATE', 'index', '*', 'LOAD', '2', '@1', '@2']
+ );
+ });
+ });
+
+ describe('with STEPS', () => {
+ describe('GROUPBY', () => {
+ describe('COUNT', () => {
+ describe('without properties', () => {
+ it('without alias', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0']
+ );
+ });
+
+ it('with alias', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT,
+ AS: 'count'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT', '0', 'AS', 'count']
+ );
+ });
+ });
+
+ describe('with properties', () => {
+ it('single', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ properties: '@property',
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '1', '@property', 'REDUCE', 'COUNT', '0']
+ );
+ });
+
+ it('multiple', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ properties: ['@1', '@2'],
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '2', '@1', '@2', 'REDUCE', 'COUNT', '0']
+ );
+ });
+ });
+ });
+
+ it('COUNT_DISTINCT', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT_DISTINCT,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCT', '1', '@property']
+ );
+ });
+
+ it('COUNT_DISTINCTISH', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.COUNT_DISTINCTISH,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'COUNT_DISTINCTISH', '1', '@property']
+ );
+ });
+
+ it('SUM', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.SUM,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'SUM', '1', '@property']
+ );
+ });
+
+ it('MIN', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.MIN,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MIN', '1', '@property']
+ );
+ });
+
+ it('MAX', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.MAX,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'MAX', '1', '@property']
+ );
+ });
+
+ it('AVG', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.AVG,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'AVG', '1', '@property']
+ );
+ });
+
+ it('STDDEV', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.STDDEV,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'STDDEV', '1', '@property']
+ );
+ });
+
+ it('QUANTILE', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.QUANTILE,
+ property: '@property',
+ quantile: 0.5
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'QUANTILE', '2', '@property', '0.5']
+ );
+ });
+
+ it('TO_LIST', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.TO_LIST,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'TOLIST', '1', '@property']
+ );
+ });
+
+ describe('FIRST_VALUE', () => {
+ it('simple', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.FIRST_VALUE,
+ property: '@property'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '1', '@property']
+ );
+ });
+
+ describe('with BY', () => {
+ describe('without direction', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.FIRST_VALUE,
+ property: '@property',
+ BY: '@by'
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
+ );
+ });
+
+
+ it('{ property: string }', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.FIRST_VALUE,
+ property: '@property',
+ BY: {
+ property: '@by'
+ }
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '3', '@property', 'BY', '@by']
+ );
+ });
+ });
+
+ it('with direction', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.FIRST_VALUE,
+ property: '@property',
+ BY: {
+ property: '@by',
+ direction: 'ASC'
+ }
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'FIRST_VALUE', '4', '@property', 'BY', '@by', 'ASC']
+ );
+ });
+ });
+ });
+
+ it('RANDOM_SAMPLE', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: {
+ type: AggregateGroupByReducers.RANDOM_SAMPLE,
+ property: '@property',
+ sampleSize: 1
+ }
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'GROUPBY', '0', 'REDUCE', 'RANDOM_SAMPLE', '2', '@property', '1']
+ );
+ });
+ });
+
+ describe('SORTBY', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.SORTBY,
+ BY: '@by'
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.SORTBY,
+ BY: ['@1', '@2']
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'SORTBY', '2', '@1', '@2']
+ );
+ });
+
+ it('with MAX', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.SORTBY,
+ BY: '@by',
+ MAX: 1
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'SORTBY', '1', '@by', 'MAX', '1']
+ );
+ });
+ });
+
+ describe('APPLY', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.APPLY,
+ expression: '@field + 1',
+ AS: 'as'
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'APPLY', '@field + 1', 'AS', 'as']
+ );
+ });
+
+ describe('LIMIT', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.LIMIT,
+ from: 0,
+ size: 1
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'LIMIT', '0', '1']
+ );
+ });
+
+ describe('FILTER', () => {
+ assert.deepEqual(
+ transformArguments('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.FILTER,
+ expression: '@field != ""'
+ }]
+ }),
+ ['FT.AGGREGATE', 'index', '*', 'FILTER', '@field != ""']
+ );
+ });
+ });
+ });
+
+ testUtils.testWithClient('client.ft.aggregate', async client => {
+ await Promise.all([
+ client.ft.create('index', {
+ field: SchemaFieldTypes.NUMERIC
+ }),
+ client.hSet('1', 'field', '1'),
+ client.hSet('2', 'field', '2')
+ ]);
+
+ assert.deepEqual(
+ await client.ft.aggregate('index', '*', {
+ STEPS: [{
+ type: AggregateSteps.GROUPBY,
+ REDUCE: [{
+ type: AggregateGroupByReducers.SUM,
+ property: '@field',
+ AS: 'sum'
+ }, {
+ type: AggregateGroupByReducers.AVG,
+ property: '@field',
+ AS: 'avg'
+ }]
+ }]
+ }),
+ {
+ total: 1,
+ results: [
+ Object.create(null, {
+ sum: {
+ value: '3',
+ configurable: true,
+ enumerable: true
+ },
+ avg: {
+ value: '1.5',
+ configurable: true,
+ enumerable: true
+ }
+ })
+ ]
+ }
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/AGGREGATE.ts b/packages/search/lib/commands/AGGREGATE.ts
new file mode 100644
index 0000000000..affc98b51d
--- /dev/null
+++ b/packages/search/lib/commands/AGGREGATE.ts
@@ -0,0 +1,283 @@
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+import { pushVerdictArgument, transformReplyTuples, TuplesObject } from '@redis/client/dist/lib/commands/generic-transformers';
+import { PropertyName, pushArgumentsWithLength, pushSortByArguments, SortByOptions } from '.';
+
+export enum AggregateSteps {
+ GROUPBY = 'GROUPBY',
+ SORTBY = 'SORTBY',
+ APPLY = 'APPLY',
+ LIMIT = 'LIMIT',
+ FILTER = 'FILTER'
+}
+
+interface AggregateStep {
+ type: T;
+}
+
+export enum AggregateGroupByReducers {
+ COUNT = 'COUNT',
+ COUNT_DISTINCT = 'COUNT_DISTINCT',
+ COUNT_DISTINCTISH = 'COUNT_DISTINCTISH',
+ SUM = 'SUM',
+ MIN = 'MIN',
+ MAX = 'MAX',
+ AVG = 'AVG',
+ STDDEV = 'STDDEV',
+ QUANTILE = 'QUANTILE',
+ TOLIST = 'TOLIST',
+ TO_LIST = 'TOLIST',
+ FIRST_VALUE = 'FIRST_VALUE',
+ RANDOM_SAMPLE = 'RANDOM_SAMPLE'
+}
+
+interface GroupByReducer {
+ type: T;
+ AS?: string;
+}
+
+type CountReducer = GroupByReducer;
+
+interface CountDistinctReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface CountDistinctishReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface SumReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface MinReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface MaxReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface AvgReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface StdDevReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface QuantileReducer extends GroupByReducer {
+ property: PropertyName;
+ quantile: number;
+}
+
+interface ToListReducer extends GroupByReducer {
+ property: PropertyName;
+}
+
+interface FirstValueReducer extends GroupByReducer {
+ property: PropertyName;
+ BY?: PropertyName | {
+ property: PropertyName;
+ direction?: 'ASC' | 'DESC';
+ };
+}
+
+interface RandomSampleReducer extends GroupByReducer {
+ property: PropertyName;
+ sampleSize: number;
+}
+
+type GroupByReducers = CountReducer | CountDistinctReducer | CountDistinctishReducer | SumReducer | MinReducer | MaxReducer | AvgReducer | StdDevReducer | QuantileReducer | ToListReducer | FirstValueReducer | RandomSampleReducer;
+
+interface GroupByStep extends AggregateStep {
+ properties?: PropertyName | Array;
+ REDUCE: GroupByReducers | Array;
+}
+
+interface SortStep extends AggregateStep {
+ BY: SortByOptions | Array;
+ MAX?: number;
+}
+
+interface ApplyStep extends AggregateStep {
+ expression: string;
+ AS: string;
+}
+
+interface LimitStep extends AggregateStep {
+ from: number;
+ size: number;
+}
+
+interface FilterStep extends AggregateStep {
+ expression: string;
+}
+
+type LoadField = PropertyName | {
+ identifier: PropertyName;
+ AS?: string;
+}
+
+interface AggregateOptions {
+ VERBATIM?: true;
+ LOAD?: LoadField | Array;
+ STEPS?: Array;
+}
+
+export function transformArguments(index: string, query: string, options?: AggregateOptions): RedisCommandArguments {
+ const args = ['FT.AGGREGATE', index, query];
+
+ if (options?.VERBATIM) {
+ args.push('VERBATIM');
+ }
+
+ if (options?.LOAD) {
+ args.push('LOAD');
+ pushArgumentsWithLength(args, () => {
+ if (Array.isArray(options.LOAD)) {
+ for (const load of options.LOAD) {
+ pushLoadField(args, load);
+ }
+ } else {
+ pushLoadField(args, options.LOAD!);
+ }
+ });
+ }
+
+ if (options?.STEPS) {
+ for (const step of options.STEPS) {
+ switch (step.type) {
+ case AggregateSteps.GROUPBY:
+ args.push('GROUPBY');
+ if (!step.properties) {
+ args.push('0');
+ } else {
+ pushVerdictArgument(args, step.properties);
+ }
+
+ if (Array.isArray(step.REDUCE)) {
+ for (const reducer of step.REDUCE) {
+ pushGroupByReducer(args, reducer);
+ }
+ } else {
+ pushGroupByReducer(args, step.REDUCE);
+ }
+
+ break;
+
+ case AggregateSteps.SORTBY:
+ pushSortByArguments(args, 'SORTBY', step.BY);
+
+ if (step.MAX) {
+ args.push('MAX', step.MAX.toString());
+ }
+
+ break;
+
+ case AggregateSteps.APPLY:
+ args.push('APPLY', step.expression, 'AS', step.AS);
+ break;
+
+ case AggregateSteps.LIMIT:
+ args.push('LIMIT', step.from.toString(), step.size.toString());
+ break;
+
+ case AggregateSteps.FILTER:
+ args.push('FILTER', step.expression);
+ break;
+ }
+ }
+ }
+
+ return args;
+}
+
+function pushLoadField(args: RedisCommandArguments, toLoad: LoadField): void {
+ if (typeof toLoad === 'string') {
+ args.push(toLoad);
+ } else {
+ args.push(toLoad.identifier);
+
+ if (toLoad.AS) {
+ args.push('AS', toLoad.AS);
+ }
+ }
+}
+
+function pushGroupByReducer(args: RedisCommandArguments, reducer: GroupByReducers): void {
+ args.push('REDUCE', reducer.type);
+
+ switch (reducer.type) {
+ case AggregateGroupByReducers.COUNT:
+ args.push('0');
+ break;
+
+ case AggregateGroupByReducers.COUNT_DISTINCT:
+ case AggregateGroupByReducers.COUNT_DISTINCTISH:
+ case AggregateGroupByReducers.SUM:
+ case AggregateGroupByReducers.MIN:
+ case AggregateGroupByReducers.MAX:
+ case AggregateGroupByReducers.AVG:
+ case AggregateGroupByReducers.STDDEV:
+ case AggregateGroupByReducers.TOLIST:
+ args.push('1', reducer.property);
+ break;
+
+ case AggregateGroupByReducers.QUANTILE:
+ args.push('2', reducer.property, reducer.quantile.toString());
+ break;
+
+ case AggregateGroupByReducers.FIRST_VALUE: {
+ pushArgumentsWithLength(args, () => {
+ args.push(reducer.property);
+
+ if (reducer.BY) {
+ args.push('BY');
+ if (typeof reducer.BY === 'string') {
+ args.push(reducer.BY);
+ } else {
+ args.push(reducer.BY.property);
+
+ if (reducer.BY.direction) {
+ args.push(reducer.BY.direction);
+ }
+ }
+ }
+ });
+
+ break;
+ }
+
+ case AggregateGroupByReducers.RANDOM_SAMPLE:
+ args.push('2', reducer.property, reducer.sampleSize.toString());
+ break;
+ }
+
+ if (reducer.AS) {
+ args.push('AS', reducer.AS);
+ }
+}
+
+type AggregateRawReply = [
+ total: number,
+ ...results: Array>
+];
+
+interface AggregateReply {
+ total: number;
+ results: Array;
+}
+
+export function transformReply(rawReply: AggregateRawReply): AggregateReply {
+ const results: Array = [];
+ for (let i = 1; i < rawReply.length; i++) {
+ results.push(
+ transformReplyTuples(rawReply[i] as Array)
+ );
+ }
+
+ return {
+ total: rawReply[0],
+ results
+ };
+}
\ No newline at end of file
diff --git a/packages/search/lib/commands/ALIASADD.spec.ts b/packages/search/lib/commands/ALIASADD.spec.ts
new file mode 100644
index 0000000000..7bb2452838
--- /dev/null
+++ b/packages/search/lib/commands/ALIASADD.spec.ts
@@ -0,0 +1,11 @@
+import { strict as assert } from 'assert';
+import { transformArguments } from './ALIASADD';
+
+describe('ALIASADD', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('alias', 'index'),
+ ['FT.ALIASADD', 'alias', 'index']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/ALIASADD.ts b/packages/search/lib/commands/ALIASADD.ts
new file mode 100644
index 0000000000..552c1add69
--- /dev/null
+++ b/packages/search/lib/commands/ALIASADD.ts
@@ -0,0 +1,5 @@
+export function transformArguments(name: string, index: string): Array {
+ return ['FT.ALIASADD', name, index];
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/ALIASDEL.spec.ts b/packages/search/lib/commands/ALIASDEL.spec.ts
new file mode 100644
index 0000000000..5255ba835d
--- /dev/null
+++ b/packages/search/lib/commands/ALIASDEL.spec.ts
@@ -0,0 +1,11 @@
+import { strict as assert } from 'assert';
+import { transformArguments } from './ALIASDEL';
+
+describe('ALIASDEL', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('alias', 'index'),
+ ['FT.ALIASDEL', 'alias', 'index']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/ALIASDEL.ts b/packages/search/lib/commands/ALIASDEL.ts
new file mode 100644
index 0000000000..434b4df3de
--- /dev/null
+++ b/packages/search/lib/commands/ALIASDEL.ts
@@ -0,0 +1,5 @@
+export function transformArguments(name: string, index: string): Array {
+ return ['FT.ALIASDEL', name, index];
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/ALIASUPDATE.spec.ts b/packages/search/lib/commands/ALIASUPDATE.spec.ts
new file mode 100644
index 0000000000..79421b1a20
--- /dev/null
+++ b/packages/search/lib/commands/ALIASUPDATE.spec.ts
@@ -0,0 +1,11 @@
+import { strict as assert } from 'assert';
+import { transformArguments } from './ALIASUPDATE';
+
+describe('ALIASUPDATE', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('alias', 'index'),
+ ['FT.ALIASUPDATE', 'alias', 'index']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/ALIASUPDATE.ts b/packages/search/lib/commands/ALIASUPDATE.ts
new file mode 100644
index 0000000000..ac64ef57c3
--- /dev/null
+++ b/packages/search/lib/commands/ALIASUPDATE.ts
@@ -0,0 +1,5 @@
+export function transformArguments(name: string, index: string): Array {
+ return ['FT.ALIASUPDATE', name, index];
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/CONFIG_GET.spec.ts b/packages/search/lib/commands/CONFIG_GET.spec.ts
new file mode 100644
index 0000000000..8614f44342
--- /dev/null
+++ b/packages/search/lib/commands/CONFIG_GET.spec.ts
@@ -0,0 +1,25 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './CONFIG_GET';
+
+describe('CONFIG GET', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('TIMEOUT'),
+ ['FT.CONFIG', 'GET', 'TIMEOUT']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.configGet', async client => {
+ assert.deepEqual(
+ await client.ft.configGet('TIMEOUT'),
+ Object.create(null, {
+ TIMEOUT: {
+ value: '500',
+ configurable: true,
+ enumerable: true
+ }
+ })
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/CONFIG_GET.ts b/packages/search/lib/commands/CONFIG_GET.ts
new file mode 100644
index 0000000000..fbf1f1164b
--- /dev/null
+++ b/packages/search/lib/commands/CONFIG_GET.ts
@@ -0,0 +1,16 @@
+export function transformArguments(option: string) {
+ return ['FT.CONFIG', 'GET', option];
+}
+
+interface ConfigGetReply {
+ [option: string]: string | null;
+}
+
+export function transformReply(rawReply: Array<[string, string | null]>): ConfigGetReply {
+ const transformedReply: ConfigGetReply = Object.create(null);
+ for (const [key, value] of rawReply) {
+ transformedReply[key] = value;
+ }
+
+ return transformedReply;
+}
diff --git a/packages/search/lib/commands/CONFIG_SET.spec.ts b/packages/search/lib/commands/CONFIG_SET.spec.ts
new file mode 100644
index 0000000000..59cb63a3d8
--- /dev/null
+++ b/packages/search/lib/commands/CONFIG_SET.spec.ts
@@ -0,0 +1,12 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './CONFIG_SET';
+
+describe('CONFIG SET', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('TIMEOUT', '500'),
+ ['FT.CONFIG', 'SET', 'TIMEOUT', '500']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/CONFIG_SET.ts b/packages/search/lib/commands/CONFIG_SET.ts
new file mode 100644
index 0000000000..93b76d79ed
--- /dev/null
+++ b/packages/search/lib/commands/CONFIG_SET.ts
@@ -0,0 +1,5 @@
+export function transformArguments(option: string, value: string): Array {
+ return ['FT.CONFIG', 'SET', option, value];
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/CREATE.spec.ts b/packages/search/lib/commands/CREATE.spec.ts
new file mode 100644
index 0000000000..2ac68cc971
--- /dev/null
+++ b/packages/search/lib/commands/CREATE.spec.ts
@@ -0,0 +1,347 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { RedisSearchLanguages, SchemaFieldTypes, SchemaTextFieldPhonetics, transformArguments } from './CREATE';
+
+describe('CREATE', () => {
+ describe('transformArguments', () => {
+ it('simple', () => {
+ assert.deepEqual(
+ transformArguments('index', {}),
+ ['FT.CREATE', 'index', 'SCHEMA']
+ );
+ });
+
+ describe('with fields', () => {
+ describe('TEXT', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: SchemaFieldTypes.TEXT
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT']
+ );
+ });
+
+ it('with NOSTEM', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ NOSTEM: true
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'NOSTEM']
+ );
+ });
+
+ it('with WEIGHT', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ WEIGHT: 1
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'WEIGHT', '1']
+ );
+ });
+
+ it('with PHONETIC', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ PHONETIC: SchemaTextFieldPhonetics.DM_EN
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'PHONETIC', SchemaTextFieldPhonetics.DM_EN]
+ );
+ });
+ });
+
+ it('NUMERIC', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: SchemaFieldTypes.NUMERIC
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'NUMERIC']
+ );
+ });
+
+ it('GEO', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: SchemaFieldTypes.GEO
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'GEO']
+ );
+ });
+
+ describe('TAG', () => {
+ describe('without options', () => {
+ it('SchemaFieldTypes.TAG', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: SchemaFieldTypes.TAG
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG']
+ );
+ });
+
+ it('{ type: SchemaFieldTypes.TAG }', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TAG
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG']
+ );
+ });
+ });
+
+ it('with SEPERATOR', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TAG,
+ SEPERATOR: 'seperator'
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TAG', 'SEPERATOR', 'seperator']
+ );
+ });
+ });
+
+ describe('with generic options', () => {
+ it('with AS', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ AS: 'as'
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'AS', 'as', 'TEXT']
+ );
+ });
+
+ it('with CASESENSITIVE', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ CASESENSITIVE: true
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'CASESENSITIVE']
+ );
+ });
+
+ describe('with SORTABLE', () => {
+ it('true', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ SORTABLE: true
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'SORTABLE']
+ );
+ });
+
+ it('UNF', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ SORTABLE: 'UNF'
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'SORTABLE', 'UNF']
+ );
+ });
+ });
+
+ it('with NOINDEX', () => {
+ assert.deepEqual(
+ transformArguments('index', {
+ field: {
+ type: SchemaFieldTypes.TEXT,
+ NOINDEX: true
+ }
+ }),
+ ['FT.CREATE', 'index', 'SCHEMA', 'field', 'TEXT', 'NOINDEX']
+ );
+ });
+ });
+ });
+
+ it('with ON', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ ON: 'HASH'
+ }),
+ ['FT.CREATE', 'index', 'ON', 'HASH', 'SCHEMA']
+ );
+ });
+
+ describe('with PREFIX', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ PREFIX: 'prefix'
+ }),
+ ['FT.CREATE', 'index', 'PREFIX', '1', 'prefix', 'SCHEMA']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ PREFIX: ['1', '2']
+ }),
+ ['FT.CREATE', 'index', 'PREFIX', '2', '1', '2', 'SCHEMA']
+ );
+ });
+ });
+
+ it('with FILTER', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ FILTER: '@field != ""'
+ }),
+ ['FT.CREATE', 'index', 'FILTER', '@field != ""', 'SCHEMA']
+ );
+ });
+
+ it('with LANGUAGE', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ LANGUAGE: RedisSearchLanguages.ARABIC
+ }),
+ ['FT.CREATE', 'index', 'LANGUAGE', RedisSearchLanguages.ARABIC, 'SCHEMA']
+ );
+ });
+
+ it('with LANGUAGE_FIELD', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ LANGUAGE_FIELD: '@field'
+ }),
+ ['FT.CREATE', 'index', 'LANGUAGE_FIELD', '@field', 'SCHEMA']
+ );
+ });
+
+ it('with SCORE', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ SCORE: 1
+ }),
+ ['FT.CREATE', 'index', 'SCORE', '1', 'SCHEMA']
+ );
+ });
+
+ it('with SCORE_FIELD', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ SCORE_FIELD: '@field'
+ }),
+ ['FT.CREATE', 'index', 'SCORE_FIELD', '@field', 'SCHEMA']
+ );
+ });
+
+ it('with MAXTEXTFIELDS', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ MAXTEXTFIELDS: true
+ }),
+ ['FT.CREATE', 'index', 'MAXTEXTFIELDS', 'SCHEMA']
+ );
+ });
+
+ it('with TEMPORARY', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ TEMPORARY: 1
+ }),
+ ['FT.CREATE', 'index', 'TEMPORARY', '1', 'SCHEMA']
+ );
+ });
+
+ it('with NOOFFSETS', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ NOOFFSETS: true
+ }),
+ ['FT.CREATE', 'index', 'NOOFFSETS', 'SCHEMA']
+ );
+ });
+
+ it('with NOHL', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ NOHL: true
+ }),
+ ['FT.CREATE', 'index', 'NOHL', 'SCHEMA']
+ );
+ });
+
+ it('with NOFIELDS', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ NOFIELDS: true
+ }),
+ ['FT.CREATE', 'index', 'NOFIELDS', 'SCHEMA']
+ );
+ });
+
+ it('with NOFREQS', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ NOFREQS: true
+ }),
+ ['FT.CREATE', 'index', 'NOFREQS', 'SCHEMA']
+ );
+ });
+
+ it('with SKIPINITIALSCAN', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ SKIPINITIALSCAN: true
+ }),
+ ['FT.CREATE', 'index', 'SKIPINITIALSCAN', 'SCHEMA']
+ );
+ });
+
+ describe('with STOPWORDS', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ STOPWORDS: 'stopword'
+ }),
+ ['FT.CREATE', 'index', 'STOPWORDS', '1', 'stopword', 'SCHEMA']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('index', {}, {
+ STOPWORDS: ['1', '2']
+ }),
+ ['FT.CREATE', 'index', 'STOPWORDS', '2', '1', '2', 'SCHEMA']
+ );
+ });
+ });
+ });
+
+ testUtils.testWithClient('client.ft.create', async client => {
+ assert.equal(
+ await client.ft.create('index', {
+ field: SchemaFieldTypes.TEXT // TODO: shouldn't be mandatory
+ }),
+ 'OK'
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/CREATE.ts b/packages/search/lib/commands/CREATE.ts
new file mode 100644
index 0000000000..94c063ec50
--- /dev/null
+++ b/packages/search/lib/commands/CREATE.ts
@@ -0,0 +1,222 @@
+import { pushOptionalVerdictArgument } from '@redis/client/dist/lib/commands/generic-transformers';
+import { PropertyName } from '.';
+
+export enum SchemaFieldTypes {
+ TEXT = 'TEXT',
+ NUMERIC = 'NUMERIC',
+ GEO = 'GEO',
+ TAG = 'TAG',
+}
+
+type CreateSchemaField> = T | ({
+ type: T;
+ AS?: string;
+ CASESENSITIVE?: true;
+ SORTABLE?: true | 'UNF';
+ NOINDEX?: true;
+} & E);
+
+export enum SchemaTextFieldPhonetics {
+ DM_EN = 'dm:en',
+ DM_FR = 'dm:fr',
+ FM_PT = 'dm:pt',
+ DM_ES = 'dm:es'
+}
+
+type CreateSchemaTextField = CreateSchemaField;
+
+type CreateSchemaNumericField = CreateSchemaField;
+
+type CreateSchemaGeoField = CreateSchemaField;
+
+type CreateSchemaTagField = CreateSchemaField;
+
+interface CreateSchema {
+ [field: string]:
+ CreateSchemaTextField |
+ CreateSchemaNumericField |
+ CreateSchemaGeoField |
+ CreateSchemaTagField
+}
+
+export enum RedisSearchLanguages {
+ ARABIC = 'Arabic',
+ BASQUE = 'Basque',
+ CATALANA = 'Catalan',
+ DANISH = 'Danish',
+ DUTCH = 'Dutch',
+ ENGLISH = 'English',
+ FINNISH = 'Finnish',
+ FRENCH = 'French',
+ GERMAN = 'German',
+ GREEK = 'Greek',
+ HUNGARIAN = 'Hungarian',
+ INDONESAIN = 'Indonesian',
+ IRISH = 'Irish',
+ ITALIAN = 'Italian',
+ LITHUANIAN = 'Lithuanian',
+ NEPALI = 'Nepali',
+ NORWEIGAN = 'Norwegian',
+ PORTUGUESE = 'Portuguese',
+ ROMANIAN = 'Romanian',
+ RUSSIAN = 'Russian',
+ SPANISH = 'Spanish',
+ SWEDISH = 'Swedish',
+ TAMIL = 'Tamil',
+ TURKISH = 'Turkish',
+ CHINESE = 'Chinese'
+}
+
+interface CreateOptions {
+ ON?: 'HASH' | 'JSON';
+ PREFIX?: string | Array;
+ FILTER?: string;
+ LANGUAGE?: RedisSearchLanguages;
+ LANGUAGE_FIELD?: PropertyName;
+ SCORE?: number;
+ SCORE_FIELD?: PropertyName;
+ // PAYLOAD_FIELD?: string;
+ MAXTEXTFIELDS?: true;
+ TEMPORARY?: number;
+ NOOFFSETS?: true;
+ NOHL?: true;
+ NOFIELDS?: true;
+ NOFREQS?: true;
+ SKIPINITIALSCAN?: true;
+ STOPWORDS?: string | Array;
+}
+
+export function transformArguments(index: string, schema: CreateSchema, options?: CreateOptions): Array {
+ const args = ['FT.CREATE', index];
+
+ if (options?.ON) {
+ args.push('ON', options.ON);
+ }
+
+ pushOptionalVerdictArgument(args, 'PREFIX', options?.PREFIX);
+
+ if (options?.FILTER) {
+ args.push('FILTER', options.FILTER);
+ }
+
+ if (options?.LANGUAGE) {
+ args.push('LANGUAGE', options.LANGUAGE);
+ }
+
+ if (options?.LANGUAGE_FIELD) {
+ args.push('LANGUAGE_FIELD', options.LANGUAGE_FIELD);
+ }
+
+ if (options?.SCORE) {
+ args.push('SCORE', options.SCORE.toString());
+ }
+
+ if (options?.SCORE_FIELD) {
+ args.push('SCORE_FIELD', options.SCORE_FIELD);
+ }
+
+ // if (options?.PAYLOAD_FIELD) {
+ // args.push('PAYLOAD_FIELD', options.PAYLOAD_FIELD);
+ // }
+
+ if (options?.MAXTEXTFIELDS) {
+ args.push('MAXTEXTFIELDS');
+ }
+
+ if (options?.TEMPORARY) {
+ args.push('TEMPORARY', options.TEMPORARY.toString());
+ }
+
+ if (options?.NOOFFSETS) {
+ args.push('NOOFFSETS');
+ }
+
+ if (options?.NOHL) {
+ args.push('NOHL');
+ }
+
+ if (options?.NOFIELDS) {
+ args.push('NOFIELDS');
+ }
+
+ if (options?.NOFREQS) {
+ args.push('NOFREQS');
+ }
+
+ if (options?.SKIPINITIALSCAN) {
+ args.push('SKIPINITIALSCAN');
+ }
+
+ pushOptionalVerdictArgument(args, 'STOPWORDS', options?.STOPWORDS);
+
+ args.push('SCHEMA');
+
+ for (const [field, fieldOptions] of Object.entries(schema)) {
+ args.push(field);
+
+ if (typeof fieldOptions === 'string') {
+ args.push(fieldOptions);
+ continue;
+ }
+
+ if (fieldOptions.AS) {
+ args.push('AS', fieldOptions.AS);
+ }
+
+ args.push(fieldOptions.type);
+
+ switch (fieldOptions.type) {
+ case 'TEXT':
+ if (fieldOptions.NOSTEM) {
+ args.push('NOSTEM');
+ }
+
+ if (fieldOptions.WEIGHT) {
+ args.push('WEIGHT', fieldOptions.WEIGHT.toString());
+ }
+
+ if (fieldOptions.PHONETIC) {
+ args.push('PHONETIC', fieldOptions.PHONETIC);
+ }
+
+ break;
+
+ // case 'NUMERIC':
+ // case 'GEO':
+ // break;
+
+ case 'TAG':
+ if (fieldOptions.SEPERATOR) {
+ args.push('SEPERATOR', fieldOptions.SEPERATOR);
+ }
+
+ break;
+ }
+
+ if (fieldOptions.CASESENSITIVE) {
+ args.push('CASESENSITIVE');
+ }
+
+ if (fieldOptions.SORTABLE) {
+ args.push('SORTABLE');
+
+ if (fieldOptions.SORTABLE === 'UNF') {
+ args.push('UNF');
+ }
+ }
+
+ if (fieldOptions.NOINDEX) {
+ args.push('NOINDEX');
+ }
+ }
+
+ return args;
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/DICTADD.spec.ts b/packages/search/lib/commands/DICTADD.spec.ts
new file mode 100644
index 0000000000..b5f29dd408
--- /dev/null
+++ b/packages/search/lib/commands/DICTADD.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './DICTADD';
+
+describe('DICTADD', () => {
+ describe('transformArguments', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('dictionary', 'term'),
+ ['FT.DICTADD', 'dictionary', 'term']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('dictionary', ['1', '2']),
+ ['FT.DICTADD', 'dictionary', '1', '2']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.dictAdd', async client => {
+ assert.equal(
+ await client.ft.dictAdd('dictionary', 'term'),
+ 1
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/DICTADD.ts b/packages/search/lib/commands/DICTADD.ts
new file mode 100644
index 0000000000..60af11fd41
--- /dev/null
+++ b/packages/search/lib/commands/DICTADD.ts
@@ -0,0 +1,8 @@
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+import { pushVerdictArguments } from '@redis/client/dist/lib/commands/generic-transformers';
+
+export function transformArguments(dictionary: string, term: string | Array): RedisCommandArguments {
+ return pushVerdictArguments(['FT.DICTADD', dictionary], term);
+}
+
+export declare function transformReply(): number;
diff --git a/packages/search/lib/commands/DICTDEL.spec.ts b/packages/search/lib/commands/DICTDEL.spec.ts
new file mode 100644
index 0000000000..5ffa6b6b84
--- /dev/null
+++ b/packages/search/lib/commands/DICTDEL.spec.ts
@@ -0,0 +1,28 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './DICTDEL';
+
+describe('DICTDEL', () => {
+ describe('transformArguments', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('dictionary', 'term'),
+ ['FT.DICTDEL', 'dictionary', 'term']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('dictionary', ['1', '2']),
+ ['FT.DICTDEL', 'dictionary', '1', '2']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.dictDel', async client => {
+ assert.equal(
+ await client.ft.dictDel('dictionary', 'term'),
+ 0
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/DICTDEL.ts b/packages/search/lib/commands/DICTDEL.ts
new file mode 100644
index 0000000000..a1b728f192
--- /dev/null
+++ b/packages/search/lib/commands/DICTDEL.ts
@@ -0,0 +1,8 @@
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+import { pushVerdictArguments } from '@redis/client/dist/lib/commands/generic-transformers';
+
+export function transformArguments(dictionary: string, term: string | Array): RedisCommandArguments {
+ return pushVerdictArguments(['FT.DICTDEL', dictionary], term);
+}
+
+export declare function transformReply(): number;
diff --git a/packages/search/lib/commands/DICTDUMP.spec.ts b/packages/search/lib/commands/DICTDUMP.spec.ts
new file mode 100644
index 0000000000..9896fb9440
--- /dev/null
+++ b/packages/search/lib/commands/DICTDUMP.spec.ts
@@ -0,0 +1,21 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './DICTDUMP';
+
+describe('DICTDUMP', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('dictionary'),
+ ['FT.DICTDUMP', 'dictionary']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.dictDump', async client => {
+ await client.ft.dictAdd('dictionary', 'string')
+
+ assert.deepEqual(
+ await client.ft.dictDump('dictionary'),
+ ['string']
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/DICTDUMP.ts b/packages/search/lib/commands/DICTDUMP.ts
new file mode 100644
index 0000000000..1427bb42cb
--- /dev/null
+++ b/packages/search/lib/commands/DICTDUMP.ts
@@ -0,0 +1,5 @@
+export function transformArguments(dictionary: string): Array {
+ return ['FT.DICTDUMP', dictionary];
+}
+
+export declare function transformReply(): Array;
diff --git a/packages/search/lib/commands/DROPINDEX.spec.ts b/packages/search/lib/commands/DROPINDEX.spec.ts
new file mode 100644
index 0000000000..751e274ba6
--- /dev/null
+++ b/packages/search/lib/commands/DROPINDEX.spec.ts
@@ -0,0 +1,33 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { SchemaFieldTypes } from './CREATE';
+import { transformArguments } from './DROPINDEX';
+
+describe('DROPINDEX', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('index'),
+ ['FT.DROPINDEX', 'index']
+ );
+ });
+
+ it('with DD', () => {
+ assert.deepEqual(
+ transformArguments('index', { DD: true }),
+ ['FT.DROPINDEX', 'index', 'DD']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.dropIndex', async client => {
+ await client.ft.create('index', {
+ field: SchemaFieldTypes.TEXT // TODO: shouldn't be mandatory
+ });
+
+ assert.equal(
+ await client.ft.dropIndex('index'),
+ 'OK'
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/DROPINDEX.ts b/packages/search/lib/commands/DROPINDEX.ts
new file mode 100644
index 0000000000..7897a9dd82
--- /dev/null
+++ b/packages/search/lib/commands/DROPINDEX.ts
@@ -0,0 +1,15 @@
+interface DropIndexOptions {
+ DD?: true;
+}
+
+export function transformArguments(index: string, options?: DropIndexOptions): Array {
+ const args = ['FT.DROPINDEX', index];
+
+ if (options?.DD) {
+ args.push('DD');
+ }
+
+ return args;
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/EXPLAIN.spec.ts b/packages/search/lib/commands/EXPLAIN.spec.ts
new file mode 100644
index 0000000000..dd55e03871
--- /dev/null
+++ b/packages/search/lib/commands/EXPLAIN.spec.ts
@@ -0,0 +1,11 @@
+import { strict as assert } from 'assert';
+import { transformArguments } from './EXPLAIN';
+
+describe('EXPLAIN', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('index', '*'),
+ ['FT.EXPLAIN', 'index', '*']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/EXPLAIN.ts b/packages/search/lib/commands/EXPLAIN.ts
new file mode 100644
index 0000000000..c41cd9a4aa
--- /dev/null
+++ b/packages/search/lib/commands/EXPLAIN.ts
@@ -0,0 +1,7 @@
+export const IS_READ_ONLY = true;
+
+export function transformArguments(index: string, query: string): Array {
+ return ['FT.EXPLAIN', index, query];
+}
+
+export declare function transformReply(): string;
diff --git a/packages/search/lib/commands/EXPLAINCLI.spec.ts b/packages/search/lib/commands/EXPLAINCLI.spec.ts
new file mode 100644
index 0000000000..238ef44eaa
--- /dev/null
+++ b/packages/search/lib/commands/EXPLAINCLI.spec.ts
@@ -0,0 +1,11 @@
+import { strict as assert } from 'assert';
+import { transformArguments } from './EXPLAINCLI';
+
+describe('EXPLAINCLI', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('index', '*'),
+ ['FT.EXPLAINCLI', 'index', '*']
+ );
+ });
+});
diff --git a/packages/search/lib/commands/EXPLAINCLI.ts b/packages/search/lib/commands/EXPLAINCLI.ts
new file mode 100644
index 0000000000..db97fb9c8d
--- /dev/null
+++ b/packages/search/lib/commands/EXPLAINCLI.ts
@@ -0,0 +1,7 @@
+export const IS_READ_ONLY = true;
+
+export function transformArguments(index: string, query: string): Array {
+ return ['FT.EXPLAINCLI', index, query];
+}
+
+export declare function transformReply(): Array;
diff --git a/packages/search/lib/commands/INFO.spec.ts b/packages/search/lib/commands/INFO.spec.ts
new file mode 100644
index 0000000000..fa50a4b0cd
--- /dev/null
+++ b/packages/search/lib/commands/INFO.spec.ts
@@ -0,0 +1,65 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { SchemaFieldTypes } from './CREATE';
+import { transformArguments } from './INFO';
+
+describe('INFO', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('index'),
+ ['FT.INFO', 'index']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.info', async client => {
+ await client.ft.create('index', {}, {
+ ON: 'HASH' // TODO: shouldn't be mandatory
+ });
+
+ assert.deepEqual(
+ await client.ft.info('index'),
+ {
+ indexName: 'index',
+ indexOptions: [],
+ indexDefinition: {
+ defaultScore: '1',
+ keyType: 'HASH',
+ prefixes: ['']
+ },
+ attributes: [],
+ numDocs: '0',
+ maxDocId: '0',
+ numTerms: '0',
+ numRecords: '0',
+ invertedSzMb: '0',
+ totalInvertedIndexBlocks: '0',
+ offsetVectorsSzMb: '0',
+ docTableSizeMb: '0',
+ sortableValuesSizeMb: '0',
+ keyTableSizeMb: '0',
+ recordsPerDocAvg: '-nan',
+ bytesPerRecordAvg: '-nan',
+ offsetsPerTermAvg: '-nan',
+ offsetBitsPerRecordAvg: '-nan',
+ hashIndexingFailures: '0',
+ indexing: '0',
+ percentIndexed: '1',
+ gcStats: {
+ bytesCollected: '0',
+ totalMsRun: '0',
+ totalCycles: '0',
+ averageCycleTimeMs: '-nan',
+ lastRunTimeMs: '0',
+ gcNumericTreesMissed: '0',
+ gcBlocksDenied: '0'
+ },
+ cursorStats: {
+ globalIdle: 0,
+ globalTotal: 0,
+ indexCapacity: 128,
+ idnexTotal: 0
+ }
+ }
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/INFO.ts b/packages/search/lib/commands/INFO.ts
new file mode 100644
index 0000000000..42451114c8
--- /dev/null
+++ b/packages/search/lib/commands/INFO.ts
@@ -0,0 +1,171 @@
+export function transformArguments(index: string): Array {
+ return ['FT.INFO', index];
+}
+
+type InfoRawReply = [
+ _: string,
+ indexName: string,
+ _: string,
+ indexOptions: Array,
+ _: string,
+ indexDefinition: [
+ _: string,
+ keyType: string,
+ _: string,
+ prefixes: Array,
+ _: string,
+ defaultScore: string
+ ],
+ _: string,
+ attributes: Array>,
+ _: string,
+ numDocs: string,
+ _: string,
+ maxDocId: string,
+ _: string,
+ numTerms: string,
+ _: string,
+ numRecords: string,
+ _: string,
+ invertedSzMb: string,
+ _: string,
+ totalInvertedIndexBlocks: string,
+ _: string,
+ offsetVectorsSzMb: string,
+ _: string,
+ docTableSizeMb: string,
+ _: string,
+ sortableValuesSizeMb: string,
+ _: string,
+ keyTableSizeMb: string,
+ _: string,
+ recordsPerDocAvg: string,
+ _: string,
+ bytesPerRecordAvg: string,
+ _: string,
+ offsetsPerTermAvg: string,
+ _: string,
+ offsetBitsPerRecordAvg: string,
+ _: string,
+ hashIndexingFailures: string,
+ _: string,
+ indexing: string,
+ _: string,
+ percentIndexed: string,
+ _: string,
+ gcStats: [
+ _: string,
+ bytesCollected: string,
+ _: string,
+ totalMsRun: string,
+ _: string,
+ totalCycles: string,
+ _: string,
+ averageCycleTimeMs: string,
+ _: string,
+ lastRunTimeMs: string,
+ _: string,
+ gcNumericTreesMissed: string,
+ _: string,
+ gcBlocksDenied: string
+ ],
+ _: string,
+ cursorStats: [
+ _: string,
+ globalIdle: number,
+ _: string,
+ globalTotal: number,
+ _: string,
+ indexCapacity: number,
+ _: string,
+ idnexTotal: number
+ ]
+];
+
+interface InfoReply {
+ indexName: string;
+ indexOptions: Array;
+ indexDefinition: {
+ keyType: string;
+ prefixes: Array;
+ defaultScore: string;
+ };
+ attributes: Array>;
+ numDocs: string;
+ maxDocId: string;
+ numTerms: string;
+ numRecords: string;
+ invertedSzMb: string;
+ totalInvertedIndexBlocks: string;
+ offsetVectorsSzMb: string;
+ docTableSizeMb: string;
+ sortableValuesSizeMb: string;
+ keyTableSizeMb: string;
+ recordsPerDocAvg: string;
+ bytesPerRecordAvg: string;
+ offsetsPerTermAvg: string;
+ offsetBitsPerRecordAvg: string;
+ hashIndexingFailures: string;
+ indexing: string;
+ percentIndexed: string;
+ gcStats: {
+ bytesCollected: string;
+ totalMsRun: string;
+ totalCycles: string;
+ averageCycleTimeMs: string;
+ lastRunTimeMs: string;
+ gcNumericTreesMissed: string;
+ gcBlocksDenied: string;
+ };
+ cursorStats: {
+ globalIdle: number;
+ globalTotal: number;
+ indexCapacity: number;
+ idnexTotal: number;
+ };
+}
+
+export function transformReply(rawReply: InfoRawReply): InfoReply {
+ return {
+ indexName: rawReply[1],
+ indexOptions: rawReply[3],
+ indexDefinition: {
+ keyType: rawReply[5][1],
+ prefixes: rawReply[5][3],
+ defaultScore: rawReply[5][5]
+ },
+ attributes: rawReply[7],
+ numDocs: rawReply[9],
+ maxDocId: rawReply[11],
+ numTerms: rawReply[13],
+ numRecords: rawReply[15],
+ invertedSzMb: rawReply[17],
+ totalInvertedIndexBlocks: rawReply[19],
+ offsetVectorsSzMb: rawReply[21],
+ docTableSizeMb: rawReply[23],
+ sortableValuesSizeMb: rawReply[25],
+ keyTableSizeMb: rawReply[27],
+ recordsPerDocAvg: rawReply[29],
+ bytesPerRecordAvg: rawReply[31],
+ offsetsPerTermAvg: rawReply[33],
+ offsetBitsPerRecordAvg: rawReply[35],
+ hashIndexingFailures: rawReply[37],
+ indexing: rawReply[39],
+ percentIndexed: rawReply[41],
+ gcStats: {
+ bytesCollected: rawReply[43][1],
+ totalMsRun: rawReply[43][3],
+ totalCycles: rawReply[43][5],
+ averageCycleTimeMs: rawReply[43][7],
+ lastRunTimeMs: rawReply[43][9],
+ gcNumericTreesMissed: rawReply[43][11],
+ gcBlocksDenied: rawReply[43][13]
+ },
+ cursorStats: {
+ globalIdle: rawReply[45][1],
+ globalTotal: rawReply[45][3],
+ indexCapacity: rawReply[45][5],
+ idnexTotal: rawReply[45][7]
+ }
+ };
+}
diff --git a/packages/search/lib/commands/PROFILE.ts b/packages/search/lib/commands/PROFILE.ts
new file mode 100644
index 0000000000..e315ea5230
--- /dev/null
+++ b/packages/search/lib/commands/PROFILE.ts
@@ -0,0 +1,26 @@
+export const IS_READ_ONLY = true;
+
+interface ProfileOptions {
+ LIMITED?: true;
+}
+
+export function transformArguments(
+ index: string,
+ type: 'SEARCH' | 'AGGREGATE',
+ query: string,
+ options?: ProfileOptions
+): Array {
+ const args = ['FT.PROFILE', index, type];
+
+ if (options?.LIMITED) {
+ args.push('LIMITED');
+ }
+
+ args.push('QUERY', query);
+
+ return args;
+}
+
+export function transformReply() {
+
+}
diff --git a/packages/search/lib/commands/SEARCH.spec.ts b/packages/search/lib/commands/SEARCH.spec.ts
new file mode 100644
index 0000000000..efe9c899ac
--- /dev/null
+++ b/packages/search/lib/commands/SEARCH.spec.ts
@@ -0,0 +1,243 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { RedisSearchLanguages, SchemaFieldTypes } from './CREATE';
+import { transformArguments } from './SEARCH';
+
+describe('SEARCH', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query'),
+ ['FT.SEARCH', 'index', 'query']
+ );
+ });
+
+ it('with VERBATIM', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { VERBATIM: true }),
+ ['FT.SEARCH', 'index', 'query', 'VERBATIM']
+ );
+ });
+
+ it('with NOSTOPWORDS', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { NOSTOPWORDS: true }),
+ ['FT.SEARCH', 'index', 'query', 'NOSTOPWORDS']
+ );
+ });
+
+ it('with INKEYS', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { INKEYS: 'key' }),
+ ['FT.SEARCH', 'index', 'query', 'INKEYS', '1', 'key']
+ );
+ });
+
+ it('with INFIELDS', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { INFIELDS: 'field' }),
+ ['FT.SEARCH', 'index', 'query', 'INFIELDS', '1', 'field']
+ );
+ });
+
+ it('with RETURN', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { RETURN: 'return' }),
+ ['FT.SEARCH', 'index', 'query', 'RETURN', '1', 'return']
+ );
+ });
+
+ describe('with SUMMARIZE', () => {
+ it('true', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { SUMMARIZE: true }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE']
+ );
+ });
+
+ describe('with FIELDS', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ SUMMARIZE: {
+ FIELDS: ['@field']
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '1', '@field']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ SUMMARIZE: {
+ FIELDS: ['@1', '@2']
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FIELDS', '2', '@1', '@2']
+ );
+ });
+ });
+
+ it('with FRAGS', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ SUMMARIZE: {
+ FRAGS: 1
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'FRAGS', '1']
+ );
+ });
+
+ it('with LEN', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ SUMMARIZE: {
+ LEN: 1
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'LEN', '1']
+ );
+ });
+
+ it('with SEPARATOR', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ SUMMARIZE: {
+ SEPARATOR: 'separator'
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'SUMMARIZE', 'SEPARATOR', 'separator']
+ );
+ });
+ });
+
+ describe('with HIGHLIGHT', () => {
+ it('true', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { HIGHLIGHT: true }),
+ ['FT.SEARCH', 'index', 'query', 'HIGHLIGHT']
+ );
+ });
+
+ describe('with FIELDS', () => {
+ it('string', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ HIGHLIGHT: {
+ FIELDS: ['@field']
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '1', '@field']
+ );
+ });
+
+ it('Array', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ HIGHLIGHT: {
+ FIELDS: ['@1', '@2']
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'FIELDS', '2', '@1', '@2']
+ );
+ });
+ });
+
+ it('with TAGS', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ HIGHLIGHT: {
+ TAGS: {
+ open: 'open',
+ close: 'close'
+ }
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'HIGHLIGHT', 'TAGS', 'open', 'close']
+ );
+ });
+ });
+
+ it('with SLOP', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { SLOP: 1 }),
+ ['FT.SEARCH', 'index', 'query', 'SLOP', '1']
+ );
+ });
+
+ it('with INORDER', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { INORDER: true }),
+ ['FT.SEARCH', 'index', 'query', 'INORDER']
+ );
+ });
+
+ it('with LANGUAGE', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { LANGUAGE: RedisSearchLanguages.ARABIC }),
+ ['FT.SEARCH', 'index', 'query', 'LANGUAGE', RedisSearchLanguages.ARABIC]
+ );
+ });
+
+ it('with EXPANDER', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { EXPANDER: 'expender' }),
+ ['FT.SEARCH', 'index', 'query', 'EXPANDER', 'expender']
+ );
+ });
+
+ it('with SCORER', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { SCORER: 'scorer' }),
+ ['FT.SEARCH', 'index', 'query', 'SCORER', 'scorer']
+ );
+ });
+
+ it('with MSORTBY', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { MSORTBY: '@by' }),
+ ['FT.SEARCH', 'index', 'query', 'MSORTBY', '1', '@by']
+ );
+ });
+
+ it('with LIMIT', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ LIMIT: {
+ from: 0,
+ size: 1
+ }
+ }),
+ ['FT.SEARCH', 'index', 'query', 'LIMIT', '0', '1']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.search', async client => {
+ await Promise.all([
+ client.ft.create('index', {
+ field: SchemaFieldTypes.NUMERIC
+ }),
+ client.hSet('1', 'field', '1')
+ ]);
+
+ assert.deepEqual(
+ await client.ft.search('index', '*'),
+ {
+ total: 1,
+ documents: [{
+ id: '1',
+ value: Object.create(null, {
+ field: {
+ value: '1',
+ configurable: true,
+ enumerable: true
+ }
+ })
+ }]
+ }
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SEARCH.ts b/packages/search/lib/commands/SEARCH.ts
new file mode 100644
index 0000000000..6b14a0a18f
--- /dev/null
+++ b/packages/search/lib/commands/SEARCH.ts
@@ -0,0 +1,202 @@
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+import { pushOptionalVerdictArgument, pushVerdictArgument, transformReplyTuples } from '@redis/client/dist/lib/commands/generic-transformers';
+import { type } from 'os';
+import { PropertyName, pushSortByArguments, SortByOptions } from '.';
+import { RedisSearchLanguages } from './CREATE';
+
+export const FIRST_KEY_INDEX = 1;
+
+export const IS_READ_ONLY = true;
+
+interface SearchOptions {
+ // NOCONTENT?: true; TODO
+ VERBATIM?: true;
+ NOSTOPWORDS?: true;
+ // WITHSCORES?: true;
+ // WITHPAYLOADS?: true;
+ WITHSORTKEYS?: true;
+ // FILTER?: {
+ // field: string;
+ // min: number | string;
+ // max: number | string;
+ // };
+ // GEOFILTER?: {
+ // field: string;
+ // lon: number;
+ // lat: number;
+ // radius: number;
+ // unit: 'm' | 'km' | 'mi' | 'ft';
+ // };
+ INKEYS?: string | Array;
+ INFIELDS?: string | Array;
+ RETURN?: string | Array;
+ SUMMARIZE?: true | {
+ FIELDS?: PropertyName | Array;
+ FRAGS?: number;
+ LEN?: number;
+ SEPARATOR?: string;
+ };
+ HIGHLIGHT?: true | {
+ FIELDS?: PropertyName | Array;
+ TAGS?: {
+ open: string;
+ close: string;
+ }
+ };
+ SLOP?: number;
+ INORDER?: true;
+ LANGUAGE?: RedisSearchLanguages;
+ EXPANDER?: string;
+ SCORER?: string;
+ // EXPLAINSCORE?: true; // TODO: WITHSCORES
+ // PAYLOAD?: ;
+ // SORTBY?: SortByOptions;
+ MSORTBY?: SortByOptions | Array;
+ LIMIT?: {
+ from: number | string;
+ size: number | string;
+ };
+}
+
+export function transformArguments(
+ index: string,
+ query: string,
+ options?: SearchOptions
+): RedisCommandArguments {
+ const args: RedisCommandArguments = ['FT.SEARCH', index, query];
+
+ if (options?.VERBATIM) {
+ args.push('VERBATIM');
+ }
+
+ if (options?.NOSTOPWORDS) {
+ args.push('NOSTOPWORDS');
+ }
+
+ // if (options?.WITHSCORES) {
+ // args.push('WITHSCORES');
+ // }
+
+ // if (options?.WITHPAYLOADS) {
+ // args.push('WITHPAYLOADS');
+ // }
+
+ pushOptionalVerdictArgument(args, 'INKEYS', options?.INKEYS);
+ pushOptionalVerdictArgument(args, 'INFIELDS', options?.INFIELDS);
+ pushOptionalVerdictArgument(args, 'RETURN', options?.RETURN);
+
+ if (options?.SUMMARIZE) {
+ args.push('SUMMARIZE');
+
+ if (typeof options.SUMMARIZE === 'object') {
+ if (options.SUMMARIZE.FIELDS) {
+ args.push('FIELDS');
+ pushVerdictArgument(args, options.SUMMARIZE.FIELDS);
+ }
+
+ if (options.SUMMARIZE.FRAGS) {
+ args.push('FRAGS', options.SUMMARIZE.FRAGS.toString());
+ }
+
+ if (options.SUMMARIZE.LEN) {
+ args.push('LEN', options.SUMMARIZE.LEN.toString());
+ }
+
+ if (options.SUMMARIZE.SEPARATOR) {
+ args.push('SEPARATOR', options.SUMMARIZE.SEPARATOR);
+ }
+ }
+ }
+
+ if (options?.HIGHLIGHT) {
+ args.push('HIGHLIGHT');
+
+ if (typeof options.HIGHLIGHT === 'object') {
+ if (options.HIGHLIGHT.FIELDS) {
+ args.push('FIELDS');
+ pushVerdictArgument(args, options.HIGHLIGHT.FIELDS);
+ }
+
+ if (options.HIGHLIGHT.TAGS) {
+ args.push('TAGS', options.HIGHLIGHT.TAGS.open, options.HIGHLIGHT.TAGS.close);
+ }
+ }
+ }
+
+ if (options?.SLOP) {
+ args.push('SLOP', options.SLOP.toString());
+ }
+
+ if (options?.INORDER) {
+ args.push('INORDER');
+ }
+
+ if (options?.LANGUAGE) {
+ args.push('LANGUAGE', options.LANGUAGE);
+ }
+
+ if (options?.EXPANDER) {
+ args.push('EXPANDER', options.EXPANDER);
+ }
+
+ if (options?.SCORER) {
+ args.push('SCORER', options.SCORER);
+ }
+
+ // if (options?.EXPLAINSCORE) {
+ // args.push('EXPLAINSCORE');
+ // }
+
+ // if (options?.PAYLOAD) {
+ // args.push('PAYLOAD', options.PAYLOAD);
+ // }
+
+ // if (options?.SORTBY) {
+ // args.push('SORTBY');
+ // pushSortByArguments(args, options.SORTBY);
+ // }
+
+ if (options?.MSORTBY) {
+ pushSortByArguments(args, 'MSORTBY', options.MSORTBY);
+ }
+
+ if (options?.LIMIT) {
+ args.push(
+ 'LIMIT',
+ options.LIMIT.from.toString(),
+ options.LIMIT.size.toString()
+ );
+ }
+
+ return args;
+}
+
+interface SearchDocumentValue {
+ [key: string]: string | number | null | Array | SearchDocumentValue;
+}
+
+interface SearchReply {
+ total: number;
+ documents: Array<{
+ id: string;
+ value: SearchDocumentValue;
+ }>;
+}
+
+export function transformReply(reply: Array): SearchReply {
+ const documents = [];
+ for (let i = 1; i < reply.length; i += 2) {
+ const tuples = reply[i + 1];
+ documents.push({
+ id: reply[i],
+ value: tuples.length === 2 && tuples[0] === '$' ?
+ JSON.parse(tuples[1]) :
+ transformReplyTuples(tuples)
+ });
+ }
+
+ return {
+ total: reply[0],
+ documents
+ };
+}
diff --git a/packages/search/lib/commands/SPELLCHECK.spec.ts b/packages/search/lib/commands/SPELLCHECK.spec.ts
new file mode 100644
index 0000000000..bacbe118b3
--- /dev/null
+++ b/packages/search/lib/commands/SPELLCHECK.spec.ts
@@ -0,0 +1,71 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { SchemaFieldTypes } from './CREATE';
+import { transformArguments } from './SPELLCHECK';
+
+describe('SPELLCHECK', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query'),
+ ['FT.SPELLCHECK', 'index', 'query']
+ );
+ });
+
+ it('with DISTANCE', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', { DISTANCE: 2 }),
+ ['FT.SPELLCHECK', 'index', 'query', 'DISTANCE', '2']
+ );
+ });
+
+ describe('with TERMS', () => {
+ it('single', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ TERMS: {
+ mode: 'INCLUDE',
+ dictionary: 'dictionary'
+ }
+ }),
+ ['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'dictionary']
+ );
+ });
+
+ it('multiple', () => {
+ assert.deepEqual(
+ transformArguments('index', 'query', {
+ TERMS: [{
+ mode: 'INCLUDE',
+ dictionary: 'include'
+ }, {
+ mode: 'EXCLUDE',
+ dictionary: 'exclude'
+ }]
+ }),
+ ['FT.SPELLCHECK', 'index', 'query', 'TERMS', 'INCLUDE', 'include', 'TERMS', 'EXCLUDE', 'exclude']
+ );
+ });
+ });
+ });
+
+ testUtils.testWithClient('client.ft.spellCheck', async client => {
+ await Promise.all([
+ client.ft.create('index', {
+ field: SchemaFieldTypes.TEXT
+ }),
+ client.hSet('key', 'field', 'query')
+ ]);
+
+ assert.deepEqual(
+ await client.ft.spellCheck('index', 'quer'),
+ [{
+ term: 'quer',
+ suggestions: [{
+ score: 1,
+ suggestion: 'query'
+ }]
+ }]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SPELLCHECK.ts b/packages/search/lib/commands/SPELLCHECK.ts
new file mode 100644
index 0000000000..ae4cb3cdce
--- /dev/null
+++ b/packages/search/lib/commands/SPELLCHECK.ts
@@ -0,0 +1,57 @@
+interface SpellCheckTerms {
+ mode: 'INCLUDE' | 'EXCLUDE';
+ dictionary: string;
+}
+
+interface SpellCheckOptions {
+ DISTANCE?: number;
+ TERMS?: SpellCheckTerms | Array;
+}
+
+export function transformArguments(index: string, query: string, options?: SpellCheckOptions): Array {
+ const args = ['FT.SPELLCHECK', index, query];
+
+ if (options?.DISTANCE) {
+ args.push('DISTANCE', options.DISTANCE.toString());
+ }
+
+ if (options?.TERMS) {
+ if (Array.isArray(options.TERMS)) {
+ for (const term of options.TERMS) {
+ pushTerms(args, term);
+ }
+ } else {
+ pushTerms(args, options.TERMS);
+ }
+ }
+
+ return args;
+}
+
+function pushTerms(args: Array, { mode, dictionary }: SpellCheckTerms): void {
+ args.push('TERMS', mode, dictionary);
+}
+
+type SpellCheckRawReply = Array<[
+ _: string,
+ term: string,
+ suggestions: Array<[score: string, suggestion: string]>
+]>;
+
+type SpellCheckReply = Array<{
+ term: string,
+ suggestions: Array<{
+ score: number,
+ suggestion: string
+ }>
+}>;
+
+export function transformReply(rawReply: SpellCheckRawReply): SpellCheckReply {
+ return rawReply.map(([, term, suggestions]) => ({
+ term,
+ suggestions: suggestions.map(([score, suggestion]) => ({
+ score: Number(score),
+ suggestion
+ }))
+ }));
+}
diff --git a/packages/search/lib/commands/SUGADD.spec.ts b/packages/search/lib/commands/SUGADD.spec.ts
new file mode 100644
index 0000000000..23294eb4ab
--- /dev/null
+++ b/packages/search/lib/commands/SUGADD.spec.ts
@@ -0,0 +1,35 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGADD';
+
+describe('SUGADD', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('key', 'string', 1),
+ ['FT.SUGADD', 'key', 'string', '1']
+ );
+ });
+
+ it('with INCR', () => {
+ assert.deepEqual(
+ transformArguments('key', 'string', 1, { INCR: true }),
+ ['FT.SUGADD', 'key', 'string', '1', 'INCR']
+ );
+ });
+
+ it('with PAYLOAD', () => {
+ assert.deepEqual(
+ transformArguments('key', 'string', 1, { PAYLOAD: 'payload' }),
+ ['FT.SUGADD', 'key', 'string', '1', 'PAYLOAD', 'payload']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.sugAdd', async client => {
+ assert.equal(
+ await client.ft.sugAdd('key', 'string', 1),
+ 1
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SUGADD.ts b/packages/search/lib/commands/SUGADD.ts
new file mode 100644
index 0000000000..d68f0d9884
--- /dev/null
+++ b/packages/search/lib/commands/SUGADD.ts
@@ -0,0 +1,20 @@
+interface SugAddOptions {
+ INCR?: true;
+ PAYLOAD?: string;
+}
+
+export function transformArguments(key: string, string: string, score: number, options?: SugAddOptions): Array {
+ const args = ['FT.SUGADD', key, string, score.toString()];
+
+ if (options?.INCR) {
+ args.push('INCR');
+ }
+
+ if (options?.PAYLOAD) {
+ args.push('PAYLOAD', options.PAYLOAD);
+ }
+
+ return args;
+}
+
+export declare function transformReply(): number;
diff --git a/packages/search/lib/commands/SUGDEL.spec.ts b/packages/search/lib/commands/SUGDEL.spec.ts
new file mode 100644
index 0000000000..3d89e3b9a7
--- /dev/null
+++ b/packages/search/lib/commands/SUGDEL.spec.ts
@@ -0,0 +1,19 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGDEL';
+
+describe('SUGDEL', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', 'string'),
+ ['FT.SUGDEL', 'key', 'string']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.sugDel', async client => {
+ assert.equal(
+ await client.ft.sugDel('key', 'string'),
+ false
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SUGDEL.ts b/packages/search/lib/commands/SUGDEL.ts
new file mode 100644
index 0000000000..be2d4262ca
--- /dev/null
+++ b/packages/search/lib/commands/SUGDEL.ts
@@ -0,0 +1,5 @@
+export function transformArguments(key: string, string: string): Array {
+ return ['FT.SUGDEL', key, string];
+}
+
+export { transformReplyBoolean as transformReply } from '@redis/client/dist/lib/commands/generic-transformers';
diff --git a/packages/search/lib/commands/SUGGET.spec.ts b/packages/search/lib/commands/SUGGET.spec.ts
new file mode 100644
index 0000000000..c24c2ff086
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET.spec.ts
@@ -0,0 +1,46 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGGET';
+
+describe('SUGGET', () => {
+ describe('transformArguments', () => {
+ it('without options', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix'),
+ ['FT.SUGGET', 'key', 'prefix']
+ );
+ });
+
+ it('with FUZZY', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix', { FUZZY: true }),
+ ['FT.SUGGET', 'key', 'prefix', 'FUZZY']
+ );
+ });
+
+ it('with MAX', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix', { MAX: 10 }),
+ ['FT.SUGGET', 'key', 'prefix', 'MAX', '10']
+ );
+ });
+ });
+
+ describe('client.ft.sugGet', () => {
+ testUtils.testWithClient('null', async client => {
+ assert.equal(
+ await client.ft.sugGet('key', 'prefix'),
+ null
+ );
+ }, GLOBAL.SERVERS.OPEN);
+
+ testUtils.testWithClient('with suggestions', async client => {
+ await client.ft.sugAdd('key', 'string', 1);
+
+ assert.deepEqual(
+ await client.ft.sugGet('key', 'string'),
+ ['string']
+ );
+ }, GLOBAL.SERVERS.OPEN);
+ });
+});
diff --git a/packages/search/lib/commands/SUGGET.ts b/packages/search/lib/commands/SUGGET.ts
new file mode 100644
index 0000000000..558cedeaa0
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET.ts
@@ -0,0 +1,22 @@
+export const IS_READ_ONLY = true;
+
+export interface SugGetOptions {
+ FUZZY?: true;
+ MAX?: number;
+}
+
+export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array {
+ const args = ['FT.SUGGET', key, prefix];
+
+ if (options?.FUZZY) {
+ args.push('FUZZY');
+ }
+
+ if (options?.MAX) {
+ args.push('MAX', options.MAX.toString());
+ }
+
+ return args;
+}
+
+export declare function transformReply(): null | Array;
diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts
new file mode 100644
index 0000000000..a4a87ebe89
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.spec.ts
@@ -0,0 +1,33 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGGET_WITHPAYLOADS';
+
+describe('SUGGET WITHPAYLOADS', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix'),
+ ['FT.SUGGET', 'key', 'prefix', 'WITHPAYLOADS']
+ );
+ });
+
+ describe('client.ft.sugGetWithPayloads', () => {
+ testUtils.testWithClient('null', async client => {
+ assert.equal(
+ await client.ft.sugGetWithPayloads('key', 'prefix'),
+ null
+ );
+ }, GLOBAL.SERVERS.OPEN);
+
+ testUtils.testWithClient('with suggestions', async client => {
+ await client.ft.sugAdd('key', 'string', 1, { PAYLOAD: 'payload' });
+
+ assert.deepEqual(
+ await client.ft.sugGetWithPayloads('key', 'string'),
+ [{
+ suggestion: 'string',
+ payload: 'payload'
+ }]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+ });
+});
diff --git a/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts
new file mode 100644
index 0000000000..7eaff4697e
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHPAYLOADS.ts
@@ -0,0 +1,29 @@
+import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET';
+
+export { IS_READ_ONLY } from './SUGGET';
+
+export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array {
+ return [
+ ...transformSugGetArguments(key, prefix, options),
+ 'WITHPAYLOADS'
+ ];
+}
+
+export interface SuggestionWithPayload {
+ suggestion: string;
+ payload: string | null;
+}
+
+export function transformReply(rawReply: Array | null): Array | null {
+ if (rawReply === null) return null;
+
+ const transformedReply = [];
+ for (let i = 0; i < rawReply.length; i += 2) {
+ transformedReply.push({
+ suggestion: rawReply[i]!,
+ payload: rawReply[i + 1]
+ });
+ }
+
+ return transformedReply;
+}
diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts
new file mode 100644
index 0000000000..e60daa917a
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHSCORES.spec.ts
@@ -0,0 +1,33 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGGET_WITHSCORES';
+
+describe('SUGGET WITHSCORES', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix'),
+ ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES']
+ );
+ });
+
+ describe('client.ft.sugGetWithScores', () => {
+ testUtils.testWithClient('null', async client => {
+ assert.equal(
+ await client.ft.sugGetWithScores('key', 'prefix'),
+ null
+ );
+ }, GLOBAL.SERVERS.OPEN);
+
+ testUtils.testWithClient('with suggestions', async client => {
+ await client.ft.sugAdd('key', 'string', 1);
+
+ assert.deepEqual(
+ await client.ft.sugGetWithScores('key', 'string'),
+ [{
+ suggestion: 'string',
+ score: 2147483648
+ }]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+ });
+});
diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES.ts b/packages/search/lib/commands/SUGGET_WITHSCORES.ts
new file mode 100644
index 0000000000..bad5bff299
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHSCORES.ts
@@ -0,0 +1,29 @@
+import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET';
+
+export { IS_READ_ONLY } from './SUGGET';
+
+export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array {
+ return [
+ ...transformSugGetArguments(key, prefix, options),
+ 'WITHSCORES'
+ ];
+}
+
+export interface SuggestionWithScores {
+ suggestion: string;
+ score: number;
+}
+
+export function transformReply(rawReply: Array | null): Array | null {
+ if (rawReply === null) return null;
+
+ const transformedReply = [];
+ for (let i = 0; i < rawReply.length; i += 2) {
+ transformedReply.push({
+ suggestion: rawReply[i],
+ score: Number(rawReply[i + 1])
+ });
+ }
+
+ return transformedReply;
+}
diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts
new file mode 100644
index 0000000000..0900d91b8d
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.spec.ts
@@ -0,0 +1,34 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGGET_WITHSCORES_WITHPAYLOADS';
+
+describe('SUGGET WITHSCORES WITHPAYLOADS', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key', 'prefix'),
+ ['FT.SUGGET', 'key', 'prefix', 'WITHSCORES', 'WITHPAYLOADS']
+ );
+ });
+
+ describe('client.ft.sugGetWithScoresWithPayloads', () => {
+ testUtils.testWithClient('null', async client => {
+ assert.equal(
+ await client.ft.sugGetWithScoresWithPayloads('key', 'prefix'),
+ null
+ );
+ }, GLOBAL.SERVERS.OPEN);
+
+ testUtils.testWithClient('with suggestions', async client => {
+ await client.ft.sugAdd('key', 'string', 1, { PAYLOAD: 'payload' });
+
+ assert.deepEqual(
+ await client.ft.sugGetWithScoresWithPayloads('key', 'string'),
+ [{
+ suggestion: 'string',
+ score: 2147483648,
+ payload: 'payload'
+ }]
+ );
+ }, GLOBAL.SERVERS.OPEN);
+ });
+});
diff --git a/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts
new file mode 100644
index 0000000000..3b2fe7667b
--- /dev/null
+++ b/packages/search/lib/commands/SUGGET_WITHSCORES_WITHPAYLOADS.ts
@@ -0,0 +1,30 @@
+import { SugGetOptions, transformArguments as transformSugGetArguments } from './SUGGET';
+import { SuggestionWithPayload } from './SUGGET_WITHPAYLOADS';
+import { SuggestionWithScores } from './SUGGET_WITHSCORES';
+
+export { IS_READ_ONLY } from './SUGGET';
+
+export function transformArguments(key: string, prefix: string, options?: SugGetOptions): Array {
+ return [
+ ...transformSugGetArguments(key, prefix, options),
+ 'WITHSCORES',
+ 'WITHPAYLOADS'
+ ];
+}
+
+type SuggestionWithScoresAndPayloads = SuggestionWithScores & SuggestionWithPayload;
+
+export function transformReply(rawReply: Array | null): Array | null {
+ if (rawReply === null) return null;
+
+ const transformedReply = [];
+ for (let i = 0; i < rawReply.length; i += 3) {
+ transformedReply.push({
+ suggestion: rawReply[i]!,
+ score: Number(rawReply[i + 1]!),
+ payload: rawReply[i + 2]
+ });
+ }
+
+ return transformedReply;
+}
diff --git a/packages/search/lib/commands/SUGLEN.spec.ts b/packages/search/lib/commands/SUGLEN.spec.ts
new file mode 100644
index 0000000000..2ea680df95
--- /dev/null
+++ b/packages/search/lib/commands/SUGLEN.spec.ts
@@ -0,0 +1,19 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SUGLEN';
+
+describe('SUGLEN', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('key'),
+ ['FT.SUGLEN', 'key']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.sugLen', async client => {
+ assert.equal(
+ await client.ft.sugLen('key'),
+ 0
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SUGLEN.ts b/packages/search/lib/commands/SUGLEN.ts
new file mode 100644
index 0000000000..15b3da6126
--- /dev/null
+++ b/packages/search/lib/commands/SUGLEN.ts
@@ -0,0 +1,7 @@
+export const IS_READ_ONLY = true;
+
+export function transformArguments(key: string): Array {
+ return ['FT.SUGLEN', key];
+}
+
+export declare function transformReply(): number;
diff --git a/packages/search/lib/commands/SYNDUMP.spec.ts b/packages/search/lib/commands/SYNDUMP.spec.ts
new file mode 100644
index 0000000000..4b0cb0c8b3
--- /dev/null
+++ b/packages/search/lib/commands/SYNDUMP.spec.ts
@@ -0,0 +1,23 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SYNDUMP';
+
+describe('SYNDUMP', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('index'),
+ ['FT.SYNDUMP', 'index']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.synDump', async client => {
+ await client.ft.create('index', {}, {
+ ON: 'HASH' // TODO: shouldn't be mandatory
+ });
+
+ assert.deepEqual(
+ await client.ft.synDump('index'),
+ []
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SYNDUMP.ts b/packages/search/lib/commands/SYNDUMP.ts
new file mode 100644
index 0000000000..5f1e71aaf7
--- /dev/null
+++ b/packages/search/lib/commands/SYNDUMP.ts
@@ -0,0 +1,5 @@
+export function transformArguments(index: string): Array {
+ return ['FT.SYNDUMP', index];
+}
+
+export declare function transformReply(): Array;
diff --git a/packages/search/lib/commands/SYNUPDATE.spec.ts b/packages/search/lib/commands/SYNUPDATE.spec.ts
new file mode 100644
index 0000000000..bf7fed8493
--- /dev/null
+++ b/packages/search/lib/commands/SYNUPDATE.spec.ts
@@ -0,0 +1,39 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './SYNUPDATE';
+
+describe('SYNUPDATE', () => {
+ describe('transformArguments', () => {
+ it('single term', () => {
+ assert.deepEqual(
+ transformArguments('index', 'groupId', 'term'),
+ ['FT.SYNUPDATE', 'index', 'groupId', 'term']
+ );
+ });
+
+ it('multiple terms', () => {
+ assert.deepEqual(
+ transformArguments('index', 'groupId', ['1', '2']),
+ ['FT.SYNUPDATE', 'index', 'groupId', '1', '2']
+ );
+ });
+
+ it('with SKIPINITIALSCAN', () => {
+ assert.deepEqual(
+ transformArguments('index', 'groupId', 'term', { SKIPINITIALSCAN: true }),
+ ['FT.SYNUPDATE', 'index', 'groupId', 'SKIPINITIALSCAN', 'term']
+ );
+ });
+ });
+
+ testUtils.testWithClient('client.ft.synUpdate', async client => {
+ await client.ft.create('index', {}, {
+ ON: 'HASH' // TODO: shouldn't be mandatory
+ });
+
+ assert.equal(
+ await client.ft.synUpdate('index', 'groupId', 'term'),
+ 'OK'
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/SYNUPDATE.ts b/packages/search/lib/commands/SYNUPDATE.ts
new file mode 100644
index 0000000000..3384ea59d9
--- /dev/null
+++ b/packages/search/lib/commands/SYNUPDATE.ts
@@ -0,0 +1,23 @@
+import { pushVerdictArguments } from '@redis/client/dist/lib/commands/generic-transformers';
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+
+interface SynUpdateOptions {
+ SKIPINITIALSCAN?: true;
+}
+
+export function transformArguments(
+ index: string,
+ groupId: string,
+ terms: string | Array,
+ options?: SynUpdateOptions
+): RedisCommandArguments {
+ const args = ['FT.SYNUPDATE', index, groupId];
+
+ if (options?.SKIPINITIALSCAN) {
+ args.push('SKIPINITIALSCAN');
+ }
+
+ return pushVerdictArguments(args, terms);
+}
+
+export declare function transformReply(): 'OK';
diff --git a/packages/search/lib/commands/TAGVALS.spec.ts b/packages/search/lib/commands/TAGVALS.spec.ts
new file mode 100644
index 0000000000..1f90939bb0
--- /dev/null
+++ b/packages/search/lib/commands/TAGVALS.spec.ts
@@ -0,0 +1,24 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { SchemaFieldTypes } from './CREATE';
+import { transformArguments } from './TAGVALS';
+
+describe('TAGVALS', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments('index', '@field'),
+ ['FT.TAGVALS', 'index', '@field']
+ );
+ });
+
+ testUtils.testWithClient('client.ft.tagVals', async client => {
+ await client.ft.create('index', {
+ field: SchemaFieldTypes.TAG
+ });
+
+ assert.deepEqual(
+ await client.ft.tagVals('index', 'field'),
+ []
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/TAGVALS.ts b/packages/search/lib/commands/TAGVALS.ts
new file mode 100644
index 0000000000..54342f0c9e
--- /dev/null
+++ b/packages/search/lib/commands/TAGVALS.ts
@@ -0,0 +1,5 @@
+export function transformArguments(index: string, fieldName: string): Array {
+ return ['FT.TAGVALS', index, fieldName];
+}
+
+export declare function transformReply(): Array;
diff --git a/packages/search/lib/commands/_LIST.spec.ts b/packages/search/lib/commands/_LIST.spec.ts
new file mode 100644
index 0000000000..602c29975f
--- /dev/null
+++ b/packages/search/lib/commands/_LIST.spec.ts
@@ -0,0 +1,19 @@
+import { strict as assert } from 'assert';
+import testUtils, { GLOBAL } from '../test-utils';
+import { transformArguments } from './_LIST';
+
+describe('_LIST', () => {
+ it('transformArguments', () => {
+ assert.deepEqual(
+ transformArguments(),
+ ['FT._LIST']
+ );
+ });
+
+ testUtils.testWithClient('client.ft._list', async client => {
+ assert.deepEqual(
+ await client.ft._list(),
+ []
+ );
+ }, GLOBAL.SERVERS.OPEN);
+});
diff --git a/packages/search/lib/commands/_LIST.ts b/packages/search/lib/commands/_LIST.ts
new file mode 100644
index 0000000000..588ec837c3
--- /dev/null
+++ b/packages/search/lib/commands/_LIST.ts
@@ -0,0 +1,5 @@
+export function transformArguments(): Array {
+ return ['FT._LIST'];
+}
+
+export declare function transformReply(): Array;
diff --git a/packages/search/lib/commands/index.spec.ts b/packages/search/lib/commands/index.spec.ts
new file mode 100644
index 0000000000..f0afa304a9
--- /dev/null
+++ b/packages/search/lib/commands/index.spec.ts
@@ -0,0 +1,46 @@
+import { strict as assert } from 'assert';
+import { pushArgumentsWithLength, pushSortByArguments } from '.';
+
+describe('pushSortByArguments', () => {
+ describe('single', () => {
+ it('string', () => {
+ assert.deepEqual(
+ pushSortByArguments([], 'SORTBT', '@property'),
+ ['SORTBT', '1', '@property']
+ );
+ });
+
+ it('.BY', () => {
+ assert.deepEqual(
+ pushSortByArguments([], 'SORTBT', { BY: '@property' }),
+ ['SORTBT', '1', '@property']
+ );
+ });
+
+ it('with DIRECTION', () => {
+ assert.deepEqual(
+ pushSortByArguments([], 'SORTBY', {
+ BY: '@property',
+ DIRECTION: 'ASC'
+ }),
+ ['SORTBY', '2', '@property', 'ASC']
+ );
+ });
+ });
+
+ it('multiple', () => {
+ assert.deepEqual(
+ pushSortByArguments([], 'SORTBY', ['@1', '@2']),
+ ['SORTBY', '2', '@1', '@2']
+ );
+ });
+});
+
+it('pushArgumentsWithLength', () => {
+ assert.deepEqual(
+ pushArgumentsWithLength(['a'], args => {
+ args.push('b', 'c');
+ }),
+ ['a', '2', 'b', 'c']
+ );
+});
diff --git a/packages/search/lib/commands/index.ts b/packages/search/lib/commands/index.ts
new file mode 100644
index 0000000000..f54a71e0e0
--- /dev/null
+++ b/packages/search/lib/commands/index.ts
@@ -0,0 +1,133 @@
+import * as _LIST from './_LIST';
+import * as AGGREGATE from './AGGREGATE';
+import * as ALIASADD from './ALIASADD';
+import * as ALIASDEL from './ALIASDEL';
+import * as ALIASUPDATE from './ALIASUPDATE';
+import * as CONFIG_GET from './CONFIG_GET';
+import * as CONFIG_SET from './CONFIG_SET';
+import * as CREATE from './CREATE';
+import * as DICTADD from './DICTADD';
+import * as DICTDEL from './DICTDEL';
+import * as DICTDUMP from './DICTDUMP';
+import * as DROPINDEX from './DROPINDEX';
+import * as EXPLAIN from './EXPLAIN';
+import * as EXPLAINCLI from './EXPLAINCLI';
+import * as INFO from './INFO';
+// import * as PROFILE from './PROFILE';
+import * as SEARCH from './SEARCH';
+import * as SPELLCHECK from './SPELLCHECK';
+import * as SUGADD from './SUGADD';
+import * as SUGDEL from './SUGDEL';
+import * as SUGGET_WITHPAYLOADS from './SUGGET_WITHPAYLOADS';
+import * as SUGGET_WITHSCORES_WITHPAYLOADS from './SUGGET_WITHSCORES_WITHPAYLOADS';
+import * as SUGGET_WITHSCORES from './SUGGET_WITHSCORES';
+import * as SUGGET from './SUGGET';
+import * as SUGLEN from './SUGLEN';
+import * as SYNDUMP from './SYNDUMP';
+import * as SYNUPDATE from './SYNUPDATE';
+import * as TAGVALS from './TAGVALS';
+import { RedisCommandArguments } from '@redis/client/dist/lib/commands';
+
+export default {
+ _LIST,
+ _list: _LIST,
+ AGGREGATE,
+ aggregate: AGGREGATE,
+ ALIASADD,
+ aliasAdd: ALIASADD,
+ ALIASDEL,
+ aliasDel: ALIASDEL,
+ ALIASUPDATE,
+ aliasUpdate: ALIASUPDATE,
+ CONFIG_GET,
+ configGet: CONFIG_GET,
+ CONFIG_SET,
+ configSet: CONFIG_SET,
+ CREATE,
+ create: CREATE,
+ DICTADD,
+ dictAdd: DICTADD,
+ DICTDEL,
+ dictDel: DICTDEL,
+ DICTDUMP,
+ dictDump: DICTDUMP,
+ DROPINDEX,
+ dropIndex: DROPINDEX,
+ EXPLAIN,
+ explain: EXPLAIN,
+ EXPLAINCLI,
+ explainCli: EXPLAINCLI,
+ INFO,
+ info: INFO,
+ // PROFILE,
+ // profile: PROFILE,
+ SEARCH,
+ search: SEARCH,
+ SPELLCHECK,
+ spellCheck: SPELLCHECK,
+ SUGADD,
+ sugAdd: SUGADD,
+ SUGDEL,
+ sugDel: SUGDEL,
+ SUGGET_WITHPAYLOADS,
+ sugGetWithPayloads: SUGGET_WITHPAYLOADS,
+ SUGGET_WITHSCORES_WITHPAYLOADS,
+ sugGetWithScoresWithPayloads: SUGGET_WITHSCORES_WITHPAYLOADS,
+ SUGGET_WITHSCORES,
+ sugGetWithScores: SUGGET_WITHSCORES,
+ SUGGET,
+ sugGet: SUGGET,
+ SUGLEN,
+ sugLen: SUGLEN,
+ SYNDUMP,
+ synDump: SYNDUMP,
+ SYNUPDATE,
+ synUpdate: SYNUPDATE,
+ TAGVALS,
+ tagVals: TAGVALS
+};
+
+export type PropertyName = `${'@' | '$.'}${string}`;
+
+export type SortByOptions = PropertyName | {
+ BY: PropertyName;
+ DIRECTION?: 'ASC' | 'DESC';
+};
+
+function pushSortByProperty(args: RedisCommandArguments, sortBy: SortByOptions): void {
+ if (typeof sortBy === 'string') {
+ args.push(sortBy);
+ } else {
+ args.push(sortBy.BY);
+
+ if (sortBy.DIRECTION) {
+ args.push(sortBy.DIRECTION);
+ }
+ }
+}
+
+export function pushSortByArguments(args: RedisCommandArguments, name: string, sortBy: SortByOptions | Array): RedisCommandArguments {
+ const lengthBefore = args.push(
+ name,
+ '' // will be overwritten
+ );
+
+ if (Array.isArray(sortBy)) {
+ for (const field of sortBy) {
+ pushSortByProperty(args, field);
+ }
+ } else {
+ pushSortByProperty(args, sortBy);
+ }
+
+ args[lengthBefore - 1] = (args.length - lengthBefore).toString();
+
+ return args;
+}
+
+export function pushArgumentsWithLength(args: RedisCommandArguments, fn: (args: RedisCommandArguments) => void): RedisCommandArguments {
+ const lengthIndex = args.push('') - 1;
+ fn(args);
+ args[lengthIndex] = (args.length - lengthIndex - 1).toString();
+ return args;
+}
diff --git a/packages/search/lib/index.ts b/packages/search/lib/index.ts
new file mode 100644
index 0000000000..bc0e103e8c
--- /dev/null
+++ b/packages/search/lib/index.ts
@@ -0,0 +1 @@
+export { default } from './commands';
diff --git a/packages/search/lib/test-utils.ts b/packages/search/lib/test-utils.ts
new file mode 100644
index 0000000000..c68504c21d
--- /dev/null
+++ b/packages/search/lib/test-utils.ts
@@ -0,0 +1,21 @@
+import TestUtils from '@redis/test-utils';
+import RediSearch from '.';
+
+export default new TestUtils({
+ dockerImageName: 'redislabs/redisearch',
+ dockerImageVersionArgument: 'redisearch-version',
+ defaultDockerVersion: '2.2.1'
+});
+
+export const GLOBAL = {
+ SERVERS: {
+ OPEN: {
+ serverArguments: ['--loadmodule /usr/lib/redis/modules/redisearch.so'],
+ clientOptions: {
+ modules: {
+ ft: RediSearch
+ }
+ }
+ }
+ }
+};
diff --git a/packages/search/package.json b/packages/search/package.json
new file mode 100644
index 0000000000..dc435cbd36
--- /dev/null
+++ b/packages/search/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "@redis/search",
+ "version": "1.0.0-rc.0",
+ "license": "MIT",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "test": "nyc -r text-summary -r html mocha -r source-map-support/register -r ts-node/register './lib/**/*.spec.ts'",
+ "build": "tsc"
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ },
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@redis/test-utils": "*",
+ "@types/node": "^16.11.6",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4"
+ }
+}
diff --git a/packages/search/tsconfig.json b/packages/search/tsconfig.json
new file mode 100644
index 0000000000..fdb86c004c
--- /dev/null
+++ b/packages/search/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "./dist"
+ },
+ "include": [
+ "./lib/**/*.ts"
+ ]
+}
diff --git a/packages/test-utils/docker/Dockerfile b/packages/test-utils/docker/Dockerfile
new file mode 100644
index 0000000000..23fc0b3a51
--- /dev/null
+++ b/packages/test-utils/docker/Dockerfile
@@ -0,0 +1,9 @@
+ARG IMAGE
+FROM ${IMAGE}
+
+ARG REDIS_ARGUMENTS
+ENV REDIS_ARGUMENTS=${REDIS_ARGUMENTS}
+
+COPY ./entrypoint.sh /
+
+ENTRYPOINT ["/entrypoint.sh"]
diff --git a/packages/test-utils/docker/entrypoint.sh b/packages/test-utils/docker/entrypoint.sh
new file mode 100755
index 0000000000..244977e83c
--- /dev/null
+++ b/packages/test-utils/docker/entrypoint.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+echo testststealkshdfklhasdf
+
+echo $REDIS_ARGUMENTS
+
+redis-server $REDIS_ARGUMENTS
diff --git a/lib/test-utils/dockers.ts b/packages/test-utils/lib/dockers.ts
similarity index 90%
rename from lib/test-utils/dockers.ts
rename to packages/test-utils/lib/dockers.ts
index 3e48618ee4..28bd1e4905 100644
--- a/lib/test-utils/dockers.ts
+++ b/packages/test-utils/lib/dockers.ts
@@ -1,8 +1,9 @@
import { createConnection } from 'net';
import { once } from 'events';
-import { RedisModules, RedisScripts } from '../commands';
-import RedisClient, { RedisClientType } from '../client';
-import { promiseTimeout } from '../utils';
+import { RedisModules, RedisScripts } from '@redis/client/lib/commands';
+import RedisClient, { RedisClientType } from '@redis/client/lib/client';
+import { promiseTimeout } from '@redis/client/lib/utils';
+import path from 'path';
import { promisify } from 'util';
import { exec } from 'child_process';
const execAsync = promisify(exec);
@@ -45,11 +46,17 @@ export interface RedisServerDocker {
dockerId: string;
}
+// ".." cause it'll be in `./dist`
+const DOCKER_FODLER_PATH = path.join(__dirname, '../docker');
+
async function spawnRedisServerDocker({ image, version }: RedisServerDockerConfig, serverArguments: Array): Promise {
const port = (await portIterator.next()).value,
{ stdout, stderr } = await execAsync(
- `docker run -d --network host ${image}:${version.join('.')} ` +
- `--save --port ${port.toString()} ${serverArguments.join(' ')}`
+ 'docker run -d --network host $(' +
+ `docker build ${DOCKER_FODLER_PATH} -q ` +
+ `--build-arg IMAGE=${image}:${version.join('.')} ` +
+ `--build-arg REDIS_ARGUMENTS="--save --port ${port.toString()} ${serverArguments.join(' ')}"` +
+ ')'
);
if (!stdout) {
diff --git a/lib/test-utils/test-utils.ts b/packages/test-utils/lib/index.ts
similarity index 83%
rename from lib/test-utils/test-utils.ts
rename to packages/test-utils/lib/index.ts
index a550e3f707..d6692cace6 100644
--- a/lib/test-utils/test-utils.ts
+++ b/packages/test-utils/lib/index.ts
@@ -1,10 +1,18 @@
-import { RedisModules, RedisScripts } from '../commands';
-import RedisClient, { RedisClientOptions, RedisClientType } from '../client';
-import RedisCluster, { RedisClusterOptions, RedisClusterType } from '../cluster';
+import { RedisModules, RedisScripts } from '@redis/client/lib/commands';
+import RedisClient, { RedisClientOptions, RedisClientType } from '@redis/client/lib/client';
+import RedisCluster, { RedisClusterOptions, RedisClusterType } from '@redis/client/lib/cluster';
import { RedisServerDockerConfig, spawnRedisServer, spawnRedisCluster } from './dockers';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
+interface TestUtilsConfig {
+ dockerImageName: string;
+ dockerImageVersionArgument: string;
+ defaultDockerVersion: string;
+ defaultClientOptions?: Partial>;
+ defaultClusterOptions?: Partial>;
+}
+
interface CommonTestOptions {
minimumDockerVersion?: Array;
}
@@ -20,20 +28,14 @@ interface ClusterTestOptions ext
clusterConfiguration?: Partial>;
}
-interface TestsUtilsConfig {
- dockerImageName: string;
- dockerImageVersionArgument: string;
- defaultDockerVersion: string;
-}
-
-export default class TestUtils {
- static #getVersion(config: TestsUtilsConfig): Array {
+export default class TestUtils {
+ static #getVersion(argumentName: string, defaultVersion: string): Array {
return yargs(hideBin(process.argv))
- .option('redis-version', {
+ .option(argumentName, {
type: 'string',
- default: config.defaultDockerVersion
+ default: defaultVersion
})
- .coerce(config.dockerImageVersionArgument, (arg: string) => {
+ .coerce(argumentName, (arg: string) => {
return arg.split('.').map(x => {
const value = Number(x);
if (Number.isNaN(value)) {
@@ -43,16 +45,16 @@ export default class TestUtils {
return value;
});
})
- .demandOption(config.dockerImageVersionArgument)
- .parseSync()[config.dockerImageVersionArgument];
+ .demandOption(argumentName)
+ .parseSync()[argumentName];
}
readonly #DOCKER_IMAGE: RedisServerDockerConfig;
- constructor(config: TestsUtilsConfig) {
+ constructor(config: TestUtilsConfig) {
this.#DOCKER_IMAGE = {
image: config.dockerImageName,
- version: TestUtils.#getVersion(config)
+ version: TestUtils.#getVersion(config.dockerImageVersionArgument, config.defaultDockerVersion)
};
}
@@ -84,7 +86,7 @@ export default class TestUtils {
title: string,
fn: (client: RedisClientType) => Promise,
options: ClientTestOptions
- ): Mocha.Test {
+ ): void {
let dockerPromise: ReturnType;
if (this.isVersionGreaterThan(options.minimumDockerVersion)) {
const dockerImage = this.#DOCKER_IMAGE;
@@ -96,7 +98,7 @@ export default class TestUtils {
});
}
- return it(title, async function() {
+ it(title, async function() {
if (!dockerPromise) return this.skip();
const client = RedisClient.create({
@@ -111,10 +113,10 @@ export default class TestUtils {
return fn(client);
}
- try {
- await client.connect();
- await client.flushAll();
+ await client.connect();
+ try {
+ await client.flushAll();
await fn(client);
} finally {
if (client.isOpen) {
@@ -135,7 +137,7 @@ export default class TestUtils {
title: string,
fn: (cluster: RedisClusterType) => Promise,
options: ClusterTestOptions
- ): Mocha.Test {
+ ): void {
let dockersPromise: ReturnType;
if (this.isVersionGreaterThan(options.minimumDockerVersion)) {
const dockerImage = this.#DOCKER_IMAGE;
@@ -147,7 +149,7 @@ export default class TestUtils {
});
}
- return it(title, async function () {
+ it(title, async function () {
if (!dockersPromise) return this.skip();
const dockers = await dockersPromise,
diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json
new file mode 100644
index 0000000000..0c934ace9f
--- /dev/null
+++ b/packages/test-utils/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@redis/test-utils",
+ "private": true,
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "build": "tsc",
+ "test": "echo \"TODO\""
+ },
+ "peerDependencies": {
+ "@redis/client": "^4.0.0-rc"
+ },
+ "devDependencies": {
+ "@istanbuljs/nyc-config-typescript": "^1.0.1",
+ "@tsconfig/node12": "^1.0.9",
+ "@types/mocha": "^9.0.0",
+ "@types/node": "^16.11.6",
+ "@types/yargs": "^17.0.5",
+ "mocha": "^9.1.3",
+ "nyc": "^15.1.0",
+ "release-it": "^14.11.6",
+ "source-map-support": "^0.5.20",
+ "ts-node": "^10.4.0",
+ "typescript": "^4.4.4",
+ "yargs": "^17.2.1"
+ }
+}
diff --git a/packages/test-utils/tsconfig.json b/packages/test-utils/tsconfig.json
new file mode 100644
index 0000000000..fdb86c004c
--- /dev/null
+++ b/packages/test-utils/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "outDir": "./dist"
+ },
+ "include": [
+ "./lib/**/*.ts"
+ ]
+}
diff --git a/tsconfig.json b/tsconfig.json
index 1f76310034..fa46effbdc 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,33 +1,15 @@
{
- "extends": "@tsconfig/node12/tsconfig.json",
+ "extends": "@tsconfig/node12/tsconfig",
"compilerOptions": {
- "outDir": "./dist",
"declaration": true,
- "useDefineForClassFields": true,
- "allowJs": true
+ "allowJs": true,
+ "useDefineForClassFields": true
},
"files": [
- "./lib/ts-declarations/cluster-key-slot.d.ts",
- "./lib/ts-declarations/redis-parser.d.ts"
- ],
- "include": [
- "./index.ts",
- "./lib/**/*.ts"
+ "./packages/client/lib/ts-declarations/cluster-key-slot.d.ts",
+ "./packages/client/lib/ts-declarations/redis-parser.d.ts"
],
"ts-node": {
"files": true
- },
- "typedocOptions": {
- "entryPoints": [
- "./index.ts",
- "./lib"
- ],
- "entryPointStrategy": "expand",
- "exclude": [
- "./lib/ts-declarations",
- "./lib/test-utils.ts"
- ],
- "theme": "./node_modules/typedoc-github-wiki-theme/dist",
- "out": "documentation"
}
}