@edirect/rate-limit-module 0.1.2

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 (96) hide show
  1. package/README.md +102 -0
  2. package/dist/src/decorators/rate-limiting-rule.decorator.d.ts +8 -0
  3. package/dist/src/decorators/rate-limiting-rule.decorator.js +8 -0
  4. package/dist/src/decorators/rate-limiting-rule.decorator.js.map +1 -0
  5. package/dist/src/guards/rate-limiting.guard.d.ts +11 -0
  6. package/dist/src/guards/rate-limiting.guard.js +105 -0
  7. package/dist/src/guards/rate-limiting.guard.js.map +1 -0
  8. package/dist/src/index.d.ts +8 -0
  9. package/dist/src/index.js +26 -0
  10. package/dist/src/index.js.map +1 -0
  11. package/dist/src/main.d.ts +1 -0
  12. package/dist/src/main.js +10 -0
  13. package/dist/src/main.js.map +1 -0
  14. package/dist/src/object.utils.d.ts +2 -0
  15. package/dist/src/object.utils.js +37 -0
  16. package/dist/src/object.utils.js.map +1 -0
  17. package/dist/src/rate-limiting.module.d.ts +2 -0
  18. package/dist/src/rate-limiting.module.js +39 -0
  19. package/dist/src/rate-limiting.module.js.map +1 -0
  20. package/dist/src/rules/dto/pagination.dto.d.ts +5 -0
  21. package/dist/src/rules/dto/pagination.dto.js +51 -0
  22. package/dist/src/rules/dto/pagination.dto.js.map +1 -0
  23. package/dist/src/rules/dto/rule.dto.d.ts +21 -0
  24. package/dist/src/rules/dto/rule.dto.js +185 -0
  25. package/dist/src/rules/dto/rule.dto.js.map +1 -0
  26. package/dist/src/rules/interface/pagination.interface.d.ts +6 -0
  27. package/dist/src/rules/interface/pagination.interface.js +3 -0
  28. package/dist/src/rules/interface/pagination.interface.js.map +1 -0
  29. package/dist/src/rules/interface/rule.interface.d.ts +26 -0
  30. package/dist/src/rules/interface/rule.interface.js +3 -0
  31. package/dist/src/rules/interface/rule.interface.js.map +1 -0
  32. package/dist/src/rules/rule.controller.d.ts +13 -0
  33. package/dist/src/rules/rule.controller.js +99 -0
  34. package/dist/src/rules/rule.controller.js.map +1 -0
  35. package/dist/src/rules/rule.module.d.ts +4 -0
  36. package/dist/src/rules/rule.module.js +44 -0
  37. package/dist/src/rules/rule.module.js.map +1 -0
  38. package/dist/src/rules/rule.repository.d.ts +14 -0
  39. package/dist/src/rules/rule.repository.js +90 -0
  40. package/dist/src/rules/rule.repository.js.map +1 -0
  41. package/dist/src/rules/rule.schema.d.ts +28 -0
  42. package/dist/src/rules/rule.schema.js +149 -0
  43. package/dist/src/rules/rule.schema.js.map +1 -0
  44. package/dist/src/rules/rule.service.d.ts +24 -0
  45. package/dist/src/rules/rule.service.js +205 -0
  46. package/dist/src/rules/rule.service.js.map +1 -0
  47. package/dist/src/shared/cache/cache.service.d.ts +9 -0
  48. package/dist/src/shared/cache/cache.service.js +38 -0
  49. package/dist/src/shared/cache/cache.service.js.map +1 -0
  50. package/dist/src/shared/redis/redis.module.d.ts +2 -0
  51. package/dist/src/shared/redis/redis.module.js +38 -0
  52. package/dist/src/shared/redis/redis.module.js.map +1 -0
  53. package/dist/src/shared/redis/redis.service.d.ts +12 -0
  54. package/dist/src/shared/redis/redis.service.js +65 -0
  55. package/dist/src/shared/redis/redis.service.js.map +1 -0
  56. package/dist/src/shared/rule-engine/interface/rule-engine.interface.d.ts +11 -0
  57. package/dist/src/shared/rule-engine/interface/rule-engine.interface.js +3 -0
  58. package/dist/src/shared/rule-engine/interface/rule-engine.interface.js.map +1 -0
  59. package/dist/src/shared/rule-engine/rule-engine.module.d.ts +9 -0
  60. package/dist/src/shared/rule-engine/rule-engine.module.js +70 -0
  61. package/dist/src/shared/rule-engine/rule-engine.module.js.map +1 -0
  62. package/dist/src/shared/rule-engine/rule-engine.service.d.ts +13 -0
  63. package/dist/src/shared/rule-engine/rule-engine.service.js +87 -0
  64. package/dist/src/shared/rule-engine/rule-engine.service.js.map +1 -0
  65. package/dist/src/shared/shared.module.d.ts +2 -0
  66. package/dist/src/shared/shared.module.js +35 -0
  67. package/dist/src/shared/shared.module.js.map +1 -0
  68. package/dist/src/validators/rule.constraint.d.ts +9 -0
  69. package/dist/src/validators/rule.constraint.js +52 -0
  70. package/dist/src/validators/rule.constraint.js.map +1 -0
  71. package/dist/src/validators/rule.validator.d.ts +2 -0
  72. package/dist/src/validators/rule.validator.js +17 -0
  73. package/dist/src/validators/rule.validator.js.map +1 -0
  74. package/dist/test/guards/rate-limiting.guard.spec.d.ts +1 -0
  75. package/dist/test/guards/rate-limiting.guard.spec.js +93 -0
  76. package/dist/test/guards/rate-limiting.guard.spec.js.map +1 -0
  77. package/dist/test/mocks/rate-limiting-module.mocks.d.ts +2 -0
  78. package/dist/test/mocks/rate-limiting-module.mocks.js +60 -0
  79. package/dist/test/mocks/rate-limiting-module.mocks.js.map +1 -0
  80. package/dist/test/mocks/rule-engine.mocks.d.ts +7 -0
  81. package/dist/test/mocks/rule-engine.mocks.js +11 -0
  82. package/dist/test/mocks/rule-engine.mocks.js.map +1 -0
  83. package/dist/test/mocks/rule.mocks.d.ts +34 -0
  84. package/dist/test/mocks/rule.mocks.js +79 -0
  85. package/dist/test/mocks/rule.mocks.js.map +1 -0
  86. package/dist/test/mocks/shared-module.mocks.d.ts +10 -0
  87. package/dist/test/mocks/shared-module.mocks.js +32 -0
  88. package/dist/test/mocks/shared-module.mocks.js.map +1 -0
  89. package/dist/test/mocks/shared.mocks.d.ts +19 -0
  90. package/dist/test/mocks/shared.mocks.js +29 -0
  91. package/dist/test/mocks/shared.mocks.js.map +1 -0
  92. package/dist/test/rules/rules.service.spec.d.ts +1 -0
  93. package/dist/test/rules/rules.service.spec.js +115 -0
  94. package/dist/test/rules/rules.service.spec.js.map +1 -0
  95. package/dist/tsconfig.tsbuildinfo +1 -0
  96. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # 📈 Rate Limiting Module
