Skip to content

Commit 9d0ae48

Browse files
committed
fix: type-safed hitinfo
1 parent 9d70e44 commit 9d0ae48

File tree

9 files changed

+53
-52
lines changed

9 files changed

+53
-52
lines changed

.changeset/happy-pillows-train.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
'@trpc-limiter/core': patch
3+
'@trpc-limiter/memory': patch
4+
'@trpc-limiter/redis': patch
5+
'@trpc-limiter/upstash': patch
6+
---
7+
8+
fix: type-safed hitinfo

README.MD

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,7 @@ const t = initTRPC.context<Context>().create()
6262

6363
const rateLimiter = createTrpcRedisLimiter<typeof t>({
6464
fingerprint: (ctx) => defaultFingerPrint(ctx.req),
65-
message: (hitInfo) =>
66-
`Too many requests, please try again later. ${Math.ceil(
67-
(hitInfo.reset - Date.now()) / 1000
68-
)}`,
65+
message: (hitInfo) => `Too many requests, please try again later. ${hitInfo}`,
6966
max: 15,
7067
windowMs: 10000,
7168
redisClient: redis,

examples/nextjs-redis/src/server/api/trpc.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,7 @@ const rateLimiter = createTrpcRedisLimiter<typeof t>({
8383
console.log("c$", c);
8484
return c;
8585
},
86-
message: (hitInfo) =>
87-
`Too many requests, please try again later. ${Math.ceil(
88-
(hitInfo.reset - Date.now()) / 1000,
89-
)}`,
86+
message: (hitInfo) => `Too many requests, please try again later. ${hitInfo}`,
9087
max: 5,
9188
windowMs: 10000,
9289
redisClient: redis,

package.json

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,6 @@
1414
"prepare": "husky install"
1515
},
1616
"lint-staged": {
17-
"*.{js,json}": "prettier --write",
18-
"packages/**/*.{js,jsx,ts,tsx}": [
19-
"eslint --fix",
20-
"prettier --write"
21-
],
22-
"examples/**/*.{js,jsx,ts,tsx}": [
23-
"eslint --fix",
24-
"prettier --write"
25-
],
2617
"package.json": "sort-package-json"
2718
},
2819
"devDependencies": {

packages/core/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ export const defineTRPCLimiter = <
7676

7777
export const defineLimiterWithProps = <
7878
T,
79-
Store extends IStoreCallback<T> = IStoreCallback<T>,
80-
Res = any
79+
Res,
80+
Store extends IStoreCallback<T> = IStoreCallback<T>
8181
>(
8282
adapter: ILimiterAdapter<Store, Res, T>,
8383
getDefaultOptions: (

packages/memory/src/store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class MemoryStore {
2222
/** Reference to the active timer. */
2323
interval: NodeJS.Timer
2424

25-
constructor(options: Required<TRPCRateLimitOptions<AnyRootConfig>>) {
25+
constructor(options: Required<TRPCRateLimitOptions<AnyRootConfig, any>>) {
2626
this.windowMs = options.windowMs
2727
this.resetTime = calculateNextResetTime(this.windowMs)
2828
this.hits = {}

packages/redis/README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ const t = initTRPC.context<Context>().create()
3535

3636
const rateLimiter = createTrpcRedisLimiter<typeof t>({
3737
fingerprint: (ctx) => defaultFingerPrint(ctx.req),
38-
message: (hitInfo) =>
39-
`Too many requests, please try again later. ${Math.ceil(
40-
(hitInfo.reset - Date.now()) / 1000
41-
)}`,
38+
message: (hitInfo) => `Too many requests, please try again later. ${hitInfo}`,
4239
max: 15,
4340
windowMs: 10000,
4441
redisClient: redis,

packages/redis/src/index.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,28 @@ import {
1010
IRateLimiterStoreOptions,
1111
} from 'rate-limiter-flexible'
1212

13-
export const createTrpcRedisLimiter = defineLimiterWithProps<{
14-
redisClient: IRateLimiterStoreOptions['storeClient']
15-
limiter?: (
16-
opts: Required<BaseOpts<AnyRootConfig, any>>
17-
) => IRateLimiterStoreOptions['insuranceLimiter']
18-
}>(
13+
const isBlocked = async (store: RateLimiterRedis, fingerprint: string) => {
14+
try {
15+
await store.consume(fingerprint)
16+
return null
17+
} catch (error) {
18+
if (error instanceof RateLimiterRes) {
19+
return Math.round(error.msBeforeNext / 1000) || 1
20+
}
21+
// Should not happen with `insuranceLimiter`
22+
throw error
23+
}
24+
}
25+
26+
export const createTrpcRedisLimiter = defineLimiterWithProps<
27+
{
28+
redisClient: IRateLimiterStoreOptions['storeClient']
29+
limiter?: (
30+
opts: Required<BaseOpts<AnyRootConfig, any>>
31+
) => IRateLimiterStoreOptions['insuranceLimiter']
32+
},
33+
NonNullable<Awaited<ReturnType<typeof isBlocked>>>
34+
>(
1935
{
2036
store: (opts) => {
2137
return new RateLimiterRedis({
@@ -26,18 +42,7 @@ export const createTrpcRedisLimiter = defineLimiterWithProps<{
2642
insuranceLimiter: opts.limiter(opts),
2743
})
2844
},
29-
async isBlocked(store, fingerprint) {
30-
try {
31-
await store.consume(fingerprint)
32-
return null
33-
} catch (error) {
34-
if (error instanceof RateLimiterRes) {
35-
return Math.round(error.msBeforeNext / 1000) || 1
36-
}
37-
// Should not happen with `insuranceLimiter`
38-
throw error
39-
}
40-
},
45+
isBlocked,
4146
},
4247
(currentState) => {
4348
return {

packages/upstash/src/index.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,28 @@ import {
22
defineLimiterWithProps,
33
BaseOpts,
44
AnyRootConfig,
5+
defaultFingerPrint,
56
} from '@trpc-limiter/core'
67
import { Ratelimit } from '@upstash/ratelimit'
78
import { RegionRatelimitConfig } from '@upstash/ratelimit/types/single'
89

9-
export const createTRPCUpstashLimiter = defineLimiterWithProps<{
10-
rateLimitOpts: (
11-
opts: Required<BaseOpts<AnyRootConfig, any>>
12-
) => RegionRatelimitConfig
13-
}>(
10+
const isBlocked = async (store: Ratelimit, fingerprint: string) => {
11+
const { success, pending, ...rest } = await store.limit(fingerprint)
12+
await pending
13+
return success ? null : rest
14+
}
15+
16+
export const createTRPCUpstashLimiter = defineLimiterWithProps<
17+
{
18+
rateLimitOpts: (
19+
opts: Required<BaseOpts<AnyRootConfig, any>>
20+
) => RegionRatelimitConfig
21+
},
22+
NonNullable<Awaited<ReturnType<typeof isBlocked>>>
23+
>(
1424
{
1525
store: (opts) => new Ratelimit(opts.rateLimitOpts(opts)),
16-
async isBlocked(store, fingerprint) {
17-
const { success, pending, ...rest } = await store.limit(fingerprint)
18-
await pending
19-
return success ? null : rest
20-
},
26+
isBlocked,
2127
},
2228
(currnetState) => {
2329
return { rateLimitOpts: currnetState.rateLimitOpts }

0 commit comments

Comments
 (0)