@thangnv-dev/rate-limiter-nest 0.0.1

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.
Files changed (37) hide show
  1. package/dist/decorators.d.ts +5 -0
  2. package/dist/decorators.d.ts.map +1 -0
  3. package/dist/decorators.js +9 -0
  4. package/dist/decorators.js.map +1 -0
  5. package/dist/global-rate-limit.guard.d.ts +11 -0
  6. package/dist/global-rate-limit.guard.d.ts.map +1 -0
  7. package/dist/global-rate-limit.guard.js +126 -0
  8. package/dist/global-rate-limit.guard.js.map +1 -0
  9. package/dist/index.d.ts +7 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +6 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/rate-limit.guard.d.ts +9 -0
  14. package/dist/rate-limit.guard.d.ts.map +1 -0
  15. package/dist/rate-limit.guard.js +53 -0
  16. package/dist/rate-limit.guard.js.map +1 -0
  17. package/dist/rate-limit.interceptor.d.ts +10 -0
  18. package/dist/rate-limit.interceptor.d.ts.map +1 -0
  19. package/dist/rate-limit.interceptor.js +53 -0
  20. package/dist/rate-limit.interceptor.js.map +1 -0
  21. package/dist/rate-limit.service.d.ts +12 -0
  22. package/dist/rate-limit.service.d.ts.map +1 -0
  23. package/dist/rate-limit.service.js +162 -0
  24. package/dist/rate-limit.service.js.map +1 -0
  25. package/dist/rate-limiter.module.d.ts +8 -0
  26. package/dist/rate-limiter.module.d.ts.map +1 -0
  27. package/dist/rate-limiter.module.js +188 -0
  28. package/dist/rate-limiter.module.js.map +1 -0
  29. package/dist/tokens.d.ts +4 -0
  30. package/dist/tokens.d.ts.map +1 -0
  31. package/dist/tokens.js +4 -0
  32. package/dist/tokens.js.map +1 -0
  33. package/dist/types.d.ts +30 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/types.js +2 -0
  36. package/dist/types.js.map +1 -0
  37. package/package.json +48 -0