2
+
3
+ This module provides a flexible **rate-limiting system** where access to operations can be restricted based on dynamic **rule expressions** such as `count_quote > 1`. If the condition evaluates to `true`, access is **blocked**.
4
+
5
+ ## ✨ Features
6
+
7
+ - Define rate-limiting rules with custom expressions.
8
+ - Dynamically inject context-aware functions for rule evaluation.
9
+ - Easily integrate with any resource via a decorator.
10
+ - Built with extensibility and modularity in mind.
11
+
12
+ ## 🧱 How It Works
13
+
14
+ 1. You define a rule using a simple expression (e.g., `count_quote > 1`).
15
+ 2. The rule is evaluated in runtime using data injected from the request context.
16
+ 3. If the expression is true, the action is blocked.
17
+
18
+ ## 🧩 Usage
19
+
20
+ ### 1. Install the Module
21
+
22
+ ```ts
23
+ @Module({
24
+ imports: [
25
+ RateLimitingModule,
26
+ RuleEngineModule.forFeatureAsync({
27
+ useFactory: async (quoteService: QuoteService) => {
28
+ return await quoteService.countQuote();
29
+ },
30
+ inject: [QuoteService],
31
+ }),
32
+ ],
33
+ })
34
+ export class YourFeatureModule {}
35
+ ```
36
+
37
+ ## 2. Decorate Your Handlers
38
+
39
+ Use the `@RateLimitingRuleMetadata` decorator to attach metadata used during rule evaluation.
40
+
41
+ ```ts
42
+ import { RateLimitingRuleMetadata } from 'path-to-rate-limiting-module';
43
+
44
+ @RateLimitingRuleMetadata({
45
+ action: 'create_quote',
46
+ partnerPath: 'partner.partnerId',
47
+ providerPath: 'provider',
48
+ productTypePath: 'productType',
49
+ })
50
+ @Post('quotes')
51
+ createQuote(@Body() body: CreateQuoteDto) {
52
+ return this.quoteService.create(body);
53
+ }
54
+ ```
55
+
56
+ * `action`: Name of the action to be controlled.
57
+ * `partnerPath`: Path to extract the partner ID from the request context.
58
+ * `providerPath`: Path to extract the provider.
59
+ * `productTypePath`: Path to extract the product type.
60
+
61
+ ## 🛠 Rule Engine Integration
62
+
63
+ This module depends on an underlying rule engine to evaluate expressions. You must provide the functions used in expressions through:
64
+
65
+ ```ts
66
+ RuleEngineModule.forFeatureAsync({
67
+ useFactory: async (useCase: RateLimitingInjectFunctionsUseCase) => {
68
+ return await useCase.getFunctions();
69
+ // returns an object like { count_quote: async () => number }
70
+ },
71
+ inject: [RateLimitingInjectFunctionsUseCase],
72
+ });
73
+ ```
74
+
75
+ ## 🧪 Example Rule
76
+
77
+ A rule stored in your system might look like:
78
+
79
+ ```json
80
+ {
81
+ "expression": "count_quote > 1",
82
+ "action": "create_quote"
83
+ }
84
+ ```
85
+
86
+ If the expression returns `true`, the rate limiter will block further `create_quote` actions for the user based on the context values.
87
+
88
+ ## 🧰 Requirements
89
+
90
+ * NestJS
91
+ * RuleEngineModule (compatible expression parser/executor)
92
+ * Custom service to inject context functions (like `RateLimitingInjectFunctionsUseCase`)
93
+
94
+ ## 📎 Notes
95
+
96
+ * Rules should be defined and stored externally (e.g., DB, config).
97
+ * The context extractor paths must match the structure of your handler inputs (e.g., body, params).
98
+ * Ensure `getFunctions()` returns **async functions** that provide the required values for the expression.
99
+
100
+ ## 🧾 License
101
+
102
+ MIT
@@ -0,0 +1,8 @@
1
+ export declare const RULE_METADATA = "RATE_LIMITING_RULE_METADATA";
2
+ export interface RateLimitingRuleMetadataOptions {
3
+ action: string;
4
+ partnerPath: string;
5
+ providerPath: string;
6
+ productTypePath: string;
7
+ }
8
+ export declare const RateLimitingRuleMetadata: (options: RateLimitingRuleMetadataOptions) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RateLimitingRuleMetadata = exports.RULE_METADATA = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ exports.RULE_METADATA = 'RATE_LIMITING_RULE_METADATA';
6
+ const RateLimitingRuleMetadata = (options) => (0, common_1.SetMetadata)(exports.RULE_METADATA, options);
7
+ exports.RateLimitingRuleMetadata = RateLimitingRuleMetadata;
8
+ //# sourceMappingURL=rate-limiting-rule.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiting-rule.decorator.js","sourceRoot":"","sources":["../../../src/decorators/rate-limiting-rule.decorator.ts"],"names":[],"mappings":";;;AAAA,2CAA6C;AAEhC,QAAA,aAAa,GAAG,6BAA6B,CAAC;AASpD,MAAM,wBAAwB,GAAG,CACtC,OAAwC,EACxC,EAAE,CAAC,IAAA,oBAAW,EAAC,qBAAa,EAAE,OAAO,CAAC,CAAC;AAF5B,QAAA,wBAAwB,4BAEI"}
@@ -0,0 +1,11 @@
1
+ import { CanActivate, ExecutionContext } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { RuleService } from '../rules/rule.service';
4
+ import { RuleEngineService } from '../shared/rule-engine/rule-engine.service';
5
+ export declare class RateLimitingRuleGuard implements CanActivate {
6
+ private readonly reflector;
7
+ private readonly ruleService;
8
+ private readonly ruleEngine;
9
+ constructor(reflector: Reflector, ruleService: RuleService, ruleEngine: RuleEngineService);
10
+ canActivate(context: ExecutionContext): Promise<boolean>;
11
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RateLimitingRuleGuard = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const core_1 = require("@nestjs/core");
18
+ const rate_limiting_rule_decorator_1 = require("../decorators/rate-limiting-rule.decorator");
19
+ const object_utils_1 = require("../object.utils");
20
+ const rule_service_1 = require("../rules/rule.service");
21
+ const rule_engine_service_1 = require("../shared/rule-engine/rule-engine.service");
22
+ let RateLimitingRuleGuard = class RateLimitingRuleGuard {
23
+ reflector;
24
+ ruleService;
25
+ ruleEngine;
26
+ constructor(reflector, ruleService, ruleEngine) {
27
+ this.reflector = reflector;
28
+ this.ruleService = ruleService;
29
+ this.ruleEngine = ruleEngine;
30
+ }
31
+ async canActivate(context) {
32
+ try {
33
+ const handler = context.getHandler();
34
+ const ruleMetaData = this.reflector.get(rate_limiting_rule_decorator_1.RULE_METADATA, handler);
35
+ if (!ruleMetaData)
36
+ return true;
37
+ const req = context.switchToHttp().getRequest();
38
+ const entity = req.body;
39
+ const { action, partnerPath, providerPath, productTypePath } = ruleMetaData;
40
+ const partner = getValueFromPathOrRoot(entity, partnerPath);
41
+ if (!partner)
42
+ return true;
43
+ const provider = getValueFromPathOrRoot(entity, providerPath);
44
+ const productType = getValueFromPathOrRoot(entity, productTypePath);
45
+ const parameters = {
46
+ enabled: 'true',
47
+ partner: partner,
48
+ provider: provider,
49
+ targetAction: action,
50
+ productType,
51
+ page: 1,
52
+ limit: 10
53
+ };
54
+ const rules = await this.ruleService.findAllWithoutPagination(parameters);
55
+ if (!rules || !rules.length)
56
+ return true;
57
+ for (const rule of rules) {
58
+ const contextVars = {
59
+ ...entity,
60
+ ...rule.variables,
61
+ };
62
+ const invalidExpressionMessage = this.ruleService.validateRuleExpression(rule.expression);
63
+ if (invalidExpressionMessage && invalidExpressionMessage.length) {
64
+ throw new common_1.ForbiddenException(invalidExpressionMessage);
65
+ }
66
+ const invalidFunctions = this.ruleEngine.validateFunctionsAreValid(rule.expression);
67
+ if (invalidFunctions && invalidFunctions.length) {
68
+ throw new common_1.ForbiddenException(`these functions are not allowed ${invalidFunctions.join(', ')}`);
69
+ }
70
+ if (rule.variablesRequired) {
71
+ const missingVars = await this.ruleEngine.validateExpressionVariables(rule.expression, contextVars);
72
+ if (missingVars && missingVars.length) {
73
+ throw new common_1.ForbiddenException(`For rate limiting validation these variables are required ${JSON.stringify(missingVars)}`);
74
+ }
75
+ }
76
+ const safeContextVars = (0, object_utils_1.withDefaultNull)(contextVars);
77
+ const notAllowed = await this.ruleEngine.evaluate(rule.expression, safeContextVars);
78
+ if (notAllowed)
79
+ throw new common_1.ForbiddenException(rule.errorMessage || `Rate Limiting rule reached limit`);
80
+ }
81
+ return true;
82
+ }
83
+ catch (err) {
84
+ return false;
85
+ }
86
+ }
87
+ };
88
+ exports.RateLimitingRuleGuard = RateLimitingRuleGuard;
89
+ exports.RateLimitingRuleGuard = RateLimitingRuleGuard = __decorate([
90
+ (0, common_1.Injectable)(),
91
+ __param(2, (0, common_1.Inject)('RULE_ENGINE_INSTANCE')),
92
+ __metadata("design:paramtypes", [core_1.Reflector,
93
+ rule_service_1.RuleService,
94
+ rule_engine_service_1.RuleEngineService])
95
+ ], RateLimitingRuleGuard);
96
+ function getValueFromPathOrRoot(obj, path) {
97
+ const valueFromPath = path
98
+ .split('.')
99
+ .reduce((acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);
100
+ if (valueFromPath !== undefined) {
101
+ return valueFromPath;
102
+ }
103
+ return obj?.[path];
104
+ }
105
+ //# sourceMappingURL=rate-limiting.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiting.guard.js","sourceRoot":"","sources":["../../../src/guards/rate-limiting.guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export * from '../test/mocks/rate-limiting-module.mocks';
2
+ export * from '../test/mocks/rule-engine.mocks';
3
+ export * from './decorators/rate-limiting-rule.decorator';
4
+ export * from './guards/rate-limiting.guard';
5
+ export * from './rate-limiting.module';
6
+ export * from './shared/rule-engine/rule-engine.module';
7
+ export declare const RULE_ENGINE_INSTANCE = "RULE_ENGINE_INSTANCE";
8
+ export declare const CUSTOM_RULE_FUNCTIONS = "CUSTOM_RULE_FUNCTIONS";
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.CUSTOM_RULE_FUNCTIONS = exports.RULE_ENGINE_INSTANCE = void 0;
18
+ __exportStar(require("../test/mocks/rate-limiting-module.mocks"), exports);
19
+ __exportStar(require("../test/mocks/rule-engine.mocks"), exports);
20
+ __exportStar(require("./decorators/rate-limiting-rule.decorator"), exports);
21
+ __exportStar(require("./guards/rate-limiting.guard"), exports);
22
+ __exportStar(require("./rate-limiting.module"), exports);
23
+ __exportStar(require("./shared/rule-engine/rule-engine.module"), exports);
24
+ exports.RULE_ENGINE_INSTANCE = 'RULE_ENGINE_INSTANCE';
25
+ exports.CUSTOM_RULE_FUNCTIONS = 'CUSTOM_RULE_FUNCTIONS';
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2EAAyD;AACzD,kEAAgD;AAChD,4EAA0D;AAC1D,+DAA6C;AAC7C,yDAAuC;AACvC,0EAAwD;AAE3C,QAAA,oBAAoB,GAAG,sBAAsB,CAAC;AAC9C,QAAA,qBAAqB,GAAG,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@nestjs/core");
4
+ const rate_limiting_module_1 = require("./rate-limiting.module");
5
+ async function bootstrap() {
6
+ const app = await core_1.NestFactory.create(rate_limiting_module_1.RateLimitingModule);
7
+ await app.listen(process.env.PORT ?? 3040);
8
+ }
9
+ bootstrap();
10
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,iEAA4D;AAE5D,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,yCAAkB,CAAC,CAAC;IACzD,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAC7C,CAAC;AACD,SAAS,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const withDefaultNull: <T extends object>(context: T) => T;
2
+ export declare const calculateDepth: (expression: string) => number;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateDepth = exports.withDefaultNull = void 0;
4
+ const withDefaultNull = (context) => {
5
+ return new Proxy(context, {
6
+ get(target, prop, receiver) {
7
+ const value = Reflect.get(target, prop, receiver);
8
+ if (value === undefined) {
9
+ return null;
10
+ }
11
+ if (value !== null &&
12
+ typeof value === 'object' &&
13
+ !Array.isArray(value) &&
14
+ value.constructor === Object) {
15
+ return (0, exports.withDefaultNull)(value);
16
+ }
17
+ return value;
18
+ },
19
+ });
20
+ };
21
+ exports.withDefaultNull = withDefaultNull;
22
+ const calculateDepth = (expression) => {
23
+ let depth = 0;
24
+ let maxDepth = 0;
25
+ for (const char of expression) {
26
+ if (char === '(') {
27
+ depth++;
28
+ maxDepth = Math.max(maxDepth, depth);
29
+ }
30
+ else if (char === ')') {
31
+ depth--;
32
+ }
33
+ }
34
+ return maxDepth;
35
+ };
36
+ exports.calculateDepth = calculateDepth;
37
+ //# sourceMappingURL=object.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object.utils.js","sourceRoot":"","sources":["../../src/object.utils.ts"],"names":[],"mappings":";;;AAAO,MAAM,eAAe,GAAG,CAAmB,OAAU,EAAK,EAAE;IACjE,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;QACxB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACxB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAElD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IACE,KAAK,KAAK,IAAI;gBACd,OAAO,KAAK,KAAK,QAAQ;gBACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBACrB,KAAK,CAAC,WAAW,KAAK,MAAM,EAC5B,CAAC;gBACD,OAAO,IAAA,uBAAe,EAAC,KAAK,CAAC,CAAC;YAChC,CAAC;YAED,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAM,CAAC;AACV,CAAC,CAAC;AArBW,QAAA,eAAe,mBAqB1B;AAEK,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAU,EAAE;IAC3D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACjB,KAAK,EAAE,CAAC;YACR,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;YACxB,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAdW,QAAA,cAAc,kBAczB"}
@@ -0,0 +1,2 @@
1
+ export declare class RateLimitingModule {
2
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RateLimitingModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const config_1 = require("@nestjs/config");
12
+ const mongoose_1 = require("@nestjs/mongoose");
13
+ const rule_module_1 = require("./rules/rule.module");
14
+ const rule_constraint_1 = require("./validators/rule.constraint");
15
+ let RateLimitingModule = class RateLimitingModule {
16
+ };
17
+ exports.RateLimitingModule = RateLimitingModule;
18
+ exports.RateLimitingModule = RateLimitingModule = __decorate([
19
+ (0, common_1.Module)({
20
+ imports: [
21
+ rule_module_1.RuleModule,
22
+ config_1.ConfigModule.forRoot({
23
+ isGlobal: true,
24
+ }),
25
+ mongoose_1.MongooseModule.forRootAsync({
26
+ imports: [config_1.ConfigModule],
27
+ useFactory: async (config) => ({
28
+ uri: config.get('MONGO_URL'),
29
+ }),
30
+ inject: [config_1.ConfigService],
31
+ }),
32
+ ],
33
+ providers: [rule_constraint_1.IsValidExpressionConstraint],
34
+ exports: [
35
+ rule_module_1.RuleModule,
36
+ ]
37
+ })
38
+ ], RateLimitingModule);
39
+ //# sourceMappingURL=rate-limiting.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiting.module.js","sourceRoot":"","sources":["../../src/rate-limiting.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,2CAA6D;AAC7D,+CAAkD;AAClD,qDAAiD;AACjD,kEAA2E;AAqBpE,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;CAAG,CAAA;AAArB,gDAAkB;6BAAlB,kBAAkB;IAnB9B,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,wBAAU;YACV,qBAAY,CAAC,OAAO,CAAC;gBACnB,QAAQ,EAAE,IAAI;aACf,CAAC;YACF,yBAAc,CAAC,YAAY,CAAC;gBAC1B,OAAO,EAAE,CAAC,qBAAY,CAAC;gBACvB,UAAU,EAAE,KAAK,EAAE,MAAqB,EAAE,EAAE,CAAC,CAAC;oBAC5C,GAAG,EAAE,MAAM,CAAC,GAAG,CAAS,WAAW,CAAC;iBACrC,CAAC;gBACF,MAAM,EAAE,CAAC,sBAAa,CAAC;aACxB,CAAC;SACH;QACD,SAAS,EAAE,CAAC,6CAA2B,CAAC;QACxC,OAAO,EAAE;YACP,wBAAU;SACX;KACF,CAAC;GACW,kBAAkB,CAAG"}
@@ -0,0 +1,5 @@
1
+ export declare class PaginationDTO {
2
+ page: number;
3
+ order?: number | undefined;
4
+ limit: number;
5
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PaginationDTO = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const swagger_1 = require("@nestjs/swagger");
15
+ const class_transformer_1 = require("class-transformer");
16
+ const class_validator_1 = require("class-validator");
17
+ class PaginationDTO {
18
+ page = 1;
19
+ order = -1;
20
+ limit = 10;
21
+ }
22
+ exports.PaginationDTO = PaginationDTO;
23
+ __decorate([
24
+ (0, swagger_1.ApiProperty)({ type: Number, required: false }),
25
+ (0, class_validator_1.IsNotEmpty)(),
26
+ (0, class_validator_1.IsInt)(),
27
+ (0, class_validator_1.IsOptional)(),
28
+ (0, class_transformer_1.Transform)(({ value }) => {
29
+ const parsed = Number.parseInt(value);
30
+ if (parsed === 0)
31
+ throw new common_1.BadRequestException('Page needs to be bigger than 0');
32
+ return parsed;
33
+ }),
34
+ __metadata("design:type", Object)
35
+ ], PaginationDTO.prototype, "page", void 0);
36
+ __decorate([
37
+ (0, swagger_1.ApiProperty)({
38
+ type: Number,
39
+ required: false,
40
+ default: -1,
41
+ description: 'You can add more than one field by using trailing commas ex: 1,-1',
42
+ }),
43
+ (0, class_validator_1.IsOptional)(),
44
+ __metadata("design:type", Object)
45
+ ], PaginationDTO.prototype, "order", void 0);
46
+ __decorate([
47
+ (0, swagger_1.ApiProperty)({ type: Number, required: false, default: 10 }),
48
+ (0, class_validator_1.IsOptional)(),
49
+ __metadata("design:type", Object)
50
+ ], PaginationDTO.prototype, "limit", void 0);
51
+ //# sourceMappingURL=pagination.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.dto.js","sourceRoot":"","sources":["../../../../src/rules/dto/pagination.dto.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAqD;AACrD,6CAA8C;AAC9C,yDAA8C;AAC9C,qDAAgE;AAEhE,MAAa,aAAa;IAWxB,IAAI,GAAG,CAAC,CAAC;IAUT,KAAK,GAAI,CAAC,CAAC,CAAC;IAIZ,KAAK,GAAG,EAAE,CAAC;CACZ;AA1BD,sCA0BC;AAfC;IAVC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC9C,IAAA,4BAAU,GAAE;IACZ,IAAA,uBAAK,GAAE;IACP,IAAA,4BAAU,GAAE;IACZ,IAAA,6BAAS,EAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,CAAC;YACd,MAAM,IAAI,4BAAmB,CAAC,gCAAgC,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;;2CACO;AAUT;IARC,IAAA,qBAAW,EAAC;QACX,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,CAAC,CAAC;QACX,WAAW,EACT,mEAAmE;KACtE,CAAC;IACD,IAAA,4BAAU,GAAE;;4CACD;AAIZ;IAFC,IAAA,qBAAW,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC3D,IAAA,4BAAU,GAAE;;4CACF"}
@@ -0,0 +1,21 @@
1
+ import { IFindRule, IRule } from "../interface/rule.interface";
2
+ import { PaginationDTO } from "./pagination.dto";
3
+ export declare class CreateRuleDTO implements IRule {
4
+ name: string;
5
+ expression: string;
6
+ targetAction: string;
7
+ errorMessage?: string;
8
+ variables?: Record<string, string>;
9
+ variablesRequired?: boolean;
10
+ productType?: string;
11
+ partner?: string;
12
+ provider?: string;
13
+ }
14
+ export declare class FindRuleDTO extends PaginationDTO implements IFindRule {
15
+ name?: string;
16
+ targetAction?: string;
17
+ partner?: string;
18
+ productType?: string;
19
+ isEnabled?: boolean;
20
+ provider?: string;
21
+ }