Files
firecrawl/apps/api/src/services/rate-limiter.ts
T

155 lines
3.1 KiB
TypeScript
Raw Normal View History

2024-04-15 17:01:47 -04:00
import { RateLimiterRedis } from "rate-limiter-flexible";
2024-04-20 14:02:22 -07:00
import { RateLimiterMode } from "../../src/types";
2024-07-16 22:41:13 -04:00
import Redis from "ioredis";
2024-04-15 17:01:47 -04:00
2024-05-30 14:31:36 -07:00
const RATE_LIMITS = {
crawl: {
2024-06-06 11:23:10 -07:00
default: 3,
2024-06-05 14:38:10 -07:00
free: 2,
2024-09-10 06:53:24 -03:00
starter: 10,
2024-05-30 14:31:36 -07:00
standard: 5,
2024-06-06 09:29:25 -07:00
standardOld: 40,
2024-07-24 16:56:19 -04:00
scale: 50,
2024-05-30 14:31:36 -07:00
hobby: 3,
standardNew: 10,
2024-06-23 18:59:08 -03:00
standardnew: 10,
2024-05-30 14:31:36 -07:00
growth: 50,
2024-08-15 18:37:19 -04:00
growthdouble: 50,
2024-05-30 14:31:36 -07:00
},
scrape: {
2024-08-27 12:08:50 -03:00
default: 20,
free: 10,
2024-09-10 06:53:24 -03:00
starter: 100,
2024-08-27 12:08:50 -03:00
standard: 100,
2024-09-10 06:53:24 -03:00
standardOld: 100,
2024-08-27 12:08:50 -03:00
scale: 500,
hobby: 20,
standardNew: 100,
standardnew: 100,
growth: 1000,
growthdouble: 1000,
},
search: {
2024-06-06 11:23:10 -07:00
default: 20,
2024-05-30 14:31:36 -07:00
free: 5,
2024-09-10 06:53:24 -03:00
starter: 50,
standard: 50,
2024-05-30 14:31:36 -07:00
standardOld: 40,
2024-07-24 16:56:19 -04:00
scale: 500,
2024-05-30 14:31:36 -07:00
hobby: 10,
standardNew: 50,
2024-06-23 18:59:08 -03:00
standardnew: 50,
2024-05-30 14:31:36 -07:00
growth: 500,
2024-08-15 18:37:19 -04:00
growthdouble: 500,
2024-05-30 14:31:36 -07:00
},
2024-08-27 12:08:50 -03:00
map:{
2024-06-06 11:23:10 -07:00
default: 20,
2024-05-30 14:31:36 -07:00
free: 5,
2024-09-10 06:53:24 -03:00
starter: 50,
standard: 50,
standardOld: 50,
2024-07-24 16:56:19 -04:00
scale: 500,
2024-05-30 14:31:36 -07:00
hobby: 10,
standardNew: 50,
2024-06-23 18:59:08 -03:00
standardnew: 50,
2024-05-30 14:31:36 -07:00
growth: 500,
2024-08-15 18:37:19 -04:00
growthdouble: 500,
2024-05-30 14:31:36 -07:00
},
2024-06-06 11:23:10 -07:00
preview: {
2024-06-06 11:53:12 -07:00
free: 5,
2024-06-06 11:23:10 -07:00
default: 5,
},
account: {
2024-06-14 12:13:02 -07:00
free: 100,
default: 100,
2024-06-06 11:23:10 -07:00
},
crawlStatus: {
2024-06-06 11:53:12 -07:00
free: 150,
2024-08-28 14:17:59 -03:00
default: 250,
2024-06-06 11:23:10 -07:00
},
testSuite: {
2024-06-06 11:53:12 -07:00
free: 10000,
2024-06-06 11:23:10 -07:00
default: 10000,
},
2024-05-30 14:31:36 -07:00
};
2024-04-20 14:02:22 -07:00
2024-07-16 22:41:13 -04:00
export const redisRateLimitClient = new Redis(
process.env.REDIS_RATE_LIMIT_URL
)
2024-04-15 17:01:47 -04:00
2024-06-06 11:23:10 -07:00
const createRateLimiter = (keyPrefix, points) =>
new RateLimiterRedis({
2024-07-16 22:41:13 -04:00
storeClient: redisRateLimitClient,
2024-06-06 11:23:10 -07:00
keyPrefix,
points,
duration: 60, // Duration in seconds
});
2024-04-15 17:01:47 -04:00
2024-06-06 11:23:10 -07:00
export const serverRateLimiter = createRateLimiter(
"server",
2024-06-06 11:56:00 -07:00
RATE_LIMITS.account.default
2024-06-06 11:23:10 -07:00
);
2024-06-06 12:05:20 -07:00
2024-05-08 15:14:39 -07:00
export const testSuiteRateLimiter = new RateLimiterRedis({
2024-07-16 22:41:13 -04:00
storeClient: redisRateLimitClient,
2024-05-14 14:26:42 -07:00
keyPrefix: "test-suite",
2024-05-19 12:23:34 -07:00
points: 10000,
2024-05-08 15:14:39 -07:00
duration: 60, // Duration in seconds
});
2024-04-15 17:01:47 -04:00
2024-08-26 16:05:11 -03:00
export const devBRateLimiter = new RateLimiterRedis({
storeClient: redisRateLimitClient,
keyPrefix: "dev-b",
points: 1200,
duration: 60, // Duration in seconds
});
2024-09-13 18:09:59 -04:00
export const manualRateLimiter = new RateLimiterRedis({
storeClient: redisRateLimitClient,
keyPrefix: "manual",
points: 2000,
duration: 60, // Duration in seconds
});
2024-08-31 14:23:55 -03:00
export const scrapeStatusRateLimiter = new RateLimiterRedis({
storeClient: redisRateLimitClient,
keyPrefix: "scrape-status",
2024-08-31 14:26:16 -03:00
points: 400,
2024-08-31 14:23:55 -03:00
duration: 60, // Duration in seconds
});
2024-09-11 14:03:34 -04:00
const testSuiteTokens = ["a01ccae", "6254cf9", "0f96e673", "23befa1b", "69141c4"];
2024-09-13 18:09:59 -04:00
const manual = ["69be9e74-7624-4990-b20d-08e0acc70cf6"];
2024-06-06 11:23:10 -07:00
export function getRateLimiter(
mode: RateLimiterMode,
token: string,
2024-08-26 16:05:11 -03:00
plan?: string,
teamId?: string
2024-06-06 11:23:10 -07:00
) {
2024-09-11 14:03:34 -04:00
if (testSuiteTokens.some(testToken => token.includes(testToken))) {
2024-05-30 14:31:36 -07:00
return testSuiteRateLimiter;
}
2024-04-20 14:02:22 -07:00
2024-08-27 15:37:36 -03:00
if(teamId && teamId === process.env.DEV_B_TEAM_ID) {
2024-08-26 16:05:11 -03:00
return devBRateLimiter;
}
2024-09-13 18:09:59 -04:00
if(teamId && manual.includes(teamId)) {
return manualRateLimiter;
}
2024-06-06 11:23:10 -07:00
const rateLimitConfig = RATE_LIMITS[mode]; // {default : 5}
2024-06-14 12:13:02 -07:00
2024-05-30 14:31:36 -07:00
if (!rateLimitConfig) return serverRateLimiter;
2024-05-08 15:14:39 -07:00
2024-06-06 11:23:10 -07:00
const planKey = plan ? plan.replace("-", "") : "default"; // "default"
const points =
rateLimitConfig[planKey] || rateLimitConfig.default || rateLimitConfig; // 5
2024-04-15 17:01:47 -04:00
2024-05-30 14:31:36 -07:00
return createRateLimiter(`${mode}-${planKey}`, points);
2024-04-15 17:01:47 -04:00
}