@upstash/redis 1.36.0-rc.1 → 1.36.0-rc.3

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/nodejs.js CHANGED
@@ -21,9 +21,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var nodejs_exports = {};
22
22
  __export(nodejs_exports, {
23
23
  Redis: () => Redis2,
24
- createSearchIndex: () => createSearchIndex,
24
+ createIndex: () => createIndex,
25
25
  errors: () => error_exports,
26
- getSearchIndex: () => getSearchIndex,
26
+ index: () => index,
27
27
  s: () => s
28
28
  });
29
29
  module.exports = __toCommonJS(nodejs_exports);
@@ -403,7 +403,7 @@ var AutoPipelineExecutor = class {
403
403
  this.activePipeline = pipeline;
404
404
  this.indexInCurrentPipeline = 0;
405
405
  }
406
- const index = this.indexInCurrentPipeline++;
406
+ const index2 = this.indexInCurrentPipeline++;
407
407
  executeWithPipeline(pipeline);
408
408
  const pipelineDone = this.deferExecution().then(() => {
409
409
  if (!this.pipelinePromises.has(pipeline)) {
@@ -415,7 +415,7 @@ var AutoPipelineExecutor = class {
415
415
  return this.pipelinePromises.get(pipeline);
416
416
  });
417
417
  const results = await pipelineDone;
418
- const commandResult = results[index];
418
+ const commandResult = results[index2];
419
419
  if (commandResult.error) {
420
420
  throw new UpstashError(`Command failed: ${commandResult.error}`);
421
421
  }
@@ -2529,55 +2529,119 @@ function flattenSchema(schema, pathPrefix = []) {
2529
2529
  }
2530
2530
  return fields;
2531
2531
  }
2532
- function parseQueryResponse(rawResponse, options) {
2533
- const results = [];
2534
- if (options && "noContent" in options && options.noContent) {
2535
- for (const item of rawResponse) {
2536
- results.push({
2537
- key: item[0],
2538
- score: item[1]
2539
- });
2540
- }
2541
- } else {
2542
- for (const item of rawResponse) {
2543
- const fields = Array.isArray(item[2]) ? item[2].map((field) => ({
2544
- [field[0]]: field[1]
2545
- })) : [];
2546
- results.push({
2547
- key: item[0],
2548
- score: item[1],
2549
- fields
2550
- });
2532
+ function deserializeQueryResponse(rawResponse, options) {
2533
+ const hasEmptySelect = options?.select && Object.keys(options.select).length === 0;
2534
+ return rawResponse.map((itemRaw) => {
2535
+ const raw = itemRaw;
2536
+ const key = raw[0];
2537
+ const score = raw[1];
2538
+ const rawFields = raw[2];
2539
+ if (hasEmptySelect) {
2540
+ return { key, score };
2541
+ }
2542
+ if (!Array.isArray(rawFields) || rawFields.length === 0) {
2543
+ return { key, score, data: {} };
2544
+ }
2545
+ const mergedFields = {};
2546
+ for (const fieldRaw of rawFields) {
2547
+ const fieldObj = kvArrayToObject(fieldRaw);
2548
+ Object.assign(mergedFields, fieldObj);
2549
+ }
2550
+ if ("$" in mergedFields) {
2551
+ const data2 = mergedFields["$"];
2552
+ return { key, score, data: data2 };
2553
+ }
2554
+ const data = dotNotationToNested(mergedFields);
2555
+ return { key, score, data };
2556
+ });
2557
+ }
2558
+ function parseFieldInfo(fieldRaw) {
2559
+ const fieldType = fieldRaw[1];
2560
+ const options = fieldRaw.slice(2);
2561
+ const fieldInfo = { type: fieldType };
2562
+ for (const option of options) {
2563
+ switch (option.toUpperCase()) {
2564
+ case "NOTOKENIZE":
2565
+ fieldInfo.noTokenize = true;
2566
+ break;
2567
+ case "NOSTEM":
2568
+ fieldInfo.noStem = true;
2569
+ break;
2570
+ case "FAST":
2571
+ fieldInfo.fast = true;
2572
+ break;
2551
2573
  }
2552
2574
  }
2553
- return results;
2575
+ return fieldInfo;
2554
2576
  }
2555
- function parseDescribeResponse(rawResponse) {
2556
- return rawResponse;
2577
+ function deserializeDescribeResponse(rawResponse) {
2578
+ const raw = kvArrayToObject(rawResponse);
2579
+ const schema = {};
2580
+ if (Array.isArray(raw.schema)) {
2581
+ for (const fieldRaw of raw.schema) {
2582
+ if (Array.isArray(fieldRaw) && fieldRaw.length >= 2) {
2583
+ const fieldName = fieldRaw[0];
2584
+ schema[fieldName] = parseFieldInfo(fieldRaw);
2585
+ }
2586
+ }
2587
+ }
2588
+ return {
2589
+ name: raw.name,
2590
+ dataType: raw.type.toLowerCase(),
2591
+ prefixes: raw.prefixes,
2592
+ ...raw.language && { language: raw.language },
2593
+ schema
2594
+ };
2557
2595
  }
2558
2596
  function parseCountResponse(rawResponse) {
2559
2597
  return typeof rawResponse === "number" ? rawResponse : parseInt(rawResponse, 10);
2560
2598
  }
2599
+ function kvArrayToObject(v) {
2600
+ if (typeof v === "object" && v !== null && !Array.isArray(v)) return v;
2601
+ if (!Array.isArray(v)) return {};
2602
+ const obj = {};
2603
+ for (let i = 0; i < v.length; i += 2) {
2604
+ if (typeof v[i] === "string") obj[v[i]] = v[i + 1];
2605
+ }
2606
+ return obj;
2607
+ }
2608
+ function dotNotationToNested(obj) {
2609
+ const result = {};
2610
+ for (const [key, value] of Object.entries(obj)) {
2611
+ const parts = key.split(".");
2612
+ let current = result;
2613
+ for (let i = 0; i < parts.length - 1; i++) {
2614
+ const part = parts[i];
2615
+ if (!(part in current)) {
2616
+ current[part] = {};
2617
+ }
2618
+ current = current[part];
2619
+ }
2620
+ current[parts[parts.length - 1]] = value;
2621
+ }
2622
+ return result;
2623
+ }
2561
2624
 
2562
2625
  // pkg/commands/search/command-builder.ts
2563
- function buildQueryCommand(redisCommand, indexName, query, options) {
2564
- const command = [redisCommand, indexName, query];
2626
+ function buildQueryCommand(redisCommand, name, options) {
2627
+ const query = JSON.stringify(options?.filter);
2628
+ const command = [redisCommand, name, query];
2565
2629
  if (options?.limit !== void 0) {
2566
2630
  command.push("LIMIT", options.limit.toString());
2567
2631
  }
2568
2632
  if (options?.offset !== void 0) {
2569
2633
  command.push("OFFSET", options.offset.toString());
2570
2634
  }
2571
- if (options?.noContent) {
2635
+ if (options?.select && Object.keys(options.select).length === 0) {
2572
2636
  command.push("NOCONTENT");
2573
2637
  }
2574
- if (options?.sortBy) {
2575
- command.push("SORTBY", options.sortBy.field);
2576
- if (options.sortBy.direction) {
2577
- command.push(options.sortBy.direction);
2578
- }
2638
+ if (options?.orderBy) {
2639
+ command.push("SORTBY");
2640
+ Object.entries(options.orderBy).forEach(([field, direction]) => {
2641
+ command.push(field, direction);
2642
+ });
2579
2643
  }
2580
- if (options && "highlight" in options && options.highlight) {
2644
+ if (options?.highlight) {
2581
2645
  command.push(
2582
2646
  "HIGHLIGHT",
2583
2647
  "FIELDS",
@@ -2588,16 +2652,20 @@ function buildQueryCommand(redisCommand, indexName, query, options) {
2588
2652
  command.push("TAGS", options.highlight.preTag, options.highlight.postTag);
2589
2653
  }
2590
2654
  }
2591
- if (options && "returnFields" in options && options.returnFields && options.returnFields.length > 0) {
2592
- command.push("RETURN", options.returnFields.length.toString(), ...options.returnFields);
2655
+ if (options?.select && Object.keys(options.select).length > 0) {
2656
+ command.push(
2657
+ "RETURN",
2658
+ Object.keys(options.select).length.toString(),
2659
+ ...Object.keys(options.select)
2660
+ );
2593
2661
  }
2594
2662
  return command;
2595
2663
  }
2596
2664
  function buildCreateIndexCommand(props) {
2597
- const { indexName, schema, dataType, prefix, language } = props;
2665
+ const { name, schema, dataType, prefix, language } = props;
2598
2666
  const prefixArray = Array.isArray(prefix) ? prefix : [prefix];
2599
2667
  const payload = [
2600
- indexName,
2668
+ name,
2601
2669
  "ON",
2602
2670
  dataType.toUpperCase(),
2603
2671
  "PREFIX",
@@ -2624,65 +2692,58 @@ function buildCreateIndexCommand(props) {
2624
2692
 
2625
2693
  // pkg/commands/search/search.ts
2626
2694
  var SearchIndex = class {
2627
- indexName;
2695
+ name;
2628
2696
  schema;
2629
2697
  client;
2630
- constructor({ indexName, schema, client }) {
2631
- this.indexName = indexName;
2698
+ constructor({ name, schema, client }) {
2699
+ this.name = name;
2632
2700
  this.schema = schema;
2633
2701
  this.client = client;
2634
2702
  }
2635
2703
  async waitIndexing() {
2636
- let command = ["SEARCH.COMMIT", this.indexName];
2704
+ const command = ["SEARCH.COMMIT", this.name];
2637
2705
  const result = await new ExecCommand(command).exec(
2638
2706
  this.client
2639
2707
  );
2640
2708
  return result;
2641
2709
  }
2642
2710
  async describe() {
2643
- let command = ["SEARCH.DESCRIBE", this.indexName];
2711
+ const command = ["SEARCH.DESCRIBE", this.name];
2644
2712
  const rawResult = await new ExecCommand(command).exec(
2645
2713
  this.client
2646
2714
  );
2647
- return parseDescribeResponse(rawResult);
2648
- }
2649
- async query(filter, options) {
2650
- const queryString = JSON.stringify(filter);
2651
- const command = buildQueryCommand(
2652
- "SEARCH.QUERY",
2653
- this.indexName,
2654
- queryString,
2655
- options
2656
- );
2715
+ return deserializeDescribeResponse(rawResult);
2716
+ }
2717
+ async query(options) {
2718
+ const command = buildQueryCommand("SEARCH.QUERY", this.name, options);
2657
2719
  const rawResult = await new ExecCommand(command).exec(
2658
2720
  this.client
2659
2721
  );
2660
- return parseQueryResponse(rawResult, options);
2722
+ return deserializeQueryResponse(rawResult, options);
2661
2723
  }
2662
- async count(filter) {
2663
- const queryString = JSON.stringify(filter);
2664
- const command = buildQueryCommand("SEARCH.COUNT", this.indexName, queryString);
2724
+ async count({ filter }) {
2725
+ const command = buildQueryCommand("SEARCH.COUNT", this.name, { filter });
2665
2726
  const rawResult = await new ExecCommand(command).exec(
2666
2727
  this.client
2667
2728
  );
2668
- return parseCountResponse(rawResult);
2729
+ return { count: parseCountResponse(rawResult) };
2669
2730
  }
2670
2731
  async drop() {
2671
- let command = ["SEARCH.DROP", this.indexName];
2732
+ const command = ["SEARCH.DROP", this.name];
2672
2733
  const result = await new ExecCommand(command).exec(
2673
2734
  this.client
2674
2735
  );
2675
2736
  return result;
2676
2737
  }
2677
2738
  };
2678
- async function createSearchIndex(props) {
2679
- const { indexName, schema, client } = props;
2739
+ async function createIndex(props) {
2740
+ const { name, schema, client } = props;
2680
2741
  const createIndexCommand = buildCreateIndexCommand(props);
2681
2742
  await new ExecCommand(createIndexCommand).exec(client);
2682
- return getSearchIndex({ indexName, schema, client });
2743
+ return index(client, name, schema);
2683
2744
  }
2684
- function getSearchIndex(props) {
2685
- return new SearchIndex(props);
2745
+ function index(client, name, schema) {
2746
+ return new SearchIndex({ name, schema, client });
2686
2747
  }
2687
2748
 
2688
2749
  // pkg/commands/search/schema-builder.ts
@@ -2708,21 +2769,16 @@ var TextFieldBuilder = class _TextFieldBuilder {
2708
2769
  } : "TEXT";
2709
2770
  }
2710
2771
  };
2711
- var NumericFieldBuilder = class _NumericFieldBuilder {
2712
- _fast;
2772
+ var NumericFieldBuilder = class {
2713
2773
  type;
2714
- constructor(type, fast = { fast: false }) {
2774
+ constructor(type) {
2715
2775
  this.type = type;
2716
- this._fast = fast;
2717
- }
2718
- fast() {
2719
- return new _NumericFieldBuilder(this.type, { fast: true });
2720
2776
  }
2721
2777
  [BUILD]() {
2722
- return this._fast.fast ? {
2778
+ return {
2723
2779
  type: this.type,
2724
2780
  fast: true
2725
- } : this.type;
2781
+ };
2726
2782
  }
2727
2783
  };
2728
2784
  var BoolFieldBuilder = class _BoolFieldBuilder {
@@ -2756,74 +2812,18 @@ var DateFieldBuilder = class _DateFieldBuilder {
2756
2812
  }
2757
2813
  };
2758
2814
  var s = {
2759
- /**
2760
- * Full-text search field (TEXT)
2761
- * @example
2762
- * s.text() // Simple text field
2763
- * s.text().noTokenize() // Exact phrase matching
2764
- * s.text().noStem() // Disable stemming
2765
- */
2766
- text() {
2815
+ string() {
2767
2816
  return new TextFieldBuilder();
2768
2817
  },
2769
- /**
2770
- * Unsigned 64-bit integer (U64)
2771
- * Range: 0 to 2^64-1
2772
- * @example
2773
- * s.unsigned() // Simple unsigned field
2774
- * s.unsigned().fast() // Enable sorting and range queries
2775
- */
2776
- unsignedInteger() {
2777
- return new NumericFieldBuilder("U64");
2818
+ number(type = "F64") {
2819
+ return new NumericFieldBuilder(type);
2778
2820
  },
2779
- /**
2780
- * Signed 64-bit integer (I64)
2781
- * Range: -2^63 to 2^63-1
2782
- * @example
2783
- * s.integer() // Simple integer field
2784
- * s.integer().fast() // Enable sorting and range queries
2785
- */
2786
- integer() {
2787
- return new NumericFieldBuilder("I64");
2788
- },
2789
- /**
2790
- * 64-bit floating point (F64)
2791
- * @example
2792
- * s.float() // Simple float field
2793
- * s.float().fast() // Enable sorting and range queries
2794
- */
2795
- float() {
2796
- return new NumericFieldBuilder("F64");
2797
- },
2798
- /**
2799
- * Boolean field (BOOL)
2800
- * @example
2801
- * s.bool() // Simple boolean field
2802
- * s.bool().fast() // Enable efficient filtering
2803
- */
2804
- bool() {
2821
+ boolean() {
2805
2822
  return new BoolFieldBuilder();
2806
2823
  },
2807
- /**
2808
- * ISO 8601 date field (DATE)
2809
- * @example
2810
- * s.date() // Simple date field
2811
- * s.date().fast() // Enable sorting and range queries
2812
- */
2813
2824
  date() {
2814
2825
  return new DateFieldBuilder();
2815
2826
  },
2816
- /**
2817
- * Create a string/JSON index schema (supports nesting)
2818
- * @example
2819
- * s.object({
2820
- * name: s.text(),
2821
- * profile: s.object({
2822
- * age: s.unsigned(),
2823
- * city: s.text()
2824
- * })
2825
- * })
2826
- */
2827
2827
  object(fields) {
2828
2828
  const result = {};
2829
2829
  for (const [key, value] of Object.entries(fields)) {
@@ -3410,7 +3410,7 @@ var Pipeline = class {
3410
3410
  /**
3411
3411
  * @see https://redis.io/commands/lset
3412
3412
  */
3413
- lset = (key, index, value) => this.chain(new LSetCommand([key, index, value], this.commandOptions));
3413
+ lset = (key, index2, value) => this.chain(new LSetCommand([key, index2, value], this.commandOptions));
3414
3414
  /**
3415
3415
  * @see https://redis.io/commands/ltrim
3416
3416
  */
@@ -4173,18 +4173,19 @@ var Redis = class {
4173
4173
  createScript(script, opts) {
4174
4174
  return opts?.readonly ? new ScriptRO(this, script) : new Script(this, script);
4175
4175
  }
4176
- createSearchIndex = (props) => {
4177
- return createSearchIndex({
4178
- ...props,
4179
- client: this.client
4180
- });
4181
- };
4182
- getSearchIndex = (props) => {
4183
- return getSearchIndex({
4184
- ...props,
4185
- client: this.client
4186
- });
4187
- };
4176
+ get search() {
4177
+ return {
4178
+ createIndex: (props) => {
4179
+ return createIndex({
4180
+ ...props,
4181
+ client: this.client
4182
+ });
4183
+ },
4184
+ index: (name, schema) => {
4185
+ return index(this.client, name, schema);
4186
+ }
4187
+ };
4188
+ }
4188
4189
  /**
4189
4190
  * Create a new pipeline that allows you to send requests in bulk.
4190
4191
  *
@@ -4521,7 +4522,7 @@ var Redis = class {
4521
4522
  /**
4522
4523
  * @see https://redis.io/commands/lset
4523
4524
  */
4524
- lset = (key, index, value) => new LSetCommand([key, index, value], this.opts).exec(this.client);
4525
+ lset = (key, index2, value) => new LSetCommand([key, index2, value], this.opts).exec(this.client);
4525
4526
  /**
4526
4527
  * @see https://redis.io/commands/ltrim
4527
4528
  */
@@ -4892,7 +4893,7 @@ var Redis = class {
4892
4893
  };
4893
4894
 
4894
4895
  // version.ts
4895
- var VERSION = "v1.36.0-rc.1";
4896
+ var VERSION = "v1.36.0-rc.3";
4896
4897
 
4897
4898
  // platforms/nodejs.ts
4898
4899
  if (typeof atob === "undefined") {
@@ -5003,8 +5004,8 @@ var Redis2 = class _Redis extends Redis {
5003
5004
  // Annotate the CommonJS export names for ESM import in node:
5004
5005
  0 && (module.exports = {
5005
5006
  Redis,
5006
- createSearchIndex,
5007
+ createIndex,
5007
5008
  errors,
5008
- getSearchIndex,
5009
+ index,
5009
5010
  s
5010
5011
  });
package/nodejs.mjs CHANGED
@@ -2,11 +2,11 @@ import {
2
2
  HttpClient,
3
3
  Redis,
4
4
  VERSION,
5
- createSearchIndex,
5
+ createIndex,
6
6
  error_exports,
7
- getSearchIndex,
7
+ index,
8
8
  s
9
- } from "./chunk-U5HO3NMB.mjs";
9
+ } from "./chunk-2HN5OIX5.mjs";
10
10
 
11
11
  // platforms/nodejs.ts
12
12
  if (typeof atob === "undefined") {
@@ -116,8 +116,8 @@ var Redis2 = class _Redis extends Redis {
116
116
  };
117
117
  export {
118
118
  Redis2 as Redis,
119
- createSearchIndex,
119
+ createIndex,
120
120
  error_exports as errors,
121
- getSearchIndex,
121
+ index,
122
122
  s
123
123
  };
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@upstash/redis","version":"v1.36.0-rc.1","main":"./nodejs.js","module":"./nodejs.mjs","types":"./nodejs.d.ts","exports":{".":{"import":"./nodejs.mjs","require":"./nodejs.js"},"./node":{"import":"./nodejs.mjs","require":"./nodejs.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./cloudflare.js":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./cloudflare.mjs":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./fastly":{"import":"./fastly.mjs","require":"./fastly.js"},"./fastly.js":{"import":"./fastly.mjs","require":"./fastly.js"},"./fastly.mjs":{"import":"./fastly.mjs","require":"./fastly.js"}},"description":"An HTTP/REST based Redis client built on top of Upstash REST API.","repository":{"type":"git","url":"git+https://github.com/upstash/upstash-redis.git"},"keywords":["redis","database","serverless","edge","upstash"],"files":["./*"],"scripts":{"build":"tsup && cp package.json README.md LICENSE dist/","test":"bun test pkg","fmt":"prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"","lint":"eslint \"**/*.{js,ts,tsx}\" --quiet --fix","format":"prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"","format:check":"prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"","lint:fix":"eslint . -c .ts,.tsx,.js,.jsx --fix","commit":"cz","lint:format":"bun run lint:fix && bun run format","check-exports":"bun run build && cd dist && attw -P"},"author":"Andreas Thomas <dev@chronark.com>","license":"MIT","bugs":{"url":"https://github.com/upstash/upstash-redis/issues"},"homepage":"https://github.com/upstash/upstash-redis#readme","devDependencies":{"@biomejs/biome":"latest","@commitlint/cli":"^19.3.0","@commitlint/config-conventional":"^19.2.2","@typescript-eslint/eslint-plugin":"8.4.0","@typescript-eslint/parser":"8.4.0","bun-types":"1.0.33","eslint":"9.10.0","eslint-plugin-unicorn":"55.0.0","husky":"^9.1.1","prettier":"^3.3.3","tsup":"^8.2.3","typescript":"latest"},"dependencies":{"uncrypto":"^0.1.3"}}
1
+ {"name":"@upstash/redis","version":"v1.36.0-rc.3","main":"./nodejs.js","module":"./nodejs.mjs","types":"./nodejs.d.ts","exports":{".":{"import":"./nodejs.mjs","require":"./nodejs.js"},"./node":{"import":"./nodejs.mjs","require":"./nodejs.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./cloudflare.js":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./cloudflare.mjs":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./fastly":{"import":"./fastly.mjs","require":"./fastly.js"},"./fastly.js":{"import":"./fastly.mjs","require":"./fastly.js"},"./fastly.mjs":{"import":"./fastly.mjs","require":"./fastly.js"}},"description":"An HTTP/REST based Redis client built on top of Upstash REST API.","repository":{"type":"git","url":"git+https://github.com/upstash/upstash-redis.git"},"keywords":["redis","database","serverless","edge","upstash"],"files":["./*"],"scripts":{"build":"tsup && cp package.json README.md LICENSE dist/","test":"bun test pkg","fmt":"prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"","lint":"eslint \"**/*.{js,ts,tsx}\" --quiet --fix","format":"prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"","format:check":"prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"","lint:fix":"eslint . -c .ts,.tsx,.js,.jsx --fix","commit":"cz","lint:format":"bun run lint:fix && bun run format","check-exports":"bun run build && cd dist && attw -P"},"author":"Andreas Thomas <dev@chronark.com>","license":"MIT","bugs":{"url":"https://github.com/upstash/upstash-redis/issues"},"homepage":"https://github.com/upstash/upstash-redis#readme","devDependencies":{"@biomejs/biome":"latest","@commitlint/cli":"^19.3.0","@commitlint/config-conventional":"^19.2.2","@typescript-eslint/eslint-plugin":"8.4.0","@typescript-eslint/parser":"8.4.0","bun-types":"1.0.33","eslint":"9.10.0","eslint-plugin-unicorn":"55.0.0","husky":"^9.1.1","prettier":"^3.3.3","tsup":"^8.2.3","typescript":"latest"},"dependencies":{"uncrypto":"^0.1.3"}}