@upstash/ratelimit 2.0.8 → 2.1.0-rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +49 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -24
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,6 +78,25 @@ For more information on getting started, you can refer to [our documentation](ht
|
|
|
78
78
|
|
|
79
79
|
See [the documentation](https://upstash.com/docs/redis/sdks/ratelimit-ts/overview) for more information details about this package.
|
|
80
80
|
|
|
81
|
+
## Telemetry
|
|
82
|
+
|
|
83
|
+
The SDK reports its name and version to Upstash as a header on the requests made
|
|
84
|
+
by the redis client you provide, so we know which SDK versions are in use. No
|
|
85
|
+
personal data, keys or identifiers are collected.
|
|
86
|
+
|
|
87
|
+
You can opt out with `enableTelemetry: false`:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const ratelimit = new Ratelimit({
|
|
91
|
+
redis: Redis.fromEnv(),
|
|
92
|
+
limiter: Ratelimit.slidingWindow(10, "10 s"),
|
|
93
|
+
enableTelemetry: false,
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
or by setting the `UPSTASH_DISABLE_TELEMETRY` environment variable. Disabling
|
|
98
|
+
telemetry on the redis client itself also disables it here.
|
|
99
|
+
|
|
81
100
|
## Contributing
|
|
82
101
|
|
|
83
102
|
### Database
|
package/dist/index.d.mts
CHANGED
|
@@ -495,6 +495,17 @@ type MultiRegionRatelimitConfig = {
|
|
|
495
495
|
* @default false
|
|
496
496
|
*/
|
|
497
497
|
dynamicLimits?: boolean;
|
|
498
|
+
/**
|
|
499
|
+
* Enable telemetry to help us improve the SDK.
|
|
500
|
+
*
|
|
501
|
+
* The sdk name and version are sent to Upstash as a header on the requests
|
|
502
|
+
* made by the redis clients you provide.
|
|
503
|
+
*
|
|
504
|
+
* Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env variable.
|
|
505
|
+
*
|
|
506
|
+
* @default true
|
|
507
|
+
*/
|
|
508
|
+
enableTelemetry?: boolean;
|
|
498
509
|
};
|
|
499
510
|
/**
|
|
500
511
|
* Ratelimiter using serverless redis from https://upstash.com/
|
|
@@ -652,6 +663,17 @@ type RegionRatelimitConfig = {
|
|
|
652
663
|
* @default false
|
|
653
664
|
*/
|
|
654
665
|
dynamicLimits?: boolean;
|
|
666
|
+
/**
|
|
667
|
+
* Enable telemetry to help us improve the SDK.
|
|
668
|
+
*
|
|
669
|
+
* The sdk name and version are sent to Upstash as a header on the requests
|
|
670
|
+
* made by the redis client you provide.
|
|
671
|
+
*
|
|
672
|
+
* Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env variable.
|
|
673
|
+
*
|
|
674
|
+
* @default true
|
|
675
|
+
*/
|
|
676
|
+
enableTelemetry?: boolean;
|
|
655
677
|
};
|
|
656
678
|
/**
|
|
657
679
|
* Ratelimiter using serverless redis from https://upstash.com/
|
package/dist/index.d.ts
CHANGED
|
@@ -495,6 +495,17 @@ type MultiRegionRatelimitConfig = {
|
|
|
495
495
|
* @default false
|
|
496
496
|
*/
|
|
497
497
|
dynamicLimits?: boolean;
|
|
498
|
+
/**
|
|
499
|
+
* Enable telemetry to help us improve the SDK.
|
|
500
|
+
*
|
|
501
|
+
* The sdk name and version are sent to Upstash as a header on the requests
|
|
502
|
+
* made by the redis clients you provide.
|
|
503
|
+
*
|
|
504
|
+
* Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env variable.
|
|
505
|
+
*
|
|
506
|
+
* @default true
|
|
507
|
+
*/
|
|
508
|
+
enableTelemetry?: boolean;
|
|
498
509
|
};
|
|
499
510
|
/**
|
|
500
511
|
* Ratelimiter using serverless redis from https://upstash.com/
|
|
@@ -652,6 +663,17 @@ type RegionRatelimitConfig = {
|
|
|
652
663
|
* @default false
|
|
653
664
|
*/
|
|
654
665
|
dynamicLimits?: boolean;
|
|
666
|
+
/**
|
|
667
|
+
* Enable telemetry to help us improve the SDK.
|
|
668
|
+
*
|
|
669
|
+
* The sdk name and version are sent to Upstash as a header on the requests
|
|
670
|
+
* made by the redis client you provide.
|
|
671
|
+
*
|
|
672
|
+
* Can also be disabled with the `UPSTASH_DISABLE_TELEMETRY` env variable.
|
|
673
|
+
*
|
|
674
|
+
* @default true
|
|
675
|
+
*/
|
|
676
|
+
enableTelemetry?: boolean;
|
|
655
677
|
};
|
|
656
678
|
/**
|
|
657
679
|
* Ratelimiter using serverless redis from https://upstash.com/
|
package/dist/index.js
CHANGED
|
@@ -179,7 +179,7 @@ var safeEval = async (ctx, script, keys, args) => {
|
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
// src/lua-scripts/single.ts
|
|
182
|
-
var fixedWindowLimitScript =
|
|
182
|
+
var fixedWindowLimitScript = `#!lua flags=allow-key-locking
|
|
183
183
|
local key = KEYS[1]
|
|
184
184
|
local dynamicLimitKey = KEYS[2] -- optional: key for dynamic limit in redis
|
|
185
185
|
local tokens = tonumber(ARGV[1]) -- default limit
|
|
@@ -204,7 +204,7 @@ var fixedWindowLimitScript = `
|
|
|
204
204
|
|
|
205
205
|
return {r, effectiveLimit}
|
|
206
206
|
`;
|
|
207
|
-
var fixedWindowRemainingTokensScript =
|
|
207
|
+
var fixedWindowRemainingTokensScript = `#!lua flags=allow-key-locking
|
|
208
208
|
local key = KEYS[1]
|
|
209
209
|
local dynamicLimitKey = KEYS[2] -- optional: key for dynamic limit in redis
|
|
210
210
|
local tokens = tonumber(ARGV[1]) -- default limit
|
|
@@ -226,7 +226,7 @@ var fixedWindowRemainingTokensScript = `
|
|
|
226
226
|
|
|
227
227
|
return {effectiveLimit - usedTokens, effectiveLimit}
|
|
228
228
|
`;
|
|
229
|
-
var slidingWindowLimitScript =
|
|
229
|
+
var slidingWindowLimitScript = `#!lua flags=allow-key-locking
|
|
230
230
|
local currentKey = KEYS[1] -- identifier including prefixes
|
|
231
231
|
local previousKey = KEYS[2] -- key of the previous bucket
|
|
232
232
|
local dynamicLimitKey = KEYS[3] -- optional: key for dynamic limit in redis
|
|
@@ -270,7 +270,7 @@ var slidingWindowLimitScript = `
|
|
|
270
270
|
end
|
|
271
271
|
return {effectiveLimit - ( newValue + requestsInPreviousWindow ), effectiveLimit}
|
|
272
272
|
`;
|
|
273
|
-
var slidingWindowRemainingTokensScript =
|
|
273
|
+
var slidingWindowRemainingTokensScript = `#!lua flags=allow-key-locking
|
|
274
274
|
local currentKey = KEYS[1] -- identifier including prefixes
|
|
275
275
|
local previousKey = KEYS[2] -- key of the previous bucket
|
|
276
276
|
local dynamicLimitKey = KEYS[3] -- optional: key for dynamic limit in redis
|
|
@@ -304,7 +304,7 @@ var slidingWindowRemainingTokensScript = `
|
|
|
304
304
|
local usedTokens = requestsInPreviousWindow + requestsInCurrentWindow
|
|
305
305
|
return {effectiveLimit - usedTokens, effectiveLimit}
|
|
306
306
|
`;
|
|
307
|
-
var tokenBucketLimitScript =
|
|
307
|
+
var tokenBucketLimitScript = `#!lua flags=allow-key-locking
|
|
308
308
|
local key = KEYS[1] -- identifier including prefixes
|
|
309
309
|
local dynamicLimitKey = KEYS[2] -- optional: key for dynamic limit in redis
|
|
310
310
|
local maxTokens = tonumber(ARGV[1]) -- default maximum number of tokens
|
|
@@ -358,7 +358,7 @@ var tokenBucketLimitScript = `
|
|
|
358
358
|
return {remaining, refilledAt + interval, effectiveLimit}
|
|
359
359
|
`;
|
|
360
360
|
var tokenBucketIdentifierNotFound = -1;
|
|
361
|
-
var tokenBucketRemainingTokensScript =
|
|
361
|
+
var tokenBucketRemainingTokensScript = `#!lua flags=allow-key-locking
|
|
362
362
|
local key = KEYS[1]
|
|
363
363
|
local dynamicLimitKey = KEYS[2] -- optional: key for dynamic limit in redis
|
|
364
364
|
local maxTokens = tonumber(ARGV[1]) -- default maximum number of tokens
|
|
@@ -380,7 +380,7 @@ var tokenBucketRemainingTokensScript = `
|
|
|
380
380
|
|
|
381
381
|
return {tonumber(bucket[2]), tonumber(bucket[1]), effectiveLimit}
|
|
382
382
|
`;
|
|
383
|
-
var cachedFixedWindowLimitScript =
|
|
383
|
+
var cachedFixedWindowLimitScript = `#!lua flags=allow-key-locking
|
|
384
384
|
local key = KEYS[1]
|
|
385
385
|
local window = ARGV[1]
|
|
386
386
|
local incrementBy = ARGV[2] -- increment rate per request at a given value, default is 1
|
|
@@ -394,7 +394,7 @@ var cachedFixedWindowLimitScript = `
|
|
|
394
394
|
|
|
395
395
|
return r
|
|
396
396
|
`;
|
|
397
|
-
var cachedFixedWindowRemainingTokenScript =
|
|
397
|
+
var cachedFixedWindowRemainingTokenScript = `#!lua flags=allow-key-locking
|
|
398
398
|
local key = KEYS[1]
|
|
399
399
|
local tokens = 0
|
|
400
400
|
|
|
@@ -406,7 +406,7 @@ var cachedFixedWindowRemainingTokenScript = `
|
|
|
406
406
|
`;
|
|
407
407
|
|
|
408
408
|
// src/lua-scripts/multi.ts
|
|
409
|
-
var fixedWindowLimitScript2 =
|
|
409
|
+
var fixedWindowLimitScript2 = `#!lua flags=allow-key-locking
|
|
410
410
|
local key = KEYS[1]
|
|
411
411
|
local id = ARGV[1]
|
|
412
412
|
local window = ARGV[2]
|
|
@@ -422,7 +422,7 @@ var fixedWindowLimitScript2 = `
|
|
|
422
422
|
|
|
423
423
|
return fields
|
|
424
424
|
`;
|
|
425
|
-
var fixedWindowRemainingTokensScript2 =
|
|
425
|
+
var fixedWindowRemainingTokensScript2 = `#!lua flags=allow-key-locking
|
|
426
426
|
local key = KEYS[1]
|
|
427
427
|
local tokens = 0
|
|
428
428
|
|
|
@@ -430,7 +430,7 @@ var fixedWindowRemainingTokensScript2 = `
|
|
|
430
430
|
|
|
431
431
|
return fields
|
|
432
432
|
`;
|
|
433
|
-
var slidingWindowLimitScript2 =
|
|
433
|
+
var slidingWindowLimitScript2 = `#!lua flags=allow-key-locking
|
|
434
434
|
local currentKey = KEYS[1] -- identifier including prefixes
|
|
435
435
|
local previousKey = KEYS[2] -- key of the previous bucket
|
|
436
436
|
local tokens = tonumber(ARGV[1]) -- tokens per window
|
|
@@ -467,7 +467,7 @@ var slidingWindowLimitScript2 = `
|
|
|
467
467
|
end
|
|
468
468
|
return {currentFields, previousFields, true}
|
|
469
469
|
`;
|
|
470
|
-
var slidingWindowRemainingTokensScript2 =
|
|
470
|
+
var slidingWindowRemainingTokensScript2 = `#!lua flags=allow-key-locking
|
|
471
471
|
local currentKey = KEYS[1] -- identifier including prefixes
|
|
472
472
|
local previousKey = KEYS[2] -- key of the previous bucket
|
|
473
473
|
local now = ARGV[1] -- current timestamp in milliseconds
|
|
@@ -522,41 +522,41 @@ var SCRIPTS = {
|
|
|
522
522
|
fixedWindow: {
|
|
523
523
|
limit: {
|
|
524
524
|
script: fixedWindowLimitScript,
|
|
525
|
-
hash: "
|
|
525
|
+
hash: "4ef8749b9e927b157546ebad13061fa86b9ffc2e"
|
|
526
526
|
},
|
|
527
527
|
getRemaining: {
|
|
528
528
|
script: fixedWindowRemainingTokensScript,
|
|
529
|
-
hash: "
|
|
529
|
+
hash: "e62252cb05b4676b27a5d396da02f0ca0d375d88"
|
|
530
530
|
}
|
|
531
531
|
},
|
|
532
532
|
slidingWindow: {
|
|
533
533
|
limit: {
|
|
534
534
|
script: slidingWindowLimitScript,
|
|
535
|
-
hash: "
|
|
535
|
+
hash: "5cd9665be7533e4dfabb3581021737fc69b41ae8"
|
|
536
536
|
},
|
|
537
537
|
getRemaining: {
|
|
538
538
|
script: slidingWindowRemainingTokensScript,
|
|
539
|
-
hash: "
|
|
539
|
+
hash: "1bdbbdb2082bb557084518c64486d7d5a29d1bfe"
|
|
540
540
|
}
|
|
541
541
|
},
|
|
542
542
|
tokenBucket: {
|
|
543
543
|
limit: {
|
|
544
544
|
script: tokenBucketLimitScript,
|
|
545
|
-
hash: "
|
|
545
|
+
hash: "8f7286b9b0f65d631f760ba615f7b3c598a569a3"
|
|
546
546
|
},
|
|
547
547
|
getRemaining: {
|
|
548
548
|
script: tokenBucketRemainingTokensScript,
|
|
549
|
-
hash: "
|
|
549
|
+
hash: "08d3b3381c507b6f7bfec1bbfa0a6053434b16bd"
|
|
550
550
|
}
|
|
551
551
|
},
|
|
552
552
|
cachedFixedWindow: {
|
|
553
553
|
limit: {
|
|
554
554
|
script: cachedFixedWindowLimitScript,
|
|
555
|
-
hash: "
|
|
555
|
+
hash: "1861a700bafe96c833a483af6b1c28a8897cfdb0"
|
|
556
556
|
},
|
|
557
557
|
getRemaining: {
|
|
558
558
|
script: cachedFixedWindowRemainingTokenScript,
|
|
559
|
-
hash: "
|
|
559
|
+
hash: "eb82f0e853d2fc9a236fa9bfbe704fda6ac2fc36"
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
},
|
|
@@ -564,21 +564,21 @@ var SCRIPTS = {
|
|
|
564
564
|
fixedWindow: {
|
|
565
565
|
limit: {
|
|
566
566
|
script: fixedWindowLimitScript2,
|
|
567
|
-
hash: "
|
|
567
|
+
hash: "e04b753a75909b7f99aae4c04cf8869a8de02a9e"
|
|
568
568
|
},
|
|
569
569
|
getRemaining: {
|
|
570
570
|
script: fixedWindowRemainingTokensScript2,
|
|
571
|
-
hash: "
|
|
571
|
+
hash: "e066c8ce3eaca142b0894ad1541e0a58c9924819"
|
|
572
572
|
}
|
|
573
573
|
},
|
|
574
574
|
slidingWindow: {
|
|
575
575
|
limit: {
|
|
576
576
|
script: slidingWindowLimitScript2,
|
|
577
|
-
hash: "
|
|
577
|
+
hash: "aeb4d8f381e8dafc8e69041baae1324d254ded44"
|
|
578
578
|
},
|
|
579
579
|
getRemaining: {
|
|
580
580
|
script: slidingWindowRemainingTokensScript2,
|
|
581
|
-
hash: "
|
|
581
|
+
hash: "87828c1088f6a8d1f512a434ea330189982a1c0a"
|
|
582
582
|
}
|
|
583
583
|
}
|
|
584
584
|
}
|
|
@@ -1059,6 +1059,27 @@ var Ratelimit = class {
|
|
|
1059
1059
|
};
|
|
1060
1060
|
};
|
|
1061
1061
|
|
|
1062
|
+
// src/version.ts
|
|
1063
|
+
var VERSION = "2.1.0-rc";
|
|
1064
|
+
|
|
1065
|
+
// src/telemetry.ts
|
|
1066
|
+
var taggedClients = /* @__PURE__ */ new WeakSet();
|
|
1067
|
+
var getSafeEnv = () => typeof process === "object" && process && typeof process.env === "object" ? process.env : {};
|
|
1068
|
+
var addTelemetry = (redis, enableTelemetry = true) => {
|
|
1069
|
+
if (!enableTelemetry || getSafeEnv().UPSTASH_DISABLE_TELEMETRY)
|
|
1070
|
+
return;
|
|
1071
|
+
if (!redis || typeof redis !== "object")
|
|
1072
|
+
return;
|
|
1073
|
+
if (taggedClients.has(redis))
|
|
1074
|
+
return;
|
|
1075
|
+
taggedClients.add(redis);
|
|
1076
|
+
try {
|
|
1077
|
+
const client = redis;
|
|
1078
|
+
client.addTelemetry?.({ sdk: `@upstash/ratelimit@${VERSION}` });
|
|
1079
|
+
} catch {
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1062
1083
|
// src/multi.ts
|
|
1063
1084
|
function randomId() {
|
|
1064
1085
|
let result = "";
|
|
@@ -1088,6 +1109,9 @@ var MultiRegionRatelimit = class extends Ratelimit {
|
|
|
1088
1109
|
cache: config.ephemeralCache ? new Cache(config.ephemeralCache) : void 0
|
|
1089
1110
|
}
|
|
1090
1111
|
});
|
|
1112
|
+
for (const redis of config.redis) {
|
|
1113
|
+
addTelemetry(redis, config.enableTelemetry);
|
|
1114
|
+
}
|
|
1091
1115
|
if (config.dynamicLimits) {
|
|
1092
1116
|
console.warn(
|
|
1093
1117
|
"Warning: Dynamic limits are not yet supported for multi-region rate limiters. The dynamicLimits option will be ignored."
|
|
@@ -1458,6 +1482,7 @@ var RegionRatelimit = class extends Ratelimit {
|
|
|
1458
1482
|
denyListThreshold: config.denyListThreshold,
|
|
1459
1483
|
dynamicLimits: config.dynamicLimits
|
|
1460
1484
|
});
|
|
1485
|
+
addTelemetry(config.redis, config.enableTelemetry);
|
|
1461
1486
|
}
|
|
1462
1487
|
/**
|
|
1463
1488
|
* Each request inside a fixed time increases a counter.
|