@upstash/redis 0.0.0-ci.e3757170 → 0.0.0-ci.ec2c4106-20221122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -279
- package/esm/deps/deno.land/x/base64@v0.2.1/base.js +100 -0
- package/esm/deps/deno.land/x/base64@v0.2.1/base64url.js +9 -0
- package/esm/deps/deno.land/x/sha1@v1.0.3/deps.js +1 -0
- package/esm/deps/deno.land/x/sha1@v1.0.3/mod.js +191 -0
- package/esm/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.js +50 -0
- package/esm/pkg/commands/getdel.js +9 -0
- package/esm/pkg/commands/lpos.js +19 -0
- package/esm/pkg/commands/mod.js +2 -0
- package/esm/pkg/commands/scan.js +3 -0
- package/esm/pkg/commands/sdiffstore.js +1 -1
- package/esm/pkg/commands/set.js +16 -4
- package/esm/pkg/commands/zmscore.js +10 -0
- package/esm/pkg/commands/zrange.js +6 -0
- package/esm/pkg/http.js +84 -3
- package/esm/pkg/pipeline.js +42 -6
- package/esm/pkg/redis.js +69 -2
- package/esm/pkg/script.js +77 -0
- package/esm/platforms/cloudflare.js +10 -2
- package/esm/platforms/fastly.js +1 -0
- package/esm/platforms/node_with_fetch.js +14 -1
- package/esm/platforms/nodejs.js +14 -1
- package/esm/version.js +1 -0
- package/package.json +1 -39
- package/script/deps/deno.land/x/base64@v0.2.1/base.js +104 -0
- package/script/deps/deno.land/x/base64@v0.2.1/base64url.js +13 -0
- package/script/deps/deno.land/x/sha1@v1.0.3/deps.js +6 -0
- package/script/deps/deno.land/x/sha1@v1.0.3/mod.js +196 -0
- package/script/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.js +55 -0
- package/script/pkg/commands/getdel.js +13 -0
- package/script/pkg/commands/lpos.js +23 -0
- package/script/pkg/commands/mod.js +2 -0
- package/script/pkg/commands/scan.js +3 -0
- package/script/pkg/commands/sdiffstore.js +1 -1
- package/script/pkg/commands/set.js +16 -4
- package/script/pkg/commands/zmscore.js +14 -0
- package/script/pkg/commands/zrange.js +6 -0
- package/script/pkg/http.js +84 -3
- package/script/pkg/pipeline.js +41 -5
- package/script/pkg/redis.js +68 -1
- package/script/pkg/script.js +81 -0
- package/script/platforms/cloudflare.js +10 -2
- package/script/platforms/fastly.js +1 -0
- package/script/platforms/node_with_fetch.js +14 -1
- package/script/platforms/nodejs.js +14 -1
- package/script/version.js +4 -0
- package/types/deps/deno.land/x/base64@v0.2.1/base.d.ts +5 -0
- package/types/deps/deno.land/x/base64@v0.2.1/base64url.d.ts +1 -0
- package/types/deps/deno.land/x/sha1@v1.0.3/deps.d.ts +1 -0
- package/types/deps/deno.land/x/sha1@v1.0.3/mod.d.ts +26 -0
- package/types/deps/denopkg.com/chiefbiiko/std-encoding@v1.0.0/mod.d.ts +3 -0
- package/types/pkg/commands/bitop.d.ts +0 -1
- package/types/pkg/commands/bitpos.d.ts +1 -1
- package/types/pkg/commands/getdel.d.ts +7 -0
- package/types/pkg/commands/lpop.d.ts +1 -1
- package/types/pkg/commands/lpos.d.ts +15 -0
- package/types/pkg/commands/mget.d.ts +1 -1
- package/types/pkg/commands/mod.d.ts +2 -0
- package/types/pkg/commands/rpop.d.ts +2 -2
- package/types/pkg/commands/scan.d.ts +1 -0
- package/types/pkg/commands/sdiffstore.d.ts +1 -1
- package/types/pkg/commands/set.d.ts +31 -2
- package/types/pkg/commands/spop.d.ts +2 -2
- package/types/pkg/commands/zadd.d.ts +1 -1
- package/types/pkg/commands/zmscore.d.ts +7 -0
- package/types/pkg/commands/zrange.d.ts +7 -0
- package/types/pkg/http.d.ts +53 -5
- package/types/pkg/pipeline.d.ts +29 -8
- package/types/pkg/redis.d.ts +40 -8
- package/types/pkg/script.d.ts +42 -0
- package/types/platforms/cloudflare.d.ts +8 -7
- package/types/platforms/fastly.d.ts +2 -6
- package/types/platforms/node_with_fetch.d.ts +2 -21
- package/types/platforms/nodejs.d.ts +3 -6
- package/types/version.d.ts +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Command } from "./command.js";
|
|
2
|
+
/**
|
|
3
|
+
* @see https://redis.io/commands/lpos
|
|
4
|
+
*/
|
|
5
|
+
export class LPosCommand extends Command {
|
|
6
|
+
constructor(cmd, opts) {
|
|
7
|
+
const args = ["lpos", cmd[0], cmd[1]];
|
|
8
|
+
if (typeof cmd[2]?.rank === "number") {
|
|
9
|
+
args.push("rank", cmd[2].rank);
|
|
10
|
+
}
|
|
11
|
+
if (typeof cmd[2]?.count === "number") {
|
|
12
|
+
args.push("count", cmd[2].count);
|
|
13
|
+
}
|
|
14
|
+
if (typeof cmd[2]?.maxLen === "number") {
|
|
15
|
+
args.push("maxLen", cmd[2].maxLen);
|
|
16
|
+
}
|
|
17
|
+
super(args, opts);
|
|
18
|
+
}
|
|
19
|
+
}
|
package/esm/pkg/commands/mod.js
CHANGED
|
@@ -19,6 +19,7 @@ export * from "./get.js";
|
|
|
19
19
|
export * from "./getbit.js";
|
|
20
20
|
export * from "./getrange.js";
|
|
21
21
|
export * from "./getset.js";
|
|
22
|
+
export * from "./getdel.js";
|
|
22
23
|
export * from "./hdel.js";
|
|
23
24
|
export * from "./hexists.js";
|
|
24
25
|
export * from "./hget.js";
|
|
@@ -42,6 +43,7 @@ export * from "./lindex.js";
|
|
|
42
43
|
export * from "./linsert.js";
|
|
43
44
|
export * from "./llen.js";
|
|
44
45
|
export * from "./lpop.js";
|
|
46
|
+
export * from "./lpos.js";
|
|
45
47
|
export * from "./lpush.js";
|
|
46
48
|
export * from "./lpushx.js";
|
|
47
49
|
export * from "./lrange.js";
|
package/esm/pkg/commands/scan.js
CHANGED
package/esm/pkg/commands/set.js
CHANGED
|
@@ -6,17 +6,29 @@ export class SetCommand extends Command {
|
|
|
6
6
|
constructor([key, value, opts], cmdOpts) {
|
|
7
7
|
const command = ["set", key, value];
|
|
8
8
|
if (opts) {
|
|
9
|
+
if ("nx" in opts && opts.nx) {
|
|
10
|
+
command.push("nx");
|
|
11
|
+
}
|
|
12
|
+
else if ("xx" in opts && opts.xx) {
|
|
13
|
+
command.push("xx");
|
|
14
|
+
}
|
|
15
|
+
if ("get" in opts && opts.get) {
|
|
16
|
+
command.push("get");
|
|
17
|
+
}
|
|
9
18
|
if ("ex" in opts && typeof opts.ex === "number") {
|
|
10
19
|
command.push("ex", opts.ex);
|
|
11
20
|
}
|
|
12
21
|
else if ("px" in opts && typeof opts.px === "number") {
|
|
13
22
|
command.push("px", opts.px);
|
|
14
23
|
}
|
|
15
|
-
if ("
|
|
16
|
-
command.push("
|
|
24
|
+
else if ("exat" in opts && typeof opts.exat === "number") {
|
|
25
|
+
command.push("exat", opts.exat);
|
|
17
26
|
}
|
|
18
|
-
else if ("
|
|
19
|
-
command.push("
|
|
27
|
+
else if ("pxat" in opts && typeof opts.pxat === "number") {
|
|
28
|
+
command.push("pxat", opts.pxat);
|
|
29
|
+
}
|
|
30
|
+
else if ("keepTtl" in opts && opts.keepTtl) {
|
|
31
|
+
command.push("keepTtl", opts.keepTtl);
|
|
20
32
|
}
|
|
21
33
|
}
|
|
22
34
|
super(command, cmdOpts);
|
|
@@ -12,6 +12,12 @@ export class ZRangeCommand extends Command {
|
|
|
12
12
|
if (opts?.byLex) {
|
|
13
13
|
command.push("bylex");
|
|
14
14
|
}
|
|
15
|
+
if (opts?.rev) {
|
|
16
|
+
command.push("rev");
|
|
17
|
+
}
|
|
18
|
+
if (typeof opts?.count !== "undefined" && typeof opts?.offset !== "undefined") {
|
|
19
|
+
command.push("limit", opts.offset, opts.count);
|
|
20
|
+
}
|
|
15
21
|
if (opts?.withScores) {
|
|
16
22
|
command.push("withscores");
|
|
17
23
|
}
|
package/esm/pkg/http.js
CHANGED
|
@@ -25,9 +25,22 @@ export class HttpClient {
|
|
|
25
25
|
writable: true,
|
|
26
26
|
value: void 0
|
|
27
27
|
});
|
|
28
|
+
this.options = {
|
|
29
|
+
backend: config.options?.backend,
|
|
30
|
+
agent: config.agent,
|
|
31
|
+
responseEncoding: config.responseEncoding ?? "base64", // default to base64
|
|
32
|
+
};
|
|
28
33
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
29
|
-
this.headers = {
|
|
30
|
-
|
|
34
|
+
this.headers = {
|
|
35
|
+
"Content-Type": "application/json",
|
|
36
|
+
"Upstash-Telemetry-Runtime": config.telemetry?.runtime,
|
|
37
|
+
"Upstash-Telemetry-Platform": config.telemetry?.platform,
|
|
38
|
+
"Upstash-Telemetry-Sdk": config.telemetry?.sdk,
|
|
39
|
+
...config.headers,
|
|
40
|
+
};
|
|
41
|
+
if (this.options.responseEncoding === "base64") {
|
|
42
|
+
this.headers["Upstash-Encoding"] = "base64";
|
|
43
|
+
}
|
|
31
44
|
if (typeof config?.retry === "boolean" && config?.retry === false) {
|
|
32
45
|
this.retry = {
|
|
33
46
|
attempts: 1,
|
|
@@ -43,11 +56,19 @@ export class HttpClient {
|
|
|
43
56
|
}
|
|
44
57
|
}
|
|
45
58
|
async request(req) {
|
|
59
|
+
const headers = Object.entries(this.headers).reduce((acc, [key, value]) => {
|
|
60
|
+
if (value) {
|
|
61
|
+
acc[key] = value;
|
|
62
|
+
}
|
|
63
|
+
return acc;
|
|
64
|
+
}, {});
|
|
65
|
+
console.log({ headers });
|
|
46
66
|
const requestOptions = {
|
|
47
67
|
method: "POST",
|
|
48
|
-
headers
|
|
68
|
+
headers,
|
|
49
69
|
body: JSON.stringify(req.body),
|
|
50
70
|
keepalive: true,
|
|
71
|
+
agent: this.options?.agent,
|
|
51
72
|
/**
|
|
52
73
|
* Fastly specific
|
|
53
74
|
*/
|
|
@@ -72,6 +93,66 @@ export class HttpClient {
|
|
|
72
93
|
if (!res.ok) {
|
|
73
94
|
throw new UpstashError(body.error);
|
|
74
95
|
}
|
|
96
|
+
if (this.options?.responseEncoding === "base64") {
|
|
97
|
+
return Array.isArray(body) ? body.map(decode) : decode(body);
|
|
98
|
+
}
|
|
75
99
|
return body;
|
|
76
100
|
}
|
|
77
101
|
}
|
|
102
|
+
function base64decode(b64) {
|
|
103
|
+
let dec = "";
|
|
104
|
+
try {
|
|
105
|
+
/**
|
|
106
|
+
* Using only atob() is not enough because it doesn't work with unicode characters
|
|
107
|
+
*/
|
|
108
|
+
const binString = atob(b64);
|
|
109
|
+
const size = binString.length;
|
|
110
|
+
const bytes = new Uint8Array(size);
|
|
111
|
+
for (let i = 0; i < size; i++) {
|
|
112
|
+
bytes[i] = binString.charCodeAt(i);
|
|
113
|
+
}
|
|
114
|
+
dec = new TextDecoder().decode(bytes);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
dec = b64;
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
return decodeURIComponent(dec);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return dec;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function decode(raw) {
|
|
127
|
+
let result = undefined;
|
|
128
|
+
switch (typeof raw.result) {
|
|
129
|
+
case "undefined":
|
|
130
|
+
return raw;
|
|
131
|
+
case "number": {
|
|
132
|
+
result = raw.result;
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
case "object": {
|
|
136
|
+
if (Array.isArray(raw.result)) {
|
|
137
|
+
result = raw.result.map((v) => typeof v === "string"
|
|
138
|
+
? base64decode(v)
|
|
139
|
+
: Array.isArray(v)
|
|
140
|
+
? v.map(base64decode)
|
|
141
|
+
: v);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
// If it's not an array it must be null
|
|
145
|
+
// Apparently null is an object in javascript
|
|
146
|
+
result = null;
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "string": {
|
|
151
|
+
result = raw.result === "OK" ? "OK" : base64decode(raw.result);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
default:
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
return { result, error: raw.error };
|
|
158
|
+
}
|
package/esm/pkg/pipeline.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AppendCommand, BitCountCommand, BitOpCommand, BitPosCommand, DBSizeCommand, DecrByCommand, DecrCommand, DelCommand, EchoCommand, EvalCommand, EvalshaCommand, ExistsCommand, ExpireAtCommand, ExpireCommand, FlushAllCommand, FlushDBCommand, GetBitCommand, GetCommand, GetRangeCommand, GetSetCommand, HDelCommand, HExistsCommand, HGetAllCommand, HGetCommand, HIncrByCommand, HIncrByFloatCommand, HKeysCommand, HLenCommand, HMGetCommand, HMSetCommand, HScanCommand, HSetCommand, HSetNXCommand, HStrLenCommand, HValsCommand, IncrByCommand, IncrByFloatCommand, IncrCommand, KeysCommand, LIndexCommand, LInsertCommand, LLenCommand, LPopCommand, LPushCommand, LPushXCommand, LRangeCommand, LRemCommand, LSetCommand, LTrimCommand, MGetCommand, MSetCommand, MSetNXCommand, PersistCommand, PExpireAtCommand, PExpireCommand, PingCommand, PSetEXCommand, PTtlCommand, PublishCommand, RandomKeyCommand, RenameCommand, RenameNXCommand, RPopCommand, RPushCommand, RPushXCommand, SAddCommand, ScanCommand, SCardCommand, ScriptExistsCommand, ScriptFlushCommand, ScriptLoadCommand, SDiffCommand, SDiffStoreCommand, SetBitCommand, SetCommand, SetExCommand, SetNxCommand, SetRangeCommand, SInterCommand, SInterStoreCommand, SIsMemberCommand, SMembersCommand, SMoveCommand, SPopCommand, SRandMemberCommand, SRemCommand, SScanCommand, StrLenCommand, SUnionCommand, SUnionStoreCommand, TimeCommand, TouchCommand, TtlCommand, TypeCommand, UnlinkCommand, ZAddCommand, ZCardCommand, ZCountCommand, ZIncrByCommand, ZInterStoreCommand, ZLexCountCommand, ZPopMaxCommand, ZPopMinCommand, ZRangeCommand, ZRankCommand, ZRemCommand, ZRemRangeByLexCommand, ZRemRangeByRankCommand, ZRemRangeByScoreCommand, ZRevRankCommand, ZScanCommand, ZScoreCommand, ZUnionStoreCommand, } from "./commands/mod.js";
|
|
1
|
+
import { AppendCommand, BitCountCommand, BitOpCommand, BitPosCommand, DBSizeCommand, DecrByCommand, DecrCommand, DelCommand, EchoCommand, EvalCommand, EvalshaCommand, ExistsCommand, ExpireAtCommand, ExpireCommand, FlushAllCommand, FlushDBCommand, GetBitCommand, GetCommand, GetDelCommand, GetRangeCommand, GetSetCommand, HDelCommand, HExistsCommand, HGetAllCommand, HGetCommand, HIncrByCommand, HIncrByFloatCommand, HKeysCommand, HLenCommand, HMGetCommand, HMSetCommand, HScanCommand, HSetCommand, HSetNXCommand, HStrLenCommand, HValsCommand, IncrByCommand, IncrByFloatCommand, IncrCommand, KeysCommand, LIndexCommand, LInsertCommand, LLenCommand, LPopCommand, LPosCommand, LPushCommand, LPushXCommand, LRangeCommand, LRemCommand, LSetCommand, LTrimCommand, MGetCommand, MSetCommand, MSetNXCommand, PersistCommand, PExpireAtCommand, PExpireCommand, PingCommand, PSetEXCommand, PTtlCommand, PublishCommand, RandomKeyCommand, RenameCommand, RenameNXCommand, RPopCommand, RPushCommand, RPushXCommand, SAddCommand, ScanCommand, SCardCommand, ScriptExistsCommand, ScriptFlushCommand, ScriptLoadCommand, SDiffCommand, SDiffStoreCommand, SetBitCommand, SetCommand, SetExCommand, SetNxCommand, SetRangeCommand, SInterCommand, SInterStoreCommand, SIsMemberCommand, SMembersCommand, SMoveCommand, SPopCommand, SRandMemberCommand, SRemCommand, SScanCommand, StrLenCommand, SUnionCommand, SUnionStoreCommand, TimeCommand, TouchCommand, TtlCommand, TypeCommand, UnlinkCommand, ZAddCommand, ZCardCommand, ZCountCommand, ZIncrByCommand, ZInterStoreCommand, ZLexCountCommand, ZPopMaxCommand, ZPopMinCommand, ZRangeCommand, ZRankCommand, ZRemCommand, ZRemRangeByLexCommand, ZRemRangeByRankCommand, ZRemRangeByScoreCommand, ZRevRankCommand, ZScanCommand, ZScoreCommand, ZUnionStoreCommand, } from "./commands/mod.js";
|
|
2
2
|
import { UpstashError } from "./error.js";
|
|
3
|
+
import { ZMScoreCommand } from "./commands/zmscore.js";
|
|
3
4
|
/**
|
|
4
5
|
* Upstash REST API supports command pipelining to send multiple commands in
|
|
5
6
|
* batch, instead of sending each command one by one and waiting for a response.
|
|
@@ -16,7 +17,7 @@ import { UpstashError } from "./error.js";
|
|
|
16
17
|
* **Examples:**
|
|
17
18
|
*
|
|
18
19
|
* ```ts
|
|
19
|
-
* const p = redis.pipeline()
|
|
20
|
+
* const p = redis.pipeline() // or redis.multi()
|
|
20
21
|
* p.set("key","value")
|
|
21
22
|
* p.get("key")
|
|
22
23
|
* const res = await p.exec()
|
|
@@ -39,7 +40,7 @@ import { UpstashError } from "./error.js";
|
|
|
39
40
|
* ```
|
|
40
41
|
*/
|
|
41
42
|
export class Pipeline {
|
|
42
|
-
constructor(
|
|
43
|
+
constructor(opts) {
|
|
43
44
|
Object.defineProperty(this, "client", {
|
|
44
45
|
enumerable: true,
|
|
45
46
|
configurable: true,
|
|
@@ -58,6 +59,12 @@ export class Pipeline {
|
|
|
58
59
|
writable: true,
|
|
59
60
|
value: void 0
|
|
60
61
|
});
|
|
62
|
+
Object.defineProperty(this, "multiExec", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true,
|
|
66
|
+
value: void 0
|
|
67
|
+
});
|
|
61
68
|
/**
|
|
62
69
|
* Send the pipeline request to upstash.
|
|
63
70
|
*
|
|
@@ -76,8 +83,9 @@ export class Pipeline {
|
|
|
76
83
|
if (this.commands.length === 0) {
|
|
77
84
|
throw new Error("Pipeline is empty");
|
|
78
85
|
}
|
|
86
|
+
const path = this.multiExec ? ["multi-exec"] : ["pipeline"];
|
|
79
87
|
const res = (await this.client.request({
|
|
80
|
-
path
|
|
88
|
+
path,
|
|
81
89
|
body: Object.values(this.commands).map((c) => c.command),
|
|
82
90
|
}));
|
|
83
91
|
return res.map(({ error, result }, i) => {
|
|
@@ -250,6 +258,15 @@ export class Pipeline {
|
|
|
250
258
|
writable: true,
|
|
251
259
|
value: (...args) => this.chain(new GetBitCommand(args, this.commandOptions))
|
|
252
260
|
});
|
|
261
|
+
/**
|
|
262
|
+
* @see https://redis.io/commands/getdel
|
|
263
|
+
*/
|
|
264
|
+
Object.defineProperty(this, "getdel", {
|
|
265
|
+
enumerable: true,
|
|
266
|
+
configurable: true,
|
|
267
|
+
writable: true,
|
|
268
|
+
value: (...args) => this.chain(new GetDelCommand(args, this.commandOptions))
|
|
269
|
+
});
|
|
253
270
|
/**
|
|
254
271
|
* @see https://redis.io/commands/getrange
|
|
255
272
|
*/
|
|
@@ -475,6 +492,15 @@ export class Pipeline {
|
|
|
475
492
|
writable: true,
|
|
476
493
|
value: (...args) => this.chain(new LPopCommand(args, this.commandOptions))
|
|
477
494
|
});
|
|
495
|
+
/**
|
|
496
|
+
* @see https://redis.io/commands/lpos
|
|
497
|
+
*/
|
|
498
|
+
Object.defineProperty(this, "lpos", {
|
|
499
|
+
enumerable: true,
|
|
500
|
+
configurable: true,
|
|
501
|
+
writable: true,
|
|
502
|
+
value: (...args) => this.chain(new LPosCommand(args, this.commandOptions))
|
|
503
|
+
});
|
|
478
504
|
/**
|
|
479
505
|
* @see https://redis.io/commands/lpush
|
|
480
506
|
*/
|
|
@@ -1002,6 +1028,15 @@ export class Pipeline {
|
|
|
1002
1028
|
writable: true,
|
|
1003
1029
|
value: (...args) => this.chain(new ZLexCountCommand(args, this.commandOptions))
|
|
1004
1030
|
});
|
|
1031
|
+
/**
|
|
1032
|
+
* @see https://redis.io/commands/zmscore
|
|
1033
|
+
*/
|
|
1034
|
+
Object.defineProperty(this, "zmscore", {
|
|
1035
|
+
enumerable: true,
|
|
1036
|
+
configurable: true,
|
|
1037
|
+
writable: true,
|
|
1038
|
+
value: (...args) => this.chain(new ZMScoreCommand(args, this.commandOptions))
|
|
1039
|
+
});
|
|
1005
1040
|
/**
|
|
1006
1041
|
* @see https://redis.io/commands/zpopmax
|
|
1007
1042
|
*/
|
|
@@ -1110,9 +1145,10 @@ export class Pipeline {
|
|
|
1110
1145
|
writable: true,
|
|
1111
1146
|
value: (...args) => this.chain(new ZUnionStoreCommand(args, this.commandOptions))
|
|
1112
1147
|
});
|
|
1113
|
-
this.client = client;
|
|
1148
|
+
this.client = opts.client;
|
|
1114
1149
|
this.commands = [];
|
|
1115
|
-
this.commandOptions = commandOptions;
|
|
1150
|
+
this.commandOptions = opts.commandOptions;
|
|
1151
|
+
this.multiExec = opts.multiExec ?? false;
|
|
1116
1152
|
}
|
|
1117
1153
|
/**
|
|
1118
1154
|
* Pushes a command into the pipelien and returns a chainable instance of the
|
package/esm/pkg/redis.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { AppendCommand, BitCountCommand, BitOpCommand, BitPosCommand, DBSizeCommand, DecrByCommand, DecrCommand, DelCommand, EchoCommand, EvalCommand, EvalshaCommand, ExistsCommand, ExpireAtCommand, ExpireCommand, FlushAllCommand, FlushDBCommand, GetBitCommand, GetCommand, GetRangeCommand, GetSetCommand, HDelCommand, HExistsCommand, HGetAllCommand, HGetCommand, HIncrByCommand, HIncrByFloatCommand, HKeysCommand, HLenCommand, HMGetCommand, HMSetCommand, HScanCommand, HSetCommand, HSetNXCommand, HStrLenCommand, HValsCommand, IncrByCommand, IncrByFloatCommand, IncrCommand, KeysCommand, LIndexCommand, LInsertCommand, LLenCommand, LPopCommand, LPushCommand, LPushXCommand, LRangeCommand, LRemCommand, LSetCommand, LTrimCommand, MGetCommand, MSetCommand, MSetNXCommand, PersistCommand, PExpireAtCommand, PExpireCommand, PingCommand, PSetEXCommand, PTtlCommand, PublishCommand, RandomKeyCommand, RenameCommand, RenameNXCommand, RPopCommand, RPushCommand, RPushXCommand, SAddCommand, ScanCommand, SCardCommand, ScriptExistsCommand, ScriptFlushCommand, ScriptLoadCommand, SDiffCommand, SDiffStoreCommand, SetBitCommand, SetCommand, SetExCommand, SetNxCommand, SetRangeCommand, SInterCommand, SInterStoreCommand, SIsMemberCommand, SMembersCommand, SMoveCommand, SPopCommand, SRandMemberCommand, SRemCommand, SScanCommand, StrLenCommand, SUnionCommand, SUnionStoreCommand, TimeCommand, TouchCommand, TtlCommand, TypeCommand, UnlinkCommand, ZAddCommand, ZCardCommand, ZCountCommand, ZIncrByCommand, ZInterStoreCommand, ZLexCountCommand, ZPopMaxCommand, ZPopMinCommand, ZRangeCommand, ZRankCommand, ZRemCommand, ZRemRangeByLexCommand, ZRemRangeByRankCommand, ZRemRangeByScoreCommand, ZRevRankCommand, ZScanCommand, ZScoreCommand, ZUnionStoreCommand, } from "./commands/mod.js";
|
|
1
|
+
import { AppendCommand, BitCountCommand, BitOpCommand, BitPosCommand, DBSizeCommand, DecrByCommand, DecrCommand, DelCommand, EchoCommand, EvalCommand, EvalshaCommand, ExistsCommand, ExpireAtCommand, ExpireCommand, FlushAllCommand, FlushDBCommand, GetBitCommand, GetCommand, GetDelCommand, GetRangeCommand, GetSetCommand, HDelCommand, HExistsCommand, HGetAllCommand, HGetCommand, HIncrByCommand, HIncrByFloatCommand, HKeysCommand, HLenCommand, HMGetCommand, HMSetCommand, HScanCommand, HSetCommand, HSetNXCommand, HStrLenCommand, HValsCommand, IncrByCommand, IncrByFloatCommand, IncrCommand, KeysCommand, LIndexCommand, LInsertCommand, LLenCommand, LPopCommand, LPosCommand, LPushCommand, LPushXCommand, LRangeCommand, LRemCommand, LSetCommand, LTrimCommand, MGetCommand, MSetCommand, MSetNXCommand, PersistCommand, PExpireAtCommand, PExpireCommand, PingCommand, PSetEXCommand, PTtlCommand, PublishCommand, RandomKeyCommand, RenameCommand, RenameNXCommand, RPopCommand, RPushCommand, RPushXCommand, SAddCommand, ScanCommand, SCardCommand, ScriptExistsCommand, ScriptFlushCommand, ScriptLoadCommand, SDiffCommand, SDiffStoreCommand, SetBitCommand, SetCommand, SetExCommand, SetNxCommand, SetRangeCommand, SInterCommand, SInterStoreCommand, SIsMemberCommand, SMembersCommand, SMoveCommand, SPopCommand, SRandMemberCommand, SRemCommand, SScanCommand, StrLenCommand, SUnionCommand, SUnionStoreCommand, TimeCommand, TouchCommand, TtlCommand, TypeCommand, UnlinkCommand, ZAddCommand, ZCardCommand, ZCountCommand, ZIncrByCommand, ZInterStoreCommand, ZLexCountCommand, ZPopMaxCommand, ZPopMinCommand, ZRangeCommand, ZRankCommand, ZRemCommand, ZRemRangeByLexCommand, ZRemRangeByRankCommand, ZRemRangeByScoreCommand, ZRevRankCommand, ZScanCommand, ZScoreCommand, ZUnionStoreCommand, } from "./commands/mod.js";
|
|
2
2
|
import { Pipeline } from "./pipeline.js";
|
|
3
|
+
import { Script } from "./script.js";
|
|
4
|
+
import { ZMScoreCommand } from "./commands/zmscore.js";
|
|
3
5
|
/**
|
|
4
6
|
* Serverless redis client for upstash.
|
|
5
7
|
*/
|
|
@@ -28,6 +30,18 @@ export class Redis {
|
|
|
28
30
|
writable: true,
|
|
29
31
|
value: void 0
|
|
30
32
|
});
|
|
33
|
+
/**
|
|
34
|
+
* Wrap a new middleware around the HTTP client.
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(this, "use", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: (middleware) => {
|
|
41
|
+
const makeRequest = this.client.request.bind(this.client);
|
|
42
|
+
this.client.request = (req) => middleware(req, makeRequest);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
31
45
|
/**
|
|
32
46
|
* Create a new pipeline that allows you to send requests in bulk.
|
|
33
47
|
*
|
|
@@ -37,7 +51,30 @@ export class Redis {
|
|
|
37
51
|
enumerable: true,
|
|
38
52
|
configurable: true,
|
|
39
53
|
writable: true,
|
|
40
|
-
value: () => new Pipeline(
|
|
54
|
+
value: () => new Pipeline({
|
|
55
|
+
client: this.client,
|
|
56
|
+
commandOptions: this.opts,
|
|
57
|
+
multiExec: false,
|
|
58
|
+
})
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* Create a new transaction to allow executing multiple steps atomically.
|
|
62
|
+
*
|
|
63
|
+
* All the commands in a transaction are serialized and executed sequentially. A request sent by
|
|
64
|
+
* another client will never be served in the middle of the execution of a Redis Transaction. This
|
|
65
|
+
* guarantees that the commands are executed as a single isolated operation.
|
|
66
|
+
*
|
|
67
|
+
* @see {@link Pipeline}
|
|
68
|
+
*/
|
|
69
|
+
Object.defineProperty(this, "multi", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
configurable: true,
|
|
72
|
+
writable: true,
|
|
73
|
+
value: () => new Pipeline({
|
|
74
|
+
client: this.client,
|
|
75
|
+
commandOptions: this.opts,
|
|
76
|
+
multiExec: true,
|
|
77
|
+
})
|
|
41
78
|
});
|
|
42
79
|
/**
|
|
43
80
|
* @see https://redis.io/commands/append
|
|
@@ -201,6 +238,15 @@ export class Redis {
|
|
|
201
238
|
writable: true,
|
|
202
239
|
value: (...args) => new GetBitCommand(args, this.opts).exec(this.client)
|
|
203
240
|
});
|
|
241
|
+
/**
|
|
242
|
+
* @see https://redis.io/commands/getdel
|
|
243
|
+
*/
|
|
244
|
+
Object.defineProperty(this, "getdel", {
|
|
245
|
+
enumerable: true,
|
|
246
|
+
configurable: true,
|
|
247
|
+
writable: true,
|
|
248
|
+
value: (...args) => new GetDelCommand(args, this.opts).exec(this.client)
|
|
249
|
+
});
|
|
204
250
|
/**
|
|
205
251
|
* @see https://redis.io/commands/getrange
|
|
206
252
|
*/
|
|
@@ -426,6 +472,15 @@ export class Redis {
|
|
|
426
472
|
writable: true,
|
|
427
473
|
value: (...args) => new LPopCommand(args, this.opts).exec(this.client)
|
|
428
474
|
});
|
|
475
|
+
/**
|
|
476
|
+
* @see https://redis.io/commands/lpos
|
|
477
|
+
*/
|
|
478
|
+
Object.defineProperty(this, "lpos", {
|
|
479
|
+
enumerable: true,
|
|
480
|
+
configurable: true,
|
|
481
|
+
writable: true,
|
|
482
|
+
value: (...args) => new LPosCommand(args, this.opts).exec(this.client)
|
|
483
|
+
});
|
|
429
484
|
/**
|
|
430
485
|
* @see https://redis.io/commands/lpush
|
|
431
486
|
*/
|
|
@@ -953,6 +1008,15 @@ export class Redis {
|
|
|
953
1008
|
writable: true,
|
|
954
1009
|
value: (...args) => new ZLexCountCommand(args, this.opts).exec(this.client)
|
|
955
1010
|
});
|
|
1011
|
+
/**
|
|
1012
|
+
* @see https://redis.io/commands/zmscore
|
|
1013
|
+
*/
|
|
1014
|
+
Object.defineProperty(this, "zmscore", {
|
|
1015
|
+
enumerable: true,
|
|
1016
|
+
configurable: true,
|
|
1017
|
+
writable: true,
|
|
1018
|
+
value: (...args) => new ZMScoreCommand(args, this.opts).exec(this.client)
|
|
1019
|
+
});
|
|
956
1020
|
/**
|
|
957
1021
|
* @see https://redis.io/commands/zpopmax
|
|
958
1022
|
*/
|
|
@@ -1064,4 +1128,7 @@ export class Redis {
|
|
|
1064
1128
|
this.client = client;
|
|
1065
1129
|
this.opts = opts;
|
|
1066
1130
|
}
|
|
1131
|
+
createScript(script) {
|
|
1132
|
+
return new Script(this, script);
|
|
1133
|
+
}
|
|
1067
1134
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { sha1 as digest } from "../deps/deno.land/x/sha1@v1.0.3/mod.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new script.
|
|
4
|
+
*
|
|
5
|
+
* Scripts offer the ability to optimistically try to execute a script without having to send the
|
|
6
|
+
* entire script to the server. If the script is loaded on the server, it tries again by sending
|
|
7
|
+
* the entire script. Afterwards, the script is cached on the server.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const redis = new Redis({...})
|
|
12
|
+
*
|
|
13
|
+
* const script = redis.createScript<string>("return ARGV[1];")
|
|
14
|
+
* const arg1 = await script.eval([], ["Hello World"])
|
|
15
|
+
* assertEquals(arg1, "Hello World")
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export class Script {
|
|
19
|
+
constructor(redis, script) {
|
|
20
|
+
Object.defineProperty(this, "script", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: void 0
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "sha1", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "redis", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: void 0
|
|
37
|
+
});
|
|
38
|
+
this.redis = redis;
|
|
39
|
+
this.sha1 = this.digest(script);
|
|
40
|
+
this.script = script;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Send an `EVAL` command to redis.
|
|
44
|
+
*/
|
|
45
|
+
async eval(keys, args) {
|
|
46
|
+
return await this.redis.eval(this.script, keys, args);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Calculates the sha1 hash of the script and then calls `EVALSHA`.
|
|
50
|
+
*/
|
|
51
|
+
async evalsha(keys, args) {
|
|
52
|
+
return await this.redis.evalsha(this.sha1, keys, args);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Optimistically try to run `EVALSHA` first.
|
|
56
|
+
* If the script is not loaded in redis, it will fall back and try again with `EVAL`.
|
|
57
|
+
*
|
|
58
|
+
* Following calls will be able to use the cached script
|
|
59
|
+
*/
|
|
60
|
+
async exec(keys, args) {
|
|
61
|
+
const res = await this.redis.evalsha(this.sha1, keys, args).catch(async (err) => {
|
|
62
|
+
if (err instanceof Error &&
|
|
63
|
+
err.message.toLowerCase().includes("noscript")) {
|
|
64
|
+
return await this.redis.eval(this.script, keys, args);
|
|
65
|
+
}
|
|
66
|
+
throw err;
|
|
67
|
+
});
|
|
68
|
+
return res;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compute the sha1 hash of the script and return its hex representation.
|
|
72
|
+
*/
|
|
73
|
+
digest(s) {
|
|
74
|
+
const hash = digest(s, "utf8", "hex");
|
|
75
|
+
return typeof hash === "string" ? hash : new TextDecoder().decode(hash);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
2
|
import { HttpClient } from "../pkg/http.js";
|
|
3
|
+
import { VERSION } from "../version.js";
|
|
3
4
|
/**
|
|
4
5
|
* Serverless redis client for upstash.
|
|
5
6
|
*/
|
|
@@ -15,7 +16,7 @@ export class Redis extends core.Redis {
|
|
|
15
16
|
* });
|
|
16
17
|
* ```
|
|
17
18
|
*/
|
|
18
|
-
constructor(config) {
|
|
19
|
+
constructor(config, env) {
|
|
19
20
|
if (config.url.startsWith(" ") ||
|
|
20
21
|
config.url.endsWith(" ") ||
|
|
21
22
|
/\r|\n/.test(config.url)) {
|
|
@@ -26,10 +27,17 @@ export class Redis extends core.Redis {
|
|
|
26
27
|
/\r|\n/.test(config.token)) {
|
|
27
28
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
28
29
|
}
|
|
30
|
+
const telemetry = {};
|
|
31
|
+
if (!env?.UPSTASH_DISABLE_TELEMETRY) {
|
|
32
|
+
telemetry.platform = "cloudflare";
|
|
33
|
+
telemetry.sdk = `@upstash/redis@${VERSION}`;
|
|
34
|
+
}
|
|
29
35
|
const client = new HttpClient({
|
|
30
36
|
retry: config.retry,
|
|
31
37
|
baseUrl: config.url,
|
|
32
38
|
headers: { authorization: `Bearer ${config.token}` },
|
|
39
|
+
responseEncoding: config.responseEncoding,
|
|
40
|
+
telemetry,
|
|
33
41
|
});
|
|
34
42
|
super(client, {
|
|
35
43
|
automaticDeserialization: config.automaticDeserialization,
|
|
@@ -57,6 +65,6 @@ export class Redis extends core.Redis {
|
|
|
57
65
|
if (!token) {
|
|
58
66
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`");
|
|
59
67
|
}
|
|
60
|
-
return new Redis({ ...opts, url, token });
|
|
68
|
+
return new Redis({ ...opts, url, token }, env);
|
|
61
69
|
}
|
|
62
70
|
}
|
package/esm/platforms/fastly.js
CHANGED
|
@@ -32,6 +32,7 @@ export class Redis extends core.Redis {
|
|
|
32
32
|
retry: config.retry,
|
|
33
33
|
headers: { authorization: `Bearer ${config.token}` },
|
|
34
34
|
options: { backend: config.backend },
|
|
35
|
+
responseEncoding: config.responseEncoding,
|
|
35
36
|
});
|
|
36
37
|
super(client, {
|
|
37
38
|
automaticDeserialization: config.automaticDeserialization,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// deno-lint-ignore-file
|
|
2
2
|
import * as core from "../pkg/redis.js";
|
|
3
3
|
import { HttpClient, } from "../pkg/http.js";
|
|
4
|
+
import { VERSION } from "../version.js";
|
|
4
5
|
import "isomorphic-fetch";
|
|
5
6
|
/**
|
|
6
7
|
* Serverless redis client for upstash.
|
|
@@ -21,11 +22,23 @@ export class Redis extends core.Redis {
|
|
|
21
22
|
/\r|\n/.test(configOrRequester.token)) {
|
|
22
23
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
23
24
|
}
|
|
25
|
+
const telemetry = {};
|
|
26
|
+
if (!process.env.UPSTASH_DISABLE_TELEMETRY) {
|
|
27
|
+
telemetry.runtime = `node@${process.version}`;
|
|
28
|
+
telemetry.platform = process.env.VERCEL
|
|
29
|
+
? "vercel"
|
|
30
|
+
: process.env.AWS_REGION
|
|
31
|
+
? "aws"
|
|
32
|
+
: "unknown";
|
|
33
|
+
telemetry.sdk = `@upstash/redis@${VERSION}`;
|
|
34
|
+
}
|
|
24
35
|
const client = new HttpClient({
|
|
25
36
|
baseUrl: configOrRequester.url,
|
|
26
37
|
retry: configOrRequester.retry,
|
|
27
38
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
28
|
-
//
|
|
39
|
+
// agent: configOrRequester.agent,
|
|
40
|
+
responseEncoding: configOrRequester.responseEncoding,
|
|
41
|
+
telemetry,
|
|
29
42
|
});
|
|
30
43
|
super(client, {
|
|
31
44
|
automaticDeserialization: configOrRequester.automaticDeserialization,
|
package/esm/platforms/nodejs.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// deno-lint-ignore-file
|
|
2
2
|
import * as core from "../pkg/redis.js";
|
|
3
3
|
import { HttpClient, } from "../pkg/http.js";
|
|
4
|
+
import { VERSION } from "../version.js";
|
|
4
5
|
/**
|
|
5
6
|
* Serverless redis client for upstash.
|
|
6
7
|
*/
|
|
@@ -20,11 +21,23 @@ export class Redis extends core.Redis {
|
|
|
20
21
|
/\r|\n/.test(configOrRequester.token)) {
|
|
21
22
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
22
23
|
}
|
|
24
|
+
const telemetry = {};
|
|
25
|
+
if (!process.env.UPSTASH_DISABLE_TELEMETRY) {
|
|
26
|
+
telemetry.runtime = `node@${process.version}`;
|
|
27
|
+
telemetry.platform = process.env.VERCEL
|
|
28
|
+
? "vercel"
|
|
29
|
+
: process.env.AWS_REGION
|
|
30
|
+
? "aws"
|
|
31
|
+
: "unknown";
|
|
32
|
+
telemetry.sdk = `@upstash/redis@${VERSION}`;
|
|
33
|
+
}
|
|
23
34
|
const client = new HttpClient({
|
|
24
35
|
baseUrl: configOrRequester.url,
|
|
25
36
|
retry: configOrRequester.retry,
|
|
26
37
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
27
|
-
|
|
38
|
+
agent: configOrRequester.agent,
|
|
39
|
+
responseEncoding: configOrRequester.responseEncoding,
|
|
40
|
+
telemetry,
|
|
28
41
|
});
|
|
29
42
|
super(client, {
|
|
30
43
|
automaticDeserialization: configOrRequester.automaticDeserialization,
|
package/esm/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const VERSION = "v0.0.0-ci.ec2c4106-20221122";
|