rate-limiter.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import {
  2. defaultConfig, defaultConfigWithRegExp, IApiRateLimitEndpointMap,
  3. } from '^/config/rate-limiter';
  4. const envVar = process.env;
  5. // https://regex101.com/r/aNDjmI/1
  6. const regExp = /^API_RATE_LIMIT_(\w+)_ENDPOINT(_WITH_REGEXP)?$/;
  7. const generateApiRateLimitConfigFromEndpoint = (envVar: NodeJS.ProcessEnv, targets: string[], withRegExp: boolean): IApiRateLimitEndpointMap => {
  8. const apiRateLimitConfig: IApiRateLimitEndpointMap = {};
  9. targets.forEach((target) => {
  10. const endpointKey = withRegExp ? `API_RATE_LIMIT_${target}_ENDPOINT_WITH_REGEXP` : `API_RATE_LIMIT_${target}_ENDPOINT`;
  11. const endpoint = envVar[endpointKey];
  12. if (endpoint == null) {
  13. return;
  14. }
  15. const methodKey = `API_RATE_LIMIT_${target}_METHODS`;
  16. const maxRequestsKey = `API_RATE_LIMIT_${target}_MAX_REQUESTS`;
  17. const method = envVar[methodKey] ?? 'ALL';
  18. const maxRequests = Number(envVar[maxRequestsKey]);
  19. if (endpoint == null || maxRequests == null) {
  20. return;
  21. }
  22. const config = {
  23. method,
  24. maxRequests,
  25. };
  26. apiRateLimitConfig[endpoint] = config;
  27. });
  28. return apiRateLimitConfig;
  29. };
  30. type ApiRateLimitConfigResult = {
  31. 'withoutRegExp': IApiRateLimitEndpointMap,
  32. 'withRegExp': IApiRateLimitEndpointMap
  33. }
  34. export const generateApiRateLimitConfig = (): ApiRateLimitConfigResult => {
  35. const apiRateConfigTargets: string[] = [];
  36. const apiRateConfigTargetsWithRegExp: string[] = [];
  37. Object.keys(envVar).forEach((key) => {
  38. const result = key.match(regExp);
  39. if (result == null) { return null }
  40. const target = result[1];
  41. const isWithRegExp = result[2] != null;
  42. if (isWithRegExp) {
  43. apiRateConfigTargetsWithRegExp.push(target);
  44. }
  45. else {
  46. apiRateConfigTargets.push(target);
  47. }
  48. });
  49. // sort priority
  50. apiRateConfigTargets.sort();
  51. apiRateConfigTargetsWithRegExp.sort();
  52. // get config
  53. const apiRateLimitConfig = generateApiRateLimitConfigFromEndpoint(envVar, apiRateConfigTargets, false);
  54. const apiRateLimitConfigWithRegExp = generateApiRateLimitConfigFromEndpoint(envVar, apiRateConfigTargetsWithRegExp, true);
  55. const config = { ...defaultConfig, ...apiRateLimitConfig };
  56. const configWithRegExp = { ...defaultConfigWithRegExp, ...apiRateLimitConfigWithRegExp };
  57. const result: ApiRateLimitConfigResult = {
  58. withoutRegExp: config,
  59. withRegExp: configWithRegExp,
  60. };
  61. return result;
  62. };