feat(config): add customizable configuration

This commit is contained in:
hansputera
2021-11-08 16:46:23 +07:00
parent 09da2d85c6
commit 1b32dc1789
7 changed files with 63 additions and 2 deletions

View File

@@ -3,6 +3,7 @@ import ow from 'ow';
import {getProvider, Providers} from '../lib/providers';
import {BaseProvider} from '../lib/providers/baseProvider';
import {rotateProvider} from '../lib/rotator';
import {ratelimitMiddleware} from '../middleware/ratelimit';
const providersType = Providers.map((p) => p.resourceName());
@@ -27,6 +28,7 @@ export default async (req: VercelRequest, res: VercelResponse) => {
}
const result = await rotateProvider(
provider as BaseProvider, req.query.url);
await ratelimitMiddleware(req);
return res.status(200).json(result);
} catch (e) {
return res.status(400).json({

View File

@@ -2,6 +2,7 @@ import type {VercelRequest, VercelResponse} from '@vercel/node';
import ow from 'ow';
import {tiktok} from '../lib';
import {ratelimitMiddleware} from '../middleware/ratelimit';
const SearchType = ['trend', 'cards'];
@@ -21,6 +22,7 @@ export default async (req: VercelRequest, res: VercelResponse) => {
})),
}));
await ratelimitMiddleware(req);
switch (req.query.t) {
case SearchType[0]:
const preview = await tiktok.searchPreview(req.query.q);

9
api/stored-links.ts Normal file
View File

@@ -0,0 +1,9 @@
import {VercelRequest, VercelResponse} from '@vercel/node';
import {matchLink} from '../lib/providers/util';
import {client} from '../lib/redis';
export default async (req: VercelRequest, res: VercelResponse) => {
const keys = await client.keys('*');
res.status(200).json(keys.filter((x) => matchLink(x)));
};

19
config.ts Normal file
View File

@@ -0,0 +1,19 @@
export const rateLimitConfig = {
'enable': true, // you can set it to 'false'
/**
* How much rate limit count per x second(s)
* -is allowed? Default: 60 requests
*/
'maxRatelimitPerXSeconds': 60,
/**
* Every x second(s), the ratelimit data will removed.
* So, their ratelimit data will removed.
* PS: Data stored on redis.
*/
'ratelimitTime': 60,
};
/**
* Provider response data will stored on redis.
*/
export const providerCache = 300;

View File

@@ -1,4 +1,5 @@
import {getRandomProvider} from '.';
import {providerCache} from '../config';
import {BaseProvider, ExtractedInfo} from './providers/baseProvider';
import {client} from './redis';
@@ -16,7 +17,8 @@ export const rotateProvider = async (
} else {
redisClient.set(url,
JSON.stringify(
{...data, provider: provider.resourceName()}), 'ex', 30);
{...data, provider: provider.resourceName()}), 'ex',
providerCache);
return {...data, provider: provider.resourceName()};
}
} else {

27
middleware/ratelimit.ts Normal file
View File

@@ -0,0 +1,27 @@
import {VercelRequest} from '@vercel/node';
import {rateLimitConfig} from '../config';
import {client} from '../lib/redis';
export const ratelimitMiddleware = async (req: VercelRequest) => {
const ip = req.headers['x-real-ip'];
return await new Promise((resolve, reject) => {
if (!rateLimitConfig.enable) return resolve(undefined);
else if (!ip) {
return reject(
new Error('Can\'t find your real ip address!'));
}
client.get('rate-' + ip, (_, result) => {
if (result) {
if (parseInt(result) > rateLimitConfig.maxRatelimitPerXSeconds) {
return reject(
new Error('Please try again, you are getting ratelimit!'));
}
client.incr('rate-' + ip);
return resolve(undefined);
} else {
client.set('rate-' + ip, '1', 'ex', rateLimitConfig.ratelimitTime);
return resolve(undefined);
}
});
});
};

View File

@@ -19,6 +19,6 @@
},
"scripts": {
"build": "echo build",
"lint": "eslint \"./lib/**/*.ts\" \"./types/*.ts\" \"./api/**/*.ts\" --fix"
"lint": "eslint \"./middleware/**/*.ts\" \"./lib/**/*.ts\" \"./types/*.ts\" \"./api/**/*.ts\" --fix"
}
}