@upstash/redis 0.0.0-ci.9846a4b6d92b334b3956b0947a58e9bef9c92a42-20250303091249 → 0.0.0-ci.9a0f7fcd9dc38c0a4ce2b192f3f9c3542ccc791c-20251125190254

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/cloudflare.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // platforms/cloudflare.ts
@@ -39,11 +29,12 @@ module.exports = __toCommonJS(cloudflare_exports);
39
29
  var error_exports = {};
40
30
  __export(error_exports, {
41
31
  UpstashError: () => UpstashError,
32
+ UpstashJSONParseError: () => UpstashJSONParseError,
42
33
  UrlError: () => UrlError
43
34
  });
44
35
  var UpstashError = class extends Error {
45
- constructor(message) {
46
- super(message);
36
+ constructor(message, options) {
37
+ super(message, options);
47
38
  this.name = "UpstashError";
48
39
  }
49
40
  };
@@ -55,6 +46,13 @@ var UrlError = class extends Error {
55
46
  this.name = "UrlError";
56
47
  }
57
48
  };
49
+ var UpstashJSONParseError = class extends UpstashError {
50
+ constructor(body, options) {
51
+ const truncatedBody = body.length > 200 ? body.slice(0, 200) + "..." : body;
52
+ super(`Unable to parse response body: ${truncatedBody}`, options);
53
+ this.name = "UpstashJSONParseError";
54
+ }
55
+ };
58
56
 
59
57
  // pkg/util.ts
