@edirect/rate-limit-module 2.0.10 โ 11.0.41
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.
- package/README.md +88 -172
- package/dist/README.md +499 -0
- package/dist/package.json +41 -0
- package/dist/src/decorators/rate-limiting-rule.decorator.d.ts +1 -0
- package/dist/src/decorators/rate-limiting-rule.decorator.d.ts.map +1 -0
- package/dist/src/decorators/rate-limiting-rule.decorator.js +0 -1
- package/dist/src/guards/rate-limiting.guard.d.ts +1 -0
- package/dist/src/guards/rate-limiting.guard.d.ts.map +1 -0
- package/dist/src/guards/rate-limiting.guard.js +43 -36
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +9 -23
- package/dist/src/main.d.ts +1 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +0 -1
- package/dist/src/object.utils.d.ts +1 -0
- package/dist/src/object.utils.d.ts.map +1 -0
- package/dist/src/object.utils.js +0 -1
- package/dist/src/rate-limiting.module.d.ts +1 -0
- package/dist/src/rate-limiting.module.d.ts.map +1 -0
- package/dist/src/rate-limiting.module.js +3 -9
- package/dist/src/rules/dto/pagination.dto.d.ts +1 -0
- package/dist/src/rules/dto/pagination.dto.d.ts.map +1 -0
- package/dist/src/rules/dto/pagination.dto.js +7 -16
- package/dist/src/rules/dto/rule.dto.d.ts +3 -2
- package/dist/src/rules/dto/rule.dto.d.ts.map +1 -0
- package/dist/src/rules/dto/rule.dto.js +35 -44
- package/dist/src/rules/interface/pagination.interface.d.ts +1 -0
- package/dist/src/rules/interface/pagination.interface.d.ts.map +1 -0
- package/dist/src/rules/interface/pagination.interface.js +0 -1
- package/dist/src/rules/interface/rule.interface.d.ts +1 -0
- package/dist/src/rules/interface/rule.interface.d.ts.map +1 -0
- package/dist/src/rules/interface/rule.interface.js +0 -1
- package/dist/src/rules/rule.controller.d.ts +1 -0
- package/dist/src/rules/rule.controller.d.ts.map +1 -0
- package/dist/src/rules/rule.controller.js +29 -41
- package/dist/src/rules/rule.module.d.ts +1 -0
- package/dist/src/rules/rule.module.d.ts.map +1 -0
- package/dist/src/rules/rule.module.js +2 -8
- package/dist/src/rules/rule.repository.d.ts +1 -0
- package/dist/src/rules/rule.repository.d.ts.map +1 -0
- package/dist/src/rules/rule.repository.js +12 -20
- package/dist/src/rules/rule.schema.d.ts +150 -3
- package/dist/src/rules/rule.schema.d.ts.map +1 -0
- package/dist/src/rules/rule.schema.js +49 -56
- package/dist/src/rules/rule.service.d.ts +3 -1
- package/dist/src/rules/rule.service.d.ts.map +1 -0
- package/dist/src/rules/rule.service.js +16 -22
- package/dist/src/shared/cache/cache.service.d.ts +2 -1
- package/dist/src/shared/cache/cache.service.d.ts.map +1 -0
- package/dist/src/shared/cache/cache.service.js +3 -12
- package/dist/src/shared/dsl/dsl.interface.d.ts +1 -0
- package/dist/src/shared/dsl/dsl.interface.d.ts.map +1 -0
- package/dist/src/shared/dsl/dsl.interface.js +0 -1
- package/dist/src/shared/dsl/dsl.service.d.ts +2 -1
- package/dist/src/shared/dsl/dsl.service.d.ts.map +1 -0
- package/dist/src/shared/dsl/dsl.service.js +38 -28
- package/dist/src/shared/redis/redis.module.d.ts +1 -0
- package/dist/src/shared/redis/redis.module.d.ts.map +1 -0
- package/dist/src/shared/redis/redis.module.js +4 -10
- package/dist/src/shared/redis/redis.service.d.ts +2 -1
- package/dist/src/shared/redis/redis.service.d.ts.map +1 -0
- package/dist/src/shared/redis/redis.service.js +5 -17
- package/dist/src/shared/rule-engine/interface/rule-engine.interface.d.ts +2 -1
- package/dist/src/shared/rule-engine/interface/rule-engine.interface.d.ts.map +1 -0
- package/dist/src/shared/rule-engine/interface/rule-engine.interface.js +0 -1
- package/dist/src/shared/rule-engine/rule-engine.module.d.ts +4 -3
- package/dist/src/shared/rule-engine/rule-engine.module.d.ts.map +1 -0
- package/dist/src/shared/rule-engine/rule-engine.module.js +4 -11
- package/dist/src/shared/rule-engine/rule-engine.service.d.ts +7 -6
- package/dist/src/shared/rule-engine/rule-engine.service.d.ts.map +1 -0
- package/dist/src/shared/rule-engine/rule-engine.service.js +14 -12
- package/dist/src/shared/shared.module.d.ts +1 -0
- package/dist/src/shared/shared.module.d.ts.map +1 -0
- package/dist/src/shared/shared.module.js +4 -10
- package/dist/src/validators/rule.constraint.d.ts +3 -2
- package/dist/src/validators/rule.constraint.d.ts.map +1 -0
- package/dist/src/validators/rule.constraint.js +13 -16
- package/dist/src/validators/rule.validator.d.ts +2 -1
- package/dist/src/validators/rule.validator.d.ts.map +1 -0
- package/dist/src/validators/rule.validator.js +0 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +43 -37
- package/dist/src/decorators/rate-limiting-rule.decorator.js.map +0 -1
- package/dist/src/guards/rate-limiting.guard.js.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/main.js.map +0 -1
- package/dist/src/mocks-modules/rate-limiting.module.d.ts +0 -21
- package/dist/src/mocks-modules/rate-limiting.module.js +0 -54
- package/dist/src/mocks-modules/rate-limiting.module.js.map +0 -1
- package/dist/src/mocks-modules/rule.module.d.ts +0 -5
- package/dist/src/mocks-modules/rule.module.js +0 -38
- package/dist/src/mocks-modules/rule.module.js.map +0 -1
- package/dist/src/mocks-modules/shared-module.mocks.d.ts +0 -10
- package/dist/src/mocks-modules/shared-module.mocks.js +0 -32
- package/dist/src/mocks-modules/shared-module.mocks.js.map +0 -1
- package/dist/src/object.utils.js.map +0 -1
- package/dist/src/rate-limiting.module.js.map +0 -1
- package/dist/src/rules/dto/pagination.dto.js.map +0 -1
- package/dist/src/rules/dto/rule.dto.js.map +0 -1
- package/dist/src/rules/interface/pagination.interface.js.map +0 -1
- package/dist/src/rules/interface/rule.interface.js.map +0 -1
- package/dist/src/rules/rule.controller.js.map +0 -1
- package/dist/src/rules/rule.module.js.map +0 -1
- package/dist/src/rules/rule.repository.js.map +0 -1
- package/dist/src/rules/rule.schema.js.map +0 -1
- package/dist/src/rules/rule.service.js.map +0 -1
- package/dist/src/shared/cache/cache.service.js.map +0 -1
- package/dist/src/shared/dls/dsl.interface.d.ts +0 -42
- package/dist/src/shared/dls/dsl.interface.js +0 -10
- package/dist/src/shared/dls/dsl.interface.js.map +0 -1
- package/dist/src/shared/dls/dsl.utils.d.ts +0 -3
- package/dist/src/shared/dls/dsl.utils.js +0 -73
- package/dist/src/shared/dls/dsl.utils.js.map +0 -1
- package/dist/src/shared/dsl/dsl.interface.js.map +0 -1
- package/dist/src/shared/dsl/dsl.service.js.map +0 -1
- package/dist/src/shared/dsl/dsl.utils.d.ts +0 -3
- package/dist/src/shared/dsl/dsl.utils.js +0 -73
- package/dist/src/shared/dsl/dsl.utils.js.map +0 -1
- package/dist/src/shared/redis/redis.module.js.map +0 -1
- package/dist/src/shared/redis/redis.service.js.map +0 -1
- package/dist/src/shared/rule-engine/interface/rule-engine.interface.js.map +0 -1
- package/dist/src/shared/rule-engine/rule-engine.module.js.map +0 -1
- package/dist/src/shared/rule-engine/rule-engine.service.js.map +0 -1
- package/dist/src/shared/shared.module.js.map +0 -1
- package/dist/src/validators/rule.constraint.js.map +0 -1
- package/dist/src/validators/rule.validator.js.map +0 -1
- package/dist/test/guards/rate-limiting.guard.spec.d.ts +0 -1
- package/dist/test/guards/rate-limiting.guard.spec.js +0 -93
- package/dist/test/guards/rate-limiting.guard.spec.js.map +0 -1
- package/dist/test/mocks/rate-limiting-module.mocks.d.ts +0 -2
- package/dist/test/mocks/rate-limiting-module.mocks.js +0 -60
- package/dist/test/mocks/rate-limiting-module.mocks.js.map +0 -1
- package/dist/test/mocks/rate-limiting.mocks.d.ts +0 -17
- package/dist/test/mocks/rate-limiting.mocks.js +0 -21
- package/dist/test/mocks/rate-limiting.mocks.js.map +0 -1
- package/dist/test/mocks/rule-engine.mocks.d.ts +0 -7
- package/dist/test/mocks/rule-engine.mocks.js +0 -11
- package/dist/test/mocks/rule-engine.mocks.js.map +0 -1
- package/dist/test/mocks/rule.mocks.d.ts +0 -32
- package/dist/test/mocks/rule.mocks.js +0 -58
- package/dist/test/mocks/rule.mocks.js.map +0 -1
- package/dist/test/mocks/shared-module.mocks.d.ts +0 -10
- package/dist/test/mocks/shared-module.mocks.js +0 -32
- package/dist/test/mocks/shared-module.mocks.js.map +0 -1
- package/dist/test/mocks/shared.mocks.d.ts +0 -19
- package/dist/test/mocks/shared.mocks.js +0 -29
- package/dist/test/mocks/shared.mocks.js.map +0 -1
- package/dist/test/modules/rate-limiting.module.d.ts +0 -4
- package/dist/test/modules/rate-limiting.module.js +0 -38
- package/dist/test/modules/rate-limiting.module.js.map +0 -1
- package/dist/test/modules/rule.module.d.ts +0 -5
- package/dist/test/modules/rule.module.js +0 -38
- package/dist/test/modules/rule.module.js.map +0 -1
- package/dist/test/rules/rules.service.spec.d.ts +0 -1
- package/dist/test/rules/rules.service.spec.js +0 -115
- package/dist/test/rules/rules.service.spec.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
# ๐ Rate Limiting Module
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
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**.
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
5
|
## โจ Features
|
|
10
6
|
|
|
11
|
-
|
|
12
|
-
|
|
13
7
|
- Define rate-limiting rules with custom expressions.
|
|
14
8
|
|
|
15
9
|
- Dynamically inject context-aware functions for rule evaluation.
|
|
@@ -18,71 +12,44 @@ This module provides a flexible **rate-limiting system** where access to operati
|
|
|
18
12
|
|
|
19
13
|
- Built with extensibility and modularity in mind.
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
15
|
## ๐งฑ How It Works
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
17
|
1. You define a rule using a simple expression (e.g., `count_quote( ) > 1`).
|
|
28
18
|
|
|
29
19
|
2. The rule is evaluated in runtime using data injected from the request context.
|
|
30
20
|
|
|
31
21
|
3. If the expression is true, the action is blocked.
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
23
|
## ๐งฉ Usage
|
|
36
24
|
|
|
37
|
-
|
|
38
|
-
|
|
39
25
|
### 1. Install the Module
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
|
|
43
27
|
```ts
|
|
44
|
-
|
|
45
28
|
@Module({
|
|
29
|
+
imports: [
|
|
30
|
+
RateLimitingModule,
|
|
46
31
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
RuleEngineModule.forFeatureAsync({
|
|
52
|
-
|
|
53
|
-
useFactory: async (quoteService: QuoteService) => {
|
|
54
|
-
|
|
55
|
-
return await quoteService.countQuote();
|
|
56
|
-
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
inject: [QuoteService],
|
|
60
|
-
|
|
61
|
-
}),
|
|
62
|
-
|
|
63
|
-
],
|
|
32
|
+
RuleEngineModule.forFeatureAsync({
|
|
33
|
+
useFactory: async (quoteService: QuoteService) => {
|
|
34
|
+
return await quoteService.countQuote();
|
|
35
|
+
},
|
|
64
36
|
|
|
37
|
+
inject: [QuoteService],
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
65
40
|
})
|
|
66
|
-
|
|
67
|
-
export class YourFeatureModule {}
|
|
68
|
-
|
|
41
|
+
export class YourFeatureModule {}
|
|
69
42
|
```
|
|
70
43
|
|
|
71
|
-
|
|
72
|
-
|
|
73
44
|
## 2. Decorate Your Handlers
|
|
74
45
|
|
|
75
|
-
|
|
76
|
-
|
|
77
46
|
Use the `@RateLimitingRuleMetadata` decorator to attach metadata used during rule evaluation.
|
|
78
47
|
|
|
79
|
-
|
|
80
|
-
|
|
81
48
|
```ts
|
|
82
49
|
|
|
83
50
|
import { RateLimitingRuleMetadata } from 'path-to-rate-limiting-module';
|
|
84
51
|
|
|
85
|
-
|
|
52
|
+
|
|
86
53
|
|
|
87
54
|
@RateLimitingRuleMetadata({
|
|
88
55
|
|
|
@@ -108,82 +75,57 @@ return this.quoteService.create(body);
|
|
|
108
75
|
|
|
109
76
|
```
|
|
110
77
|
|
|
111
|
-
|
|
78
|
+
- `action`: Name of the action to be controlled.
|
|
112
79
|
|
|
113
|
-
|
|
80
|
+
- `partnerPath`: Path to extract the partner ID from the request context.
|
|
114
81
|
|
|
115
|
-
|
|
82
|
+
- `providerPath`: Path to extract the provider.
|
|
116
83
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
* `productTypePath`: Path to extract the product type.
|
|
120
|
-
|
|
121
|
-
|
|
84
|
+
- `productTypePath`: Path to extract the product type.
|
|
122
85
|
|
|
123
86
|
## ๐ Rule Engine Integration
|
|
124
87
|
|
|
125
|
-
|
|
126
|
-
|
|
127
88
|
This module depends on an underlying rule engine to evaluate expressions. You must provide the functions used in expressions through:
|
|
128
89
|
|
|
129
|
-
|
|
130
|
-
|
|
131
90
|
```ts
|
|
132
|
-
|
|
133
91
|
RuleEngineModule.forFeatureAsync({
|
|
92
|
+
useFactory: async (useCase: RateLimitingInjectFunctionsUseCase) => {
|
|
93
|
+
return await useCase.getFunctions();
|
|
134
94
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return await useCase.getFunctions();
|
|
138
|
-
|
|
139
|
-
// returns an object like { count_quote: async () => number }
|
|
140
|
-
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
inject: [RateLimitingInjectFunctionsUseCase],
|
|
95
|
+
// returns an object like { count_quote: async () => number }
|
|
96
|
+
},
|
|
144
97
|
|
|
98
|
+
inject: [RateLimitingInjectFunctionsUseCase],
|
|
145
99
|
});
|
|
146
|
-
|
|
147
100
|
```
|
|
148
101
|
|
|
149
|
-
|
|
150
|
-
|
|
151
102
|
## ๐งช Example Rule
|
|
152
103
|
|
|
153
|
-
|
|
154
104
|
A rule stored in your system might look like:
|
|
155
105
|
|
|
156
|
-
|
|
157
106
|
```json
|
|
158
|
-
|
|
159
107
|
{
|
|
160
|
-
|
|
161
|
-
|
|
108
|
+
"expression": "count_quote() > 1",
|
|
109
|
+
"action": "create_quote"
|
|
162
110
|
}
|
|
163
|
-
|
|
164
111
|
```
|
|
165
112
|
|
|
166
|
-
|
|
167
|
-
|
|
168
113
|
If the expression returns `true`, the rate limiter will block further `create_quote` actions for the user based on the context values.
|
|
169
114
|
|
|
170
|
-
|
|
171
115
|
## ๐ง Dynamic Parameter Resolution
|
|
172
116
|
|
|
173
117
|
When building queries based on request context, it's possible to reference nested values using paths. This system supports:
|
|
174
118
|
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
- Interpreting date expressions safely, like `date(-5d)` (5 days ago), without using `eval`.
|
|
119
|
+
- Resolving values using variable placeholders like `:applicant.documents[0].value`.
|
|
120
|
+
- Interpreting date expressions safely, like `date(-5d)` (5 days ago), without using `eval`.
|
|
178
121
|
|
|
179
122
|
### Supported Syntax
|
|
180
|
-
```json
|
|
181
123
|
|
|
124
|
+
```json
|
|
182
125
|
{
|
|
183
126
|
"value": ":applicant.documents[0].value",
|
|
184
127
|
"label": "applicant.documents.value"
|
|
185
128
|
}
|
|
186
|
-
|
|
187
129
|
```
|
|
188
130
|
|
|
189
131
|
Will extract the value from the context:
|
|
@@ -191,14 +133,12 @@ Will extract the value from the context:
|
|
|
191
133
|
```json
|
|
192
134
|
{
|
|
193
135
|
"applicant": {
|
|
194
|
-
"documents": [
|
|
195
|
-
{ "type": "NIF", "value": "ABCDE" }
|
|
196
|
-
]
|
|
136
|
+
"documents": [{ "type": "NIF", "value": "ABCDE" }]
|
|
197
137
|
}
|
|
198
138
|
}
|
|
199
139
|
```
|
|
200
|
-
Result: `"ABCDE"`
|
|
201
140
|
|
|
141
|
+
Result: `"ABCDE"`
|
|
202
142
|
|
|
203
143
|
You can also use dynamic dates:
|
|
204
144
|
|
|
@@ -214,19 +154,15 @@ Result: `"2025-07-10T00:00:00.000Z"` (7 days ago)
|
|
|
214
154
|
|
|
215
155
|
### Supported Date Units
|
|
216
156
|
|
|
217
|
-
-
|
|
218
|
-
|
|
219
|
-
-
|
|
220
|
-
|
|
221
|
-
- `y`: Years
|
|
157
|
+
- `d`: Days (default)
|
|
158
|
+
- `M`: Months
|
|
159
|
+
- `y`: Years
|
|
222
160
|
|
|
223
161
|
Examples:
|
|
224
162
|
|
|
225
|
-
-
|
|
226
|
-
|
|
227
|
-
-
|
|
228
|
-
|
|
229
|
-
- `date(0)` โ Today
|
|
163
|
+
- `date(-5d)` โ 5 days ago
|
|
164
|
+
- `date(-1M)` โ 1 month ago
|
|
165
|
+
- `date(0)` โ Today
|
|
230
166
|
|
|
231
167
|
No dynamic code execution (`eval`, `new Function`) is used โ expressions are parsed securely.
|
|
232
168
|
|
|
@@ -243,6 +179,7 @@ You can optionally define an `op` (operation) field to specify how the value sho
|
|
|
243
179
|
"op": "gte"
|
|
244
180
|
}
|
|
245
181
|
```
|
|
182
|
+
|
|
246
183
|
๐ This means: only include records created after **7 days ago**.
|
|
247
184
|
|
|
248
185
|
```json
|
|
@@ -255,6 +192,7 @@ You can optionally define an `op` (operation) field to specify how the value sho
|
|
|
255
192
|
"op": "range"
|
|
256
193
|
}
|
|
257
194
|
```
|
|
195
|
+
|
|
258
196
|
๐ This sets a static date or value range. Can be used for numbers, dates, or custom fields.
|
|
259
197
|
|
|
260
198
|
### `rangeDate` โ Dynamic Date Range
|
|
@@ -269,8 +207,8 @@ You can optionally define an `op` (operation) field to specify how the value sho
|
|
|
269
207
|
"op": "rangeDate"
|
|
270
208
|
}
|
|
271
209
|
```
|
|
272
|
-
๐ This automatically resolves both `from` and `to` values as dates. For example, this would generate a date range from **30 days ago** to **now**.
|
|
273
210
|
|
|
211
|
+
๐ This automatically resolves both `from` and `to` values as dates. For example, this would generate a date range from **30 days ago** to **now**.
|
|
274
212
|
|
|
275
213
|
## ๐งฌ DSL Support and MongoDB Integration
|
|
276
214
|
|
|
@@ -292,6 +230,7 @@ These DSL expressions are **not executed as raw code**, but safely parsed and ev
|
|
|
292
230
|
One powerful feature of this module is the ability to **transform DSL filters into MongoDB-compatible query objects**.
|
|
293
231
|
|
|
294
232
|
For example, the following DSL input:
|
|
233
|
+
|
|
295
234
|
```json
|
|
296
235
|
{
|
|
297
236
|
createdAt: {
|
|
@@ -300,17 +239,15 @@ For example, the following DSL input:
|
|
|
300
239
|
}
|
|
301
240
|
}
|
|
302
241
|
```
|
|
242
|
+
|
|
303
243
|
This is handled by utility functions like `buildDlsOp`, which map DSL constructs to database query.
|
|
304
244
|
|
|
305
245
|
### โ
Benefits of Using DSL
|
|
306
246
|
|
|
307
|
-
-
|
|
308
|
-
|
|
309
|
-
-
|
|
310
|
-
|
|
311
|
-
- **Security:** No raw `eval` or dynamic JS execution
|
|
312
|
-
|
|
313
|
-
- **Readability:** DSL is expressive for non-technical stakeholders
|
|
247
|
+
- **Separation of logic from code:** Business rules can be stored in DB or configs
|
|
248
|
+
- **Extensibility:** Easy to support new operators or DB backends (e.g., SQL, Elasticsearch)
|
|
249
|
+
- **Security:** No raw `eval` or dynamic JS execution
|
|
250
|
+
- **Readability:** DSL is expressive for non-technical stakeholders
|
|
314
251
|
|
|
315
252
|
By combining DSL definitions with path-based context extraction and safe runtime resolution, this module provides a highly flexible and secure rate-limiting engine ready for dynamic environments.
|
|
316
253
|
|
|
@@ -398,32 +335,27 @@ Optional. Defines the operator (`eq`, `range`, `rangeDate`, `gte`, etc.)
|
|
|
398
335
|
|
|
399
336
|
Fallback value(s) to be used if dynamic resolution fails (e.g., missing path or function)
|
|
400
337
|
|
|
401
|
-
|
|
338
|
+
---
|
|
402
339
|
|
|
403
340
|
### ๐ง Special Value Formats
|
|
404
341
|
|
|
405
|
-
-
|
|
406
|
-
|
|
407
|
-
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
- Static values like `"moneyhero"` are passed as-is
|
|
412
|
-
|
|
413
|
-
### ๐งช Use Case Example
|
|
342
|
+
- `:path.to.value` โ Dynamically extracted from the context object
|
|
343
|
+
- `date(-7d)` โ Resolved as a safe date expression
|
|
344
|
+
- `fn:getValueFromSale` โ Calls a predefined function to resolve the value dynamically
|
|
345
|
+
- Static values like `"moneyhero"` are passed as-is
|
|
346
|
+
|
|
347
|
+
### ๐งช Use Case Example
|
|
414
348
|
|
|
415
349
|
Imagine your service defines a method like:
|
|
416
350
|
|
|
417
|
-
|
|
418
351
|
async countQuoteByParams(filters: Record<string, any>): Promise<number>
|
|
419
352
|
|
|
420
353
|
At runtime, the module will:
|
|
421
354
|
|
|
422
355
|
1. Resolve each `value` in the `query` array using context and supported expressions.
|
|
423
|
-
|
|
424
356
|
2. Construct a query object:
|
|
425
357
|
|
|
426
|
-
```json
|
|
358
|
+
```json
|
|
427
359
|
{
|
|
428
360
|
partner: { partnerId: "bolttech" },
|
|
429
361
|
productType: "car-insurance",
|
|
@@ -439,9 +371,10 @@ At runtime, the module will:
|
|
|
439
371
|
```
|
|
440
372
|
|
|
441
373
|
3. Inject this into `countQuoteByParams(...)`
|
|
442
|
-
This approach gives you a highly flexible, configurable system for controlling dynamic function parameters via context-based DSLs and runtime evaluation.
|
|
374
|
+
This approach gives you a highly flexible, configurable system for controlling dynamic function parameters via context-based DSLs and runtime evaluation.
|
|
375
|
+
|
|
376
|
+
---
|
|
443
377
|
|
|
444
|
-
----------
|
|
445
378
|
## ๐ง Custom Runtime Functions with `variables.functions`
|
|
446
379
|
|
|
447
380
|
In addition to defining query parameters in `variables.queries`, the system also supports **custom runtime functions** through the `variables.functions` array.
|
|
@@ -454,11 +387,11 @@ These functions can be executed **before query construction** to compute values
|
|
|
454
387
|
|
|
455
388
|
Each function definition includes:
|
|
456
389
|
|
|
457
|
-
| Field
|
|
458
|
-
|
|
459
|
-
| `name`
|
|
460
|
-
| `fn`
|
|
461
|
-
| `variables
|
|
390
|
+
| Field | Description |
|
|
391
|
+
| ----------- | -------------------------------------------------------------------------- |
|
|
392
|
+
| `name` | Unique function identifier |
|
|
393
|
+
| `fn` | The function to execute, in the format `functionName(args...)` |
|
|
394
|
+
| `variables` | Parameters passed to the function, which can include subqueries and values |
|
|
462
395
|
|
|
463
396
|
### ๐ Example
|
|
464
397
|
|
|
@@ -494,6 +427,7 @@ Each function definition includes:
|
|
|
494
427
|
]
|
|
495
428
|
}
|
|
496
429
|
```
|
|
430
|
+
|
|
497
431
|
### ๐ Using the Function Output in Queries
|
|
498
432
|
|
|
499
433
|
To use the result of a function, reference it in a `query.value` using the syntax: `fn:functionName`.
|
|
@@ -504,80 +438,62 @@ CopyEdit
|
|
|
504
438
|
|
|
505
439
|
```json
|
|
506
440
|
{
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
441
|
+
"label": "createdAt",
|
|
442
|
+
"op": "range",
|
|
443
|
+
"value": {
|
|
444
|
+
"from": "fn:getValueFromSale",
|
|
445
|
+
"to": "date(0)"
|
|
446
|
+
},
|
|
447
|
+
"defaultValue": {
|
|
448
|
+
"from": "date(-5d)",
|
|
449
|
+
"to": "date(0)"
|
|
450
|
+
}
|
|
517
451
|
}
|
|
518
|
-
```
|
|
452
|
+
```
|
|
519
453
|
|
|
520
454
|
๐ In this case, `getValueFromSale(...)` will run **before** the query is constructed, and the result will be injected into the `from` field.
|
|
521
455
|
|
|
522
|
-
|
|
456
|
+
---
|
|
523
457
|
|
|
524
458
|
### ๐งฉ How It Works
|
|
525
459
|
|
|
526
460
|
1. The engine scans all `functions` in `variables.functions`.
|
|
527
|
-
|
|
528
461
|
2. For each `query` entry in `variables.queries`, if `value` (or `from`, `to`) starts with `fn:`, it:
|
|
529
|
-
|
|
530
|
-
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
- Executes the declared function like `getValueFromSale(queries, target)`
|
|
535
|
-
|
|
462
|
+
- Finds the corresponding `function` by name
|
|
463
|
+
- Resolves its `variables` (supporting nested `:context.paths`)
|
|
464
|
+
- Executes the declared function like `getValueFromSale(queries, target)`
|
|
465
|
+
|
|
536
466
|
3. The return value of the function replaces the `fn:` reference.
|
|
537
|
-
|
|
538
467
|
|
|
539
|
-
|
|
468
|
+
---
|
|
540
469
|
|
|
541
470
|
### โ
Benefits
|
|
542
471
|
|
|
543
|
-
-
|
|
544
|
-
|
|
545
|
-
-
|
|
546
|
-
|
|
547
|
-
- Promotes **reuse** of custom logic across different rules or queries
|
|
548
|
-
|
|
549
|
-
- Provides **defaultValue** fallback in case of failure
|
|
550
|
-
|
|
472
|
+
- Enables **pre-processing logic** in a declarative way
|
|
473
|
+
- Keeps rule/query definitions **clean and context-aware**
|
|
474
|
+
- Promotes **reuse** of custom logic across different rules or queries
|
|
475
|
+
- Provides **defaultValue** fallback in case of failure
|
|
551
476
|
|
|
552
|
-
|
|
477
|
+
---
|
|
553
478
|
|
|
554
479
|
> ๐ก Tip: Functions must be registered and resolvable at runtime by your system. The evaluation engine must be able to map the function name (`getValueFromSale`) to a real implementation.
|
|
555
480
|
|
|
556
|
-
|
|
557
|
-
|
|
558
481
|
## ๐งฐ Requirements
|
|
559
482
|
|
|
560
|
-
|
|
561
|
-
* NestJS
|
|
562
|
-
|
|
563
|
-
* RuleEngineModule (compatible expression parser/executor)
|
|
483
|
+
- NestJS
|
|
564
484
|
|
|
565
|
-
|
|
485
|
+
- RuleEngineModule (compatible expression parser/executor)
|
|
566
486
|
|
|
487
|
+
- Custom service to inject context functions (like `RateLimitingInjectFunctionsUseCase`)
|
|
567
488
|
|
|
568
489
|
## ๐ Notes
|
|
569
|
-
|
|
570
490
|
|
|
571
|
-
|
|
491
|
+
- Rules should be defined and stored externally (e.g., DB, config).
|
|
572
492
|
|
|
573
|
-
|
|
493
|
+
- The context extractor paths must match the structure of your handler inputs (e.g., body, params).
|
|
574
494
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
495
|
+
- Ensure `getFunctions()` returns **async functions** that provide the required values for the expression.
|
|
578
496
|
|
|
579
497
|
## ๐งพ License
|
|
580
498
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
MIT
|
|
499
|
+
MIT
|