@@ -0,0 +1,5 @@
1
+ import type { RateLimitOverride } from './types.js';
2
+ export declare const RATE_LIMIT_OVERRIDE_METADATA_KEY = "content-forge:rate-limit-override";
3
+ export declare function RateLimit(override?: RateLimitOverride): MethodDecorator & ClassDecorator;
4
+ export declare function DisableRateLimit(): MethodDecorator & ClassDecorator;
5
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,eAAO,MAAM,gCAAgC,sCAAsC,CAAA;AAEnF,wBAAgB,SAAS,CACvB,QAAQ,GAAE,iBAAsB,GAC/B,eAAe,GAAG,cAAc,CAElC;AAED,wBAAgB,gBAAgB,IAAI,eAAe,GAAG,cAAc,CAEnE"}
@@ -0,0 +1,9 @@
1
+ import { SetMetadata } from '@nestjs/common';
2
+ export const RATE_LIMIT_OVERRIDE_METADATA_KEY = 'content-forge:rate-limit-override';
3
+ export function RateLimit(override = {}) {
4
+ return SetMetadata(RATE_LIMIT_OVERRIDE_METADATA_KEY, override);
5
+ }
6
+ export function DisableRateLimit() {
7
+ return SetMetadata(RATE_LIMIT_OVERRIDE_METADATA_KEY, { disabled: true });
8
+ }
9
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAG5C,MAAM,CAAC,MAAM,gCAAgC,GAAG,mCAAmC,CAAA;AAEnF,MAAM,UAAU,SAAS,CACvB,WAA8B,EAAE;IAEhC,OAAO,WAAW,CAAC,gCAAgC,EAAE,QAAQ,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,WAAW,CAAC,gCAAgC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAA8B,CAAC,CAAA;AACtG,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type CanActivate, type ExecutionContext } from '@nestjs/common';
2
+ import { RateLimitService } from './rate-limit.service.js';
3
+ import type { RateLimiterNestModuleOptions } from './types.js';
4
+ export declare class GlobalRateLimitGuard implements CanActivate {
5
+ private readonly rateLimitService;
6
+ private readonly compiledRoutes;
7
+ constructor(rateLimitService: RateLimitService, options: RateLimiterNestModuleOptions);
8
+ canActivate(context: ExecutionContext): Promise<boolean>;
9
+ private resolveProfileName;
10
+ }
11
+ //# sourceMappingURL=global-rate-limit.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-rate-limit.guard.d.ts","sourceRoot":"","sources":["../src/global-rate-limit.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAE5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,EAGV,4BAA4B,EAC7B,MAAM,YAAY,CAAA;AAcnB,qBACa,oBAAqB,YAAW,WAAW;IAIpD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAHnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA8B;gBAG1C,gBAAgB,EAAE,gBAAgB,EAEnD,OAAO,EAAE,4BAA4B;IAKjC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAc9D,OAAO,CAAC,kBAAkB;CAiB3B"}
@@ -0,0 +1,126 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Inject, Injectable } from '@nestjs/common';
14
+ import { RATE_LIMITER_NEST_OPTIONS_TOKEN } from './tokens.js';
15
+ import { RateLimitService } from './rate-limit.service.js';
16
+ let GlobalRateLimitGuard = class GlobalRateLimitGuard {
17
+ rateLimitService;
18
+ compiledRoutes;
19
+ constructor(rateLimitService, options) {
20
+ this.rateLimitService = rateLimitService;
21
+ this.compiledRoutes = compileRouteRules(options.global?.routes ?? []);
22
+ }
23
+ async canActivate(context) {
24
+ if (context.getType() !== 'http') {
25
+ return true;
26
+ }
27
+ const profileName = this.resolveProfileName(context);
28
+ if (!profileName) {
29
+ return true;
30
+ }
31
+ await this.rateLimitService.enforce(context, profileName);
32
+ return true;
33
+ }
34
+ resolveProfileName(context) {
35
+ const request = context.switchToHttp().getRequest();
36
+ const method = normalizeHttpMethod(request.method);
37
+ const path = normalizeRequestPath(request);
38
+ for (const route of this.compiledRoutes) {
39
+ if (route.methods && !route.methods.has(method)) {
40
+ continue;
41
+ }
42
+ if (!route.pathRegex.test(path)) {
43
+ continue;
44
+ }
45
+ return route.profileName;
46
+ }
47
+ return undefined;
48
+ }
49
+ };
50
+ GlobalRateLimitGuard = __decorate([
51
+ Injectable(),
52
+ __param(1, Inject(RATE_LIMITER_NEST_OPTIONS_TOKEN)),
53
+ __metadata("design:paramtypes", [RateLimitService, Object])
54
+ ], GlobalRateLimitGuard);
55
+ export { GlobalRateLimitGuard };
56
+ function compileRouteRules(routes) {
57
+ return routes.map((route) => ({
58
+ profileName: route.profile.trim(),
59
+ methods: compileMethods(route.methods),
60
+ pathRegex: compilePathPattern(route.path),
61
+ }));
62
+ }
63
+ function compileMethods(methods) {
64
+ if (!methods || methods.length === 0) {
65
+ return undefined;
66
+ }
67
+ const normalizedMethods = new Set();
68
+ for (const method of methods) {
69
+ const normalized = normalizeHttpMethod(method);
70
+ if (normalized === '*') {
71
+ return undefined;
72
+ }
73
+ normalizedMethods.add(normalized);
74
+ }
75
+ return normalizedMethods;
76
+ }
77
+ function normalizeRequestPath(request) {
78
+ const originalUrl = typeof request.originalUrl === 'string' ? request.originalUrl : undefined;
79
+ const url = typeof request.url === 'string' ? request.url : undefined;
80
+ const rawPath = originalUrl ?? url ?? '/';
81
+ const queryIndex = rawPath.indexOf('?');
82
+ const noQueryPath = queryIndex >= 0 ? rawPath.slice(0, queryIndex) : rawPath;
83
+ return normalizePath(noQueryPath);
84
+ }
85
+ function normalizeHttpMethod(value) {
86
+ if (typeof value !== 'string') {
87
+ return 'GET';
88
+ }
89
+ const trimmed = value.trim().toUpperCase();
90
+ return trimmed || 'GET';
91
+ }
92
+ function compilePathPattern(pattern) {
93
+ const normalizedPattern = normalizePath(pattern);
94
+ if (normalizedPattern === '*') {
95
+ return /^.*$/;
96
+ }
97
+ const segments = normalizedPattern.split('/').filter((segment) => segment.length > 0);
98
+ const regexBody = segments
99
+ .map((segment) => {
100
+ if (segment === '*') {
101
+ return '.*';
102
+ }
103
+ if (segment.startsWith(':')) {
104
+ return '[^/]+';
105
+ }
106
+ return escapeRegExp(segment);
107
+ })
108
+ .join('/');
109
+ const source = normalizedPattern.startsWith('/') ? `/${regexBody}` : regexBody;
110
+ return new RegExp(`^${source}$`);
111
+ }
112
+ function normalizePath(path) {
113
+ const trimmed = path.trim();
114
+ if (!trimmed || trimmed === '*') {
115
+ return '*';
116
+ }
117
+ const withLeadingSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
118
+ if (withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')) {
119
+ return withLeadingSlash.slice(0, -1);
120
+ }
121
+ return withLeadingSlash;
122
+ }
123
+ function escapeRegExp(value) {
124
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
125
+ }
126
+ //# sourceMappingURL=global-rate-limit.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-rate-limit.guard.js","sourceRoot":"","sources":["../src/global-rate-limit.guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { RATE_LIMITER_TOKEN, RATE_LIMITER_NEST_OPTIONS_TOKEN, RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN, } from './tokens.js';
2
+ export { GlobalRateLimitGuard } from './global-rate-limit.guard.js';
3
+ export { RateLimit, RateLimitGuard } from './rate-limit.guard.js';
4
+ export { RateLimitService } from './rate-limit.service.js';
5
+ export { RateLimiterModule } from './rate-limiter.module.js';
6
+ export type { RateLimitGlobalConfig, RateLimitGlobalRouteConfig, RateLimitHttpMethod, RateLimitProfile, RateLimitPolicy, RateLimitBucketKeyFactory, RateLimiterNestFeatureOptions, RateLimiterNestModuleOptions, RateLimiterNestAsyncOptions, } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,+BAA+B,EAC/B,oCAAoC,GACrC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,YAAY,EACV,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EACzB,6BAA6B,EAC7B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ export { RATE_LIMITER_TOKEN, RATE_LIMITER_NEST_OPTIONS_TOKEN, RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN, } from './tokens.js';
2
+ export { GlobalRateLimitGuard } from './global-rate-limit.guard.js';
3
+ export { RateLimit, RateLimitGuard } from './rate-limit.guard.js';
4
+ export { RateLimitService } from './rate-limit.service.js';
5
+ export { RateLimiterModule } from './rate-limiter.module.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,+BAA+B,EAC/B,oCAAoC,GACrC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,9 @@
1
+ import { type CanActivate, type ExecutionContext, type Type } from '@nestjs/common';
2
+ import { RateLimitService } from './rate-limit.service.js';
3
+ export declare class RateLimitGuard implements CanActivate {
4
+ private readonly rateLimitService;
5
+ constructor(rateLimitService: RateLimitService);
6
+ canActivate(context: ExecutionContext): Promise<boolean>;
7
+ }
8
+ export declare function RateLimit(name?: string): Type<CanActivate>;
9
+ //# sourceMappingURL=rate-limit.guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.guard.d.ts","sourceRoot":"","sources":["../src/rate-limit.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EAErB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAI1D,qBACa,cAAe,YAAW,WAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,gBAAgB;IAEzD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAI/D;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAuB,GAAG,IAAI,CAAC,WAAW,CAAC,CAcxE"}
@@ -0,0 +1,53 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, mixin, } from '@nestjs/common';
11
+ import { RateLimitService } from './rate-limit.service.js';
12
+ const DEFAULT_PROFILE_NAME = 'default';
13
+ let RateLimitGuard = class RateLimitGuard {
14
+ rateLimitService;
15
+ constructor(rateLimitService) {
16
+ this.rateLimitService = rateLimitService;
17
+ }
18
+ async canActivate(context) {
19
+ await this.rateLimitService.enforce(context, DEFAULT_PROFILE_NAME);
20
+ return true;
21
+ }
22
+ };
23
+ RateLimitGuard = __decorate([
24
+ Injectable(),
25
+ __metadata("design:paramtypes", [RateLimitService])
26
+ ], RateLimitGuard);
27
+ export { RateLimitGuard };
28
+ export function RateLimit(name = DEFAULT_PROFILE_NAME) {
29
+ const profileName = resolveProfileName(name);
30
+ let ProfileRateLimitGuard = class ProfileRateLimitGuard {
31
+ rateLimitService;
32
+ constructor(rateLimitService) {
33
+ this.rateLimitService = rateLimitService;
34
+ }
35
+ async canActivate(context) {
36
+ await this.rateLimitService.enforce(context, profileName);
37
+ return true;
38
+ }
39
+ };
40
+ ProfileRateLimitGuard = __decorate([
41
+ Injectable(),
42
+ __metadata("design:paramtypes", [RateLimitService])
43
+ ], ProfileRateLimitGuard);
44
+ return mixin(ProfileRateLimitGuard);
45
+ }
46
+ function resolveProfileName(name) {
47
+ const trimmed = name.trim();
48
+ if (trimmed) {
49
+ return trimmed;
50
+ }
51
+ return DEFAULT_PROFILE_NAME;
52
+ }
53
+ //# sourceMappingURL=rate-limit.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.guard.js","sourceRoot":"","sources":["../src/rate-limit.guard.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,UAAU,EAGV,KAAK,GAEN,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAG/B,IAAM,cAAc,GAApB,MAAM,cAAc;IACI;IAA7B,YAA6B,gBAAkC;QAAlC,qBAAgB,GAAhB,gBAAgB,CAAkB;IAAG,CAAC;IAEnE,KAAK,CAAC,WAAW,CAAC,OAAyB;QACzC,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;QAClE,OAAO,IAAI,CAAA;IACb,CAAC;CACF,CAAA;AAPY,cAAc;IAD1B,UAAU,EAAE;qCAEoC,gBAAgB;GADpD,cAAc,CAO1B;;AAED,MAAM,UAAU,SAAS,CAAC,IAAI,GAAG,oBAAoB;IACnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAE5C,IACM,qBAAqB,GAD3B,MACM,qBAAqB;QACI;QAA7B,YAA6B,gBAAkC;YAAlC,qBAAgB,GAAhB,gBAAgB,CAAkB;QAAG,CAAC;QAEnE,KAAK,CAAC,WAAW,CAAC,OAAyB;YACzC,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YACzD,OAAO,IAAI,CAAA;QACb,CAAC;KACF,CAAA;IAPK,qBAAqB;QAD1B,UAAU,EAAE;yCAEoC,gBAAgB;OAD3D,qBAAqB,CAO1B;IAED,OAAO,KAAK,CAAC,qBAAqB,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,OAAO,oBAAoB,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type CallHandler, type ExecutionContext, type NestInterceptor, type Type } from '@nestjs/common';
2
+ import type { Observable } from 'rxjs';
3
+ import { RateLimitService } from './rate-limit.service.js';
4
+ export declare class RateLimitInterceptor implements NestInterceptor {
5
+ private readonly rateLimitService;
6
+ constructor(rateLimitService: RateLimitService);
7
+ intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<unknown>>;
8
+ }
9
+ export declare function RateLimit(name?: string): Type<NestInterceptor>;
10
+ //# sourceMappingURL=rate-limit.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.interceptor.d.ts","sourceRoot":"","sources":["../src/rate-limit.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAEpB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAI1D,qBACa,oBAAqB,YAAW,eAAe;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAAhB,gBAAgB,EAAE,gBAAgB;IAEzD,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;CAI5F;AAED,wBAAgB,SAAS,CAAC,IAAI,SAAuB,GAAG,IAAI,CAAC,eAAe,CAAC,CAc5E"}
@@ -0,0 +1,53 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable, mixin, } from '@nestjs/common';
11
+ import { RateLimitService } from './rate-limit.service.js';
12
+ const DEFAULT_PROFILE_NAME = 'default';
13
+ let RateLimitInterceptor = class RateLimitInterceptor {
14
+ rateLimitService;
15
+ constructor(rateLimitService) {
16
+ this.rateLimitService = rateLimitService;
17
+ }
18
+ async intercept(context, next) {
19
+ await this.rateLimitService.enforce(context, DEFAULT_PROFILE_NAME);
20
+ return next.handle();
21
+ }
22
+ };
23
+ RateLimitInterceptor = __decorate([
24
+ Injectable(),
25
+ __metadata("design:paramtypes", [RateLimitService])
26
+ ], RateLimitInterceptor);
27
+ export { RateLimitInterceptor };
28
+ export function RateLimit(name = DEFAULT_PROFILE_NAME) {
29
+ const profileName = resolveProfileName(name);
30
+ let ProfileRateLimitInterceptor = class ProfileRateLimitInterceptor {
31
+ rateLimitService;
32
+ constructor(rateLimitService) {
33
+ this.rateLimitService = rateLimitService;
34
+ }
35
+ async intercept(context, next) {
36
+ await this.rateLimitService.enforce(context, profileName);
37
+ return next.handle();
38
+ }
39
+ };
40
+ ProfileRateLimitInterceptor = __decorate([
41
+ Injectable(),
42
+ __metadata("design:paramtypes", [RateLimitService])
43
+ ], ProfileRateLimitInterceptor);
44
+ return mixin(ProfileRateLimitInterceptor);
45
+ }
46
+ function resolveProfileName(name) {
47
+ const trimmed = name.trim();
48
+ if (trimmed) {
49
+ return trimmed;
50
+ }
51
+ return DEFAULT_PROFILE_NAME;
52
+ }
53
+ //# sourceMappingURL=rate-limit.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.interceptor.js","sourceRoot":"","sources":["../src/rate-limit.interceptor.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EACL,UAAU,EAIV,KAAK,GAEN,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,MAAM,oBAAoB,GAAG,SAAS,CAAA;AAG/B,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACF;IAA7B,YAA6B,gBAAkC;QAAlC,qBAAgB,GAAhB,gBAAgB,CAAkB;IAAG,CAAC;IAEnE,KAAK,CAAC,SAAS,CAAC,OAAyB,EAAE,IAAiB;QAC1D,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;QAClE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;IACtB,CAAC;CACF,CAAA;AAPY,oBAAoB;IADhC,UAAU,EAAE;qCAEoC,gBAAgB;GADpD,oBAAoB,CAOhC;;AAED,MAAM,UAAU,SAAS,CAAC,IAAI,GAAG,oBAAoB;IACnD,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAE5C,IACM,2BAA2B,GADjC,MACM,2BAA2B;QACF;QAA7B,YAA6B,gBAAkC;YAAlC,qBAAgB,GAAhB,gBAAgB,CAAkB;QAAG,CAAC;QAEnE,KAAK,CAAC,SAAS,CAAC,OAAyB,EAAE,IAAiB;YAC1D,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAA;YACzD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;QACtB,CAAC;KACF,CAAA;IAPK,2BAA2B;QADhC,UAAU,EAAE;yCAEoC,gBAAgB;OAD3D,2BAA2B,CAOhC;IAED,OAAO,KAAK,CAAC,2BAA2B,CAAC,CAAA;AAC3C,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,OAAO,oBAAoB,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ExecutionContext } from '@nestjs/common';
2
+ import type { RateLimiter } from '@thangnv-dev/rate-limiter-node';
3
+ import type { RateLimiterNestModuleOptions } from './types.js';
4
+ export declare class RateLimitService {
5
+ private readonly rateLimiter;
6
+ private readonly options;
7
+ constructor(rateLimiter: RateLimiter, options: RateLimiterNestModuleOptions);
8
+ enforce(context: ExecutionContext, profileName: string): Promise<void>;
9
+ private resolvePolicy;
10
+ private applyRateLimitHeaders;
11
+ }
12
+ //# sourceMappingURL=rate-limit.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.service.d.ts","sourceRoot":"","sources":["../src/rate-limit.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,gCAAgC,CAAA;AAExF,OAAO,KAAK,EAAoB,4BAA4B,EAAE,MAAM,YAAY,CAAA;AAsBhF,qBACa,gBAAgB;IAEG,OAAO,CAAC,QAAQ,CAAC,WAAW;IAExD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFqB,WAAW,EAAE,WAAW,EAEpD,OAAO,EAAE,4BAA4B;IAGlD,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5E,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,qBAAqB;CAY9B"}
@@ -0,0 +1,162 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { HttpException, HttpStatus, Inject, Injectable, } from '@nestjs/common';
14
+ import { RATE_LIMITER_NEST_OPTIONS_TOKEN, RATE_LIMITER_TOKEN } from './tokens.js';
15
+ const HEADER_RATELIMIT_LIMIT = 'RateLimit-Limit';
16
+ const HEADER_RATELIMIT_REMAINING = 'RateLimit-Remaining';
17
+ const HEADER_RATELIMIT_RESET = 'RateLimit-Reset';
18
+ const HEADER_RETRY_AFTER = 'Retry-After';
19
+ let RateLimitService = class RateLimitService {
20
+ rateLimiter;
21
+ options;
22
+ constructor(rateLimiter, options) {
23
+ this.rateLimiter = rateLimiter;
24
+ this.options = options;
25
+ }
26
+ async enforce(context, profileName) {
27
+ if (context.getType() !== 'http') {
28
+ return;
29
+ }
30
+ const policy = this.resolvePolicy(profileName);
31
+ const http = context.switchToHttp();
32
+ const response = http.getResponse();
33
+ const bucketKeyFactory = policy.bucketKeyFactory
34
+ ?? this.options.bucketKeyFactory
35
+ ?? defaultRateLimitBucketKeyFactory;
36
+ const result = await this.rateLimiter.take({
37
+ key: bucketKeyFactory(context),
38
+ capacity: policy.capacity,
39
+ refillTokens: policy.refillTokens,
40
+ refillInterval: policy.refillInterval,
41
+ tokens: policy.tokens,
42
+ });
43
+ this.applyRateLimitHeaders(response, result);
44
+ if (!result.allowed) {
45
+ response.setHeader(HEADER_RETRY_AFTER, toWholeSeconds(result.retryAfter).toString());
46
+ throw new HttpException('Rate limit exceeded', HttpStatus.TOO_MANY_REQUESTS);
47
+ }
48
+ }
49
+ resolvePolicy(profileName) {
50
+ const normalizedName = profileName.trim();
51
+ const policy = this.options.profiles[normalizedName];
52
+ if (!policy) {
53
+ throw new Error(`Rate limit profile not found: ${normalizedName}`);
54
+ }
55
+ return policy;
56
+ }
57
+ applyRateLimitHeaders(response, result) {
58
+ const limit = result.limit.toString();
59
+ const remaining = result.remaining.toString();
60
+ const resetSeconds = toWholeSeconds(result.retryAfter).toString();
61
+ response.setHeader(HEADER_RATELIMIT_LIMIT, limit);
62
+ response.setHeader(HEADER_RATELIMIT_REMAINING, remaining);
63
+ response.setHeader(HEADER_RATELIMIT_RESET, resetSeconds);
64
+ }
65
+ };
66
+ RateLimitService = __decorate([
67
+ Injectable(),
68
+ __param(0, Inject(RATE_LIMITER_TOKEN)),
69
+ __param(1, Inject(RATE_LIMITER_NEST_OPTIONS_TOKEN)),
70
+ __metadata("design:paramtypes", [Object, Object])
71
+ ], RateLimitService);
72
+ export { RateLimitService };
73
+ function defaultRateLimitBucketKeyFactory(context) {
74
+ const request = context.switchToHttp().getRequest();
75
+ const method = normalizeMethod(request.method);
76
+ const routePath = normalizeRoutePath(request);
77
+ const subject = normalizeSubject(request);
78
+ return `${method}:${routePath}:${subject}`;
79
+ }
80
+ function normalizeMethod(value) {
81
+ if (typeof value !== 'string') {
82
+ return 'GET';
83
+ }
84
+ const trimmed = value.trim().toUpperCase();
85
+ return trimmed || 'GET';
86
+ }
87
+ function normalizeRoutePath(request) {
88
+ const routePath = request.route?.path;
89
+ if (typeof routePath === 'string' && routePath.trim()) {
90
+ return routePath.trim();
91
+ }
92
+ const originalUrl = typeof request.originalUrl === 'string' ? request.originalUrl : undefined;
93
+ const url = typeof request.url === 'string' ? request.url : undefined;
94
+ const rawPath = originalUrl ?? url ?? '/';
95
+ const queryIndex = rawPath.indexOf('?');
96
+ if (queryIndex >= 0) {
97
+ return rawPath.slice(0, queryIndex) || '/';
98
+ }
99
+ return rawPath || '/';
100
+ }
101
+ function normalizeSubject(request) {
102
+ const userId = resolveUserId(request.user);
103
+ if (userId) {
104
+ return `user:${userId}`;
105
+ }
106
+ const forwardedFor = resolveForwardedFor(request.headers);
107
+ if (forwardedFor) {
108
+ return `ip:${forwardedFor}`;
109
+ }
110
+ if (typeof request.ip === 'string' && request.ip.trim()) {
111
+ return `ip:${request.ip.trim()}`;
112
+ }
113
+ const remoteAddress = request.socket?.remoteAddress;
114
+ if (typeof remoteAddress === 'string' && remoteAddress.trim()) {
115
+ return `ip:${remoteAddress.trim()}`;
116
+ }
117
+ return 'anon';
118
+ }
119
+ function resolveUserId(user) {
120
+ if (typeof user !== 'object' || user === null) {
121
+ return undefined;
122
+ }
123
+ const record = user;
124
+ const id = record.id;
125
+ if (typeof id !== 'string') {
126
+ return undefined;
127
+ }
128
+ const trimmed = id.trim();
129
+ return trimmed || undefined;
130
+ }
131
+ function resolveForwardedFor(headers) {
132
+ if (!headers) {
133
+ return undefined;
134
+ }
135
+ const value = headers['x-forwarded-for'];
136
+ if (typeof value === 'string') {
137
+ const first = value.split(',')[0]?.trim();
138
+ return first || undefined;
139
+ }
140
+ if (Array.isArray(value)) {
141
+ for (const entry of value) {
142
+ if (typeof entry === 'string' && entry.trim()) {
143
+ const first = entry.split(',')[0]?.trim();
144
+ if (first) {
145
+ return first;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ return undefined;
151
+ }
152
+ function toWholeSeconds(duration) {
153
+ const seconds = toFiniteNonNegativeNumber(duration.total({ unit: 'second' }));
154
+ return Math.ceil(seconds);
155
+ }
156
+ function toFiniteNonNegativeNumber(value) {
157
+ if (!Number.isFinite(value) || value <= 0) {
158
+ return 0;
159
+ }
160
+ return value;
161
+ }
162
+ //# sourceMappingURL=rate-limit.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.service.js","sourceRoot":"","sources":["../src/rate-limit.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type DynamicModule } from '@nestjs/common';
2
+ import type { RateLimiterNestAsyncOptions, RateLimiterNestFeatureOptions, RateLimiterNestModuleOptions } from './types.js';
3
+ export declare class RateLimiterModule {
4
+ static forRoot(options: RateLimiterNestModuleOptions): DynamicModule;
5
+ static forRootAsync(options: RateLimiterNestAsyncOptions): DynamicModule;
6
+ static forFeature(options: RateLimiterNestFeatureOptions): DynamicModule;
7
+ }
8
+ //# sourceMappingURL=rate-limiter.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.module.d.ts","sourceRoot":"","sources":["../src/rate-limiter.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAA;AAU1E,OAAO,KAAK,EAEV,2BAA2B,EAC3B,6BAA6B,EAC7B,4BAA4B,EAC7B,MAAM,YAAY,CAAA;AAInB,qBACa,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,4BAA4B,GAAG,aAAa;IAwCpE,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,2BAA2B,GAAG,aAAa;IAiDxE,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,6BAA6B,GAAG,aAAa;CAgCzE"}
@@ -0,0 +1,188 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var RateLimiterModule_1;
8
+ import { Module } from '@nestjs/common';
9
+ import { APP_GUARD } from '@nestjs/core';
10
+ import { RATE_LIMITER_NEST_OPTIONS_TOKEN, RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN, RATE_LIMITER_TOKEN, } from './tokens.js';
11
+ import { GlobalRateLimitGuard } from './global-rate-limit.guard.js';
12
+ import { RateLimitService } from './rate-limit.service.js';
13
+ import { RateLimitGuard } from './rate-limit.guard.js';
14
+ const RATE_LIMITER_NEST_FEATURE_OPTIONS_TOKEN = Symbol('RATE_LIMITER_NEST_FEATURE_OPTIONS_TOKEN');
15
+ let RateLimiterModule = RateLimiterModule_1 = class RateLimiterModule {
16
+ static forRoot(options) {
17
+ validateRootOptions(options);
18
+ const providers = [
19
+ {
20
+ provide: RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
21
+ useValue: options,
22
+ },
23
+ {
24
+ provide: RATE_LIMITER_NEST_OPTIONS_TOKEN,
25
+ useExisting: RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
26
+ },
27
+ {
28
+ provide: RATE_LIMITER_TOKEN,
29
+ useValue: options.rateLimiter,
30
+ },
31
+ RateLimitService,
32
+ RateLimitGuard,
33
+ GlobalRateLimitGuard,
34
+ {
35
+ provide: APP_GUARD,
36
+ useExisting: GlobalRateLimitGuard,
37
+ },
38
+ ];
39
+ return {
40
+ module: RateLimiterModule_1,
41
+ global: true,
42
+ providers,
43
+ exports: [
44
+ RATE_LIMITER_TOKEN,
45
+ RATE_LIMITER_NEST_OPTIONS_TOKEN,
46
+ RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
47
+ RateLimitService,
48
+ RateLimitGuard,
49
+ GlobalRateLimitGuard,
50
+ ],
51
+ };
52
+ }
53
+ static forRootAsync(options) {
54
+ const rootOptionsProvider = {
55
+ provide: RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
56
+ useFactory: async (...args) => {
57
+ const resolved = await options.useFactory(...args);
58
+ validateRootOptions(resolved);
59
+ return resolved;
60
+ },
61
+ inject: [...(options.inject ?? [])],
62
+ };
63
+ const optionsAliasProvider = {
64
+ provide: RATE_LIMITER_NEST_OPTIONS_TOKEN,
65
+ useExisting: RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
66
+ };
67
+ const rateLimiterProvider = {
68
+ provide: RATE_LIMITER_TOKEN,
69
+ inject: [RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN],
70
+ useFactory: (resolved) => resolved.rateLimiter,
71
+ };
72
+ return {
73
+ module: RateLimiterModule_1,
74
+ global: true,
75
+ imports: options.imports,
76
+ providers: [
77
+ rootOptionsProvider,
78
+ optionsAliasProvider,
79
+ rateLimiterProvider,
80
+ RateLimitService,
81
+ RateLimitGuard,
82
+ GlobalRateLimitGuard,
83
+ {
84
+ provide: APP_GUARD,
85
+ useExisting: GlobalRateLimitGuard,
86
+ },
87
+ ],
88
+ exports: [
89
+ RATE_LIMITER_TOKEN,
90
+ RATE_LIMITER_NEST_OPTIONS_TOKEN,
91
+ RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN,
92
+ RateLimitService,
93
+ RateLimitGuard,
94
+ GlobalRateLimitGuard,
95
+ ],
96
+ };
97
+ }
98
+ static forFeature(options) {
99
+ validateFeatureOptions(options);
100
+ const providers = [
101
+ {
102
+ provide: RATE_LIMITER_NEST_FEATURE_OPTIONS_TOKEN,
103
+ useValue: options,
104
+ },
105
+ {
106
+ provide: RATE_LIMITER_NEST_OPTIONS_TOKEN,
107
+ inject: [RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN, RATE_LIMITER_NEST_FEATURE_OPTIONS_TOKEN],
108
+ useFactory: (rootOptions, featureOptions) => mergeFeatureOptions(rootOptions, featureOptions),
109
+ },
110
+ RateLimitService,
111
+ RateLimitGuard,
112
+ GlobalRateLimitGuard,
113
+ ];
114
+ return {
115
+ module: RateLimiterModule_1,
116
+ providers,
117
+ exports: [
118
+ RATE_LIMITER_NEST_OPTIONS_TOKEN,
119
+ RateLimitService,
120
+ RateLimitGuard,
121
+ GlobalRateLimitGuard,
122
+ ],
123
+ };
124
+ }
125
+ };
126
+ RateLimiterModule = RateLimiterModule_1 = __decorate([
127
+ Module({})
128
+ ], RateLimiterModule);
129
+ export { RateLimiterModule };
130
+ function validateRootOptions(options) {
131
+ validateProfiles(options.profiles, 'profiles');
132
+ validateGlobalRoutes(options);
133
+ }
134
+ function validateFeatureOptions(options) {
135
+ validateProfiles(options.profiles, 'feature profiles');
136
+ }
137
+ function validateProfiles(profileMap, sourceName) {
138
+ const profileNames = Object.keys(profileMap);
139
+ if (profileNames.length === 0) {
140
+ throw new TypeError(`${sourceName} must include at least one profile`);
141
+ }
142
+ for (const profileName of profileNames) {
143
+ if (!profileName.trim()) {
144
+ throw new TypeError(`${sourceName} contains an invalid empty profile name`);
145
+ }
146
+ }
147
+ }
148
+ function mergeFeatureOptions(rootOptions, featureOptions) {
149
+ return {
150
+ ...rootOptions,
151
+ profiles: {
152
+ ...rootOptions.profiles,
153
+ ...featureOptions.profiles,
154
+ },
155
+ };
156
+ }
157
+ function validateGlobalRoutes(options) {
158
+ const routes = options.global?.routes;
159
+ if (!routes || routes.length === 0) {
160
+ return;
161
+ }
162
+ for (const route of routes) {
163
+ validateGlobalRoute(route, options.profiles);
164
+ }
165
+ }
166
+ function validateGlobalRoute(route, profiles) {
167
+ const profileName = route.profile.trim();
168
+ if (!profileName) {
169
+ throw new TypeError('global route profile must not be empty');
170
+ }
171
+ if (!profiles[profileName]) {
172
+ throw new TypeError(`global route profile not found: ${profileName}`);
173
+ }
174
+ const path = route.path.trim();
175
+ if (!path) {
176
+ throw new TypeError('global route path must not be empty');
177
+ }
178
+ const methods = route.methods;
179
+ if (!methods) {
180
+ return;
181
+ }
182
+ for (const method of methods) {
183
+ if (!method.trim()) {
184
+ throw new TypeError(`global route has an invalid method for path: ${path}`);
185
+ }
186
+ }
187
+ }
188
+ //# sourceMappingURL=rate-limiter.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.module.js","sourceRoot":"","sources":["../src/rate-limiter.module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const RATE_LIMITER_TOKEN: unique symbol;
2
+ export declare const RATE_LIMITER_NEST_OPTIONS_TOKEN: unique symbol;
3
+ export declare const RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN: unique symbol;
4
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,eAA+B,CAAA;AAC9D,eAAO,MAAM,+BAA+B,eAA4C,CAAA;AACxF,eAAO,MAAM,oCAAoC,eAAiD,CAAA"}
package/dist/tokens.js ADDED
@@ -0,0 +1,4 @@
1
+ export const RATE_LIMITER_TOKEN = Symbol('RATE_LIMITER_TOKEN');
2
+ export const RATE_LIMITER_NEST_OPTIONS_TOKEN = Symbol('RATE_LIMITER_NEST_OPTIONS_TOKEN');
3
+ export const RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN = Symbol('RATE_LIMITER_NEST_ROOT_OPTIONS_TOKEN');
4
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAA;AAC9D,MAAM,CAAC,MAAM,+BAA+B,GAAG,MAAM,CAAC,iCAAiC,CAAC,CAAA;AACxF,MAAM,CAAC,MAAM,oCAAoC,GAAG,MAAM,CAAC,sCAAsC,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ import type { ExecutionContext, InjectionToken, ModuleMetadata } from '@nestjs/common';
2
+ import type { RateLimiter, RateLimiterTakeInput } from '@thangnv-dev/rate-limiter-node';
3
+ export type RateLimitPolicy = Pick<RateLimiterTakeInput, 'capacity' | 'refillTokens' | 'refillInterval' | 'tokens'>;
4
+ export type RateLimitBucketKeyFactory = (context: ExecutionContext) => string;
5
+ export type RateLimitProfile = RateLimitPolicy & {
6
+ readonly bucketKeyFactory?: RateLimitBucketKeyFactory;
7
+ };
8
+ export type RateLimitHttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | '*';
9
+ export interface RateLimitGlobalRouteConfig {
10
+ readonly path: string;
11
+ readonly profile: string;
12
+ readonly methods?: readonly RateLimitHttpMethod[];
13
+ }
14
+ export interface RateLimitGlobalConfig {
15
+ readonly routes: readonly RateLimitGlobalRouteConfig[];
16
+ }
17
+ export interface RateLimiterNestModuleOptions {
18
+ readonly rateLimiter: RateLimiter;
19
+ readonly profiles: Record<string, RateLimitProfile>;
20
+ readonly bucketKeyFactory?: RateLimitBucketKeyFactory;
21
+ readonly global?: RateLimitGlobalConfig;
22
+ }
23
+ export interface RateLimiterNestAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
24
+ readonly inject?: InjectionToken[];
25
+ readonly useFactory: (...args: unknown[]) => Promise<RateLimiterNestModuleOptions> | RateLimiterNestModuleOptions;
26
+ }
27
+ export interface RateLimiterNestFeatureOptions {
28
+ readonly profiles: Record<string, RateLimitProfile>;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAA;AAEvF,MAAM,MAAM,eAAe,GAAG,IAAI,CAChC,oBAAoB,EACpB,UAAU,GAAG,cAAc,GAAG,gBAAgB,GAAG,QAAQ,CAC1D,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAA;AAE7E,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG;IAC/C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,yBAAyB,CAAA;CACtD,CAAA;AAED,MAAM,MAAM,mBAAmB,GAC3B,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,MAAM,GACN,SAAS,GACT,GAAG,CAAA;AAEP,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAA;CAClD;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,0BAA0B,EAAE,CAAA;CACvD;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,yBAAyB,CAAA;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAA;CACxC;AAED,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IAClF,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,4BAA4B,CAAC,GAAG,4BAA4B,CAAA;CAClH;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;CACpD"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@thangnv-dev/rate-limiter-nest",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc -p tsconfig.build.json",
22
+ "lint": "eslint .",
23
+ "typecheck": "tsc --noEmit",
24
+ "test": "vitest run"
25
+ },
26
+ "dependencies": {
27
+ "@thangnv-dev/rate-limiter-node": "workspace:^"
28
+ },
29
+ "devDependencies": {
30
+ "@nestjs/common": "^11.1.14",
31
+ "@nestjs/core": "^11.1.14",
32
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
33
+ "@typescript-eslint/parser": "^8.56.0",
34
+ "eslint": "^10.0.0",
35
+ "reflect-metadata": "^0.2.2",
36
+ "rxjs": "^7.8.2",
37
+ "temporal-polyfill": "^0.3.0",
38
+ "typescript": "^5.9.3",
39
+ "vitest": "^4.0.18"
40
+ },
41
+ "peerDependencies": {
42
+ "@nestjs/common": "^11.0.0",
43
+ "@nestjs/core": "^11.0.0",
44
+ "reflect-metadata": "^0.2.0",
45
+ "rxjs": "^7.8.0",
46
+ "temporal-polyfill": "*"
47
+ }
48
+ }