@lidofinance/next-ip-rate-limit 0.43.0 → 0.45.0
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.cjs +11 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +11 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -82,10 +82,11 @@ const $c63185ef25ccfd28$export$d0a20d44a54350ab = ({ id: id, res: res, req: req,
|
|
|
82
82
|
let $abe9c276dfd79488$var$rateLimitStorage;
|
|
83
83
|
const $abe9c276dfd79488$export$122bebc9e141287c = (data)=>{
|
|
84
84
|
if (!$abe9c276dfd79488$var$rateLimitStorage) $abe9c276dfd79488$var$rateLimitStorage = new (0, $9e3ba9e2f0393d79$export$230ecc6ad0ef6558)();
|
|
85
|
+
const now = Date.now() / 1000;
|
|
85
86
|
const { res: res, req: req, limit: limit, timeFrame: timeFrame } = data;
|
|
86
87
|
const headers = (0, $54a02752d7f6015e$export$a063967512de3ebf);
|
|
87
88
|
const id = `ip:${(0, $c63185ef25ccfd28$export$67218453e01a0be8)(req)}`;
|
|
88
|
-
const time = Math.floor(
|
|
89
|
+
const time = Math.floor(now / timeFrame);
|
|
89
90
|
const key = `${id}:${time}`;
|
|
90
91
|
const callCount = $abe9c276dfd79488$var$rateLimitStorage.inc(key, data.timeFrame);
|
|
91
92
|
const remaining = limit - (callCount || 0);
|
|
@@ -93,12 +94,15 @@ const $abe9c276dfd79488$export$122bebc9e141287c = (data)=>{
|
|
|
93
94
|
res.setHeader(headers.limit, `${limit}`);
|
|
94
95
|
res.setHeader(headers.remaining, `${remaining < 0 ? 0 : remaining}`);
|
|
95
96
|
res.setHeader(headers.reset, `${reset}`);
|
|
96
|
-
if (remaining < 0)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
if (remaining < 0) {
|
|
98
|
+
const retryAfter = Math.ceil(Math.max(reset - now, 0));
|
|
99
|
+
(0, $c63185ef25ccfd28$export$d0a20d44a54350ab)({
|
|
100
|
+
id: id,
|
|
101
|
+
res: res,
|
|
102
|
+
req: req,
|
|
103
|
+
retryAfter: retryAfter
|
|
104
|
+
});
|
|
105
|
+
}
|
|
102
106
|
return res;
|
|
103
107
|
};
|
|
104
108
|
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;;;;;;;;;;;AEEO,MAAM;IAIX,aAAc;aAFN,aAA+B,EAAE;QAGvC,IAAI,CAAC,WAAW,IAAI;IACtB;IAEA,IAAI,GAAW,EAAE,KAAa,EAAE,WAAmB,EAAE;QACnD,IAAI,CAAC,SAAS,IAAI,KAAK;mBAAE;QAAM;QAE/B,IAAI,IAAI,CAAC,SAAS,IAAI,MAAM,WAC1B,aAAa,IAAI,CAAC,SAAS,IAAI,MAAM;QAGvC,2FAA2F;QAC3F,+EAA+E;QAC/E,MAAM,YAAY,WAAW;YAC3B,aAAa;YAEb,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW,OAAO,CAAC,KAAO,MAAM;YACvD,IAAI,CAAC,OAAO;QACd,GAAG,cAAc;QACjB,IAAI,CAAC,WAAW,KAAK;IACvB;IAEA,IAAI,GAAW,EAAE;QACf,OAAO,IAAI,CAAC,SAAS,IAAI,MAAM;IACjC;IAEA,IAAI,GAAW,EAAE,WAAmB,EAAE;QACpC,IAAI,IAAI,CAAC,SAAS,IAAI,MACpB,IAAI,CAAC,IAAI,KAAK,AAAC,CAAA,IAAI,CAAC,SAAS,IAAI,MAAM,SAAS,CAAA,IAAK,GAAG;aAExD,IAAI,CAAC,IAAI,KAAK,GAAG;QAGnB,OAAO,IAAI,CAAC,IAAI;IAClB;IACA,OAAO,GAAW,EAAE;QAClB,IAAI,IAAI,CAAC,SAAS,IAAI,MACpB,IAAI,CAAC,SAAS,OAAO;IAEzB;AACF;;;;;;;AE9CO,MAAM,4CAAqB;IAChC,OAAO,CAAC,iBAAiB,CAAC;IAC1B,WAAW,CAAC,qBAAqB,CAAC;IAClC,OAAO,CAAC,iBAAiB,CAAC;AAC5B;AAEO,MAAM,4CAAgB;;;ADEtB,MAAM,4CAAQ,CAAC;IACpB,MAAM,iBAAiB,IAAI,OAAO,CAAC,mBAAmB;IACtD,MAAM,MAAM,IAAI,OAAO,CAAC,kBAAkB;IAE1C,IAAI,gBAAgB,OAAO,MAAM,QAAQ,kBAAkB,cAAc,CAAC,EAAE,GAAG,eAAe,MAAM,IAAI,CAAC,EAAE;IAE3G,OAAO,MAAO,MAAM,QAAQ,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,MAAM,IAAI,CAAC,EAAE,GAAI;AACnE;AAEO,MAAM,4CAA2C,CAAC,MAAE,EAAE,OAAE,GAAG,OAAE,GAAG,cAAE,UAAU,EAAE;IACnF,IAAI,OAAO;IACX,IAAI,YAAY,IAAI,UAAU,eAAe,WAAW;IACxD,MAAM,IAAI,MAAM,CAAC,EAAE,CAAA,GAAA,yCAAY,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,OAAO,GAAG,CAAC;AAC3D;;;;AFhBA,IAAI;AAEG,MAAM,4CAAyB,CAAC;IACrC,IAAI,CAAC,wCAAkB,yCAAmB,IAAI,CAAA,GAAA,yCAAe;IAE7D,MAAM,OAAE,GAAG,OAAE,GAAG,SAAE,KAAK,aAAE,SAAS,EAAE,GAAG;IACvC,MAAM,UAAU,CAAA,GAAA,yCAAiB;IACjC,MAAM,KAAK,CAAC,GAAG,EAAE,CAAA,GAAA,yCAAI,EAAE,KAAK,CAAC;IAE7B,MAAM,OAAO,KAAK,MAAM,
|
|
1
|
+
{"mappings":"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","sources":["packages/next/ip-rate-limit/src/index.ts","packages/next/ip-rate-limit/src/ip-rate-limit.ts","packages/next/ip-rate-limit/src/storage.ts","packages/next/ip-rate-limit/src/utils.ts","packages/next/ip-rate-limit/src/constants.ts","packages/next/ip-rate-limit/src/wrapper.ts","packages/next/ip-rate-limit/src/types.ts"],"sourcesContent":["export * from './ip-rate-limit'\nexport * from './wrapper'\nexport * from './constants'\nexport * from './types'\n","import { RateLimitStorage } from './storage'\nimport { getIP, rateLimitedResponse } from './utils'\nimport { RATE_LIMIT_HEADERS } from './constants'\nimport { RateLimit } from './types'\n\nlet rateLimitStorage: RateLimitStorage\n\nexport const ipRateLimit: RateLimit = (data) => {\n if (!rateLimitStorage) rateLimitStorage = new RateLimitStorage()\n\n const now = Date.now() / 1000\n\n const { res, req, limit, timeFrame } = data\n const headers = RATE_LIMIT_HEADERS\n const id = `ip:${getIP(req)}`\n\n const time = Math.floor(now / timeFrame)\n const key = `${id}:${time}`\n\n const callCount = rateLimitStorage.inc(key, data.timeFrame)\n const remaining = limit - (callCount || 0)\n const reset = (time + 1) * timeFrame\n\n res.setHeader(headers.limit, `${limit}`)\n res.setHeader(headers.remaining, `${remaining < 0 ? 0 : remaining}`)\n res.setHeader(headers.reset, `${reset}`)\n\n if (remaining < 0) {\n const retryAfter = Math.ceil(Math.max(reset - now, 0))\n rateLimitedResponse({ id, res, req, retryAfter })\n }\n\n return res\n}\n","import { RateLimitStorageType } from './types'\n\nexport class RateLimitStorage {\n private _storage: RateLimitStorageType\n private timeoutIds: NodeJS.Timeout[] = []\n\n constructor() {\n this._storage = new Map()\n }\n\n set(key: string, value: number, durationSec: number) {\n this._storage.set(key, { value })\n\n if (this._storage.get(key)?.timeoutId) {\n clearTimeout(this._storage.get(key)?.timeoutId)\n }\n\n // code based on the work with setTimeouts from the code from the nestjs throttling service\n // https://github.com/nestjs/throttler/blob/master/src/throttler.service.ts#L25\n const timeoutId = setTimeout(() => {\n clearTimeout(timeoutId)\n\n this.timeoutIds = this.timeoutIds.filter((id) => id != timeoutId)\n this.delete(key)\n }, durationSec * 1000)\n this.timeoutIds.push(timeoutId)\n }\n\n get(key: string) {\n return this._storage.get(key)?.value\n }\n\n inc(key: string, durationSec: number) {\n if (this._storage.has(key)) {\n this.set(key, (this._storage.get(key)?.value || 0) + 1, durationSec)\n } else {\n this.set(key, 1, durationSec)\n }\n\n return this.get(key)\n }\n delete(key: string) {\n if (this._storage.has(key)) {\n this._storage.delete(key)\n }\n }\n}\n","import { NextApiRequest } from 'next'\nimport { ERROR_MESSAGE } from './constants'\nimport { RateLimitedResponse } from './types'\n\n// now we use headers from \"cloudflare\" and rely on their validity.\n// If there are no \"cloudflare\" headers, we use the \"x-forwarded-for\" header,\n// but keep in mind that these headers can be changed by anyone\n// https://developers.cloudflare.com/fundamentals/get-started/reference/http-request-headers/\nexport const getIP = (req: NextApiRequest) => {\n const cfConnectionIp = req.headers['cf_connecting_ip']\n const xff = req.headers['x-forwarded-for']\n\n if (cfConnectionIp) return Array.isArray(cfConnectionIp) ? cfConnectionIp[0] : cfConnectionIp.split(',')[0]\n\n return xff ? (Array.isArray(xff) ? xff[0] : xff.split(',')[0]) : '127.0.0.1'\n}\n\nexport const rateLimitedResponse: RateLimitedResponse = ({ id, res, req, retryAfter }) => {\n res.status(429)\n if (retryAfter) res.setHeader('Retry-After', retryAfter.toString())\n throw new Error(`${ERROR_MESSAGE} ${id} ${req.url || ''}`)\n}\n","export const RATE_LIMIT_HEADERS = {\n limit: `X-RateLimit-Limit`,\n remaining: `X-RateLimit-Remaining`,\n reset: `X-RateLimit-Reset`,\n}\n\nexport const ERROR_MESSAGE = 'API rate limit exceeded for'\n","import { RequestWrapper } from '@lidofinance/next-api-wrapper'\n\nimport { ipRateLimit } from './ip-rate-limit'\nimport { RateLimitWrapperArgs } from './types'\n\nexport const rateLimitWrapper =\n ({ rateLimit, rateLimitTimeFrame }: RateLimitWrapperArgs): RequestWrapper =>\n async (req, res, next) => {\n ipRateLimit({\n req,\n res,\n limit: rateLimit,\n timeFrame: rateLimitTimeFrame,\n })\n\n await next?.(req, res, next)\n }\n","import { NextApiResponse, NextApiRequest } from 'next'\n\nexport type RateLimitStorageType = Map<string, { value: number; timeoutId?: NodeJS.Timeout }>\n\nexport type RateLimitedResponse = (data: {\n res: NextApiResponse\n id: string\n req: NextApiRequest\n retryAfter?: number\n}) => void\n\nexport type RateLimit = (data: {\n req: NextApiRequest\n res: NextApiResponse\n limit: number\n timeFrame: number\n}) => NextApiResponse\n\nexport type RateLimitWrapperArgs = {\n rateLimit: number\n rateLimitTimeFrame: number\n}\n"],"names":[],"version":3,"file":"index.cjs.map","sourceRoot":"../../../../"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;AAEA,mCAAmC,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7F,kCAAkC,CAAC,IAAI,EAAE;IACvC,GAAG,EAAE,eAAe,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,cAAc,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,KAAK,IAAI,CAAA;AAEV,wBAAwB,CAAC,IAAI,EAAE;IAC7B,GAAG,EAAE,cAAc,CAAA;IACnB,GAAG,EAAE,eAAe,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB,KAAK,eAAe,CAAA;AAErB,mCAAmC;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;CAC3B,CAAA;AErBD,OAAO,MAAM;;;;CAIZ,CAAA;AAED,OAAO,MAAM,6CAA6C,CAAA;AEC1D,OAAO,MAAM,aAAa,
|
|
1
|
+
{"mappings":";;AAEA,mCAAmC,GAAG,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7F,kCAAkC,CAAC,IAAI,EAAE;IACvC,GAAG,EAAE,eAAe,CAAA;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,cAAc,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,KAAK,IAAI,CAAA;AAEV,wBAAwB,CAAC,IAAI,EAAE;IAC7B,GAAG,EAAE,cAAc,CAAA;IACnB,GAAG,EAAE,eAAe,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB,KAAK,eAAe,CAAA;AAErB,mCAAmC;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;CAC3B,CAAA;AErBD,OAAO,MAAM;;;;CAIZ,CAAA;AAED,OAAO,MAAM,6CAA6C,CAAA;AEC1D,OAAO,MAAM,aAAa,SA0BzB,CAAA;AC5BD,OAAO,MAAM,sDACyB,oBAAoB,KAAG,cAU1D,CAAA","sources":["packages/next/ip-rate-limit/src/src/types.ts","packages/next/ip-rate-limit/src/src/storage.ts","packages/next/ip-rate-limit/src/src/constants.ts","packages/next/ip-rate-limit/src/src/utils.ts","packages/next/ip-rate-limit/src/src/ip-rate-limit.ts","packages/next/ip-rate-limit/src/src/wrapper.ts","packages/next/ip-rate-limit/src/src/index.ts","packages/next/ip-rate-limit/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,"export * from './ip-rate-limit'\nexport * from './wrapper'\nexport * from './constants'\nexport * from './types'\n"],"names":[],"version":3,"file":"index.d.ts.map","sourceRoot":"../../../../"}
|
package/dist/index.mjs
CHANGED
|
@@ -66,10 +66,11 @@ const $15f73ba5d70a67f1$export$d0a20d44a54350ab = ({ id: id, res: res, req: req,
|
|
|
66
66
|
let $4a980b7982e8368e$var$rateLimitStorage;
|
|
67
67
|
const $4a980b7982e8368e$export$122bebc9e141287c = (data)=>{
|
|
68
68
|
if (!$4a980b7982e8368e$var$rateLimitStorage) $4a980b7982e8368e$var$rateLimitStorage = new (0, $a5fb111f145df95d$export$230ecc6ad0ef6558)();
|
|
69
|
+
const now = Date.now() / 1000;
|
|
69
70
|
const { res: res, req: req, limit: limit, timeFrame: timeFrame } = data;
|
|
70
71
|
const headers = (0, $1022f9b28fec0213$export$a063967512de3ebf);
|
|
71
72
|
const id = `ip:${(0, $15f73ba5d70a67f1$export$67218453e01a0be8)(req)}`;
|
|
72
|
-
const time = Math.floor(
|
|
73
|
+
const time = Math.floor(now / timeFrame);
|
|
73
74
|
const key = `${id}:${time}`;
|
|
74
75
|
const callCount = $4a980b7982e8368e$var$rateLimitStorage.inc(key, data.timeFrame);
|
|
75
76
|
const remaining = limit - (callCount || 0);
|
|
@@ -77,12 +78,15 @@ const $4a980b7982e8368e$export$122bebc9e141287c = (data)=>{
|
|
|
77
78
|
res.setHeader(headers.limit, `${limit}`);
|
|
78
79
|
res.setHeader(headers.remaining, `${remaining < 0 ? 0 : remaining}`);
|
|
79
80
|
res.setHeader(headers.reset, `${reset}`);
|
|
80
|
-
if (remaining < 0)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
if (remaining < 0) {
|
|
82
|
+
const retryAfter = Math.ceil(Math.max(reset - now, 0));
|
|
83
|
+
(0, $15f73ba5d70a67f1$export$d0a20d44a54350ab)({
|
|
84
|
+
id: id,
|
|
85
|
+
res: res,
|
|
86
|
+
req: req,
|
|
87
|
+
retryAfter: retryAfter
|
|
88
|
+
});
|
|
89
|
+
}
|
|
86
90
|
return res;
|
|
87
91
|
};
|
|
88
92
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;AEEO,MAAM;IAIX,aAAc;aAFN,aAA+B,EAAE;QAGvC,IAAI,CAAC,WAAW,IAAI;IACtB;IAEA,IAAI,GAAW,EAAE,KAAa,EAAE,WAAmB,EAAE;QACnD,IAAI,CAAC,SAAS,IAAI,KAAK;mBAAE;QAAM;QAE/B,IAAI,IAAI,CAAC,SAAS,IAAI,MAAM,WAC1B,aAAa,IAAI,CAAC,SAAS,IAAI,MAAM;QAGvC,2FAA2F;QAC3F,+EAA+E;QAC/E,MAAM,YAAY,WAAW;YAC3B,aAAa;YAEb,IAAI,CAAC,aAAa,IAAI,CAAC,WAAW,OAAO,CAAC,KAAO,MAAM;YACvD,IAAI,CAAC,OAAO;QACd,GAAG,cAAc;QACjB,IAAI,CAAC,WAAW,KAAK;IACvB;IAEA,IAAI,GAAW,EAAE;QACf,OAAO,IAAI,CAAC,SAAS,IAAI,MAAM;IACjC;IAEA,IAAI,GAAW,EAAE,WAAmB,EAAE;QACpC,IAAI,IAAI,CAAC,SAAS,IAAI,MACpB,IAAI,CAAC,IAAI,KAAK,AAAC,CAAA,IAAI,CAAC,SAAS,IAAI,MAAM,SAAS,CAAA,IAAK,GAAG;aAExD,IAAI,CAAC,IAAI,KAAK,GAAG;QAGnB,OAAO,IAAI,CAAC,IAAI;IAClB;IACA,OAAO,GAAW,EAAE;QAClB,IAAI,IAAI,CAAC,SAAS,IAAI,MACpB,IAAI,CAAC,SAAS,OAAO;IAEzB;AACF;;;;;;;AE9CO,MAAM,4CAAqB;IAChC,OAAO,CAAC,iBAAiB,CAAC;IAC1B,WAAW,CAAC,qBAAqB,CAAC;IAClC,OAAO,CAAC,iBAAiB,CAAC;AAC5B;AAEO,MAAM,4CAAgB;;;ADEtB,MAAM,4CAAQ,CAAC;IACpB,MAAM,iBAAiB,IAAI,OAAO,CAAC,mBAAmB;IACtD,MAAM,MAAM,IAAI,OAAO,CAAC,kBAAkB;IAE1C,IAAI,gBAAgB,OAAO,MAAM,QAAQ,kBAAkB,cAAc,CAAC,EAAE,GAAG,eAAe,MAAM,IAAI,CAAC,EAAE;IAE3G,OAAO,MAAO,MAAM,QAAQ,OAAO,GAAG,CAAC,EAAE,GAAG,IAAI,MAAM,IAAI,CAAC,EAAE,GAAI;AACnE;AAEO,MAAM,4CAA2C,CAAC,MAAE,EAAE,OAAE,GAAG,OAAE,GAAG,cAAE,UAAU,EAAE;IACnF,IAAI,OAAO;IACX,IAAI,YAAY,IAAI,UAAU,eAAe,WAAW;IACxD,MAAM,IAAI,MAAM,CAAC,EAAE,CAAA,GAAA,yCAAY,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,OAAO,GAAG,CAAC;AAC3D;;;;AFhBA,IAAI;AAEG,MAAM,4CAAyB,CAAC;IACrC,IAAI,CAAC,wCAAkB,yCAAmB,IAAI,CAAA,GAAA,yCAAe;IAE7D,MAAM,OAAE,GAAG,OAAE,GAAG,SAAE,KAAK,aAAE,SAAS,EAAE,GAAG;IACvC,MAAM,UAAU,CAAA,GAAA,yCAAiB;IACjC,MAAM,KAAK,CAAC,GAAG,EAAE,CAAA,GAAA,yCAAI,EAAE,KAAK,CAAC;IAE7B,MAAM,OAAO,KAAK,MAAM,
|
|
1
|
+
{"mappings":"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","sources":["packages/next/ip-rate-limit/src/index.ts","packages/next/ip-rate-limit/src/ip-rate-limit.ts","packages/next/ip-rate-limit/src/storage.ts","packages/next/ip-rate-limit/src/utils.ts","packages/next/ip-rate-limit/src/constants.ts","packages/next/ip-rate-limit/src/wrapper.ts","packages/next/ip-rate-limit/src/types.ts"],"sourcesContent":["export * from './ip-rate-limit'\nexport * from './wrapper'\nexport * from './constants'\nexport * from './types'\n","import { RateLimitStorage } from './storage'\nimport { getIP, rateLimitedResponse } from './utils'\nimport { RATE_LIMIT_HEADERS } from './constants'\nimport { RateLimit } from './types'\n\nlet rateLimitStorage: RateLimitStorage\n\nexport const ipRateLimit: RateLimit = (data) => {\n if (!rateLimitStorage) rateLimitStorage = new RateLimitStorage()\n\n const now = Date.now() / 1000\n\n const { res, req, limit, timeFrame } = data\n const headers = RATE_LIMIT_HEADERS\n const id = `ip:${getIP(req)}`\n\n const time = Math.floor(now / timeFrame)\n const key = `${id}:${time}`\n\n const callCount = rateLimitStorage.inc(key, data.timeFrame)\n const remaining = limit - (callCount || 0)\n const reset = (time + 1) * timeFrame\n\n res.setHeader(headers.limit, `${limit}`)\n res.setHeader(headers.remaining, `${remaining < 0 ? 0 : remaining}`)\n res.setHeader(headers.reset, `${reset}`)\n\n if (remaining < 0) {\n const retryAfter = Math.ceil(Math.max(reset - now, 0))\n rateLimitedResponse({ id, res, req, retryAfter })\n }\n\n return res\n}\n","import { RateLimitStorageType } from './types'\n\nexport class RateLimitStorage {\n private _storage: RateLimitStorageType\n private timeoutIds: NodeJS.Timeout[] = []\n\n constructor() {\n this._storage = new Map()\n }\n\n set(key: string, value: number, durationSec: number) {\n this._storage.set(key, { value })\n\n if (this._storage.get(key)?.timeoutId) {\n clearTimeout(this._storage.get(key)?.timeoutId)\n }\n\n // code based on the work with setTimeouts from the code from the nestjs throttling service\n // https://github.com/nestjs/throttler/blob/master/src/throttler.service.ts#L25\n const timeoutId = setTimeout(() => {\n clearTimeout(timeoutId)\n\n this.timeoutIds = this.timeoutIds.filter((id) => id != timeoutId)\n this.delete(key)\n }, durationSec * 1000)\n this.timeoutIds.push(timeoutId)\n }\n\n get(key: string) {\n return this._storage.get(key)?.value\n }\n\n inc(key: string, durationSec: number) {\n if (this._storage.has(key)) {\n this.set(key, (this._storage.get(key)?.value || 0) + 1, durationSec)\n } else {\n this.set(key, 1, durationSec)\n }\n\n return this.get(key)\n }\n delete(key: string) {\n if (this._storage.has(key)) {\n this._storage.delete(key)\n }\n }\n}\n","import { NextApiRequest } from 'next'\nimport { ERROR_MESSAGE } from './constants'\nimport { RateLimitedResponse } from './types'\n\n// now we use headers from \"cloudflare\" and rely on their validity.\n// If there are no \"cloudflare\" headers, we use the \"x-forwarded-for\" header,\n// but keep in mind that these headers can be changed by anyone\n// https://developers.cloudflare.com/fundamentals/get-started/reference/http-request-headers/\nexport const getIP = (req: NextApiRequest) => {\n const cfConnectionIp = req.headers['cf_connecting_ip']\n const xff = req.headers['x-forwarded-for']\n\n if (cfConnectionIp) return Array.isArray(cfConnectionIp) ? cfConnectionIp[0] : cfConnectionIp.split(',')[0]\n\n return xff ? (Array.isArray(xff) ? xff[0] : xff.split(',')[0]) : '127.0.0.1'\n}\n\nexport const rateLimitedResponse: RateLimitedResponse = ({ id, res, req, retryAfter }) => {\n res.status(429)\n if (retryAfter) res.setHeader('Retry-After', retryAfter.toString())\n throw new Error(`${ERROR_MESSAGE} ${id} ${req.url || ''}`)\n}\n","export const RATE_LIMIT_HEADERS = {\n limit: `X-RateLimit-Limit`,\n remaining: `X-RateLimit-Remaining`,\n reset: `X-RateLimit-Reset`,\n}\n\nexport const ERROR_MESSAGE = 'API rate limit exceeded for'\n","import { RequestWrapper } from '@lidofinance/next-api-wrapper'\n\nimport { ipRateLimit } from './ip-rate-limit'\nimport { RateLimitWrapperArgs } from './types'\n\nexport const rateLimitWrapper =\n ({ rateLimit, rateLimitTimeFrame }: RateLimitWrapperArgs): RequestWrapper =>\n async (req, res, next) => {\n ipRateLimit({\n req,\n res,\n limit: rateLimit,\n timeFrame: rateLimitTimeFrame,\n })\n\n await next?.(req, res, next)\n }\n","import { NextApiResponse, NextApiRequest } from 'next'\n\nexport type RateLimitStorageType = Map<string, { value: number; timeoutId?: NodeJS.Timeout }>\n\nexport type RateLimitedResponse = (data: {\n res: NextApiResponse\n id: string\n req: NextApiRequest\n retryAfter?: number\n}) => void\n\nexport type RateLimit = (data: {\n req: NextApiRequest\n res: NextApiResponse\n limit: number\n timeFrame: number\n}) => NextApiResponse\n\nexport type RateLimitWrapperArgs = {\n rateLimit: number\n rateLimitTimeFrame: number\n}\n"],"names":[],"version":3,"file":"index.mjs.map","sourceRoot":"../../../../"}
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"url": "https://github.com/lidofinance/warehouse/issues"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"version": "0.
|
|
10
|
+
"version": "0.45.0",
|
|
11
11
|
"files": [
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"next": "^12.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@lidofinance/config-prettier": "~0.
|
|
38
|
+
"@lidofinance/config-prettier": "~0.45.0",
|
|
39
39
|
"@types/jest": "^29.0.0",
|
|
40
40
|
"@types/node": "^20.0.0",
|
|
41
41
|
"jest": "^29.0.0",
|
|
@@ -43,6 +43,6 @@
|
|
|
43
43
|
"ts-jest": "^29.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@lidofinance/next-api-wrapper": "~0.
|
|
46
|
+
"@lidofinance/next-api-wrapper": "~0.45.0"
|
|
47
47
|
}
|
|
48
48
|
}
|