Skip to content

Commit 1e10c95

Browse files
committed
feat: add declarations for methods
1 parent 4e8c567 commit 1e10c95

File tree

15 files changed

+12661
-31
lines changed

15 files changed

+12661
-31
lines changed

.eslintrc.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"plugin:@typescript-eslint/eslint-recommended",
66
"prettier"
77
],
8+
"ignorePatterns": ["bin/generateRedisCommander/template.ts"],
89
"parser": "@typescript-eslint/parser",
910
"plugins": ["@typescript-eslint"],
1011
"env": { "node": true },
@@ -18,6 +19,7 @@
1819
"@typescript-eslint/no-this-alias": 0,
1920
"@typescript-eslint/ban-ts-ignore": 0,
2021
"@typescript-eslint/ban-ts-comment": 0,
22+
"@typescript-eslint/adjacent-overload-signatures": 0,
2123
"@typescript-eslint/ban-types": 0,
2224
"@typescript-eslint/no-empty-interface": 0,
2325
"@typescript-eslint/no-empty-function": 0,

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
node_modules
22
*.cpuprofile
3-
/test.js
3+
/test.*
44
/.idea
55
built
66

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const typeMaps = require("./typeMaps");
2+
3+
module.exports = {
4+
debug: [
5+
[{ name: "subcommand", type: "string" }],
6+
[
7+
{ name: "subcommand", type: "string" },
8+
{ name: "args", type: typeMaps.string, multiple: true },
9+
],
10+
],
11+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const returnTypes = require("./returnTypes");
2+
const argumentTypes = require("./argumentTypes");
3+
const typeMaps = require("./typeMaps");
4+
const { getCommanderInterface } = require("ioredis-interface-generator");
5+
6+
const ignoredCommands = ["monitor", "multi"];
7+
const commands = require("redis-commands").list.filter(
8+
(name) => !ignoredCommands.includes(name)
9+
);
10+
11+
const fs = require("fs");
12+
const path = require("path");
13+
14+
const template = fs.readFileSync(path.join(__dirname, "/template.ts"), "utf8");
15+
16+
async function main() {
17+
const interface = await getCommanderInterface({
18+
commands,
19+
complexityLimit: 50,
20+
redisOpts: {
21+
port: process.env.REDIS_PORT,
22+
},
23+
returnTypes,
24+
argumentTypes,
25+
typeMaps: typeMaps,
26+
});
27+
28+
fs.writeFileSync(
29+
path.join(__dirname, "..", "..", "lib/utils/RedisCommander.ts"),
30+
template.replace("////", () => interface)
31+
);
32+
}
33+
34+
main()
35+
.catch(console.error)
36+
.then(() => process.exit(0));
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
module.exports = {
2+
multi: "ChainableCommander",
3+
get: "string | null",
4+
set: (types) => {
5+
if (types.find((type) => type.includes("GET"))) {
6+
return "string | null";
7+
}
8+
if (types.find((type) => type.includes("NX") || type.includes("XX"))) {
9+
return "'OK' | null";
10+
}
11+
return "'OK'";
12+
},
13+
ping: (types) => {
14+
return types.length ? "string" : "'PONG'";
15+
},
16+
append: "number",
17+
asking: "'OK'",
18+
auth: "'OK'",
19+
bgrewriteaof: "string",
20+
bgsave: "'OK'",
21+
bitcount: "number",
22+
bitfield_ro: "unknown[]",
23+
bitop: "number",
24+
bitpos: "number",
25+
blpop: "[string, string] | null",
26+
brpop: "[string, string] | null",
27+
brpoplpush: "string | null",
28+
blmove: "string | null",
29+
lmpop: "unknown[] | null",
30+
blmpop: "unknown[] | null",
31+
bzpopmin: "unknown[] | null",
32+
bzpopmax: "unknown[] | null",
33+
command: "unknown[]",
34+
copy: "number",
35+
dbsize: "number",
36+
decr: "number",
37+
decrby: "number",
38+
del: "number",
39+
discard: "'OK'",
40+
dump: "string",
41+
echo: "string",
42+
exec: "[error: Error, result: unknown][] | null",
43+
exists: "number",
44+
expire: "number",
45+
expireat: "number",
46+
expiretime: "number",
47+
failover: "'OK'",
48+
flushall: "'OK'",
49+
flushdb: "'OK'",
50+
geoadd: "number",
51+
geohash: "string[]",
52+
geopos: "unknown[] | null",
53+
geodist: "string | null",
54+
georadius: "unknown[]",
55+
geosearch: "unknown[]",
56+
geosearchstore: "number",
57+
getbit: "number",
58+
getdel: "string | null",
59+
getex: "string | null",
60+
getrange: "string",
61+
getset: "string | null",
62+
hdel: "number",
63+
hello: "unknown[]",
64+
hexists: "number",
65+
hget: "string | null",
66+
hincrby: "number",
67+
hincrbyfloat: "string",
68+
hkeys: "string[]",
69+
hlen: "number",
70+
hmget: "(string | null)[]",
71+
hmset: "'OK'",
72+
hset: "number",
73+
hsetnx: "number",
74+
hrandfield: "string | unknown[] | null",
75+
hstrlen: "number",
76+
hvals: "string[]",
77+
incr: "number",
78+
incrby: "number",
79+
incrbyfloat: "string",
80+
info: "string",
81+
lolwut: "string",
82+
keys: "string[]",
83+
lastsave: "number",
84+
lindex: "string | null",
85+
linsert: "number",
86+
llen: "number",
87+
lpop: "string" | "unknown[] | null",
88+
lpos: null,
89+
lpush: "number",
90+
lpushx: "number",
91+
lrange: "string[]",
92+
lrem: "number",
93+
lset: "'OK'",
94+
ltrim: "'OK'",
95+
mget: "(string | null)[]",
96+
migrate: "'OK'",
97+
move: "number",
98+
mset: "'OK'",
99+
msetnx: "number",
100+
persist: "number",
101+
pexpire: "number",
102+
pexpireat: "number",
103+
pexpiretime: "number",
104+
pfadd: "number",
105+
pfcount: "number",
106+
pfmerge: "'OK'",
107+
pubsub: "unknown[]",
108+
pttl: "number",
109+
publish: "number",
110+
quit: "'OK'",
111+
randomkey: "string | null",
112+
readonly: "'OK'",
113+
readwrite: "'OK'",
114+
rename: "'OK'",
115+
renamenx: "number",
116+
reset: "'OK'",
117+
restore: "'OK'",
118+
role: "unknown[]",
119+
rpop: "string" | "unknown[] | null",
120+
rpoplpush: "string",
121+
lmove: "string",
122+
rpush: "number",
123+
rpushx: "number",
124+
sadd: "number",
125+
save: "'OK'",
126+
scard: "number",
127+
sdiff: "string[]",
128+
sdiffstore: "number",
129+
select: "'OK'",
130+
setbit: "number",
131+
setex: "'OK'",
132+
setnx: "number",
133+
setrange: "number",
134+
shutdown: "'OK'",
135+
sinter: "string[]",
136+
sintercard: "number",
137+
sinterstore: "number",
138+
sismember: "number",
139+
smismember: "unknown[]",
140+
slaveof: "'OK'",
141+
replicaof: "'OK'",
142+
smembers: "string[]",
143+
smove: "number",
144+
sort: "number" | "unknown[]",
145+
sortRo: "unknown[]",
146+
spop: (types) => (types.length > 1 ? "string[]" : "string | null"),
147+
srandmember: "string" | "unknown[] | null",
148+
srem: "number",
149+
strlen: "number",
150+
sunion: "string[]",
151+
sunionstore: "number",
152+
swapdb: "'OK'",
153+
time: "number[]",
154+
touch: "number",
155+
ttl: "number",
156+
type: "string",
157+
unlink: "number",
158+
unwatch: "'OK'",
159+
wait: "number",
160+
watch: "'OK'",
161+
zadd: (types) => {
162+
if (types.find((type) => type.includes("INCR"))) {
163+
if (types.find((type) => type.includes("XX") || type.includes("NX"))) {
164+
return "string | null";
165+
}
166+
return "string";
167+
}
168+
return "number";
169+
},
170+
zcard: "number",
171+
zcount: "number",
172+
zdiff: "string[]",
173+
zdiffstore: "number",
174+
zincrby: "string",
175+
zinter: "string[]",
176+
zintercard: "number",
177+
zinterstore: "number",
178+
zlexcount: "number",
179+
zpopmax: "string[]",
180+
zpopmin: "string[]",
181+
zrandmember: (types) => {
182+
return types.includes("number") ? "string | null" : "string[]";
183+
},
184+
zrangestore: "number",
185+
zrange: "string[]",
186+
zrangebylex: "string[]",
187+
zrevrangebylex: "string[]",
188+
zrangebyscore: "string[]",
189+
zrank: "number | null",
190+
zrem: "number",
191+
zremrangebylex: "number",
192+
zremrangebyrank: "number",
193+
zremrangebyscore: "number",
194+
zrevrange: "string[]",
195+
zrevrangebyscore: "string[]",
196+
zrevrank: "number | null",
197+
zscore: "string",
198+
zunion: "unknown[]",
199+
zmscore: "unknown[] | null",
200+
zunionstore: "number",
201+
scan: "[cursor: string, elements: string[]]",
202+
sscan: "[cursor: string, elements: string[]]",
203+
hscan: "[cursor: string, elements: string[]]",
204+
zscan: "[cursor: string, elements: string[]]",
205+
xadd: "string | null",
206+
xtrim: "number",
207+
xdel: "number",
208+
xrange: "[id: string, fields: string[]][]",
209+
xrevrange: "[id: string, fields: string[]][]",
210+
xlen: "number",
211+
xread: (types) => {
212+
if (types.find((type) => type.includes("BLOCK"))) {
213+
return "unknown[] | null";
214+
}
215+
return "unknown[]";
216+
},
217+
xreadgroup: "unknown[]",
218+
xack: "number",
219+
xclaim: "unknown[]",
220+
xautoclaim: "unknown[]",
221+
xpending: "unknown[]",
222+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
type RedisKey = string | Buffer;
2+
type RedisValue = string | Buffer | number;
3+
type Callback<T> = (err: Error | null, res: T) => void;
4+
5+
// Inspired by https://github.com/mmkal/handy-redis/blob/main/src/generated/interface.ts.
6+
// Should be fixed with https://github.com/Microsoft/TypeScript/issues/1213
7+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
8+
export interface ResultTypes<Result, Context> {
9+
default: Promise<Result>;
10+
pipeline: ChainableCommander;
11+
}
12+
13+
export interface ChainableCommander
14+
extends RedisCommander<{ type: "pipeline" }> {}
15+
16+
export type ClientContext = { type: keyof ResultTypes<unknown, unknown> };
17+
export type Result<T, Context extends ClientContext> =
18+
// prettier-break
19+
ResultTypes<T, Context>[Context["type"]];
20+
21+
interface RedisCommander<Context extends ClientContext = { type: "default" }> {
22+
multi(): ChainableCommander;
23+
////
24+
}
25+
26+
export default RedisCommander;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
key: "RedisKey",
3+
string: "string | Buffer | number",
4+
pattern: "string",
5+
number: "number | string",
6+
};

lib/Redis.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import { EventEmitter } from "events";
22
import * as commands from "redis-commands";
33
import asCallback from "standard-as-callback";
44
import { AbstractConnector, Command, ScanStream, SentinelConnector } from ".";
5-
import Commander from "./utils/Commander";
65
import { StandaloneConnector } from "./connectors";
76
import * as eventHandler from "./redis/event_handler";
87
import {
98
DEFAULT_REDIS_OPTIONS,
109
ReconnectOnError,
1110
RedisOptions,
1211
} from "./redis/RedisOptions";
13-
import { addTransactionSupport } from "./transaction";
12+
import { addTransactionSupport, Transaction } from "./transaction";
1413
import { CallbackFunction, ICommandItem, NetStream } from "./types";
1514
import {
1615
CONNECTION_CLOSED_ERROR_MSG,
@@ -20,6 +19,7 @@ import {
2019
resolveTLSProfile,
2120
} from "./utils";
2221
import applyMixin from "./utils/applyMixin";
22+
import Commander from "./utils/Commander";
2323
import { defaults, noop } from "./utils/lodash";
2424
import Deque = require("denque");
2525
const debug = Debug("redis");
@@ -409,7 +409,6 @@ class Redis extends Commander {
409409
this.condition.select !== item.select &&
410410
item.command.name !== "select"
411411
) {
412-
// @ts-expect-error
413412
this.select(item.select);
414413
}
415414
// TODO
@@ -460,8 +459,7 @@ class Redis extends Commander {
460459
*/
461460
private _readyCheck(callback: CallbackFunction) {
462461
const _this = this;
463-
// @ts-expect-error
464-
this.info(function (err: Error | null, res: string) {
462+
this.info(function (err, res) {
465463
if (err) {
466464
return callback(err);
467465
}
@@ -782,5 +780,6 @@ applyMixin(Redis, EventEmitter);
782780
});
783781

784782
addTransactionSupport(Redis.prototype);
783+
interface Redis extends Transaction {}
785784

786785
export default Redis;

lib/autoPipelining.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export function shouldUseAutoPipelining(
9494
*/
9595
export function getFirstValueInFlattenedArray(
9696
args: ArgumentType[]
97-
): string | undefined {
97+
): string | Buffer | number | null | undefined {
9898
for (let i = 0; i < args.length; i++) {
9999
const arg = args[i];
100100
if (typeof arg === "string") {
@@ -107,7 +107,7 @@ export function getFirstValueInFlattenedArray(
107107
}
108108
const flattened = flatten([arg]);
109109
if (flattened.length > 0) {
110-
return String(flattened[0]);
110+
return flattened[0];
111111
}
112112
}
113113
return undefined;

0 commit comments

Comments
 (0)