@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 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
+ ```
@@ -1,8 +1,4 @@
1
1
  import { Command } from "./command.js";
2
- /**
3
- * @param result De
4
- * @returns
5
- */
6
2
  function deserialize(result) {
7
3
  if (result.length === 0) {
8
4
  return null;
@@ -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
+ }
@@ -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
  }
@@ -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,
@@ -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.16.1",
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);
@@ -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
  }
@@ -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
  */
@@ -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,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = void 0;
4
+ exports.VERSION = "v1.18.0";
@@ -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";
@@ -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;
@@ -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
  */
@@ -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";