@upstash/redis 1.16.1 → 1.18.0
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 +16 -0
- package/esm/pkg/commands/hgetall.js +0 -4
- package/esm/pkg/commands/hrandfield.js +39 -0
- package/esm/pkg/commands/mod.js +2 -1
- package/esm/pkg/http.js +9 -0
- package/esm/pkg/pipeline.js +10 -0
- package/esm/pkg/redis.js +11 -1
- package/esm/platforms/cloudflare.js +9 -2
- package/esm/platforms/node_with_fetch.js +12 -0
- package/esm/platforms/nodejs.js +12 -0
- package/esm/version.js +1 -0
- package/package.json +1 -1
- package/script/pkg/commands/hgetall.js +0 -4
- package/script/pkg/commands/hrandfield.js +43 -0
- package/script/pkg/commands/mod.js +2 -1
- package/script/pkg/http.js +9 -0
- package/script/pkg/pipeline.js +10 -0
- package/script/pkg/redis.js +10 -0
- package/script/platforms/cloudflare.js +9 -2
- package/script/platforms/node_with_fetch.js +12 -0
- package/script/platforms/nodejs.js +12 -0
- package/script/version.js +4 -0
- package/types/pkg/commands/hrandfield.d.ts +9 -0
- package/types/pkg/commands/mod.d.ts +2 -1
- package/types/pkg/http.d.ts +17 -0
- package/types/pkg/pipeline.d.ts +4 -0
- package/types/pkg/redis.d.ts +8 -0
- package/types/platforms/cloudflare.d.ts +6 -2
- package/types/version.d.ts +1 -0
package/README.md
CHANGED
|
@@ -100,3 +100,19 @@ the url and token
|
|
|
100
100
|
```sh
|
|
101
101
|
UPSTASH_REDIS_REST_URL=".." UPSTASH_REDIS_REST_TOKEN=".." deno test -A
|
|
102
102
|
```
|
|
103
|
+
|
|
104
|
+
### Telemetry
|
|
105
|
+
|
|
106
|
+
This library sends anonymous telemetry data to help us improve your experience.
|
|
107
|
+
We collect the following:
|
|
108
|
+
|
|
109
|
+
- SDK version
|
|
110
|
+
- Platform (Deno, Cloudflare, Vercel)
|
|
111
|
+
- Runtime version (node@18.x)
|
|
112
|
+
|
|
113
|
+
You can opt out by setting the `UPSTASH_DISABLE_TELEMETRY` environment variable
|
|
114
|
+
to any truthy value.
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
UPSTASH_DISABLE_TELEMETRY=1
|
|
118
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Command } from "./command.js";
|
|
2
|
+
function deserialize(result) {
|
|
3
|
+
if (result.length === 0) {
|
|
4
|
+
return null;
|
|
5
|
+
}
|
|
6
|
+
const obj = {};
|
|
7
|
+
while (result.length >= 2) {
|
|
8
|
+
const key = result.shift();
|
|
9
|
+
const value = result.shift();
|
|
10
|
+
try {
|
|
11
|
+
obj[key] = JSON.parse(value);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
obj[key] = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @see https://redis.io/commands/hrandfield
|
|
21
|
+
*/
|
|
22
|
+
export class HRandFieldCommand extends Command {
|
|
23
|
+
constructor(cmd, opts) {
|
|
24
|
+
const command = ["hrandfield", cmd[0]];
|
|
25
|
+
if (typeof cmd[1] === "number") {
|
|
26
|
+
command.push(cmd[1]);
|
|
27
|
+
}
|
|
28
|
+
if (cmd[2]) {
|
|
29
|
+
command.push("WITHVALUES");
|
|
30
|
+
}
|
|
31
|
+
super(command, {
|
|
32
|
+
// @ts-ignore TODO:
|
|
33
|
+
deserialize: cmd[2]
|
|
34
|
+
? (result) => deserialize(result)
|
|
35
|
+
: opts?.deserialize,
|
|
36
|
+
...opts,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
package/esm/pkg/commands/mod.js
CHANGED
|
@@ -17,9 +17,9 @@ export * from "./flushall.js";
|
|
|
17
17
|
export * from "./flushdb.js";
|
|
18
18
|
export * from "./get.js";
|
|
19
19
|
export * from "./getbit.js";
|
|
20
|
+
export * from "./getdel.js";
|
|
20
21
|
export * from "./getrange.js";
|
|
21
22
|
export * from "./getset.js";
|
|
22
|
-
export * from "./getdel.js";
|
|
23
23
|
export * from "./hdel.js";
|
|
24
24
|
export * from "./hexists.js";
|
|
25
25
|
export * from "./hget.js";
|
|
@@ -30,6 +30,7 @@ export * from "./hkeys.js";
|
|
|
30
30
|
export * from "./hlen.js";
|
|
31
31
|
export * from "./hmget.js";
|
|
32
32
|
export * from "./hmset.js";
|
|
33
|
+
export * from "./hrandfield.js";
|
|
33
34
|
export * from "./hscan.js";
|
|
34
35
|
export * from "./hset.js";
|
|
35
36
|
export * from "./hsetnx.js";
|
package/esm/pkg/http.js
CHANGED
|
@@ -35,6 +35,15 @@ export class HttpClient {
|
|
|
35
35
|
"Content-Type": "application/json",
|
|
36
36
|
...config.headers,
|
|
37
37
|
};
|
|
38
|
+
if (config.telemetry?.runtime) {
|
|
39
|
+
this.headers["Upstash-Telemetry-Runtime"] = config.telemetry.runtime;
|
|
40
|
+
}
|
|
41
|
+
if (config.telemetry?.platform) {
|
|
42
|
+
this.headers["Upstash-Telemetry-Platform"] = config.telemetry.platform;
|
|
43
|
+
}
|
|
44
|
+
if (config.telemetry?.sdk) {
|
|
45
|
+
this.headers["Upstash-Telemetry-Sdk"] = config.telemetry.sdk;
|
|
46
|
+
}
|
|
38
47
|
if (this.options.responseEncoding === "base64") {
|
|
39
48
|
this.headers["Upstash-Encoding"] = "base64";
|
|
40
49
|
}
|
package/esm/pkg/pipeline.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
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
3
|
import { ZMScoreCommand } from "./commands/zmscore.js";
|
|
4
|
+
import { HRandFieldCommand } from "./commands/hrandfield.js";
|
|
4
5
|
/**
|
|
5
6
|
* Upstash REST API supports command pipelining to send multiple commands in
|
|
6
7
|
* batch, instead of sending each command one by one and waiting for a response.
|
|
@@ -375,6 +376,15 @@ export class Pipeline {
|
|
|
375
376
|
writable: true,
|
|
376
377
|
value: (key, kv) => this.chain(new HMSetCommand([key, kv], this.commandOptions))
|
|
377
378
|
});
|
|
379
|
+
/**
|
|
380
|
+
* @see https://redis.io/commands/hrandfield
|
|
381
|
+
*/
|
|
382
|
+
Object.defineProperty(this, "hrandfield", {
|
|
383
|
+
enumerable: true,
|
|
384
|
+
configurable: true,
|
|
385
|
+
writable: true,
|
|
386
|
+
value: (key, count, withValues) => this.chain(new HRandFieldCommand([key, count, withValues], this.commandOptions))
|
|
387
|
+
});
|
|
378
388
|
/**
|
|
379
389
|
* @see https://redis.io/commands/hscan
|
|
380
390
|
*/
|
package/esm/pkg/redis.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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";
|
|
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, HRandFieldCommand, 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
3
|
import { Script } from "./script.js";
|
|
4
4
|
import { ZMScoreCommand } from "./commands/zmscore.js";
|
|
@@ -355,6 +355,16 @@ export class Redis {
|
|
|
355
355
|
writable: true,
|
|
356
356
|
value: (key, kv) => new HMSetCommand([key, kv], this.opts).exec(this.client)
|
|
357
357
|
});
|
|
358
|
+
/**
|
|
359
|
+
* @see https://redis.io/commands/hrandfield
|
|
360
|
+
*/
|
|
361
|
+
Object.defineProperty(this, "hrandfield", {
|
|
362
|
+
enumerable: true,
|
|
363
|
+
configurable: true,
|
|
364
|
+
writable: true,
|
|
365
|
+
value: (key, count, withValues) => new HRandFieldCommand([key, count, withValues], this.opts)
|
|
366
|
+
.exec(this.client)
|
|
367
|
+
});
|
|
358
368
|
/**
|
|
359
369
|
* @see https://redis.io/commands/hscan
|
|
360
370
|
*/
|
|
@@ -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,11 +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}` },
|
|
33
39
|
responseEncoding: config.responseEncoding,
|
|
40
|
+
telemetry,
|
|
34
41
|
});
|
|
35
42
|
super(client, {
|
|
36
43
|
automaticDeserialization: config.automaticDeserialization,
|
|
@@ -58,6 +65,6 @@ export class Redis extends core.Redis {
|
|
|
58
65
|
if (!token) {
|
|
59
66
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`");
|
|
60
67
|
}
|
|
61
|
-
return new Redis({ ...opts, url, token });
|
|
68
|
+
return new Redis({ ...opts, url, token }, env);
|
|
62
69
|
}
|
|
63
70
|
}
|
|
@@ -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,12 +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,
|
|
29
40
|
responseEncoding: configOrRequester.responseEncoding,
|
|
41
|
+
telemetry,
|
|
30
42
|
});
|
|
31
43
|
super(client, {
|
|
32
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,12 +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,
|
|
28
39
|
responseEncoding: configOrRequester.responseEncoding,
|
|
40
|
+
telemetry,
|
|
29
41
|
});
|
|
30
42
|
super(client, {
|
|
31
43
|
automaticDeserialization: configOrRequester.automaticDeserialization,
|
package/esm/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const VERSION = "v1.18.0";
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"main": "./script/platforms/nodejs.js",
|
|
4
4
|
"types": "./types/platforms/nodejs.d.ts",
|
|
5
5
|
"name": "@upstash/redis",
|
|
6
|
-
"version": "v1.
|
|
6
|
+
"version": "v1.18.0",
|
|
7
7
|
"description": "An HTTP/REST based Redis client built on top of Upstash REST API.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HGetAllCommand = void 0;
|
|
4
4
|
const command_js_1 = require("./command.js");
|
|
5
|
-
/**
|
|
6
|
-
* @param result De
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
5
|
function deserialize(result) {
|
|
10
6
|
if (result.length === 0) {
|
|
11
7
|
return null;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HRandFieldCommand = void 0;
|
|
4
|
+
const command_js_1 = require("./command.js");
|
|
5
|
+
function deserialize(result) {
|
|
6
|
+
if (result.length === 0) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
const obj = {};
|
|
10
|
+
while (result.length >= 2) {
|
|
11
|
+
const key = result.shift();
|
|
12
|
+
const value = result.shift();
|
|
13
|
+
try {
|
|
14
|
+
obj[key] = JSON.parse(value);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
obj[key] = value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @see https://redis.io/commands/hrandfield
|
|
24
|
+
*/
|
|
25
|
+
class HRandFieldCommand extends command_js_1.Command {
|
|
26
|
+
constructor(cmd, opts) {
|
|
27
|
+
const command = ["hrandfield", cmd[0]];
|
|
28
|
+
if (typeof cmd[1] === "number") {
|
|
29
|
+
command.push(cmd[1]);
|
|
30
|
+
}
|
|
31
|
+
if (cmd[2]) {
|
|
32
|
+
command.push("WITHVALUES");
|
|
33
|
+
}
|
|
34
|
+
super(command, {
|
|
35
|
+
// @ts-ignore TODO:
|
|
36
|
+
deserialize: cmd[2]
|
|
37
|
+
? (result) => deserialize(result)
|
|
38
|
+
: opts?.deserialize,
|
|
39
|
+
...opts,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.HRandFieldCommand = HRandFieldCommand;
|
|
@@ -33,9 +33,9 @@ __exportStar(require("./flushall.js"), exports);
|
|
|
33
33
|
__exportStar(require("./flushdb.js"), exports);
|
|
34
34
|
__exportStar(require("./get.js"), exports);
|
|
35
35
|
__exportStar(require("./getbit.js"), exports);
|
|
36
|
+
__exportStar(require("./getdel.js"), exports);
|
|
36
37
|
__exportStar(require("./getrange.js"), exports);
|
|
37
38
|
__exportStar(require("./getset.js"), exports);
|
|
38
|
-
__exportStar(require("./getdel.js"), exports);
|
|
39
39
|
__exportStar(require("./hdel.js"), exports);
|
|
40
40
|
__exportStar(require("./hexists.js"), exports);
|
|
41
41
|
__exportStar(require("./hget.js"), exports);
|
|
@@ -46,6 +46,7 @@ __exportStar(require("./hkeys.js"), exports);
|
|
|
46
46
|
__exportStar(require("./hlen.js"), exports);
|
|
47
47
|
__exportStar(require("./hmget.js"), exports);
|
|
48
48
|
__exportStar(require("./hmset.js"), exports);
|
|
49
|
+
__exportStar(require("./hrandfield.js"), exports);
|
|
49
50
|
__exportStar(require("./hscan.js"), exports);
|
|
50
51
|
__exportStar(require("./hset.js"), exports);
|
|
51
52
|
__exportStar(require("./hsetnx.js"), exports);
|
package/script/pkg/http.js
CHANGED
|
@@ -38,6 +38,15 @@ class HttpClient {
|
|
|
38
38
|
"Content-Type": "application/json",
|
|
39
39
|
...config.headers,
|
|
40
40
|
};
|
|
41
|
+
if (config.telemetry?.runtime) {
|
|
42
|
+
this.headers["Upstash-Telemetry-Runtime"] = config.telemetry.runtime;
|
|
43
|
+
}
|
|
44
|
+
if (config.telemetry?.platform) {
|
|
45
|
+
this.headers["Upstash-Telemetry-Platform"] = config.telemetry.platform;
|
|
46
|
+
}
|
|
47
|
+
if (config.telemetry?.sdk) {
|
|
48
|
+
this.headers["Upstash-Telemetry-Sdk"] = config.telemetry.sdk;
|
|
49
|
+
}
|
|
41
50
|
if (this.options.responseEncoding === "base64") {
|
|
42
51
|
this.headers["Upstash-Encoding"] = "base64";
|
|
43
52
|
}
|
package/script/pkg/pipeline.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Pipeline = void 0;
|
|
|
4
4
|
const mod_js_1 = require("./commands/mod.js");
|
|
5
5
|
const error_js_1 = require("./error.js");
|
|
6
6
|
const zmscore_js_1 = require("./commands/zmscore.js");
|
|
7
|
+
const hrandfield_js_1 = require("./commands/hrandfield.js");
|
|
7
8
|
/**
|
|
8
9
|
* Upstash REST API supports command pipelining to send multiple commands in
|
|
9
10
|
* batch, instead of sending each command one by one and waiting for a response.
|
|
@@ -378,6 +379,15 @@ class Pipeline {
|
|
|
378
379
|
writable: true,
|
|
379
380
|
value: (key, kv) => this.chain(new mod_js_1.HMSetCommand([key, kv], this.commandOptions))
|
|
380
381
|
});
|
|
382
|
+
/**
|
|
383
|
+
* @see https://redis.io/commands/hrandfield
|
|
384
|
+
*/
|
|
385
|
+
Object.defineProperty(this, "hrandfield", {
|
|
386
|
+
enumerable: true,
|
|
387
|
+
configurable: true,
|
|
388
|
+
writable: true,
|
|
389
|
+
value: (key, count, withValues) => this.chain(new hrandfield_js_1.HRandFieldCommand([key, count, withValues], this.commandOptions))
|
|
390
|
+
});
|
|
381
391
|
/**
|
|
382
392
|
* @see https://redis.io/commands/hscan
|
|
383
393
|
*/
|
package/script/pkg/redis.js
CHANGED
|
@@ -358,6 +358,16 @@ class Redis {
|
|
|
358
358
|
writable: true,
|
|
359
359
|
value: (key, kv) => new mod_js_1.HMSetCommand([key, kv], this.opts).exec(this.client)
|
|
360
360
|
});
|
|
361
|
+
/**
|
|
362
|
+
* @see https://redis.io/commands/hrandfield
|
|
363
|
+
*/
|
|
364
|
+
Object.defineProperty(this, "hrandfield", {
|
|
365
|
+
enumerable: true,
|
|
366
|
+
configurable: true,
|
|
367
|
+
writable: true,
|
|
368
|
+
value: (key, count, withValues) => new mod_js_1.HRandFieldCommand([key, count, withValues], this.opts)
|
|
369
|
+
.exec(this.client)
|
|
370
|
+
});
|
|
361
371
|
/**
|
|
362
372
|
* @see https://redis.io/commands/hscan
|
|
363
373
|
*/
|
|
@@ -26,6 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.Redis = void 0;
|
|
27
27
|
const core = __importStar(require("../pkg/redis.js"));
|
|
28
28
|
const http_js_1 = require("../pkg/http.js");
|
|
29
|
+
const version_js_1 = require("../version.js");
|
|
29
30
|
/**
|
|
30
31
|
* Serverless redis client for upstash.
|
|
31
32
|
*/
|
|
@@ -41,7 +42,7 @@ class Redis extends core.Redis {
|
|
|
41
42
|
* });
|
|
42
43
|
* ```
|
|
43
44
|
*/
|
|
44
|
-
constructor(config) {
|
|
45
|
+
constructor(config, env) {
|
|
45
46
|
if (config.url.startsWith(" ") ||
|
|
46
47
|
config.url.endsWith(" ") ||
|
|
47
48
|
/\r|\n/.test(config.url)) {
|
|
@@ -52,11 +53,17 @@ class Redis extends core.Redis {
|
|
|
52
53
|
/\r|\n/.test(config.token)) {
|
|
53
54
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
54
55
|
}
|
|
56
|
+
const telemetry = {};
|
|
57
|
+
if (!env?.UPSTASH_DISABLE_TELEMETRY) {
|
|
58
|
+
telemetry.platform = "cloudflare";
|
|
59
|
+
telemetry.sdk = `@upstash/redis@${version_js_1.VERSION}`;
|
|
60
|
+
}
|
|
55
61
|
const client = new http_js_1.HttpClient({
|
|
56
62
|
retry: config.retry,
|
|
57
63
|
baseUrl: config.url,
|
|
58
64
|
headers: { authorization: `Bearer ${config.token}` },
|
|
59
65
|
responseEncoding: config.responseEncoding,
|
|
66
|
+
telemetry,
|
|
60
67
|
});
|
|
61
68
|
super(client, {
|
|
62
69
|
automaticDeserialization: config.automaticDeserialization,
|
|
@@ -84,7 +91,7 @@ class Redis extends core.Redis {
|
|
|
84
91
|
if (!token) {
|
|
85
92
|
throw new Error("Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`");
|
|
86
93
|
}
|
|
87
|
-
return new Redis({ ...opts, url, token });
|
|
94
|
+
return new Redis({ ...opts, url, token }, env);
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
exports.Redis = Redis;
|
|
@@ -27,6 +27,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
27
27
|
exports.Redis = void 0;
|
|
28
28
|
const core = __importStar(require("../pkg/redis.js"));
|
|
29
29
|
const http_js_1 = require("../pkg/http.js");
|
|
30
|
+
const version_js_1 = require("../version.js");
|
|
30
31
|
require("isomorphic-fetch");
|
|
31
32
|
/**
|
|
32
33
|
* Serverless redis client for upstash.
|
|
@@ -47,12 +48,23 @@ class Redis extends core.Redis {
|
|
|
47
48
|
/\r|\n/.test(configOrRequester.token)) {
|
|
48
49
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
49
50
|
}
|
|
51
|
+
const telemetry = {};
|
|
52
|
+
if (!process.env.UPSTASH_DISABLE_TELEMETRY) {
|
|
53
|
+
telemetry.runtime = `node@${process.version}`;
|
|
54
|
+
telemetry.platform = process.env.VERCEL
|
|
55
|
+
? "vercel"
|
|
56
|
+
: process.env.AWS_REGION
|
|
57
|
+
? "aws"
|
|
58
|
+
: "unknown";
|
|
59
|
+
telemetry.sdk = `@upstash/redis@${version_js_1.VERSION}`;
|
|
60
|
+
}
|
|
50
61
|
const client = new http_js_1.HttpClient({
|
|
51
62
|
baseUrl: configOrRequester.url,
|
|
52
63
|
retry: configOrRequester.retry,
|
|
53
64
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
54
65
|
// agent: configOrRequester.agent,
|
|
55
66
|
responseEncoding: configOrRequester.responseEncoding,
|
|
67
|
+
telemetry,
|
|
56
68
|
});
|
|
57
69
|
super(client, {
|
|
58
70
|
automaticDeserialization: configOrRequester.automaticDeserialization,
|
|
@@ -27,6 +27,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
27
27
|
exports.Redis = void 0;
|
|
28
28
|
const core = __importStar(require("../pkg/redis.js"));
|
|
29
29
|
const http_js_1 = require("../pkg/http.js");
|
|
30
|
+
const version_js_1 = require("../version.js");
|
|
30
31
|
/**
|
|
31
32
|
* Serverless redis client for upstash.
|
|
32
33
|
*/
|
|
@@ -46,12 +47,23 @@ class Redis extends core.Redis {
|
|
|
46
47
|
/\r|\n/.test(configOrRequester.token)) {
|
|
47
48
|
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
48
49
|
}
|
|
50
|
+
const telemetry = {};
|
|
51
|
+
if (!process.env.UPSTASH_DISABLE_TELEMETRY) {
|
|
52
|
+
telemetry.runtime = `node@${process.version}`;
|
|
53
|
+
telemetry.platform = process.env.VERCEL
|
|
54
|
+
? "vercel"
|
|
55
|
+
: process.env.AWS_REGION
|
|
56
|
+
? "aws"
|
|
57
|
+
: "unknown";
|
|
58
|
+
telemetry.sdk = `@upstash/redis@${version_js_1.VERSION}`;
|
|
59
|
+
}
|
|
49
60
|
const client = new http_js_1.HttpClient({
|
|
50
61
|
baseUrl: configOrRequester.url,
|
|
51
62
|
retry: configOrRequester.retry,
|
|
52
63
|
headers: { authorization: `Bearer ${configOrRequester.token}` },
|
|
53
64
|
agent: configOrRequester.agent,
|
|
54
65
|
responseEncoding: configOrRequester.responseEncoding,
|
|
66
|
+
telemetry,
|
|
55
67
|
});
|
|
56
68
|
super(client, {
|
|
57
69
|
automaticDeserialization: configOrRequester.automaticDeserialization,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Command, CommandOptions } from "./command.js";
|
|
2
|
+
/**
|
|
3
|
+
* @see https://redis.io/commands/hrandfield
|
|
4
|
+
*/
|
|
5
|
+
export declare class HRandFieldCommand<TData extends string | string[] | Record<string, unknown>> extends Command<string | string[], TData> {
|
|
6
|
+
constructor(cmd: [key: string], opts?: CommandOptions<string, string>);
|
|
7
|
+
constructor(cmd: [key: string, count: number], opts?: CommandOptions<string[], string[]>);
|
|
8
|
+
constructor(cmd: [key: string, count: number, withValues: boolean], opts?: CommandOptions<string[], Partial<TData>>);
|
|
9
|
+
}
|
|
@@ -17,9 +17,9 @@ export * from "./flushall.js";
|
|
|
17
17
|
export * from "./flushdb.js";
|
|
18
18
|
export * from "./get.js";
|
|
19
19
|
export * from "./getbit.js";
|
|
20
|
+
export * from "./getdel.js";
|
|
20
21
|
export * from "./getrange.js";
|
|
21
22
|
export * from "./getset.js";
|
|
22
|
-
export * from "./getdel.js";
|
|
23
23
|
export * from "./hdel.js";
|
|
24
24
|
export * from "./hexists.js";
|
|
25
25
|
export * from "./hget.js";
|
|
@@ -30,6 +30,7 @@ export * from "./hkeys.js";
|
|
|
30
30
|
export * from "./hlen.js";
|
|
31
31
|
export * from "./hmget.js";
|
|
32
32
|
export * from "./hmset.js";
|
|
33
|
+
export * from "./hrandfield.js";
|
|
33
34
|
export * from "./hscan.js";
|
|
34
35
|
export * from "./hset.js";
|
|
35
36
|
export * from "./hsetnx.js";
|
package/types/pkg/http.d.ts
CHANGED
|
@@ -67,6 +67,23 @@ export declare type HttpClientConfig = {
|
|
|
67
67
|
options?: Options;
|
|
68
68
|
retry?: RetryConfig;
|
|
69
69
|
agent?: any;
|
|
70
|
+
telemetry?: {
|
|
71
|
+
/**
|
|
72
|
+
* Upstash-Telemetry-Sdk
|
|
73
|
+
* @example @upstash/redis@v1.1.1
|
|
74
|
+
*/
|
|
75
|
+
sdk?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Upstash-Telemetry-Platform
|
|
78
|
+
* @example cloudflare
|
|
79
|
+
*/
|
|
80
|
+
platform?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Upstash-Telemetry-Runtime
|
|
83
|
+
* @example node@v18
|
|
84
|
+
*/
|
|
85
|
+
runtime?: string;
|
|
86
|
+
};
|
|
70
87
|
} & RequesterConfig;
|
|
71
88
|
export declare class HttpClient implements Requester {
|
|
72
89
|
baseUrl: string;
|
package/types/pkg/pipeline.d.ts
CHANGED
|
@@ -197,6 +197,10 @@ export declare class Pipeline {
|
|
|
197
197
|
hmset: <TData>(key: string, kv: {
|
|
198
198
|
[field: string]: TData;
|
|
199
199
|
}) => this;
|
|
200
|
+
/**
|
|
201
|
+
* @see https://redis.io/commands/hrandfield
|
|
202
|
+
*/
|
|
203
|
+
hrandfield: <TData extends string | string[] | Record<string, unknown>>(key: string, count?: number, withValues?: boolean) => this;
|
|
200
204
|
/**
|
|
201
205
|
* @see https://redis.io/commands/hscan
|
|
202
206
|
*/
|
package/types/pkg/redis.d.ts
CHANGED
|
@@ -181,6 +181,14 @@ export declare class Redis {
|
|
|
181
181
|
hmset: <TData>(key: string, kv: {
|
|
182
182
|
[field: string]: TData;
|
|
183
183
|
}) => Promise<"OK">;
|
|
184
|
+
/**
|
|
185
|
+
* @see https://redis.io/commands/hrandfield
|
|
186
|
+
*/
|
|
187
|
+
hrandfield: {
|
|
188
|
+
(key: string): Promise<string>;
|
|
189
|
+
(key: string, count: number): Promise<string[]>;
|
|
190
|
+
<TData extends Record<string, unknown>>(key: string, count: number, withValues: boolean): Promise<Partial<TData>>;
|
|
191
|
+
};
|
|
184
192
|
/**
|
|
185
193
|
* @see https://redis.io/commands/hscan
|
|
186
194
|
*/
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as core from "../pkg/redis.js";
|
|
2
2
|
import type { Requester, UpstashRequest, UpstashResponse } from "../pkg/http.js";
|
|
3
3
|
import { RequesterConfig } from "../pkg/http.js";
|
|
4
|
+
declare type Env = {
|
|
5
|
+
UPSTASH_DISABLE_TELEMETRY?: string;
|
|
6
|
+
};
|
|
4
7
|
export type { Requester, UpstashRequest, UpstashResponse };
|
|
5
8
|
/**
|
|
6
9
|
* Connection credentials for upstash redis.
|
|
@@ -15,7 +18,7 @@ export declare type RedisConfigCloudflare = {
|
|
|
15
18
|
* UPSTASH_REDIS_REST_TOKEN
|
|
16
19
|
*/
|
|
17
20
|
token: string;
|
|
18
|
-
} & core.RedisOptions & RequesterConfig;
|
|
21
|
+
} & core.RedisOptions & RequesterConfig & Env;
|
|
19
22
|
/**
|
|
20
23
|
* Serverless redis client for upstash.
|
|
21
24
|
*/
|
|
@@ -31,9 +34,10 @@ export declare class Redis extends core.Redis {
|
|
|
31
34
|
* });
|
|
32
35
|
* ```
|
|
33
36
|
*/
|
|
34
|
-
constructor(config: RedisConfigCloudflare);
|
|
37
|
+
constructor(config: RedisConfigCloudflare, env?: Env);
|
|
35
38
|
static fromEnv(env?: {
|
|
36
39
|
UPSTASH_REDIS_REST_URL: string;
|
|
37
40
|
UPSTASH_REDIS_REST_TOKEN: string;
|
|
41
|
+
UPSTASH_DISABLE_TELEMETRY?: string;
|
|
38
42
|
}, opts?: Omit<RedisConfigCloudflare, "url" | "token">): Redis;
|
|
39
43
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VERSION = "v1.18.0";
|