60
58
  function parseRecursive(obj) {
@@ -80,6 +78,14 @@ function parseResponse(result) {
80
78
  function deserializeScanResponse(result) {
81
79
  return [result[0], ...parseResponse(result.slice(1))];
82
80
  }
81
+ function deserializeScanWithTypesResponse(result) {
82
+ const [cursor, keys] = result;
83
+ const parsedKeys = [];
84
+ for (let i = 0; i < keys.length; i += 2) {
85
+ parsedKeys.push({ key: keys[i], type: keys[i + 1] });
86
+ }
87
+ return [cursor, parsedKeys];
88
+ }
83
89
  function mergeHeaders(...headers) {
84
90
  const merged = {};
85
91
  for (const header of headers) {
@@ -144,6 +150,8 @@ var HttpClient = class {
144
150
  const requestHeaders = mergeHeaders(this.headers, req.headers ?? {});
145
151
  const requestUrl = [this.baseUrl, ...req.path ?? []].join("/");
146
152
  const isEventStream = requestHeaders.Accept === "text/event-stream";
153
+ const signal = req.signal ?? this.options.signal;
154
+ const isSignalFunction = typeof signal === "function";
147
155
  const requestOptions = {
148
156
  //@ts-expect-error this should throw due to bun regression
149
157
  cache: this.options.cache,
@@ -152,7 +160,7 @@ var HttpClient = class {
152
160
  body: JSON.stringify(req.body),
153
161
  keepalive: this.options.keepAlive,
154
162
  agent: this.options.agent,
155
- signal: req.signal ?? this.options.signal,
163
+ signal: isSignalFunction ? signal() : signal,
156
164
  /**
157
165
  * Fastly specific
158
166
  */
@@ -174,13 +182,15 @@ var HttpClient = class {
174
182
  res = await fetch(requestUrl, requestOptions);
175
183
  break;
176
184
  } catch (error_) {
177
- if (this.options.signal?.aborted) {
185
+ if (requestOptions.signal?.aborted && isSignalFunction) {
186
+ throw error_;
187
+ } else if (requestOptions.signal?.aborted) {
178
188
  const myBlob = new Blob([
179
- JSON.stringify({ result: this.options.signal.reason ?? "Aborted" })
189
+ JSON.stringify({ result: requestOptions.signal.reason ?? "Aborted" })
180
190
  ]);
181
191
  const myOptions = {
182
192
  status: 200,
183
- statusText: this.options.signal.reason ?? "Aborted"
193
+ statusText: requestOptions.signal.reason ?? "Aborted"
184
194
  };
185
195
  res = new Response(myBlob, myOptions);
186
196
  break;
@@ -195,7 +205,13 @@ var HttpClient = class {
195
205
  throw error ?? new Error("Exhausted all retries");
196
206
  }
197
207
  if (!res.ok) {
198
- const body2 = await res.json();
208
+ let body2;
209
+ const rawBody2 = await res.text();
210
+ try {
211
+ body2 = JSON.parse(rawBody2);
212
+ } catch (error2) {
213
+ throw new UpstashJSONParseError(rawBody2, { cause: error2 });
214
+ }
199
215
  throw new UpstashError(`${body2.error}, command was: ${JSON.stringify(req.body)}`);
200
216
  }
201
217
  if (this.readYourWrites) {
@@ -233,7 +249,13 @@ var HttpClient = class {
233
249
  })();
234
250
  return { result: 1 };
235
251
  }
236
- const body = await res.json();
252
+ let body;
253
+ const rawBody = await res.text();
254
+ try {
255
+ body = JSON.parse(rawBody);
256
+ } catch (error2) {
257
+ throw new UpstashJSONParseError(rawBody, { cause: error2 });
258
+ }
237
259
  if (this.readYourWrites) {
238
260
  const headers = res.headers;
239
261
  this.upstashSyncToken = headers.get("upstash-sync-token") ?? "";
@@ -305,6 +327,24 @@ function merge(obj, key, value) {
305
327
  }
306
328
 
307
329
  // pkg/auto-pipeline.ts
330
+ var EXCLUDE_COMMANDS = /* @__PURE__ */ new Set([
331
+ "scan",
332
+ "keys",
333
+ "flushdb",
334
+ "flushall",
335
+ "dbsize",
336
+ "hscan",
337
+ "hgetall",
338
+ "hkeys",
339
+ "lrange",
340
+ "sscan",
341
+ "smembers",
342
+ "xrange",
343
+ "xrevrange",
344
+ "zscan",
345
+ "zrange",
346
+ "exec"
347
+ ]);
308
348
  function createAutoPipelineProxy(_redis, json) {
309
349
  const redis = _redis;
310
350
  if (!redis.autoPipelineExecutor) {
@@ -319,7 +359,8 @@ function createAutoPipelineProxy(_redis, json) {
319
359
  return createAutoPipelineProxy(redis2, true);
320
360
  }
321
361
  const commandInRedisButNotPipeline = command in redis2 && !(command in redis2.autoPipelineExecutor.pipeline);
322
- if (commandInRedisButNotPipeline) {
362
+ const isCommandExcluded = EXCLUDE_COMMANDS.has(command);
363
+ if (commandInRedisButNotPipeline || isCommandExcluded) {
323
364
  return redis2[command];
324
365
  }
325
366
  const isFunction = json ? typeof redis2.autoPipelineExecutor.pipeline.json[command] === "function" : typeof redis2.autoPipelineExecutor.pipeline[command] === "function";
@@ -572,6 +613,13 @@ var EchoCommand = class extends Command {
572
613
  }
573
614
  };
574
615
 
616
+ // pkg/commands/evalRo.ts
617
+ var EvalROCommand = class extends Command {
618
+ constructor([script, keys, args], opts) {
619
+ super(["eval_ro", script, keys.length, ...keys, ...args ?? []], opts);
620
+ }
621
+ };
622
+
575
623
  // pkg/commands/eval.ts
576
624
  var EvalCommand = class extends Command {
577
625
  constructor([script, keys, args], opts) {
@@ -579,6 +627,13 @@ var EvalCommand = class extends Command {
579
627
  }
580
628
  };
581
629
 
630
+ // pkg/commands/evalshaRo.ts
631
+ var EvalshaROCommand = class extends Command {
632
+ constructor([sha, keys, args], opts) {
633
+ super(["evalsha_ro", sha, keys.length, ...keys, ...args ?? []], opts);
634
+ }
635
+ };
636
+
582
637
  // pkg/commands/evalsha.ts
583
638
  var EvalshaCommand = class extends Command {
584
639
  constructor([sha, keys, args], opts) {
@@ -859,6 +914,122 @@ var HExistsCommand = class extends Command {
859
914
  }
860
915
  };
861
916
 
917
+ // pkg/commands/hexpire.ts
918
+ var HExpireCommand = class extends Command {
919
+ constructor(cmd, opts) {
920
+ const [key, fields, seconds, option] = cmd;
921
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
922
+ super(
923
+ [
924
+ "hexpire",
925
+ key,
926
+ seconds,
927
+ ...option ? [option] : [],
928
+ "FIELDS",
929
+ fieldArray.length,
930
+ ...fieldArray
931
+ ],
932
+ opts
933
+ );
934
+ }
935
+ };
936
+
937
+ // pkg/commands/hexpireat.ts
938
+ var HExpireAtCommand = class extends Command {
939
+ constructor(cmd, opts) {
940
+ const [key, fields, timestamp, option] = cmd;
941
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
942
+ super(
943
+ [
944
+ "hexpireat",
945
+ key,
946
+ timestamp,
947
+ ...option ? [option] : [],
948
+ "FIELDS",
949
+ fieldArray.length,
950
+ ...fieldArray
951
+ ],
952
+ opts
953
+ );
954
+ }
955
+ };
956
+
957
+ // pkg/commands/hexpiretime.ts
958
+ var HExpireTimeCommand = class extends Command {
959
+ constructor(cmd, opts) {
960
+ const [key, fields] = cmd;
961
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
962
+ super(["hexpiretime", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
963
+ }
964
+ };
965
+
966
+ // pkg/commands/hpersist.ts
967
+ var HPersistCommand = class extends Command {
968
+ constructor(cmd, opts) {
969
+ const [key, fields] = cmd;
970
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
971
+ super(["hpersist", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
972
+ }
973
+ };
974
+
975
+ // pkg/commands/hpexpire.ts
976
+ var HPExpireCommand = class extends Command {
977
+ constructor(cmd, opts) {
978
+ const [key, fields, milliseconds, option] = cmd;
979
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
980
+ super(
981
+ [
982
+ "hpexpire",
983
+ key,
984
+ milliseconds,
985
+ ...option ? [option] : [],
986
+ "FIELDS",
987
+ fieldArray.length,
988
+ ...fieldArray
989
+ ],
990
+ opts
991
+ );
992
+ }
993
+ };
994
+
995
+ // pkg/commands/hpexpireat.ts
996
+ var HPExpireAtCommand = class extends Command {
997
+ constructor(cmd, opts) {
998
+ const [key, fields, timestamp, option] = cmd;
999
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
1000
+ super(
1001
+ [
1002
+ "hpexpireat",
1003
+ key,
1004
+ timestamp,
1005
+ ...option ? [option] : [],
1006
+ "FIELDS",
1007
+ fieldArray.length,
1008
+ ...fieldArray
1009
+ ],
1010
+ opts
1011
+ );
1012
+ }
1013
+ };
1014
+
1015
+ // pkg/commands/hpexpiretime.ts
1016
+ var HPExpireTimeCommand = class extends Command {
1017
+ constructor(cmd, opts) {
1018
+ const [key, fields] = cmd;
1019
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
1020
+ super(["hpexpiretime", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
1021
+ }
1022
+ };
1023
+
1024
+ // pkg/commands/hpttl.ts
1025
+ var HPTtlCommand = class extends Command {
1026
+ constructor(cmd, opts) {
1027
+ const [key, fields] = cmd;
1028
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
1029
+ super(["hpttl", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
1030
+ }
1031
+ };
1032
+
862
1033
  // pkg/commands/hget.ts
863
1034
  var HGetCommand = class extends Command {
864
1035
  constructor(cmd, opts) {
@@ -872,9 +1043,9 @@ function deserialize(result) {
872
1043
  return null;
873
1044
  }
874
1045
  const obj = {};
875
- while (result.length >= 2) {
876
- const key = result.shift();
877
- const value = result.shift();
1046
+ for (let i = 0; i < result.length; i += 2) {
1047
+ const key = result[i];
1048
+ const value = result[i + 1];
878
1049
  try {
879
1050
  const valueIsNumberAndNotSafeInteger = !Number.isNaN(Number(value)) && !Number.isSafeInteger(Number(value));
880
1051
  obj[key] = valueIsNumberAndNotSafeInteger ? value : JSON.parse(value);
@@ -958,9 +1129,9 @@ function deserialize3(result) {
958
1129
  return null;
959
1130
  }
960
1131
  const obj = {};
961
- while (result.length >= 2) {
962
- const key = result.shift();
963
- const value = result.shift();
1132
+ for (let i = 0; i < result.length; i += 2) {
1133
+ const key = result[i];
1134
+ const value = result[i + 1];
964
1135
  try {
965
1136
  obj[key] = JSON.parse(value);
966
1137
  } catch {
@@ -1024,6 +1195,15 @@ var HStrLenCommand = class extends Command {
1024
1195
  }
1025
1196
  };
1026
1197
 
1198
+ // pkg/commands/httl.ts
1199
+ var HTtlCommand = class extends Command {
1200
+ constructor(cmd, opts) {
1201
+ const [key, fields] = cmd;
1202
+ const fieldArray = Array.isArray(fields) ? fields : [fields];
1203
+ super(["httl", key, "FIELDS", fieldArray.length, ...fieldArray], opts);
1204
+ }
1205
+ };
1206
+
1027
1207
  // pkg/commands/hvals.ts
1028
1208
  var HValsCommand = class extends Command {
1029
1209
  constructor(cmd, opts) {
@@ -1143,6 +1323,14 @@ var JsonGetCommand = class extends Command {
1143
1323
  }
1144
1324
  };
1145
1325
 
1326
+ // pkg/commands/json_merge.ts
1327
+ var JsonMergeCommand = class extends Command {
1328
+ constructor(cmd, opts) {
1329
+ const command = ["JSON.MERGE", ...cmd];
1330
+ super(command, opts);
1331
+ }
1332
+ };
1333
+
1146
1334
  // pkg/commands/json_mget.ts
1147
1335
  var JsonMGetCommand = class extends Command {
1148
1336
  constructor(cmd, opts) {
@@ -1503,11 +1691,14 @@ var ScanCommand = class extends Command {
1503
1691
  if (typeof opts?.count === "number") {
1504
1692
  command.push("count", opts.count);
1505
1693
  }
1506
- if (opts?.type && opts.type.length > 0) {
1694
+ if (opts && "withType" in opts && opts.withType === true) {
1695
+ command.push("withtype");
1696
+ } else if (opts && "type" in opts && opts.type && opts.type.length > 0) {
1507
1697
  command.push("type", opts.type);
1508
1698
  }
1509
1699
  super(command, {
1510
- deserialize: deserializeScanResponse,
1700
+ // @ts-expect-error ignore types here
1701
+ deserialize: opts?.withType ? deserializeScanWithTypesResponse : deserializeScanResponse,
1511
1702
  ...cmdOpts
1512
1703
  });
1513
1704
  }
@@ -1933,15 +2124,15 @@ var XPendingCommand = class extends Command {
1933
2124
  function deserialize4(result) {
1934
2125
  const obj = {};
1935
2126
  for (const e of result) {
1936
- while (e.length >= 2) {
1937
- const streamId = e.shift();
1938
- const entries = e.shift();
2127
+ for (let i = 0; i < e.length; i += 2) {
2128
+ const streamId = e[i];
2129
+ const entries = e[i + 1];
1939
2130
  if (!(streamId in obj)) {
1940
2131
  obj[streamId] = {};
1941
2132
  }
1942
- while (entries.length >= 2) {
1943
- const field = entries.shift();
1944
- const value = entries.shift();
2133
+ for (let j = 0; j < entries.length; j += 2) {
2134
+ const field = entries[j];
2135
+ const value = entries[j + 1];
1945
2136
  try {
1946
2137
  obj[streamId][field] = JSON.parse(value);
1947
2138
  } catch {
@@ -2030,15 +2221,15 @@ var XRevRangeCommand = class extends Command {
2030
2221
  function deserialize5(result) {
2031
2222
  const obj = {};
2032
2223
  for (const e of result) {
2033
- while (e.length >= 2) {
2034
- const streamId = e.shift();
2035
- const entries = e.shift();
2224
+ for (let i = 0; i < e.length; i += 2) {
2225
+ const streamId = e[i];
2226
+ const entries = e[i + 1];
2036
2227
  if (!(streamId in obj)) {
2037
2228
  obj[streamId] = {};
2038
2229
  }
2039
- while (entries.length >= 2) {
2040
- const field = entries.shift();
2041
- const value = entries.shift();
2230
+ for (let j = 0; j < entries.length; j += 2) {
2231
+ const field = entries[j];
2232
+ const value = entries[j + 1];
2042
2233
  try {
2043
2234
  obj[streamId][field] = JSON.parse(value);
2044
2235
  } catch {
@@ -2323,11 +2514,13 @@ var Subscriber = class extends EventTarget {
2323
2514
  subscriptions;
2324
2515
  client;
2325
2516
  listeners;
2326
- constructor(client, channels, isPattern = false) {
2517
+ opts;
2518
+ constructor(client, channels, isPattern = false, opts) {
2327
2519
  super();
2328
2520
  this.client = client;
2329
2521
  this.subscriptions = /* @__PURE__ */ new Map();
2330
2522
  this.listeners = /* @__PURE__ */ new Map();
2523
+ this.opts = opts;
2331
2524
  for (const channel of channels) {
2332
2525
  if (isPattern) {
2333
2526
  this.subscribeToPattern(channel);
@@ -2386,7 +2579,7 @@ var Subscriber = class extends EventTarget {
2386
2579
  const channel = messageData.slice(secondCommaIndex + 1, thirdCommaIndex);
2387
2580
  const messageStr = messageData.slice(thirdCommaIndex + 1);
2388
2581
  try {
2389
- const message = JSON.parse(messageStr);
2582
+ const message = this.opts?.automaticDeserialization === false ? messageStr : JSON.parse(messageStr);
2390
2583
  this.dispatchToListeners("pmessage", { pattern, channel, message });
2391
2584
  this.dispatchToListeners(`pmessage:${pattern}`, { pattern, channel, message });
2392
2585
  } catch (error) {
@@ -2400,7 +2593,7 @@ var Subscriber = class extends EventTarget {
2400
2593
  const count = Number.parseInt(messageStr);
2401
2594
  this.dispatchToListeners(type, count);
2402
2595
  } else {
2403
- const message = JSON.parse(messageStr);
2596
+ const message = this.opts?.automaticDeserialization === false ? messageStr : parseWithTryCatch(messageStr);
2404
2597
  this.dispatchToListeners(type, { channel, message });
2405
2598
  this.dispatchToListeners(`${type}:${channel}`, { channel, message });
2406
2599
  }
@@ -2473,6 +2666,13 @@ var SubscribeCommand = class extends Command {
2473
2666
  });
2474
2667
  }
2475
2668
  };
2669
+ var parseWithTryCatch = (str) => {
2670
+ try {
2671
+ return JSON.parse(str);
2672
+ } catch {
2673
+ return str;
2674
+ }
2675
+ };
2476
2676
 
2477
2677
  // pkg/commands/zdiffstore.ts
2478
2678
  var ZDiffStoreCommand = class extends Command {
@@ -2614,10 +2814,18 @@ var Pipeline = class {
2614
2814
  * @see https://redis.io/commands/echo
2615
2815
  */
2616
2816
  echo = (...args) => this.chain(new EchoCommand(args, this.commandOptions));
2817
+ /**
2818
+ * @see https://redis.io/commands/eval_ro
2819
+ */
2820
+ evalRo = (...args) => this.chain(new EvalROCommand(args, this.commandOptions));
2617
2821
  /**
2618
2822
  * @see https://redis.io/commands/eval
2619
2823
  */
2620
2824
  eval = (...args) => this.chain(new EvalCommand(args, this.commandOptions));
2825
+ /**
2826
+ * @see https://redis.io/commands/evalsha_ro
2827
+ */
2828
+ evalshaRo = (...args) => this.chain(new EvalshaROCommand(args, this.commandOptions));
2621
2829
  /**
2622
2830
  * @see https://redis.io/commands/evalsha
2623
2831
  */
@@ -2698,6 +2906,42 @@ var Pipeline = class {
2698
2906
  * @see https://redis.io/commands/hexists
2699
2907
  */
2700
2908
  hexists = (...args) => this.chain(new HExistsCommand(args, this.commandOptions));
2909
+ /**
2910
+ * @see https://redis.io/commands/hexpire
2911
+ */
2912
+ hexpire = (...args) => this.chain(new HExpireCommand(args, this.commandOptions));
2913
+ /**
2914
+ * @see https://redis.io/commands/hexpireat
2915
+ */
2916
+ hexpireat = (...args) => this.chain(new HExpireAtCommand(args, this.commandOptions));
2917
+ /**
2918
+ * @see https://redis.io/commands/hexpiretime
2919
+ */
2920
+ hexpiretime = (...args) => this.chain(new HExpireTimeCommand(args, this.commandOptions));
2921
+ /**
2922
+ * @see https://redis.io/commands/httl
2923
+ */
2924
+ httl = (...args) => this.chain(new HTtlCommand(args, this.commandOptions));
2925
+ /**
2926
+ * @see https://redis.io/commands/hpexpire
2927
+ */
2928
+ hpexpire = (...args) => this.chain(new HPExpireCommand(args, this.commandOptions));
2929
+ /**
2930
+ * @see https://redis.io/commands/hpexpireat
2931
+ */
2932
+ hpexpireat = (...args) => this.chain(new HPExpireAtCommand(args, this.commandOptions));
2933
+ /**
2934
+ * @see https://redis.io/commands/hpexpiretime
2935
+ */
2936
+ hpexpiretime = (...args) => this.chain(new HPExpireTimeCommand(args, this.commandOptions));
2937
+ /**
2938
+ * @see https://redis.io/commands/hpttl
2939
+ */
2940
+ hpttl = (...args) => this.chain(new HPTtlCommand(args, this.commandOptions));
2941
+ /**
2942
+ * @see https://redis.io/commands/hpersist
2943
+ */
2944
+ hpersist = (...args) => this.chain(new HPersistCommand(args, this.commandOptions));
2701
2945
  /**
2702
2946
  * @see https://redis.io/commands/hget
2703
2947
  */
@@ -3215,6 +3459,10 @@ var Pipeline = class {
3215
3459
  * @see https://redis.io/commands/json.get
3216
3460
  */
3217
3461
  get: (...args) => this.chain(new JsonGetCommand(args, this.commandOptions)),
3462
+ /**
3463
+ * @see https://redis.io/commands/json.merge
3464
+ */
3465
+ merge: (...args) => this.chain(new JsonMergeCommand(args, this.commandOptions)),
3218
3466
  /**
3219
3467
  * @see https://redis.io/commands/json.mget
3220
3468
  */
@@ -3268,27 +3516,43 @@ var Pipeline = class {
3268
3516
  };
3269
3517
 
3270
3518
  // pkg/script.ts
3271
- var import_enc_hex = __toESM(require("crypto-js/enc-hex.js"));
3272
- var import_sha1 = __toESM(require("crypto-js/sha1.js"));
3519
+ var import_uncrypto = require("uncrypto");
3273
3520
  var Script = class {
3274
3521
  script;
3522
+ /**
3523
+ * @deprecated This property is initialized to an empty string and will be set in the init method
3524
+ * asynchronously. Do not use this property immidiately after the constructor.
3525
+ *
3526
+ * This property is only exposed for backwards compatibility and will be removed in the
3527
+ * future major release.
3528
+ */
3275
3529
  sha1;
3276
3530
  redis;
3277
3531
  constructor(redis, script) {
3278
3532
  this.redis = redis;
3279
- this.sha1 = this.digest(script);
3280
3533
  this.script = script;
3534
+ this.sha1 = "";
3535
+ void this.init(script);
3536
+ }
3537
+ /**
3538
+ * Initialize the script by computing its SHA-1 hash.
3539
+ */
3540
+ async init(script) {
3541
+ if (this.sha1) return;
3542
+ this.sha1 = await this.digest(script);
3281
3543
  }
3282
3544
  /**
3283
3545
  * Send an `EVAL` command to redis.
3284
3546
  */
3285
3547
  async eval(keys, args) {
3548
+ await this.init(this.script);
3286
3549
  return await this.redis.eval(this.script, keys, args);
3287
3550
  }
3288
3551
  /**
3289
3552
  * Calculates the sha1 hash of the script and then calls `EVALSHA`.
3290
3553
  */
3291
3554
  async evalsha(keys, args) {
3555
+ await this.init(this.script);
3292
3556
  return await this.redis.evalsha(this.sha1, keys, args);
3293
3557
  }
3294
3558
  /**
@@ -3298,6 +3562,7 @@ var Script = class {
3298
3562
  * Following calls will be able to use the cached script
3299
3563
  */
3300
3564
  async exec(keys, args) {
3565
+ await this.init(this.script);
3301
3566
  const res = await this.redis.evalsha(this.sha1, keys, args).catch(async (error) => {
3302
3567
  if (error instanceof Error && error.message.toLowerCase().includes("noscript")) {
3303
3568
  return await this.redis.eval(this.script, keys, args);
@@ -3309,8 +3574,75 @@ var Script = class {
3309
3574
  /**
3310
3575
  * Compute the sha1 hash of the script and return its hex representation.
3311
3576
  */
3312
- digest(s) {
3313
- return import_enc_hex.default.stringify((0, import_sha1.default)(s));
3577
+ async digest(s) {
3578
+ const data = new TextEncoder().encode(s);
3579
+ const hashBuffer = await import_uncrypto.subtle.digest("SHA-1", data);
3580
+ const hashArray = [...new Uint8Array(hashBuffer)];
3581
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
3582
+ }
3583
+ };
3584
+
3585
+ // pkg/scriptRo.ts
3586
+ var import_uncrypto2 = require("uncrypto");
3587
+ var ScriptRO = class {
3588
+ script;
3589
+ /**
3590
+ * @deprecated This property is initialized to an empty string and will be set in the init method
3591
+ * asynchronously. Do not use this property immidiately after the constructor.
3592
+ *
3593
+ * This property is only exposed for backwards compatibility and will be removed in the
3594
+ * future major release.
3595
+ */
3596
+ sha1;
3597
+ redis;
3598
+ constructor(redis, script) {
3599
+ this.redis = redis;
3600
+ this.sha1 = "";
3601
+ this.script = script;
3602
+ void this.init(script);
3603
+ }
3604
+ async init(script) {
3605
+ if (this.sha1) return;
3606
+ this.sha1 = await this.digest(script);
3607
+ }
3608
+ /**
3609
+ * Send an `EVAL_RO` command to redis.
3610
+ */
3611
+ async evalRo(keys, args) {
3612
+ await this.init(this.script);
3613
+ return await this.redis.evalRo(this.script, keys, args);
3614
+ }
3615
+ /**
3616
+ * Calculates the sha1 hash of the script and then calls `EVALSHA_RO`.
3617
+ */
3618
+ async evalshaRo(keys, args) {
3619
+ await this.init(this.script);
3620
+ return await this.redis.evalshaRo(this.sha1, keys, args);
3621
+ }
3622
+ /**
3623
+ * Optimistically try to run `EVALSHA_RO` first.
3624
+ * If the script is not loaded in redis, it will fall back and try again with `EVAL_RO`.
3625
+ *
3626
+ * Following calls will be able to use the cached script
3627
+ */
3628
+ async exec(keys, args) {
3629
+ await this.init(this.script);
3630
+ const res = await this.redis.evalshaRo(this.sha1, keys, args).catch(async (error) => {
3631
+ if (error instanceof Error && error.message.toLowerCase().includes("noscript")) {
3632
+ return await this.redis.evalRo(this.script, keys, args);
3633
+ }
3634
+ throw error;
3635
+ });
3636
+ return res;
3637
+ }
3638
+ /**
3639
+ * Compute the sha1 hash of the script and return its hex representation.
3640
+ */
3641
+ async digest(s) {
3642
+ const data = new TextEncoder().encode(s);
3643
+ const hashBuffer = await import_uncrypto2.subtle.digest("SHA-1", data);
3644
+ const hashArray = [...new Uint8Array(hashBuffer)];
3645
+ return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
3314
3646
  }
3315
3647
  };
3316
3648
 
@@ -3388,6 +3720,10 @@ var Redis = class {
3388
3720
  * @see https://redis.io/commands/json.get
3389
3721
  */
3390
3722
  get: (...args) => new JsonGetCommand(args, this.opts).exec(this.client),
3723
+ /**
3724
+ * @see https://redis.io/commands/json.merge
3725
+ */
3726
+ merge: (...args) => new JsonMergeCommand(args, this.opts).exec(this.client),
3391
3727
  /**
3392
3728
  * @see https://redis.io/commands/json.mget
3393
3729
  */
@@ -3457,8 +3793,36 @@ var Redis = class {
3457
3793
  } catch {
3458
3794
  }
3459
3795
  };
3460
- createScript(script) {
3461
- return new Script(this, script);
3796
+ /**
3797
+ * Creates a new script.
3798
+ *
3799
+ * Scripts offer the ability to optimistically try to execute a script without having to send the
3800
+ * entire script to the server. If the script is loaded on the server, it tries again by sending
3801
+ * the entire script. Afterwards, the script is cached on the server.
3802
+ *
3803
+ * @param script - The script to create
3804
+ * @param opts - Optional options to pass to the script `{ readonly?: boolean }`
3805
+ * @returns A new script
3806
+ *
3807
+ * @example
3808
+ * ```ts
3809
+ * const redis = new Redis({...})
3810
+ *
3811
+ * const script = redis.createScript<string>("return ARGV[1];")
3812
+ * const arg1 = await script.eval([], ["Hello World"])
3813
+ * expect(arg1, "Hello World")
3814
+ * ```
3815
+ * @example
3816
+ * ```ts
3817
+ * const redis = new Redis({...})
3818
+ *
3819
+ * const script = redis.createScript<string>("return ARGV[1];", { readonly: true })
3820
+ * const arg1 = await script.evalRo([], ["Hello World"])
3821
+ * expect(arg1, "Hello World")
3822
+ * ```
3823
+ */
3824
+ createScript(script, opts) {
3825
+ return opts?.readonly ? new ScriptRO(this, script) : new Script(this, script);
3462
3826
  }
3463
3827
  /**
3464
3828
  * Create a new pipeline that allows you to send requests in bulk.
@@ -3545,10 +3909,18 @@ var Redis = class {
3545
3909
  * @see https://redis.io/commands/echo
3546
3910
  */
3547
3911
  echo = (...args) => new EchoCommand(args, this.opts).exec(this.client);
3912
+ /**
3913
+ * @see https://redis.io/commands/eval_ro
3914
+ */
3915
+ evalRo = (...args) => new EvalROCommand(args, this.opts).exec(this.client);
3548
3916
  /**
3549
3917
  * @see https://redis.io/commands/eval
3550
3918
  */
3551
3919
  eval = (...args) => new EvalCommand(args, this.opts).exec(this.client);
3920
+ /**
3921
+ * @see https://redis.io/commands/evalsha_ro
3922
+ */
3923
+ evalshaRo = (...args) => new EvalshaROCommand(args, this.opts).exec(this.client);
3552
3924
  /**
3553
3925
  * @see https://redis.io/commands/evalsha
3554
3926
  */
@@ -3633,6 +4005,42 @@ var Redis = class {
3633
4005
  * @see https://redis.io/commands/hexists
3634
4006
  */
3635
4007
  hexists = (...args) => new HExistsCommand(args, this.opts).exec(this.client);
4008
+ /**
4009
+ * @see https://redis.io/commands/hexpire
4010
+ */
4011
+ hexpire = (...args) => new HExpireCommand(args, this.opts).exec(this.client);
4012
+ /**
4013
+ * @see https://redis.io/commands/hexpireat
4014
+ */
4015
+ hexpireat = (...args) => new HExpireAtCommand(args, this.opts).exec(this.client);
4016
+ /**
4017
+ * @see https://redis.io/commands/hexpiretime
4018
+ */
4019
+ hexpiretime = (...args) => new HExpireTimeCommand(args, this.opts).exec(this.client);
4020
+ /**
4021
+ * @see https://redis.io/commands/httl
4022
+ */
4023
+ httl = (...args) => new HTtlCommand(args, this.opts).exec(this.client);
4024
+ /**
4025
+ * @see https://redis.io/commands/hpexpire
4026
+ */
4027
+ hpexpire = (...args) => new HPExpireCommand(args, this.opts).exec(this.client);
4028
+ /**
4029
+ * @see https://redis.io/commands/hpexpireat
4030
+ */
4031
+ hpexpireat = (...args) => new HPExpireAtCommand(args, this.opts).exec(this.client);
4032
+ /**
4033
+ * @see https://redis.io/commands/hpexpiretime
4034
+ */
4035
+ hpexpiretime = (...args) => new HPExpireTimeCommand(args, this.opts).exec(this.client);
4036
+ /**
4037
+ * @see https://redis.io/commands/hpttl
4038
+ */
4039
+ hpttl = (...args) => new HPTtlCommand(args, this.opts).exec(this.client);
4040
+ /**
4041
+ * @see https://redis.io/commands/hpersist
4042
+ */
4043
+ hpersist = (...args) => new HPersistCommand(args, this.opts).exec(this.client);
3636
4044
  /**
3637
4045
  * @see https://redis.io/commands/hget
3638
4046
  */
@@ -3806,7 +4214,7 @@ var Redis = class {
3806
4214
  */
3807
4215
  psubscribe = (patterns) => {
3808
4216
  const patternArray = Array.isArray(patterns) ? patterns : [patterns];
3809
- return new Subscriber(this.client, patternArray, true);
4217
+ return new Subscriber(this.client, patternArray, true, this.opts);
3810
4218
  };
3811
4219
  /**
3812
4220
  * @see https://redis.io/commands/pttl
@@ -3844,10 +4252,9 @@ var Redis = class {
3844
4252
  * @see https://redis.io/commands/sadd
3845
4253
  */
3846
4254
  sadd = (key, member, ...members) => new SAddCommand([key, member, ...members], this.opts).exec(this.client);
3847
- /**
3848
- * @see https://redis.io/commands/scan
3849
- */
3850
- scan = (...args) => new ScanCommand(args, this.opts).exec(this.client);
4255
+ scan(cursor, opts) {
4256
+ return new ScanCommand([cursor, opts], this.opts).exec(this.client);
4257
+ }
3851
4258
  /**
3852
4259
  * @see https://redis.io/commands/scard
3853
4260
  */
@@ -3941,7 +4348,7 @@ var Redis = class {
3941
4348
  */
3942
4349
  subscribe = (channels) => {
3943
4350
  const channelArray = Array.isArray(channels) ? channels : [channels];
3944
- return new Subscriber(this.client, channelArray);
4351
+ return new Subscriber(this.client, channelArray, false, this.opts);
3945
4352
  };
3946
4353
  /**
3947
4354
  * @see https://redis.io/commands/sunion
@@ -4168,7 +4575,7 @@ var Redis2 = class _Redis extends Redis {
4168
4575
  readYourWrites: config.readYourWrites
4169
4576
  });
4170
4577
  super(client, {
4171
- enableTelemetry: !env?.UPSTASH_DISABLE_TELEMETRY,
4578
+ enableTelemetry: config.enableTelemetry ?? !env?.UPSTASH_DISABLE_TELEMETRY,
4172
4579
  automaticDeserialization: config.automaticDeserialization,
4173
4580
  latencyLogging: config.latencyLogging,
4174
4581
  enableAutoPipelining: config.enableAutoPipelining