@upstash/ratelimit 2.0.3 → 2.0.5-canary

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/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Aggregate } from '@upstash/core-analytics';
2
- import { Pipeline } from '@upstash/redis';
2
+ import { Redis as Redis$1 } from '@upstash/redis';
3
3
 
4
4
  /**
5
5
  * EphemeralCache is used to block certain identifiers right away in case they have already exceeded the ratelimit.
6
6
  */
7
- interface EphemeralCache {
7
+ type EphemeralCache = {
8
8
  isBlocked: (identifier: string) => {
9
9
  blocked: boolean;
10
10
  reset: number;
@@ -16,7 +16,7 @@ interface EphemeralCache {
16
16
  pop: (key: string) => void;
17
17
  empty: () => void;
18
18
  size: () => number;
19
- }
19
+ };
20
20
  type RegionContext = {
21
21
  redis: Redis;
22
22
  cache?: EphemeralCache;
@@ -90,7 +90,6 @@ type Algorithm<TContext> = () => {
90
90
  }>;
91
91
  resetTokens: (ctx: TContext, identifier: string) => Promise<void>;
92
92
  };
93
- type IsDenied = 0 | 1;
94
93
  type DeniedValue = string | undefined;
95
94
  type LimitOptions = {
96
95
  geo?: Geo;
@@ -102,17 +101,7 @@ type LimitOptions = {
102
101
  /**
103
102
  * This is all we need from the redis sdk.
104
103
  */
105
- interface Redis {
106
- sadd: <TData>(key: string, ...members: TData[]) => Promise<number>;
107
- hset: <TValue>(key: string, obj: {
108
- [key: string]: TValue;
109
- }) => Promise<number>;
110
- eval: <TArgs extends unknown[], TData = unknown>(...args: [script: string, keys: string[], args: TArgs]) => Promise<TData>;
111
- evalsha: <TArgs extends unknown[], TData = unknown>(...args: [sha1: string, keys: string[], args: TArgs]) => Promise<TData>;
112
- scriptLoad: (...args: [script: string]) => Promise<string>;
113
- smismember: (key: string, members: string[]) => Promise<IsDenied[]>;
114
- multi: () => Pipeline;
115
- }
104
+ type Redis = Redis$1;
116
105
 
117
106
  type Geo = {
118
107
  country?: string;
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Aggregate } from '@upstash/core-analytics';
2
- import { Pipeline } from '@upstash/redis';
2
+ import { Redis as Redis$1 } from '@upstash/redis';
3
3
 
4
4
  /**
5
5
  * EphemeralCache is used to block certain identifiers right away in case they have already exceeded the ratelimit.
6
6
  */
7
- interface EphemeralCache {
7
+ type EphemeralCache = {
8
8
  isBlocked: (identifier: string) => {
9
9
  blocked: boolean;
10
10
  reset: number;
@@ -16,7 +16,7 @@ interface EphemeralCache {
16
16
  pop: (key: string) => void;
17
17
  empty: () => void;
18
18
  size: () => number;
19
- }
19
+ };
20
20
  type RegionContext = {
21
21
  redis: Redis;
22
22
  cache?: EphemeralCache;
@@ -90,7 +90,6 @@ type Algorithm<TContext> = () => {
90
90
  }>;
91
91
  resetTokens: (ctx: TContext, identifier: string) => Promise<void>;
92
92
  };
93
- type IsDenied = 0 | 1;
94
93
  type DeniedValue = string | undefined;
95
94
  type LimitOptions = {
96
95
  geo?: Geo;
@@ -102,17 +101,7 @@ type LimitOptions = {
102
101
  /**
103
102
  * This is all we need from the redis sdk.
104
103
  */
105
- interface Redis {
106
- sadd: <TData>(key: string, ...members: TData[]) => Promise<number>;
107
- hset: <TValue>(key: string, obj: {
108
- [key: string]: TValue;
109
- }) => Promise<number>;
110
- eval: <TArgs extends unknown[], TData = unknown>(...args: [script: string, keys: string[], args: TArgs]) => Promise<TData>;
111
- evalsha: <TArgs extends unknown[], TData = unknown>(...args: [sha1: string, keys: string[], args: TArgs]) => Promise<TData>;
112
- scriptLoad: (...args: [script: string]) => Promise<string>;
113
- smismember: (key: string, members: string[]) => Promise<IsDenied[]>;
114
- multi: () => Pipeline;
115
- }
104
+ type Redis = Redis$1;
116
105
 
117
106
  type Geo = {
118
107
  country?: string;
package/dist/index.js CHANGED
@@ -49,10 +49,10 @@ var Analytics = class {
49
49
  * @returns
50
50
  */
51
51
  extractGeo(req) {
52
- if (typeof req.geo !== "undefined") {
52
+ if (req.geo !== void 0) {
53
53
  return req.geo;
54
54
  }
55
- if (typeof req.cf !== "undefined") {
55
+ if (req.cf !== void 0) {
56
56
  return req.cf;
57
57
  }
58
58
  return {};
@@ -141,18 +141,24 @@ function ms(d) {
141
141
  const time = Number.parseInt(match[1]);
142
142
  const unit = match[2];
143
143
  switch (unit) {
144
- case "ms":
144
+ case "ms": {
145
145
  return time;
146
- case "s":
146
+ }
147
+ case "s": {
147
148
  return time * 1e3;
148
- case "m":
149
+ }
150
+ case "m": {
149
151
  return time * 1e3 * 60;
150
- case "h":
152
+ }
153
+ case "h": {
151
154
  return time * 1e3 * 60 * 60;
152
- case "d":
155
+ }
156
+ case "d": {
153
157
  return time * 1e3 * 60 * 60 * 24;
154
- default:
158
+ }
159
+ default: {
155
160
  throw new Error(`Unable to parse window size: ${d}`);
161
+ }
156
162
  }
157
163
  }
158
164
 
@@ -594,7 +600,7 @@ var updateIpDenyList = async (redis, prefix, threshold, ttl) => {
594
600
  const transaction = redis.multi();
595
601
  transaction.sdiffstore(allDenyLists, allDenyLists, ipDenyList);
596
602
  transaction.del(ipDenyList);
597
- transaction.sadd(ipDenyList, ...allIps);
603
+ transaction.sadd(ipDenyList, allIps.at(0), ...allIps.slice(1));
598
604
  transaction.sdiffstore(ipDenyList, ipDenyList, allDenyLists);
599
605
  transaction.sunionstore(allDenyLists, allDenyLists, ipDenyList);
600
606
  transaction.set(statusKey, "valid", { px: ttl ?? getIpListTTL() });
@@ -696,7 +702,7 @@ var Ratelimit = class {
696
702
  }) : void 0;
697
703
  if (config.ephemeralCache instanceof Map) {
698
704
  this.ctx.cache = new Cache(config.ephemeralCache);
699
- } else if (typeof config.ephemeralCache === "undefined") {
705
+ } else if (config.ephemeralCache === void 0) {
700
706
  this.ctx.cache = new Cache(/* @__PURE__ */ new Map());
701
707
  }
702
708
  }
@@ -827,15 +833,10 @@ var Ratelimit = class {
827
833
  const key = this.getKey(identifier);
828
834
  const definedMembers = this.getDefinedMembers(identifier, req);
829
835
  const deniedValue = checkDenyListCache(definedMembers);
830
- let result;
831
- if (deniedValue) {
832
- result = [defaultDeniedResponse(deniedValue), { deniedValue, invalidIpDenyList: false }];
833
- } else {
834
- result = await Promise.all([
835
- this.limiter().limit(this.ctx, key, req?.rate),
836
- this.enableProtection ? checkDenyList(this.primaryRedis, this.prefix, definedMembers) : { deniedValue: void 0, invalidIpDenyList: false }
837
- ]);
838
- }
836
+ const result = deniedValue ? [defaultDeniedResponse(deniedValue), { deniedValue, invalidIpDenyList: false }] : await Promise.all([
837
+ this.limiter().limit(this.ctx, key, req?.rate),
838
+ this.enableProtection ? checkDenyList(this.primaryRedis, this.prefix, definedMembers) : { deniedValue: void 0, invalidIpDenyList: false }
839
+ ]);
839
840
  return resolveLimitPayload(this.primaryRedis, this.prefix, result, this.denyListThreshold);
840
841
  };
841
842
  /**
@@ -885,9 +886,9 @@ var Ratelimit = class {
885
886
  time: Date.now(),
886
887
  success: ratelimitResponse.reason === "denyList" ? "denied" : ratelimitResponse.success,
887
888
  ...geo
888
- }).catch((err) => {
889
+ }).catch((error) => {
889
890
  let errorMessage = "Failed to record analytics";
890
- if (`${err}`.includes("WRONGTYPE")) {
891
+ if (`${error}`.includes("WRONGTYPE")) {
891
892
  errorMessage = `
892
893
  Failed to record analytics. See the information below:
893
894
 
@@ -900,11 +901,11 @@ var Ratelimit = class {
900
901
 
901
902
  `;
902
903
  }
903
- console.warn(errorMessage, err);
904
+ console.warn(errorMessage, error);
904
905
  });
905
906
  ratelimitResponse.pending = Promise.all([ratelimitResponse.pending, analyticsP]);
906
- } catch (err) {
907
- console.warn("Failed to record analytics", err);
907
+ } catch (error) {
908
+ console.warn("Failed to record analytics", error);
908
909
  }
909
910
  ;
910
911
  }
@@ -1015,18 +1016,17 @@ var MultiRegionRatelimit = class extends Ratelimit {
1015
1016
  const remaining = tokens - usedTokens;
1016
1017
  async function sync() {
1017
1018
  const individualIDs = await Promise.all(dbs.map((s) => s.request));
1018
- const allIDs = Array.from(
1019
- new Set(
1020
- individualIDs.flatMap((_) => _).reduce((acc, curr, index) => {
1021
- if (index % 2 === 0) {
1022
- acc.push(curr);
1023
- }
1024
- return acc;
1025
- }, [])
1026
- ).values()
1027
- );
1019
+ const allIDs = [...new Set(
1020
+ individualIDs.flat().reduce((acc, curr, index) => {
1021
+ if (index % 2 === 0) {
1022
+ acc.push(curr);
1023
+ }
1024
+ return acc;
1025
+ }, [])
1026
+ ).values()];
1028
1027
  for (const db of dbs) {
1029
- const usedDbTokens = (await db.request).reduce(
1028
+ const usedDbTokensRequest = await db.request;
1029
+ const usedDbTokens = usedDbTokensRequest.reduce(
1030
1030
  (accTokens, usedToken, index) => {
1031
1031
  let parsedToken = 0;
1032
1032
  if (index % 2) {
@@ -1036,7 +1036,8 @@ var MultiRegionRatelimit = class extends Ratelimit {
1036
1036
  },
1037
1037
  0
1038
1038
  );
1039
- const dbIds = (await db.request).reduce((ids, currentId, index) => {
1039
+ const dbIdsRequest = await db.request;
1040
+ const dbIds = dbIdsRequest.reduce((ids, currentId, index) => {
1040
1041
  if (index % 2 === 0) {
1041
1042
  ids.push(currentId);
1042
1043
  }
@@ -1183,16 +1184,14 @@ var MultiRegionRatelimit = class extends Ratelimit {
1183
1184
  const remaining = tokens - usedTokens;
1184
1185
  async function sync() {
1185
1186
  const res = await Promise.all(dbs.map((s) => s.request));
1186
- const allCurrentIds = Array.from(
1187
- new Set(
1188
- res.flatMap(([current2]) => current2).reduce((acc, curr, index) => {
1189
- if (index % 2 === 0) {
1190
- acc.push(curr);
1191
- }
1192
- return acc;
1193
- }, [])
1194
- ).values()
1195
- );
1187
+ const allCurrentIds = [...new Set(
1188
+ res.flatMap(([current2]) => current2).reduce((acc, curr, index) => {
1189
+ if (index % 2 === 0) {
1190
+ acc.push(curr);
1191
+ }
1192
+ return acc;
1193
+ }, [])
1194
+ ).values()];
1196
1195
  for (const db of dbs) {
1197
1196
  const [current2, _previous, _success] = await db.request;
1198
1197
  const dbIds = current2.reduce((ids, currentId, index) => {