|
| 1 | +# redis-js SDK |
| 2 | + |
| 3 | +## Adding a New Redis Command |
| 4 | + |
| 5 | +You need to touch **6 files** (2 new, 4 existing): |
| 6 | + |
| 7 | +### 1. Create the command file: `pkg/commands/<command_name>.ts` |
| 8 | + |
| 9 | +```typescript |
| 10 | +import type { CommandOptions } from "./command"; |
| 11 | +import { Command } from "./command"; |
| 12 | +/** |
| 13 | + * @see https://redis.io/commands/<command-name> |
| 14 | + */ |
| 15 | +export class MyCommand extends Command<TResult, TData> { |
| 16 | + constructor(cmd: [...args], opts?: CommandOptions<TResult, TData>) { |
| 17 | + super(["mycommand", ...builtArgs], opts); |
| 18 | + } |
| 19 | +} |
| 20 | +``` |
| 21 | + |
| 22 | +Key patterns: |
| 23 | + |
| 24 | +- `Command<number, number>` for commands returning a count (SCARD, SINTERCARD, SINTERSTORE) |
| 25 | +- `Command<unknown[], TData[]>` for commands returning arrays (SINTER, SMEMBERS) |
| 26 | +- Constructor first param is a tuple of the command's Redis arguments |
| 27 | +- Constructor second param is always `CommandOptions` |
| 28 | +- Call `super(["commandname", ...args], opts)` to build the Redis command array |
| 29 | +- For optional params (like LIMIT), conditionally push to the command array: |
| 30 | + ```typescript |
| 31 | + if (opts?.limit !== undefined) { |
| 32 | + command.push("LIMIT", opts.limit); |
| 33 | + } |
| 34 | + ``` |
| 35 | +- For commands taking a variable number of keys with a numkeys param, accept `keys: string[]` and spread: `["cmd", keys.length, ...keys]` |
| 36 | + |
| 37 | +### 2. Create the test file: `pkg/commands/<command_name>.test.ts` |
| 38 | + |
| 39 | +```typescript |
| 40 | +import { keygen, newHttpClient, randomID } from "../test-utils"; |
| 41 | +import { afterAll, expect, test } from "bun:test"; |
| 42 | +import { SAddCommand } from "./sadd"; // or whatever setup commands needed |
| 43 | +import { MyCommand } from "./my_command"; |
| 44 | + |
| 45 | +const client = newHttpClient(); |
| 46 | +const { newKey, cleanup } = keygen(); |
| 47 | +afterAll(cleanup); |
| 48 | + |
| 49 | +test("description", async () => { |
| 50 | + const key = newKey(); |
| 51 | + // setup |
| 52 | + const res = await new MyCommand([...args]).exec(client); |
| 53 | + expect(res).toEqual(expected); |
| 54 | +}); |
| 55 | +``` |
| 56 | + |
| 57 | +Run tests with: `npx bun test pkg/commands/<command_name>.test.ts` |
| 58 | + |
| 59 | +### 3. Add export to `pkg/commands/mod.ts` |
| 60 | + |
| 61 | +Insert `export * from "./<command_name>";` in alphabetical order among existing exports. |
| 62 | + |
| 63 | +### 4. Add type export to `pkg/commands/types.ts` |
| 64 | + |
| 65 | +Insert `export { type MyCommand } from "./<command_name>";` in alphabetical order. |
| 66 | + |
| 67 | +### 5. Add method to `pkg/redis.ts` |
| 68 | + |
| 69 | +- Add `MyCommand` to the import block from `"./commands/mod"` (alphabetical within the S/Z/etc group) |
| 70 | +- Add method to the class (alphabetical among similar commands): |
| 71 | + |
| 72 | +```typescript |
| 73 | +/** |
| 74 | + * @see https://redis.io/commands/<command-name> |
| 75 | + */ |
| 76 | +mycommand = (...args: CommandArgs<typeof MyCommand>) => |
| 77 | + new MyCommand(args, this.opts).exec(this.client); |
| 78 | +``` |
| 79 | + |
| 80 | +### 6. Add method to `pkg/pipeline.ts` |
| 81 | + |
| 82 | +- Same import addition as redis.ts |
| 83 | +- Add method using `this.chain()` instead of `.exec()`: |
| 84 | + |
| 85 | +```typescript |
| 86 | +/** |
| 87 | + * @see https://redis.io/commands/<command-name> |
| 88 | + */ |
| 89 | +mycommand = (...args: CommandArgs<typeof MyCommand>) => |
| 90 | + this.chain(new MyCommand(args, this.commandOptions)); |
| 91 | +``` |
| 92 | + |
| 93 | +### Checklist |
| 94 | + |
| 95 | +- [ ] `pkg/commands/<name>.ts` - Command class |
| 96 | +- [ ] `pkg/commands/<name>.test.ts` - Tests |
| 97 | +- [ ] `pkg/commands/mod.ts` - Add `export *` line |
| 98 | +- [ ] `pkg/commands/types.ts` - Add `export { type }` line |
| 99 | +- [ ] `pkg/redis.ts` - Add import + method |
| 100 | +- [ ] `pkg/pipeline.ts` - Add import + method |
| 101 | +- [ ] Run `npx bun test pkg/commands/<name>.test.ts` to verify |
0 commit comments