@upstash/redis 1.37.0-rc → 1.37.0-rc.10

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.
@@ -77,8 +77,18 @@ function mergeHeaders(...headers) {
77
77
  }
78
78
  return merged;
79
79
  }
80
+ function kvArrayToObject(v) {
81
+ if (typeof v === "object" && v !== null && !Array.isArray(v)) return v;
82
+ if (!Array.isArray(v)) return {};
83
+ const obj = {};
84
+ for (let i = 0; i < v.length; i += 2) {
85
+ if (typeof v[i] === "string") obj[v[i]] = v[i + 1];
86
+ }
87
+ return obj;
88
+ }
80
89
 
81
90
  // pkg/http.ts
91
+ var MAX_BUFFER_SIZE = 1024 * 1024;
82
92
  var HttpClient = class {
83
93
  baseUrl;
84
94
  headers;
@@ -202,11 +212,16 @@ var HttpClient = class {
202
212
  const decoder = new TextDecoder();
203
213
  (async () => {
204
214
  try {
215
+ let buffer = "";
205
216
  while (true) {
206
217
  const { value, done } = await reader.read();
207
218
  if (done) break;
208
- const chunk = decoder.decode(value);
209
- const lines = chunk.split("\n");
219
+ buffer += decoder.decode(value, { stream: true });
220
+ const lines = buffer.split("\n");
221
+ buffer = lines.pop() || "";
222
+ if (buffer.length > MAX_BUFFER_SIZE) {
223
+ throw new Error("Buffer size exceeded (1MB)");
224
+ }
210
225
  for (const line of lines) {
211
226
  if (line.startsWith("data: ")) {
212
227
  const data = line.slice(6);
@@ -378,6 +393,429 @@ var Command = class {
378
393
  }
379
394
  };
380
395
 
396
+ // pkg/commands/exec.ts
397
+ var ExecCommand = class extends Command {
398
+ constructor(cmd, opts) {
399
+ const normalizedCmd = cmd.map((arg) => typeof arg === "string" ? arg : String(arg));
400
+ super(normalizedCmd, opts);
401
+ }
402
+ };
403
+
404
+ // pkg/commands/search/types.ts
405
+ var FIELD_TYPES = ["TEXT", "U64", "I64", "F64", "BOOL", "DATE", "KEYWORD"];
406
+
407
+ // pkg/commands/search/utils.ts
408
+ function isFieldType(value) {
409
+ return typeof value === "string" && FIELD_TYPES.includes(value);
410
+ }
411
+ function isDetailedField(value) {
412
+ return typeof value === "object" && value !== null && "type" in value && isFieldType(value.type);
413
+ }
414
+ function isNestedSchema(value) {
415
+ return typeof value === "object" && value !== null && !isDetailedField(value);
416
+ }
417
+ function flattenSchema(schema, pathPrefix = []) {
418
+ const fields = [];
419
+ for (const [key, value] of Object.entries(schema)) {
420
+ const currentPath = [...pathPrefix, key];
421
+ const pathString = currentPath.join(".");
422
+ if (isFieldType(value)) {
423
+ fields.push({
424
+ path: pathString,
425
+ type: value
426
+ });
427
+ } else if (isDetailedField(value)) {
428
+ fields.push({
429
+ path: pathString,
430
+ type: value.type,
431
+ fast: "fast" in value ? value.fast : void 0,
432
+ noTokenize: "noTokenize" in value ? value.noTokenize : void 0,
433
+ noStem: "noStem" in value ? value.noStem : void 0,
434
+ from: "from" in value ? value.from : void 0
435
+ });
436
+ } else if (isNestedSchema(value)) {
437
+ const nestedFields = flattenSchema(value, currentPath);
438
+ fields.push(...nestedFields);
439
+ }
440
+ }
441
+ return fields;
442
+ }
443
+ function deserializeQueryResponse(rawResponse) {
444
+ return rawResponse.map((itemRaw) => {
445
+ const raw = itemRaw;
446
+ const key = raw[0];
447
+ const score = Number(raw[1]);
448
+ const rawFields = raw[2];
449
+ if (rawFields === void 0) {
450
+ return { key, score };
451
+ }
452
+ if (!Array.isArray(rawFields) || rawFields.length === 0) {
453
+ return { key, score, data: {} };
454
+ }
455
+ let data = {};
456
+ for (const fieldRaw of rawFields) {
457
+ const key2 = fieldRaw[0];
458
+ const value = fieldRaw[1];
459
+ const pathParts = key2.split(".");
460
+ if (pathParts.length == 1) {
461
+ data[key2] = value;
462
+ } else {
463
+ let currentObj = data;
464
+ for (let i = 0; i < pathParts.length - 1; i++) {
465
+ const pathPart = pathParts[i];
466
+ if (!(pathPart in currentObj)) {
467
+ currentObj[pathPart] = {};
468
+ }
469
+ currentObj = currentObj[pathPart];
470
+ }
471
+ currentObj[pathParts.at(-1)] = value;
472
+ }
473
+ }
474
+ if ("$" in data) {
475
+ data = data["$"];
476
+ }
477
+ return { key, score, data };
478
+ });
479
+ }
480
+ function deserializeDescribeResponse(rawResponse) {
481
+ const description = {};
482
+ for (let i = 0; i < rawResponse.length; i += 2) {
483
+ const descriptor = rawResponse[i];
484
+ switch (descriptor) {
485
+ case "name": {
486
+ description["name"] = rawResponse[i + 1];
487
+ break;
488
+ }
489
+ case "type": {
490
+ description["dataType"] = rawResponse[i + 1].toLowerCase();
491
+ break;
492
+ }
493
+ case "prefixes": {
494
+ description["prefixes"] = rawResponse[i + 1];
495
+ break;
496
+ }
497
+ case "language": {
498
+ description["language"] = rawResponse[i + 1];
499
+ break;
500
+ }
501
+ case "schema": {
502
+ const schema = {};
503
+ for (const fieldDescription of rawResponse[i + 1]) {
504
+ const fieldName = fieldDescription[0];
505
+ const fieldInfo = { type: fieldDescription[1] };
506
+ if (fieldDescription.length > 2) {
507
+ for (let j = 2; j < fieldDescription.length; j++) {
508
+ const fieldOption = fieldDescription[j];
509
+ switch (fieldOption) {
510
+ case "NOSTEM": {
511
+ fieldInfo.noStem = true;
512
+ break;
513
+ }
514
+ case "NOTOKENIZE": {
515
+ fieldInfo.noTokenize = true;
516
+ break;
517
+ }
518
+ case "FAST": {
519
+ fieldInfo.fast = true;
520
+ break;
521
+ }
522
+ }
523
+ }
524
+ }
525
+ schema[fieldName] = fieldInfo;
526
+ }
527
+ description["schema"] = schema;
528
+ break;
529
+ }
530
+ }
531
+ }
532
+ return description;
533
+ }
534
+ function parseCountResponse(rawResponse) {
535
+ return typeof rawResponse === "number" ? rawResponse : Number.parseInt(rawResponse, 10);
536
+ }
537
+ function deserializeAggregateResponse(rawResponse) {
538
+ return parseAggregationArray(rawResponse);
539
+ }
540
+ function parseAggregationArray(arr) {
541
+ const result = {};
542
+ for (let i = 0; i < arr.length; i += 2) {
543
+ const key = arr[i];
544
+ const value = arr[i + 1];
545
+ if (Array.isArray(value)) {
546
+ if (value.length > 0 && typeof value[0] === "string") {
547
+ result[key] = value[0] === "buckets" ? parseBucketsValue(value) : parseStatsValue(value);
548
+ } else {
549
+ result[key] = parseAggregationArray(value);
550
+ }
551
+ } else {
552
+ result[key] = value;
553
+ }
554
+ }
555
+ return result;
556
+ }
557
+ function coerceNumericString(value) {
558
+ if (typeof value === "string" && value !== "" && !Number.isNaN(Number(value))) {
559
+ return Number(value);
560
+ }
561
+ return value;
562
+ }
563
+ function parseStatsValue(arr) {
564
+ const result = {};
565
+ for (let i = 0; i < arr.length; i += 2) {
566
+ const key = arr[i];
567
+ const value = arr[i + 1];
568
+ if (Array.isArray(value) && value.length > 0) {
569
+ if (typeof value[0] === "string") {
570
+ result[key] = parseStatsValue(value);
571
+ } else if (Array.isArray(value[0]) && typeof value[0][0] === "string") {
572
+ result[key] = value.map((item) => parseStatsValue(item));
573
+ } else {
574
+ result[key] = value;
575
+ }
576
+ } else {
577
+ result[key] = coerceNumericString(value);
578
+ }
579
+ }
580
+ return result;
581
+ }
582
+ function parseBucketsValue(arr) {
583
+ if (arr[0] === "buckets" && Array.isArray(arr[1])) {
584
+ const result = {
585
+ buckets: arr[1].map((bucket) => {
586
+ const bucketObj = {};
587
+ for (let i = 0; i < bucket.length; i += 2) {
588
+ const key = bucket[i];
589
+ const value = bucket[i + 1];
590
+ bucketObj[key] = Array.isArray(value) && value.length > 0 && typeof value[0] === "string" ? parseStatsValue(value) : value;
591
+ }
592
+ return bucketObj;
593
+ })
594
+ };
595
+ for (let i = 2; i < arr.length; i += 2) {
596
+ result[arr[i]] = arr[i + 1];
597
+ }
598
+ return result;
599
+ }
600
+ return arr;
601
+ }
602
+
603
+ // pkg/commands/search/command-builder.ts
604
+ function buildQueryCommand(redisCommand, name, options) {
605
+ const query = JSON.stringify(options?.filter ?? {});
606
+ const command = [redisCommand, name, query];
607
+ if (options?.limit !== void 0) {
608
+ command.push("LIMIT", options.limit.toString());
609
+ }
610
+ if (options?.offset !== void 0) {
611
+ command.push("OFFSET", options.offset.toString());
612
+ }
613
+ if (options?.select && Object.keys(options.select).length === 0) {
614
+ command.push("NOCONTENT");
615
+ }
616
+ if (options) {
617
+ if ("orderBy" in options && options.orderBy) {
618
+ command.push("ORDERBY");
619
+ for (const [field, direction] of Object.entries(options.orderBy)) {
620
+ command.push(field, direction);
621
+ }
622
+ } else if ("scoreFunc" in options && options.scoreFunc) {
623
+ command.push("SCOREFUNC", ...buildScoreFunc(options.scoreFunc));
624
+ }
625
+ }
626
+ if (options?.highlight) {
627
+ command.push(
628
+ "HIGHLIGHT",
629
+ "FIELDS",
630
+ options.highlight.fields.length.toString(),
631
+ ...options.highlight.fields
632
+ );
633
+ if (options.highlight.preTag && options.highlight.postTag) {
634
+ command.push("TAGS", options.highlight.preTag, options.highlight.postTag);
635
+ }
636
+ }
637
+ if (options?.select && Object.keys(options.select).length > 0) {
638
+ command.push(
639
+ "SELECT",
640
+ Object.keys(options.select).length.toString(),
641
+ ...Object.keys(options.select)
642
+ );
643
+ }
644
+ return command;
645
+ }
646
+ function buildScoreFunc(scoreBy) {
647
+ const result = [];
648
+ if (typeof scoreBy === "string") {
649
+ result.push("FIELDVALUE", scoreBy);
650
+ } else if ("fields" in scoreBy) {
651
+ if (scoreBy.combineMode) {
652
+ result.push("COMBINEMODE", scoreBy.combineMode.toUpperCase());
653
+ }
654
+ if (scoreBy.scoreMode) {
655
+ result.push("SCOREMODE", scoreBy.scoreMode.toUpperCase());
656
+ }
657
+ for (const field of scoreBy.fields) {
658
+ result.push(...buildScoreFuncField(field));
659
+ }
660
+ } else {
661
+ result.push(...buildScoreFuncField(scoreBy));
662
+ }
663
+ return result;
664
+ }
665
+ function buildScoreFuncField(field) {
666
+ const result = [];
667
+ if (typeof field === "string") {
668
+ result.push("FIELDVALUE", field);
669
+ } else {
670
+ if (field.scoreMode) {
671
+ result.push("SCOREMODE", field.scoreMode.toUpperCase());
672
+ }
673
+ result.push("FIELDVALUE", field.field);
674
+ if (field.modifier) {
675
+ result.push("MODIFIER", field.modifier.toUpperCase());
676
+ }
677
+ if (field.factor !== void 0) {
678
+ result.push("FACTOR", field.factor.toString());
679
+ }
680
+ if (field.missing !== void 0) {
681
+ result.push("MISSING", field.missing.toString());
682
+ }
683
+ }
684
+ return result;
685
+ }
686
+ function buildCreateIndexCommand(params) {
687
+ const { name, schema, dataType, prefix, language, skipInitialScan, existsOk } = params;
688
+ const prefixArray = Array.isArray(prefix) ? prefix : [prefix];
689
+ const payload = [
690
+ name,
691
+ ...skipInitialScan ? ["SKIPINITIALSCAN"] : [],
692
+ ...existsOk ? ["EXISTSOK"] : [],
693
+ "ON",
694
+ dataType.toUpperCase(),
695
+ "PREFIX",
696
+ prefixArray.length.toString(),
697
+ ...prefixArray,
698
+ ...language ? ["LANGUAGE", language] : [],
699
+ "SCHEMA"
700
+ ];
701
+ const fields = flattenSchema(schema);
702
+ for (const field of fields) {
703
+ payload.push(field.path, field.type);
704
+ if (field.fast) {
705
+ payload.push("FAST");
706
+ }
707
+ if (field.noTokenize) {
708
+ payload.push("NOTOKENIZE");
709
+ }
710
+ if (field.noStem) {
711
+ payload.push("NOSTEM");
712
+ }
713
+ if (field.from) {
714
+ payload.push("FROM", field.from);
715
+ }
716
+ }
717
+ return ["SEARCH.CREATE", ...payload];
718
+ }
719
+ function buildAggregateCommand(name, options) {
720
+ const query = JSON.stringify(options?.filter ?? {});
721
+ const aggregations = JSON.stringify(options.aggregations);
722
+ return ["SEARCH.AGGREGATE", name, query, aggregations];
723
+ }
724
+
725
+ // pkg/commands/search/search.ts
726
+ var SearchIndex = class {
727
+ name;
728
+ schema;
729
+ client;
730
+ constructor({ name, schema, client }) {
731
+ this.name = name;
732
+ this.schema = schema;
733
+ this.client = client;
734
+ }
735
+ async waitIndexing() {
736
+ const command = ["SEARCH.WAITINDEXING", this.name];
737
+ return await new ExecCommand(command).exec(this.client);
738
+ }
739
+ async describe() {
740
+ const command = ["SEARCH.DESCRIBE", this.name];
741
+ const rawResult = await new ExecCommand(command).exec(
742
+ this.client
743
+ );
744
+ if (!rawResult) return null;
745
+ return deserializeDescribeResponse(rawResult);
746
+ }
747
+ async query(options) {
748
+ const command = buildQueryCommand("SEARCH.QUERY", this.name, options);
749
+ const rawResult = await new ExecCommand(command).exec(
750
+ this.client
751
+ );
752
+ if (!rawResult) return rawResult;
753
+ return deserializeQueryResponse(rawResult);
754
+ }
755
+ async aggregate(options) {
756
+ const command = buildAggregateCommand(this.name, options);
757
+ const rawResult = await new ExecCommand(
758
+ command
759
+ ).exec(this.client);
760
+ return deserializeAggregateResponse(rawResult);
761
+ }
762
+ async count({ filter }) {
763
+ const command = buildQueryCommand("SEARCH.COUNT", this.name, { filter });
764
+ const rawResult = await new ExecCommand(command).exec(
765
+ this.client
766
+ );
767
+ return { count: parseCountResponse(rawResult) };
768
+ }
769
+ async drop() {
770
+ const command = ["SEARCH.DROP", this.name];
771
+ const result = await new ExecCommand(command).exec(this.client);
772
+ return result;
773
+ }
774
+ async addAlias({ alias }) {
775
+ const command = ["SEARCH.ALIASADD", alias, this.name];
776
+ const result = await new ExecCommand(command).exec(this.client);
777
+ return result;
778
+ }
779
+ };
780
+ async function createIndex(client, params) {
781
+ const { name, schema } = params;
782
+ const createIndexCommand = buildCreateIndexCommand(params);
783
+ await new ExecCommand(createIndexCommand).exec(client);
784
+ return initIndex(client, { name, schema });
785
+ }
786
+ function initIndex(client, params) {
787
+ const { name, schema } = params;
788
+ return new SearchIndex({ name, schema, client });
789
+ }
790
+ async function listAliases(client) {
791
+ const command = ["SEARCH.LISTALIASES"];
792
+ const rawResult = await new ExecCommand(command).exec(client);
793
+ if (rawResult === 0 || Array.isArray(rawResult) && rawResult.length === 0) {
794
+ return {};
795
+ }
796
+ if (!Array.isArray(rawResult)) {
797
+ return {};
798
+ }
799
+ const aliases = {};
800
+ for (const pair of rawResult) {
801
+ if (Array.isArray(pair) && pair.length === 2) {
802
+ const [alias, index] = pair;
803
+ aliases[alias] = index;
804
+ }
805
+ }
806
+ return aliases;
807
+ }
808
+ async function addAlias(client, { indexName, alias }) {
809
+ const command = ["SEARCH.ALIASADD", alias, indexName];
810
+ const result = await new ExecCommand(command).exec(client);
811
+ return result;
812
+ }
813
+ async function delAlias(client, { alias }) {
814
+ const command = ["SEARCH.ALIASDEL", alias];
815
+ const result = await new ExecCommand(command).exec(client);
816
+ return result;
817
+ }
818
+
381
819
  // pkg/commands/hrandfield.ts
382
820
  function deserialize(result) {
383
821
  if (result.length === 0) {
@@ -478,6 +916,13 @@ var BitPosCommand = class extends Command {
478
916
  }
479
917
  };
480
918
 
919
+ // pkg/commands/client_setinfo.ts
920
+ var ClientSetInfoCommand = class extends Command {
921
+ constructor([attribute, value], opts) {
922
+ super(["CLIENT", "SETINFO", attribute.toUpperCase(), value], opts);
923
+ }
924
+ };
925
+
481
926
  // pkg/commands/copy.ts
482
927
  var CopyCommand = class extends Command {
483
928
  constructor([key, destinationKey, opts], commandOptions) {
@@ -556,14 +1001,6 @@ var EvalshaCommand = class extends Command {
556
1001
  }
557
1002
  };
558
1003
 
559
- // pkg/commands/exec.ts
560
- var ExecCommand = class extends Command {
561
- constructor(cmd, opts) {
562
- const normalizedCmd = cmd.map((arg) => typeof arg === "string" ? arg : String(arg));
563
- super(normalizedCmd, opts);
564
- }
565
- };
566
-
567
1004
  // pkg/commands/exists.ts
568
1005
  var ExistsCommand = class extends Command {
569
1006
  constructor(cmd, opts) {
@@ -585,6 +1022,23 @@ var ExpireAtCommand = class extends Command {
585
1022
  }
586
1023
  };
587
1024
 
1025
+ // pkg/commands/fcall.ts
1026
+ var FCallCommand = class extends Command {
1027
+ constructor([functionName, keys, args], opts) {
1028
+ super(["fcall", functionName, ...keys ? [keys.length, ...keys] : [0], ...args ?? []], opts);
1029
+ }
1030
+ };
1031
+
1032
+ // pkg/commands/fcall_ro.ts
1033
+ var FCallRoCommand = class extends Command {
1034
+ constructor([functionName, keys, args], opts) {
1035
+ super(
1036
+ ["fcall_ro", functionName, ...keys ? [keys.length, ...keys] : [0], ...args ?? []],
1037
+ opts
1038
+ );
1039
+ }
1040
+ };
1041
+
588
1042
  // pkg/commands/flushall.ts
589
1043
  var FlushAllCommand = class extends Command {
590
1044
  constructor(args, opts) {
@@ -607,6 +1061,85 @@ var FlushDBCommand = class extends Command {
607
1061
  }
608
1062
  };
609
1063
 
1064
+ // pkg/commands/function_delete.ts
1065
+ var FunctionDeleteCommand = class extends Command {
1066
+ constructor([libraryName], opts) {
1067
+ super(["function", "delete", libraryName], opts);
1068
+ }
1069
+ };
1070
+
1071
+ // pkg/commands/function_flush.ts
1072
+ var FunctionFlushCommand = class extends Command {
1073
+ constructor(opts) {
1074
+ super(["function", "flush"], opts);
1075
+ }
1076
+ };
1077
+
1078
+ // pkg/commands/function_list.ts
1079
+ var FunctionListCommand = class extends Command {
1080
+ constructor([args], opts) {
1081
+ const command = ["function", "list"];
1082
+ if (args?.libraryName) {
1083
+ command.push("libraryname", args.libraryName);
1084
+ }
1085
+ if (args?.withCode) {
1086
+ command.push("withcode");
1087
+ }
1088
+ super(command, { deserialize: deserialize2, ...opts });
1089
+ }
1090
+ };
1091
+ function deserialize2(result) {
1092
+ if (!Array.isArray(result)) return [];
1093
+ return result.map((libRaw) => {
1094
+ const lib = kvArrayToObject(libRaw);
1095
+ const functionsParsed = lib.functions.map(
1096
+ (fnRaw) => kvArrayToObject(fnRaw)
1097
+ );
1098
+ return {
1099
+ libraryName: lib.library_name,
1100
+ engine: lib.engine,
1101
+ functions: functionsParsed.map((fn) => ({
1102
+ name: fn.name,
1103
+ description: fn.description ?? void 0,
1104
+ flags: fn.flags
1105
+ })),
1106
+ libraryCode: lib.library_code
1107
+ };
1108
+ });
1109
+ }
1110
+
1111
+ // pkg/commands/function_load.ts
1112
+ var FunctionLoadCommand = class extends Command {
1113
+ constructor([args], opts) {
1114
+ super(["function", "load", ...args.replace ? ["replace"] : [], args.code], opts);
1115
+ }
1116
+ };
1117
+
1118
+ // pkg/commands/function_stats.ts
1119
+ var FunctionStatsCommand = class extends Command {
1120
+ constructor(opts) {
1121
+ super(["function", "stats"], { deserialize: deserialize3, ...opts });
1122
+ }
1123
+ };
1124
+ function deserialize3(result) {
1125
+ const rawEngines = kvArrayToObject(kvArrayToObject(result).engines);
1126
+ const parsedEngines = Object.fromEntries(
1127
+ Object.entries(rawEngines).map(([key, value]) => [key, kvArrayToObject(value)])
1128
+ );
1129
+ const final = {
1130
+ engines: Object.fromEntries(
1131
+ Object.entries(parsedEngines).map(([key, value]) => [
1132
+ key,
1133
+ {
1134
+ librariesCount: value.libraries_count,
1135
+ functionsCount: value.functions_count
1136
+ }
1137
+ ])
1138
+ )
1139
+ };
1140
+ return final;
1141
+ }
1142
+
610
1143
  // pkg/commands/geo_add.ts
611
1144
  var GeoAddCommand = class extends Command {
612
1145
  constructor([key, arg1, ...arg2], opts) {
@@ -953,7 +1486,7 @@ var HGetCommand = class extends Command {
953
1486
  };
954
1487
 
955
1488
  // pkg/commands/hgetall.ts
956
- function deserialize2(result) {
1489
+ function deserialize4(result) {
957
1490
  if (result.length === 0) {
958
1491
  return null;
959
1492
  }
@@ -970,15 +1503,72 @@ function deserialize2(result) {
970
1503
  }
971
1504
  return obj;
972
1505
  }
973
- var HGetAllCommand = class extends Command {
974
- constructor(cmd, opts) {
975
- super(["hgetall", ...cmd], {
976
- deserialize: (result) => deserialize2(result),
1506
+ var HGetAllCommand = class extends Command {
1507
+ constructor(cmd, opts) {
1508
+ super(["hgetall", ...cmd], {
1509
+ deserialize: (result) => deserialize4(result),
1510
+ ...opts
1511
+ });
1512
+ }
1513
+ };
1514
+
1515
+ // pkg/commands/hmget.ts
1516
+ function deserialize5(fields, result) {
1517
+ if (result.every((field) => field === null)) {
1518
+ return null;
1519
+ }
1520
+ const obj = {};
1521
+ for (const [i, field] of fields.entries()) {
1522
+ try {
1523
+ obj[field] = JSON.parse(result[i]);
1524
+ } catch {
1525
+ obj[field] = result[i];
1526
+ }
1527
+ }
1528
+ return obj;
1529
+ }
1530
+ var HMGetCommand = class extends Command {
1531
+ constructor([key, ...fields], opts) {
1532
+ super(["hmget", key, ...fields], {
1533
+ deserialize: (result) => deserialize5(fields, result),
1534
+ ...opts
1535
+ });
1536
+ }
1537
+ };
1538
+
1539
+ // pkg/commands/hgetdel.ts
1540
+ var HGetDelCommand = class extends Command {
1541
+ constructor([key, ...fields], opts) {
1542
+ super(["hgetdel", key, "FIELDS", fields.length, ...fields], {
1543
+ deserialize: (result) => deserialize5(fields.map(String), result),
977
1544
  ...opts
978
1545
  });
979
1546
  }
980
1547
  };
981
1548
 
1549
+ // pkg/commands/hgetex.ts
1550
+ var HGetExCommand = class extends Command {
1551
+ constructor([key, opts, ...fields], cmdOpts) {
1552
+ const command = ["hgetex", key];
1553
+ if ("ex" in opts && typeof opts.ex === "number") {
1554
+ command.push("EX", opts.ex);
1555
+ } else if ("px" in opts && typeof opts.px === "number") {
1556
+ command.push("PX", opts.px);
1557
+ } else if ("exat" in opts && typeof opts.exat === "number") {
1558
+ command.push("EXAT", opts.exat);
1559
+ } else if ("pxat" in opts && typeof opts.pxat === "number") {
1560
+ command.push("PXAT", opts.pxat);
1561
+ } else if ("persist" in opts && opts.persist) {
1562
+ command.push("PERSIST");
1563
+ }
1564
+ command.push("FIELDS", fields.length, ...fields);
1565
+ super(command, {
1566
+ deserialize: (result) => deserialize5(fields.map(String), result),
1567
+ ...cmdOpts
1568
+ });
1569
+ }
1570
+ };
1571
+
982
1572
  // pkg/commands/hincrby.ts
983
1573
  var HIncrByCommand = class extends Command {
984
1574
  constructor(cmd, opts) {
@@ -1007,30 +1597,6 @@ var HLenCommand = class extends Command {
1007
1597
  }
1008
1598
  };
1009
1599
 
1010
- // pkg/commands/hmget.ts
1011
- function deserialize3(fields, result) {
1012
- if (result.every((field) => field === null)) {
1013
- return null;
1014
- }
1015
- const obj = {};
1016
- for (const [i, field] of fields.entries()) {
1017
- try {
1018
- obj[field] = JSON.parse(result[i]);
1019
- } catch {
1020
- obj[field] = result[i];
1021
- }
1022
- }
1023
- return obj;
1024
- }
1025
- var HMGetCommand = class extends Command {
1026
- constructor([key, ...fields], opts) {
1027
- super(["hmget", key, ...fields], {
1028
- deserialize: (result) => deserialize3(fields, result),
1029
- ...opts
1030
- });
1031
- }
1032
- };
1033
-
1034
1600
  // pkg/commands/hmset.ts
1035
1601
  var HMSetCommand = class extends Command {
1036
1602
  constructor([key, kv], opts) {
@@ -1062,6 +1628,35 @@ var HSetCommand = class extends Command {
1062
1628
  }
1063
1629
  };
1064
1630
 
1631
+ // pkg/commands/hsetex.ts
1632
+ var HSetExCommand = class extends Command {
1633
+ constructor([key, opts, kv], cmdOpts) {
1634
+ const command = ["hsetex", key];
1635
+ if (opts.conditional) {
1636
+ command.push(opts.conditional.toUpperCase());
1637
+ }
1638
+ if (opts.expiration) {
1639
+ if ("ex" in opts.expiration && typeof opts.expiration.ex === "number") {
1640
+ command.push("EX", opts.expiration.ex);
1641
+ } else if ("px" in opts.expiration && typeof opts.expiration.px === "number") {
1642
+ command.push("PX", opts.expiration.px);
1643
+ } else if ("exat" in opts.expiration && typeof opts.expiration.exat === "number") {
1644
+ command.push("EXAT", opts.expiration.exat);
1645
+ } else if ("pxat" in opts.expiration && typeof opts.expiration.pxat === "number") {
1646
+ command.push("PXAT", opts.expiration.pxat);
1647
+ } else if ("keepttl" in opts.expiration && opts.expiration.keepttl) {
1648
+ command.push("KEEPTTL");
1649
+ }
1650
+ }
1651
+ const entries = Object.entries(kv);
1652
+ command.push("FIELDS", entries.length);
1653
+ for (const [field, value] of entries) {
1654
+ command.push(field, value);
1655
+ }
1656
+ super(command, cmdOpts);
1657
+ }
1658
+ };
1659
+
1065
1660
  // pkg/commands/hsetnx.ts
1066
1661
  var HSetNXCommand = class extends Command {
1067
1662
  constructor(cmd, opts) {
@@ -1845,6 +2440,16 @@ var XAckCommand = class extends Command {
1845
2440
  }
1846
2441
  };
1847
2442
 
2443
+ // pkg/commands/xackdel.ts
2444
+ var XAckDelCommand = class extends Command {
2445
+ constructor([key, group, opts, ...ids], cmdOpts) {
2446
+ const command = ["XACKDEL", key, group];
2447
+ command.push(opts.toUpperCase());
2448
+ command.push("IDS", ids.length, ...ids);
2449
+ super(command, cmdOpts);
2450
+ }
2451
+ };
2452
+
1848
2453
  // pkg/commands/xadd.ts
1849
2454
  var XAddCommand = class extends Command {
1850
2455
  constructor([key, id, entries, opts], commandOptions) {
@@ -1917,6 +2522,18 @@ var XDelCommand = class extends Command {
1917
2522
  }
1918
2523
  };
1919
2524
 
2525
+ // pkg/commands/xdelex.ts
2526
+ var XDelExCommand = class extends Command {
2527
+ constructor([key, opts, ...ids], cmdOpts) {
2528
+ const command = ["XDELEX", key];
2529
+ if (opts) {
2530
+ command.push(opts.toUpperCase());
2531
+ }
2532
+ command.push("IDS", ids.length, ...ids);
2533
+ super(command, cmdOpts);
2534
+ }
2535
+ };
2536
+
1920
2537
  // pkg/commands/xgroup.ts
1921
2538
  var XGroupCommand = class extends Command {
1922
2539
  constructor([key, opts], commandOptions) {
@@ -2002,7 +2619,7 @@ var XPendingCommand = class extends Command {
2002
2619
  };
2003
2620
 
2004
2621
  // pkg/commands/xrange.ts
2005
- function deserialize4(result) {
2622
+ function deserialize6(result) {
2006
2623
  const obj = {};
2007
2624
  for (const e of result) {
2008
2625
  for (let i = 0; i < e.length; i += 2) {
@@ -2031,7 +2648,7 @@ var XRangeCommand = class extends Command {
2031
2648
  command.push("COUNT", count);
2032
2649
  }
2033
2650
  super(command, {
2034
- deserialize: (result) => deserialize4(result),
2651
+ deserialize: (result) => deserialize6(result),
2035
2652
  ...opts
2036
2653
  });
2037
2654
  }
@@ -2094,12 +2711,12 @@ var XRevRangeCommand = class extends Command {
2094
2711
  command.push("COUNT", count);
2095
2712
  }
2096
2713
  super(command, {
2097
- deserialize: (result) => deserialize5(result),
2714
+ deserialize: (result) => deserialize7(result),
2098
2715
  ...opts
2099
2716
  });
2100
2717
  }
2101
2718
  };
2102
- function deserialize5(result) {
2719
+ function deserialize7(result) {
2103
2720
  const obj = {};
2104
2721
  for (const e of result) {
2105
2722
  for (let i = 0; i < e.length; i += 2) {
@@ -2481,6 +3098,10 @@ var Pipeline = class {
2481
3098
  * @see https://redis.io/commands/bitpos
2482
3099
  */
2483
3100
  bitpos = (...args) => this.chain(new BitPosCommand(args, this.commandOptions));
3101
+ /**
3102
+ * @see https://redis.io/commands/client-setinfo
3103
+ */
3104
+ clientSetinfo = (...args) => this.chain(new ClientSetInfoCommand(args, this.commandOptions));
2484
3105
  /**
2485
3106
  * @see https://redis.io/commands/copy
2486
3107
  */
@@ -2645,6 +3266,14 @@ var Pipeline = class {
2645
3266
  * @see https://redis.io/commands/hgetall
2646
3267
  */
2647
3268
  hgetall = (...args) => this.chain(new HGetAllCommand(args, this.commandOptions));
3269
+ /**
3270
+ * @see https://redis.io/commands/hgetdel
3271
+ */
3272
+ hgetdel = (...args) => this.chain(new HGetDelCommand(args, this.commandOptions));
3273
+ /**
3274
+ * @see https://redis.io/commands/hgetex
3275
+ */
3276
+ hgetex = (...args) => this.chain(new HGetExCommand(args, this.commandOptions));
2648
3277
  /**
2649
3278
  * @see https://redis.io/commands/hincrby
2650
3279
  */
@@ -2681,6 +3310,10 @@ var Pipeline = class {
2681
3310
  * @see https://redis.io/commands/hset
2682
3311
  */
2683
3312
  hset = (key, kv) => this.chain(new HSetCommand([key, kv], this.commandOptions));
3313
+ /**
3314
+ * @see https://redis.io/commands/hsetex
3315
+ */
3316
+ hsetex = (...args) => this.chain(new HSetExCommand(args, this.commandOptions));
2684
3317
  /**
2685
3318
  * @see https://redis.io/commands/hsetnx
2686
3319
  */
@@ -2985,10 +3618,18 @@ var Pipeline = class {
2985
3618
  * @see https://redis.io/commands/xack
2986
3619
  */
2987
3620
  xack = (...args) => this.chain(new XAckCommand(args, this.commandOptions));
3621
+ /**
3622
+ * @see https://redis.io/commands/xackdel
3623
+ */
3624
+ xackdel = (...args) => this.chain(new XAckDelCommand(args, this.commandOptions));
2988
3625
  /**
2989
3626
  * @see https://redis.io/commands/xdel
2990
3627
  */
2991
3628
  xdel = (...args) => this.chain(new XDelCommand(args, this.commandOptions));
3629
+ /**
3630
+ * @see https://redis.io/commands/xdelex
3631
+ */
3632
+ xdelex = (...args) => this.chain(new XDelExCommand(args, this.commandOptions));
2992
3633
  /**
2993
3634
  * @see https://redis.io/commands/xgroup
2994
3635
  */
@@ -3208,364 +3849,139 @@ var Pipeline = class {
3208
3849
  type: (...args) => this.chain(new JsonTypeCommand(args, this.commandOptions))
3209
3850
  };
3210
3851
  }
3211
- };
3212
-
3213
- // pkg/auto-pipeline.ts
3214
- var EXCLUDE_COMMANDS = /* @__PURE__ */ new Set([
3215
- "scan",
3216
- "keys",
3217
- "flushdb",
3218
- "flushall",
3219
- "dbsize",
3220
- "hscan",
3221
- "hgetall",
3222
- "hkeys",
3223
- "lrange",
3224
- "sscan",
3225
- "smembers",
3226
- "xrange",
3227
- "xrevrange",
3228
- "zscan",
3229
- "zrange",
3230
- "exec"
3231
- ]);
3232
- function createAutoPipelineProxy(_redis, json) {
3233
- const redis = _redis;
3234
- if (!redis.autoPipelineExecutor) {
3235
- redis.autoPipelineExecutor = new AutoPipelineExecutor(redis);
3236
- }
3237
- return new Proxy(redis, {
3238
- get: (redis2, command) => {
3239
- if (command === "pipelineCounter") {
3240
- return redis2.autoPipelineExecutor.pipelineCounter;
3241
- }
3242
- if (command === "json") {
3243
- return createAutoPipelineProxy(redis2, true);
3244
- }
3245
- const commandInRedisButNotPipeline = command in redis2 && !(command in redis2.autoPipelineExecutor.pipeline);
3246
- const isCommandExcluded = EXCLUDE_COMMANDS.has(command);
3247
- if (commandInRedisButNotPipeline || isCommandExcluded) {
3248
- return redis2[command];
3249
- }
3250
- const isFunction = json ? typeof redis2.autoPipelineExecutor.pipeline.json[command] === "function" : typeof redis2.autoPipelineExecutor.pipeline[command] === "function";
3251
- if (isFunction) {
3252
- return (...args) => {
3253
- return redis2.autoPipelineExecutor.withAutoPipeline((pipeline) => {
3254
- if (json) {
3255
- pipeline.json[command](
3256
- ...args
3257
- );
3258
- } else {
3259
- pipeline[command](...args);
3260
- }
3261
- });
3262
- };
3263
- }
3264
- return redis2.autoPipelineExecutor.pipeline[command];
3265
- }
3266
- });
3267
- }
3268
- var AutoPipelineExecutor = class {
3269
- pipelinePromises = /* @__PURE__ */ new WeakMap();
3270
- activePipeline = null;
3271
- indexInCurrentPipeline = 0;
3272
- redis;
3273
- pipeline;
3274
- // only to make sure that proxy can work
3275
- pipelineCounter = 0;
3276
- // to keep track of how many times a pipeline was executed
3277
- constructor(redis) {
3278
- this.redis = redis;
3279
- this.pipeline = redis.pipeline();
3280
- }
3281
- async withAutoPipeline(executeWithPipeline) {
3282
- const pipeline = this.activePipeline ?? this.redis.pipeline();
3283
- if (!this.activePipeline) {
3284
- this.activePipeline = pipeline;
3285
- this.indexInCurrentPipeline = 0;
3286
- }
3287
- const index = this.indexInCurrentPipeline++;
3288
- executeWithPipeline(pipeline);
3289
- const pipelineDone = this.deferExecution().then(() => {
3290
- if (!this.pipelinePromises.has(pipeline)) {
3291
- const pipelinePromise = pipeline.exec({ keepErrors: true });
3292
- this.pipelineCounter += 1;
3293
- this.pipelinePromises.set(pipeline, pipelinePromise);
3294
- this.activePipeline = null;
3295
- }
3296
- return this.pipelinePromises.get(pipeline);
3297
- });
3298
- const results = await pipelineDone;
3299
- const commandResult = results[index];
3300
- if (commandResult.error) {
3301
- throw new UpstashError(`Command failed: ${commandResult.error}`);
3302
- }
3303
- return commandResult.result;
3304
- }
3305
- async deferExecution() {
3306
- await Promise.resolve();
3307
- await Promise.resolve();
3308
- }
3309
- };
3310
-
3311
- // pkg/commands/search/types.ts
3312
- var FIELD_TYPES = ["TEXT", "U64", "I64", "F64", "BOOL", "DATE"];
3313
-
3314
- // pkg/commands/search/utils.ts
3315
- function isFieldType(value) {
3316
- return typeof value === "string" && FIELD_TYPES.includes(value);
3317
- }
3318
- function isDetailedField(value) {
3319
- return typeof value === "object" && value !== null && "type" in value && isFieldType(value.type);
3320
- }
3321
- function isNestedSchema(value) {
3322
- return typeof value === "object" && value !== null && !isDetailedField(value);
3323
- }
3324
- function flattenSchema(schema, pathPrefix = []) {
3325
- const fields = [];
3326
- for (const [key, value] of Object.entries(schema)) {
3327
- const currentPath = [...pathPrefix, key];
3328
- const pathString = currentPath.join(".");
3329
- if (isFieldType(value)) {
3330
- fields.push({
3331
- path: pathString,
3332
- type: value
3333
- });
3334
- } else if (isDetailedField(value)) {
3335
- fields.push({
3336
- path: pathString,
3337
- type: value.type,
3338
- fast: "fast" in value ? value.fast : void 0,
3339
- noTokenize: "noTokenize" in value ? value.noTokenize : void 0,
3340
- noStem: "noStem" in value ? value.noStem : void 0,
3341
- from: "from" in value ? value.from : void 0
3342
- });
3343
- } else if (isNestedSchema(value)) {
3344
- const nestedFields = flattenSchema(value, currentPath);
3345
- fields.push(...nestedFields);
3346
- }
3347
- }
3348
- return fields;
3349
- }
3350
- function deserializeQueryResponse(rawResponse) {
3351
- return rawResponse.map((itemRaw) => {
3352
- const raw = itemRaw;
3353
- const key = raw[0];
3354
- const score = raw[1];
3355
- const rawFields = raw[2];
3356
- if (rawFields === void 0) {
3357
- return { key, score };
3358
- }
3359
- if (!Array.isArray(rawFields) || rawFields.length === 0) {
3360
- return { key, score, data: {} };
3361
- }
3362
- let data = {};
3363
- for (const fieldRaw of rawFields) {
3364
- const key2 = fieldRaw[0];
3365
- const value = fieldRaw[1];
3366
- const pathParts = key2.split(".");
3367
- if (pathParts.length == 1) {
3368
- data[key2] = value;
3369
- } else {
3370
- let currentObj = data;
3371
- for (let i = 0; i < pathParts.length - 1; i++) {
3372
- const pathPart = pathParts[i];
3373
- if (!(pathPart in currentObj)) {
3374
- currentObj[pathPart] = {};
3375
- }
3376
- currentObj = currentObj[pathPart];
3377
- }
3378
- currentObj[pathParts.at(-1)] = value;
3379
- }
3380
- }
3381
- if ("$" in data) {
3382
- data = data["$"];
3383
- }
3384
- return { key, score, data };
3385
- });
3386
- }
3387
- function deserializeDescribeResponse(rawResponse) {
3388
- const description = {};
3389
- for (let i = 0; i < rawResponse.length; i += 2) {
3390
- const descriptor = rawResponse[i];
3391
- switch (descriptor) {
3392
- case "name": {
3393
- description["name"] = rawResponse[i + 1];
3394
- break;
3395
- }
3396
- case "type": {
3397
- description["dataType"] = rawResponse[i + 1].toLowerCase();
3398
- break;
3852
+ get functions() {
3853
+ return {
3854
+ /**
3855
+ * @see https://redis.io/docs/latest/commands/function-load/
3856
+ */
3857
+ load: (...args) => this.chain(new FunctionLoadCommand(args, this.commandOptions)),
3858
+ /**
3859
+ * @see https://redis.io/docs/latest/commands/function-list/
3860
+ */
3861
+ list: (...args) => this.chain(new FunctionListCommand(args, this.commandOptions)),
3862
+ /**
3863
+ * @see https://redis.io/docs/latest/commands/function-delete/
3864
+ */
3865
+ delete: (...args) => this.chain(new FunctionDeleteCommand(args, this.commandOptions)),
3866
+ /**
3867
+ * @see https://redis.io/docs/latest/commands/function-flush/
3868
+ */
3869
+ flush: () => this.chain(new FunctionFlushCommand(this.commandOptions)),
3870
+ /**
3871
+ * @see https://redis.io/docs/latest/commands/function-stats/
3872
+ */
3873
+ stats: () => this.chain(new FunctionStatsCommand(this.commandOptions)),
3874
+ /**
3875
+ * @see https://redis.io/docs/latest/commands/fcall/
3876
+ */
3877
+ call: (...args) => this.chain(new FCallCommand(args, this.commandOptions)),
3878
+ /**
3879
+ * @see https://redis.io/docs/latest/commands/fcall_ro/
3880
+ */
3881
+ callRo: (...args) => this.chain(new FCallRoCommand(args, this.commandOptions))
3882
+ };
3883
+ }
3884
+ };
3885
+
3886
+ // pkg/auto-pipeline.ts
3887
+ var EXCLUDE_COMMANDS = /* @__PURE__ */ new Set([
3888
+ "scan",
3889
+ "keys",
3890
+ "flushdb",
3891
+ "flushall",
3892
+ "dbsize",
3893
+ "hscan",
3894
+ "hgetall",
3895
+ "hkeys",
3896
+ "lrange",
3897
+ "sscan",
3898
+ "smembers",
3899
+ "xrange",
3900
+ "xrevrange",
3901
+ "zscan",
3902
+ "zrange",
3903
+ "exec"
3904
+ ]);
3905
+ function createAutoPipelineProxy(_redis, namespace = "root") {
3906
+ const redis = _redis;
3907
+ if (!redis.autoPipelineExecutor) {
3908
+ redis.autoPipelineExecutor = new AutoPipelineExecutor(redis);
3909
+ }
3910
+ return new Proxy(redis, {
3911
+ get: (redis2, command) => {
3912
+ if (command === "pipelineCounter") {
3913
+ return redis2.autoPipelineExecutor.pipelineCounter;
3399
3914
  }
3400
- case "prefixes": {
3401
- description["prefixes"] = rawResponse[i + 1];
3402
- break;
3915
+ if (namespace === "root" && command === "json") {
3916
+ return createAutoPipelineProxy(redis2, "json");
3403
3917
  }
3404
- case "language": {
3405
- description["language"] = rawResponse[i + 1];
3406
- break;
3918
+ if (namespace === "root" && command === "functions") {
3919
+ return createAutoPipelineProxy(redis2, "functions");
3407
3920
  }
3408
- case "schema": {
3409
- const schema = {};
3410
- for (const fieldDescription of rawResponse[i + 1]) {
3411
- const fieldName = fieldDescription[0];
3412
- const fieldInfo = { type: fieldDescription[1] };
3413
- if (fieldDescription.length > 2) {
3414
- for (let j = 2; j < fieldDescription.length; j++) {
3415
- const fieldOption = fieldDescription[j];
3416
- switch (fieldOption) {
3417
- case "NOSTEM": {
3418
- fieldInfo.noStem = true;
3419
- break;
3420
- }
3421
- case "NOTOKENIZE": {
3422
- fieldInfo.noTokenize = true;
3423
- break;
3424
- }
3425
- case "FAST": {
3426
- fieldInfo.fast = true;
3427
- break;
3428
- }
3429
- }
3430
- }
3431
- }
3432
- schema[fieldName] = fieldInfo;
3921
+ if (namespace === "root") {
3922
+ const commandInRedisButNotPipeline = command in redis2 && !(command in redis2.autoPipelineExecutor.pipeline);
3923
+ const isCommandExcluded = EXCLUDE_COMMANDS.has(command);
3924
+ if (commandInRedisButNotPipeline || isCommandExcluded) {
3925
+ return redis2[command];
3433
3926
  }
3434
- description["schema"] = schema;
3435
- break;
3436
3927
  }
3928
+ const pipeline = redis2.autoPipelineExecutor.pipeline;
3929
+ const targetFunction = namespace === "json" ? pipeline.json[command] : namespace === "functions" ? pipeline.functions[command] : pipeline[command];
3930
+ const isFunction = typeof targetFunction === "function";
3931
+ if (isFunction) {
3932
+ return (...args) => {
3933
+ return redis2.autoPipelineExecutor.withAutoPipeline((pipeline2) => {
3934
+ const targetFunction2 = namespace === "json" ? pipeline2.json[command] : namespace === "functions" ? pipeline2.functions[command] : pipeline2[command];
3935
+ targetFunction2(...args);
3936
+ });
3937
+ };
3938
+ }
3939
+ return targetFunction;
3437
3940
  }
3438
- }
3439
- return description;
3440
- }
3441
- function parseCountResponse(rawResponse) {
3442
- return typeof rawResponse === "number" ? rawResponse : Number.parseInt(rawResponse, 10);
3941
+ });
3443
3942
  }
3444
-
3445
- // pkg/commands/search/command-builder.ts
3446
- function buildQueryCommand(redisCommand, name, options) {
3447
- const query = JSON.stringify(options?.filter ?? {});
3448
- const command = [redisCommand, name, query];
3449
- if (options?.limit !== void 0) {
3450
- command.push("LIMIT", options.limit.toString());
3451
- }
3452
- if (options?.offset !== void 0) {
3453
- command.push("OFFSET", options.offset.toString());
3454
- }
3455
- if (options?.select && Object.keys(options.select).length === 0) {
3456
- command.push("NOCONTENT");
3457
- }
3458
- if (options?.orderBy) {
3459
- command.push("SORTBY");
3460
- for (const [field, direction] of Object.entries(options.orderBy)) {
3461
- command.push(field, direction);
3462
- }
3463
- }
3464
- if (options?.highlight) {
3465
- command.push(
3466
- "HIGHLIGHT",
3467
- "FIELDS",
3468
- options.highlight.fields.length.toString(),
3469
- ...options.highlight.fields
3470
- );
3471
- if (options.highlight.preTag && options.highlight.postTag) {
3472
- command.push("TAGS", options.highlight.preTag, options.highlight.postTag);
3473
- }
3474
- }
3475
- if (options?.select && Object.keys(options.select).length > 0) {
3476
- command.push(
3477
- "RETURN",
3478
- Object.keys(options.select).length.toString(),
3479
- ...Object.keys(options.select)
3480
- );
3943
+ var AutoPipelineExecutor = class {
3944
+ pipelinePromises = /* @__PURE__ */ new WeakMap();
3945
+ activePipeline = null;
3946
+ indexInCurrentPipeline = 0;
3947
+ redis;
3948
+ pipeline;
3949
+ // only to make sure that proxy can work
3950
+ pipelineCounter = 0;
3951
+ // to keep track of how many times a pipeline was executed
3952
+ constructor(redis) {
3953
+ this.redis = redis;
3954
+ this.pipeline = redis.pipeline();
3481
3955
  }
3482
- return command;
3483
- }
3484
- function buildCreateIndexCommand(params) {
3485
- const { name, schema, dataType, prefix, language, skipInitialScan, existsOk } = params;
3486
- const prefixArray = Array.isArray(prefix) ? prefix : [prefix];
3487
- const payload = [
3488
- name,
3489
- ...skipInitialScan ? ["SKIPINITIALSCAN"] : [],
3490
- ...existsOk ? ["EXISTSOK"] : [],
3491
- "ON",
3492
- dataType.toUpperCase(),
3493
- "PREFIX",
3494
- prefixArray.length.toString(),
3495
- ...prefixArray,
3496
- ...language ? ["LANGUAGE", language] : [],
3497
- "SCHEMA"
3498
- ];
3499
- const fields = flattenSchema(schema);
3500
- for (const field of fields) {
3501
- payload.push(field.path, field.type);
3502
- if (field.fast) {
3503
- payload.push("FAST");
3504
- }
3505
- if (field.noTokenize) {
3506
- payload.push("NOTOKENIZE");
3507
- }
3508
- if (field.noStem) {
3509
- payload.push("NOSTEM");
3956
+ async withAutoPipeline(executeWithPipeline) {
3957
+ const pipeline = this.activePipeline ?? this.redis.pipeline();
3958
+ if (!this.activePipeline) {
3959
+ this.activePipeline = pipeline;
3960
+ this.indexInCurrentPipeline = 0;
3510
3961
  }
3511
- if (field.from) {
3512
- payload.push("FROM", field.from);
3962
+ const index = this.indexInCurrentPipeline++;
3963
+ executeWithPipeline(pipeline);
3964
+ const pipelineDone = this.deferExecution().then(() => {
3965
+ if (!this.pipelinePromises.has(pipeline)) {
3966
+ const pipelinePromise = pipeline.exec({ keepErrors: true });
3967
+ this.pipelineCounter += 1;
3968
+ this.pipelinePromises.set(pipeline, pipelinePromise);
3969
+ this.activePipeline = null;
3970
+ }
3971
+ return this.pipelinePromises.get(pipeline);
3972
+ });
3973
+ const results = await pipelineDone;
3974
+ const commandResult = results[index];
3975
+ if (commandResult.error) {
3976
+ throw new UpstashError(`Command failed: ${commandResult.error}`);
3513
3977
  }
3978
+ return commandResult.result;
3514
3979
  }
3515
- return ["SEARCH.CREATE", ...payload];
3516
- }
3517
-
3518
- // pkg/commands/search/search.ts
3519
- var SearchIndex = class {
3520
- name;
3521
- schema;
3522
- client;
3523
- constructor({ name, schema, client }) {
3524
- this.name = name;
3525
- this.schema = schema;
3526
- this.client = client;
3527
- }
3528
- async waitIndexing() {
3529
- const command = ["SEARCH.WAITINDEXING", this.name];
3530
- await new ExecCommand(command).exec(this.client);
3531
- }
3532
- async describe() {
3533
- const command = ["SEARCH.DESCRIBE", this.name];
3534
- const rawResult = await new ExecCommand(command).exec(
3535
- this.client
3536
- );
3537
- return deserializeDescribeResponse(rawResult);
3538
- }
3539
- async query(options) {
3540
- const command = buildQueryCommand("SEARCH.QUERY", this.name, options);
3541
- const rawResult = await new ExecCommand(command).exec(
3542
- this.client
3543
- );
3544
- return deserializeQueryResponse(rawResult);
3545
- }
3546
- async count({ filter }) {
3547
- const command = buildQueryCommand("SEARCH.COUNT", this.name, { filter });
3548
- const rawResult = await new ExecCommand(command).exec(
3549
- this.client
3550
- );
3551
- return { count: parseCountResponse(rawResult) };
3552
- }
3553
- async drop() {
3554
- const command = ["SEARCH.DROP", this.name];
3555
- const result = await new ExecCommand(command).exec(this.client);
3556
- return result;
3980
+ async deferExecution() {
3981
+ await Promise.resolve();
3982
+ await Promise.resolve();
3557
3983
  }
3558
3984
  };
3559
- async function createIndex(client, params) {
3560
- const { name, schema } = params;
3561
- const createIndexCommand = buildCreateIndexCommand(params);
3562
- await new ExecCommand(createIndexCommand).exec(client);
3563
- return initIndex(client, { name, schema });
3564
- }
3565
- function initIndex(client, params) {
3566
- const { name, schema } = params;
3567
- return new SearchIndex({ name, schema, client });
3568
- }
3569
3985
 
3570
3986
  // pkg/commands/psubscribe.ts
3571
3987
  var PSubscribeCommand = class extends Command {
@@ -4012,6 +4428,40 @@ var Redis = class {
4012
4428
  type: (...args) => new JsonTypeCommand(args, this.opts).exec(this.client)
4013
4429
  };
4014
4430
  }
4431
+ get functions() {
4432
+ return {
4433
+ /**
4434
+ * @see https://redis.io/docs/latest/commands/function-load/
4435
+ */
4436
+ load: (...args) => new FunctionLoadCommand(args, this.opts).exec(this.client),
4437
+ /**
4438
+ * @see https://redis.io/docs/latest/commands/function-list/
4439
+ */
4440
+ list: (...args) => new FunctionListCommand(args, this.opts).exec(this.client),
4441
+ /**
4442
+ * @see https://redis.io/docs/latest/commands/function-delete/
4443
+ */
4444
+ delete: (...args) => new FunctionDeleteCommand(args, this.opts).exec(this.client),
4445
+ /**
4446
+ * @see https://redis.io/docs/latest/commands/function-flush/
4447
+ */
4448
+ flush: () => new FunctionFlushCommand(this.opts).exec(this.client),
4449
+ /**
4450
+ * @see https://redis.io/docs/latest/commands/function-stats/
4451
+ *
4452
+ * Note: `running_script` field is not supported and therefore not included in the type.
4453
+ */
4454
+ stats: () => new FunctionStatsCommand(this.opts).exec(this.client),
4455
+ /**
4456
+ * @see https://redis.io/docs/latest/commands/fcall/
4457
+ */
4458
+ call: (...args) => new FCallCommand(args, this.opts).exec(this.client),
4459
+ /**
4460
+ * @see https://redis.io/docs/latest/commands/fcall_ro/
4461
+ */
4462
+ callRo: (...args) => new FCallRoCommand(args, this.opts).exec(this.client)
4463
+ };
4464
+ }
4015
4465
  /**
4016
4466
  * Wrap a new middleware around the HTTP client.
4017
4467
  */
@@ -4069,6 +4519,17 @@ var Redis = class {
4069
4519
  },
4070
4520
  index: (params) => {
4071
4521
  return initIndex(this.client, params);
4522
+ },
4523
+ alias: {
4524
+ list: () => {
4525
+ return listAliases(this.client);
4526
+ },
4527
+ add: ({ indexName, alias }) => {
4528
+ return addAlias(this.client, { indexName, alias });
4529
+ },
4530
+ delete: ({ alias }) => {
4531
+ return delAlias(this.client, { alias });
4532
+ }
4072
4533
  }
4073
4534
  };
4074
4535
  }
@@ -4133,6 +4594,10 @@ var Redis = class {
4133
4594
  * @see https://redis.io/commands/bitpos
4134
4595
  */
4135
4596
  bitpos = (...args) => new BitPosCommand(args, this.opts).exec(this.client);
4597
+ /**
4598
+ * @see https://redis.io/commands/client-setinfo
4599
+ */
4600
+ clientSetinfo = (...args) => new ClientSetInfoCommand(args, this.opts).exec(this.client);
4136
4601
  /**
4137
4602
  * @see https://redis.io/commands/copy
4138
4603
  */
@@ -4297,6 +4762,14 @@ var Redis = class {
4297
4762
  * @see https://redis.io/commands/hgetall
4298
4763
  */
4299
4764
  hgetall = (...args) => new HGetAllCommand(args, this.opts).exec(this.client);
4765
+ /**
4766
+ * @see https://redis.io/commands/hgetdel
4767
+ */
4768
+ hgetdel = (...args) => new HGetDelCommand(args, this.opts).exec(this.client);
4769
+ /**
4770
+ * @see https://redis.io/commands/hgetex
4771
+ */
4772
+ hgetex = (...args) => new HGetExCommand(args, this.opts).exec(this.client);
4300
4773
  /**
4301
4774
  * @see https://redis.io/commands/hincrby
4302
4775
  */
@@ -4333,6 +4806,10 @@ var Redis = class {
4333
4806
  * @see https://redis.io/commands/hset
4334
4807
  */
4335
4808
  hset = (key, kv) => new HSetCommand([key, kv], this.opts).exec(this.client);
4809
+ /**
4810
+ * @see https://redis.io/commands/hsetex
4811
+ */
4812
+ hsetex = (...args) => new HSetExCommand(args, this.opts).exec(this.client);
4336
4813
  /**
4337
4814
  * @see https://redis.io/commands/hsetnx
4338
4815
  */
@@ -4634,10 +5111,18 @@ var Redis = class {
4634
5111
  * @see https://redis.io/commands/xack
4635
5112
  */
4636
5113
  xack = (...args) => new XAckCommand(args, this.opts).exec(this.client);
5114
+ /**
5115
+ * @see https://redis.io/commands/xackdel
5116
+ */
5117
+ xackdel = (...args) => new XAckDelCommand(args, this.opts).exec(this.client);
4637
5118
  /**
4638
5119
  * @see https://redis.io/commands/xdel
4639
5120
  */
4640
5121
  xdel = (...args) => new XDelCommand(args, this.opts).exec(this.client);
5122
+ /**
5123
+ * @see https://redis.io/commands/xdelex
5124
+ */
5125
+ xdelex = (...args) => new XDelExCommand(args, this.opts).exec(this.client);
4641
5126
  /**
4642
5127
  * @see https://redis.io/commands/xgroup
4643
5128
  */
@@ -4779,11 +5264,12 @@ var Redis = class {
4779
5264
  };
4780
5265
 
4781
5266
  // version.ts
4782
- var VERSION = "v1.37.0-rc";
5267
+ var VERSION = "v1.37.0-rc.10";
4783
5268
 
4784
5269
  export {
4785
5270
  error_exports,
4786
5271
  HttpClient,
5272
+ SearchIndex,
4787
5273
  Redis,
4788
5274
  VERSION
4789
5275
  };