@trentapps/manager-protocol 1.1.3 → 1.2.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.
- package/README.md +164 -17
- package/dist/analyzers/CSSAnalyzer.d.ts +180 -8
- package/dist/analyzers/CSSAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/CSSAnalyzer.js +561 -105
- package/dist/analyzers/CSSAnalyzer.js.map +1 -1
- package/dist/config/dashboard.d.ts +55 -0
- package/dist/config/dashboard.d.ts.map +1 -0
- package/dist/config/dashboard.js +103 -0
- package/dist/config/dashboard.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +7 -0
- package/dist/config/index.js.map +1 -0
- package/dist/dashboard/httpDashboard.d.ts +100 -0
- package/dist/dashboard/httpDashboard.d.ts.map +1 -0
- package/dist/dashboard/httpDashboard.js +1276 -0
- package/dist/dashboard/httpDashboard.js.map +1 -0
- package/dist/dashboard/index.d.ts +6 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +7 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/engine/AuditLogger.d.ts +370 -2
- package/dist/engine/AuditLogger.d.ts.map +1 -1
- package/dist/engine/AuditLogger.js +1064 -24
- package/dist/engine/AuditLogger.js.map +1 -1
- package/dist/engine/GitHubClient.d.ts +183 -0
- package/dist/engine/GitHubClient.d.ts.map +1 -0
- package/dist/engine/GitHubClient.js +411 -0
- package/dist/engine/GitHubClient.js.map +1 -0
- package/dist/engine/RateLimiter.d.ts +5 -3
- package/dist/engine/RateLimiter.d.ts.map +1 -1
- package/dist/engine/RateLimiter.js +49 -72
- package/dist/engine/RateLimiter.js.map +1 -1
- package/dist/engine/RuleDependencyAnalyzer.d.ts +73 -0
- package/dist/engine/RuleDependencyAnalyzer.d.ts.map +1 -0
- package/dist/engine/RuleDependencyAnalyzer.js +475 -0
- package/dist/engine/RuleDependencyAnalyzer.js.map +1 -0
- package/dist/engine/RulesEngine.d.ts +102 -3
- package/dist/engine/RulesEngine.d.ts.map +1 -1
- package/dist/engine/RulesEngine.js +326 -21
- package/dist/engine/RulesEngine.js.map +1 -1
- package/dist/engine/TaskManager.d.ts +10 -14
- package/dist/engine/TaskManager.d.ts.map +1 -1
- package/dist/engine/TaskManager.js +169 -197
- package/dist/engine/TaskManager.js.map +1 -1
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +5 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/rules/azure.d.ts.map +1 -1
- package/dist/rules/azure.js +12 -14
- package/dist/rules/azure.js.map +1 -1
- package/dist/rules/compliance.d.ts.map +1 -1
- package/dist/rules/compliance.js +23 -41
- package/dist/rules/compliance.js.map +1 -1
- package/dist/rules/condition-optimizer.d.ts +151 -0
- package/dist/rules/condition-optimizer.d.ts.map +1 -0
- package/dist/rules/condition-optimizer.js +479 -0
- package/dist/rules/condition-optimizer.js.map +1 -0
- package/dist/rules/css.d.ts.map +1 -1
- package/dist/rules/css.js +538 -0
- package/dist/rules/css.js.map +1 -1
- package/dist/rules/field-standards.d.ts +1172 -0
- package/dist/rules/field-standards.d.ts.map +1 -0
- package/dist/rules/field-standards.js +908 -0
- package/dist/rules/field-standards.js.map +1 -0
- package/dist/rules/flask.d.ts.map +1 -1
- package/dist/rules/flask.js +18 -31
- package/dist/rules/flask.js.map +1 -1
- package/dist/rules/index.d.ts +220 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +155 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/ml-ai.d.ts.map +1 -1
- package/dist/rules/ml-ai.js +11 -13
- package/dist/rules/ml-ai.js.map +1 -1
- package/dist/rules/patterns.d.ts +568 -0
- package/dist/rules/patterns.d.ts.map +1 -0
- package/dist/rules/patterns.js +1359 -0
- package/dist/rules/patterns.js.map +1 -0
- package/dist/rules/security.d.ts.map +1 -1
- package/dist/rules/security.js +580 -19
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/shared-patterns.d.ts +268 -0
- package/dist/rules/shared-patterns.d.ts.map +1 -0
- package/dist/rules/shared-patterns.js +556 -0
- package/dist/rules/shared-patterns.js.map +1 -0
- package/dist/rules/storage.d.ts +8 -2
- package/dist/rules/storage.d.ts.map +1 -1
- package/dist/rules/storage.js +541 -3
- package/dist/rules/storage.js.map +1 -1
- package/dist/rules/stripe.d.ts.map +1 -1
- package/dist/rules/stripe.js +19 -26
- package/dist/rules/stripe.js.map +1 -1
- package/dist/rules/websocket.d.ts.map +1 -1
- package/dist/rules/websocket.js +32 -40
- package/dist/rules/websocket.js.map +1 -1
- package/dist/supervisor/AgentSupervisor.d.ts +52 -0
- package/dist/supervisor/AgentSupervisor.d.ts.map +1 -1
- package/dist/supervisor/AgentSupervisor.js +120 -1
- package/dist/supervisor/AgentSupervisor.js.map +1 -1
- package/dist/supervisor/ManagedServerRegistry.d.ts +139 -2
- package/dist/supervisor/ManagedServerRegistry.d.ts.map +1 -1
- package/dist/supervisor/ManagedServerRegistry.js +590 -6
- package/dist/supervisor/ManagedServerRegistry.js.map +1 -1
- package/dist/supervisor/ProjectTracker.d.ts +2 -1
- package/dist/supervisor/ProjectTracker.d.ts.map +1 -1
- package/dist/supervisor/ProjectTracker.js +5 -9
- package/dist/supervisor/ProjectTracker.js.map +1 -1
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/rule-tester.d.ts +217 -0
- package/dist/testing/rule-tester.d.ts.map +1 -0
- package/dist/testing/rule-tester.examples.d.ts +57 -0
- package/dist/testing/rule-tester.examples.d.ts.map +1 -0
- package/dist/testing/rule-tester.examples.js +375 -0
- package/dist/testing/rule-tester.examples.js.map +1 -0
- package/dist/testing/rule-tester.js +381 -0
- package/dist/testing/rule-tester.js.map +1 -0
- package/dist/testing/rule-validator.d.ts +141 -0
- package/dist/testing/rule-validator.d.ts.map +1 -0
- package/dist/testing/rule-validator.js +640 -0
- package/dist/testing/rule-validator.js.map +1 -0
- package/dist/types/index.d.ts +265 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +57 -2
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/rate-limiting.d.ts +268 -0
- package/dist/utils/rate-limiting.d.ts.map +1 -0
- package/dist/utils/rate-limiting.js +403 -0
- package/dist/utils/rate-limiting.js.map +1 -0
- package/dist/utils/shared.d.ts +306 -0
- package/dist/utils/shared.d.ts.map +1 -0
- package/dist/utils/shared.js +464 -0
- package/dist/utils/shared.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Agent Supervisor - Rate Limiting Utilities
|
|
3
|
+
*
|
|
4
|
+
* Reusable utilities for rate limiting:
|
|
5
|
+
* - Bucket key building for different scopes
|
|
6
|
+
* - Sliding window time-based tracking
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Scope types for rate limit bucket keys
|
|
10
|
+
*/
|
|
11
|
+
export type BucketScope = 'global' | 'agent' | 'session' | 'user' | 'action_type';
|
|
12
|
+
/**
|
|
13
|
+
* Identifiers used to build bucket keys
|
|
14
|
+
*/
|
|
15
|
+
export interface BucketIdentifiers {
|
|
16
|
+
agentId?: string;
|
|
17
|
+
sessionId?: string;
|
|
18
|
+
userId?: string;
|
|
19
|
+
actionType?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Window algorithm types
|
|
23
|
+
*/
|
|
24
|
+
export type WindowAlgorithm = 'fixed' | 'sliding';
|
|
25
|
+
/**
|
|
26
|
+
* Statistics for a time window
|
|
27
|
+
*/
|
|
28
|
+
export interface WindowStats {
|
|
29
|
+
/** Number of requests in the current window */
|
|
30
|
+
count: number;
|
|
31
|
+
/** Number of requests remaining before limit */
|
|
32
|
+
remaining: number;
|
|
33
|
+
/** Timestamp when the window started (ms since epoch) */
|
|
34
|
+
windowStart: number;
|
|
35
|
+
/** Timestamp when the window resets (ms since epoch) */
|
|
36
|
+
resetAt: number;
|
|
37
|
+
/** ISO string of reset time */
|
|
38
|
+
resetAtISO: string;
|
|
39
|
+
/** Whether the limit has been exceeded */
|
|
40
|
+
exceeded: boolean;
|
|
41
|
+
/** Percentage of limit used (0-100) */
|
|
42
|
+
usagePercent: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Configuration for SlidingWindow
|
|
46
|
+
*/
|
|
47
|
+
export interface SlidingWindowConfig {
|
|
48
|
+
/** Window duration in milliseconds */
|
|
49
|
+
windowMs: number;
|
|
50
|
+
/** Maximum requests allowed in the window */
|
|
51
|
+
maxRequests: number;
|
|
52
|
+
/** Optional burst limit for short-term spikes */
|
|
53
|
+
burstLimit?: number;
|
|
54
|
+
/** Window algorithm: 'fixed' resets at boundaries, 'sliding' moves with time */
|
|
55
|
+
algorithm?: WindowAlgorithm;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build a bucket key based on scope and identifiers.
|
|
59
|
+
*
|
|
60
|
+
* Key format: `{prefix}:{scope}:{identifier}`
|
|
61
|
+
*
|
|
62
|
+
* This creates consistent, collision-free keys for rate limit buckets.
|
|
63
|
+
*
|
|
64
|
+
* @param scope - The scope for the bucket (global, agent, session, user, action_type)
|
|
65
|
+
* @param identifiers - Object containing identifier values
|
|
66
|
+
* @param prefix - Optional prefix for namespacing (e.g., config ID)
|
|
67
|
+
* @returns A unique bucket key string
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Global scope
|
|
72
|
+
* buildBucketKey('global', {}) // "global"
|
|
73
|
+
* buildBucketKey('global', {}, 'rate-1') // "rate-1:global"
|
|
74
|
+
*
|
|
75
|
+
* // Agent scope
|
|
76
|
+
* buildBucketKey('agent', { agentId: 'agent-123' }) // "agent:agent-123"
|
|
77
|
+
*
|
|
78
|
+
* // Session scope with prefix
|
|
79
|
+
* buildBucketKey('session', { sessionId: 'sess-456' }, 'api-limit')
|
|
80
|
+
* // "api-limit:session:sess-456"
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildBucketKey(scope: BucketScope, identifiers: BucketIdentifiers, prefix?: string): string;
|
|
84
|
+
/**
|
|
85
|
+
* Parse a bucket key to extract scope and identifier.
|
|
86
|
+
*
|
|
87
|
+
* @param key - The bucket key to parse
|
|
88
|
+
* @returns Object with scope and identifier, or null if invalid
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* parseBucketKey('rate-1:agent:agent-123')
|
|
93
|
+
* // { prefix: 'rate-1', scope: 'agent', identifier: 'agent-123' }
|
|
94
|
+
*
|
|
95
|
+
* parseBucketKey('global')
|
|
96
|
+
* // { prefix: undefined, scope: 'global', identifier: undefined }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export declare function parseBucketKey(key: string): {
|
|
100
|
+
prefix?: string;
|
|
101
|
+
scope: BucketScope | 'unknown';
|
|
102
|
+
identifier?: string;
|
|
103
|
+
} | null;
|
|
104
|
+
/**
|
|
105
|
+
* SlidingWindow class for time-based window tracking.
|
|
106
|
+
*
|
|
107
|
+
* Supports both fixed and sliding window algorithms:
|
|
108
|
+
* - Fixed: Window resets at fixed boundaries (simpler, less memory)
|
|
109
|
+
* - Sliding: Window slides with time (more accurate, tracks individual requests)
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* // Create a window: 100 requests per minute
|
|
114
|
+
* const window = new SlidingWindow({
|
|
115
|
+
* windowMs: 60000,
|
|
116
|
+
* maxRequests: 100,
|
|
117
|
+
* algorithm: 'fixed'
|
|
118
|
+
* });
|
|
119
|
+
*
|
|
120
|
+
* // Check and record a request
|
|
121
|
+
* if (window.canAccept()) {
|
|
122
|
+
* window.record();
|
|
123
|
+
* // Process request
|
|
124
|
+
* } else {
|
|
125
|
+
* // Rate limited
|
|
126
|
+
* const stats = window.getStats();
|
|
127
|
+
* console.log(`Retry after ${stats.resetAt}`);
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare class SlidingWindow {
|
|
132
|
+
private config;
|
|
133
|
+
private count;
|
|
134
|
+
private burstCount;
|
|
135
|
+
private windowStart;
|
|
136
|
+
private requestTimestamps;
|
|
137
|
+
constructor(config: SlidingWindowConfig);
|
|
138
|
+
/**
|
|
139
|
+
* Check if the window has expired and needs reset.
|
|
140
|
+
*
|
|
141
|
+
* For fixed windows: Checks if current time is past window boundary.
|
|
142
|
+
* For sliding windows: Always returns false (sliding handles this differently).
|
|
143
|
+
*
|
|
144
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
145
|
+
* @returns Whether the window has expired
|
|
146
|
+
*/
|
|
147
|
+
isExpired(now?: number): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Reset the window to initial state.
|
|
150
|
+
*
|
|
151
|
+
* @param now - Timestamp to use as new window start (defaults to Date.now())
|
|
152
|
+
*/
|
|
153
|
+
reset(now?: number): void;
|
|
154
|
+
/**
|
|
155
|
+
* Check if the window can accept another request.
|
|
156
|
+
* Automatically resets expired windows (for fixed algorithm).
|
|
157
|
+
*
|
|
158
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
159
|
+
* @returns Whether a request can be accepted
|
|
160
|
+
*/
|
|
161
|
+
canAccept(now?: number): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Check if the window can accept based on burst limit only.
|
|
164
|
+
*
|
|
165
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
166
|
+
* @returns Whether burst limit allows acceptance
|
|
167
|
+
*/
|
|
168
|
+
canAcceptBurst(now?: number): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Record a request in the window.
|
|
171
|
+
*
|
|
172
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
173
|
+
*/
|
|
174
|
+
record(now?: number): void;
|
|
175
|
+
/**
|
|
176
|
+
* Get current window statistics.
|
|
177
|
+
*
|
|
178
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
179
|
+
* @returns WindowStats object with current state
|
|
180
|
+
*/
|
|
181
|
+
getStats(now?: number): WindowStats;
|
|
182
|
+
/**
|
|
183
|
+
* Get the current count of requests in the window.
|
|
184
|
+
*
|
|
185
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
186
|
+
* @returns Current request count
|
|
187
|
+
*/
|
|
188
|
+
getCount(now?: number): number;
|
|
189
|
+
/**
|
|
190
|
+
* Get remaining requests before limit is hit.
|
|
191
|
+
*
|
|
192
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
193
|
+
* @returns Number of remaining requests
|
|
194
|
+
*/
|
|
195
|
+
getRemaining(now?: number): number;
|
|
196
|
+
/**
|
|
197
|
+
* Get timestamp when the window resets.
|
|
198
|
+
*
|
|
199
|
+
* @returns Reset timestamp in milliseconds since epoch
|
|
200
|
+
*/
|
|
201
|
+
getResetTime(): number;
|
|
202
|
+
/**
|
|
203
|
+
* Get the window configuration.
|
|
204
|
+
*
|
|
205
|
+
* @returns The window configuration
|
|
206
|
+
*/
|
|
207
|
+
getConfig(): Required<SlidingWindowConfig>;
|
|
208
|
+
/**
|
|
209
|
+
* Set internal state (useful for persistence/restoration).
|
|
210
|
+
*
|
|
211
|
+
* @param state - State to restore
|
|
212
|
+
*/
|
|
213
|
+
setState(state: {
|
|
214
|
+
count: number;
|
|
215
|
+
windowStart: number;
|
|
216
|
+
burstCount?: number;
|
|
217
|
+
}): void;
|
|
218
|
+
/**
|
|
219
|
+
* Get internal state (useful for persistence).
|
|
220
|
+
*
|
|
221
|
+
* @returns Current internal state
|
|
222
|
+
*/
|
|
223
|
+
getState(): {
|
|
224
|
+
count: number;
|
|
225
|
+
windowStart: number;
|
|
226
|
+
burstCount: number;
|
|
227
|
+
};
|
|
228
|
+
private maybeResetWindow;
|
|
229
|
+
private getSlidingCount;
|
|
230
|
+
private cleanupOldTimestamps;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Create a sliding window with common presets.
|
|
234
|
+
*
|
|
235
|
+
* @param preset - Preset name
|
|
236
|
+
* @returns Configured SlidingWindow
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* // 60 requests per minute
|
|
241
|
+
* const perMinute = createWindowPreset('per-minute');
|
|
242
|
+
*
|
|
243
|
+
* // 1000 requests per hour
|
|
244
|
+
* const perHour = createWindowPreset('per-hour');
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export declare function createWindowPreset(preset: 'per-second' | 'per-minute' | 'per-hour' | 'per-day'): SlidingWindow;
|
|
248
|
+
/**
|
|
249
|
+
* Create multiple bucket keys for different scopes from the same identifiers.
|
|
250
|
+
*
|
|
251
|
+
* @param identifiers - Identifiers to use
|
|
252
|
+
* @param prefix - Optional prefix for all keys
|
|
253
|
+
* @returns Object with keys for each scope
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* const keys = createBucketKeys({ agentId: 'a1', userId: 'u1' }, 'rate');
|
|
258
|
+
* // {
|
|
259
|
+
* // global: 'rate:global',
|
|
260
|
+
* // agent: 'rate:agent:a1',
|
|
261
|
+
* // user: 'rate:user:u1',
|
|
262
|
+
* // session: 'rate:session:unknown',
|
|
263
|
+
* // action_type: 'rate:action:unknown'
|
|
264
|
+
* // }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
export declare function createBucketKeys(identifiers: BucketIdentifiers, prefix?: string): Record<BucketScope, string>;
|
|
268
|
+
//# sourceMappingURL=rate-limiting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiting.d.ts","sourceRoot":"","sources":["../../src/utils/rate-limiting.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Agent Supervisor - Rate Limiting Utilities
|
|
3
|
+
*
|
|
4
|
+
* Reusable utilities for rate limiting:
|
|
5
|
+
* - Bucket key building for different scopes
|
|
6
|
+
* - Sliding window time-based tracking
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// BUCKET KEY BUILDING
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Separator used in bucket keys to prevent collisions
|
|
13
|
+
*/
|
|
14
|
+
const KEY_SEPARATOR = ':';
|
|
15
|
+
/**
|
|
16
|
+
* Default identifier when none is provided
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_IDENTIFIER = 'unknown';
|
|
19
|
+
/**
|
|
20
|
+
* Build a bucket key based on scope and identifiers.
|
|
21
|
+
*
|
|
22
|
+
* Key format: `{prefix}:{scope}:{identifier}`
|
|
23
|
+
*
|
|
24
|
+
* This creates consistent, collision-free keys for rate limit buckets.
|
|
25
|
+
*
|
|
26
|
+
* @param scope - The scope for the bucket (global, agent, session, user, action_type)
|
|
27
|
+
* @param identifiers - Object containing identifier values
|
|
28
|
+
* @param prefix - Optional prefix for namespacing (e.g., config ID)
|
|
29
|
+
* @returns A unique bucket key string
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* // Global scope
|
|
34
|
+
* buildBucketKey('global', {}) // "global"
|
|
35
|
+
* buildBucketKey('global', {}, 'rate-1') // "rate-1:global"
|
|
36
|
+
*
|
|
37
|
+
* // Agent scope
|
|
38
|
+
* buildBucketKey('agent', { agentId: 'agent-123' }) // "agent:agent-123"
|
|
39
|
+
*
|
|
40
|
+
* // Session scope with prefix
|
|
41
|
+
* buildBucketKey('session', { sessionId: 'sess-456' }, 'api-limit')
|
|
42
|
+
* // "api-limit:session:sess-456"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function buildBucketKey(scope, identifiers, prefix) {
|
|
46
|
+
let key;
|
|
47
|
+
switch (scope) {
|
|
48
|
+
case 'global':
|
|
49
|
+
key = 'global';
|
|
50
|
+
break;
|
|
51
|
+
case 'agent':
|
|
52
|
+
key = `agent${KEY_SEPARATOR}${identifiers.agentId || DEFAULT_IDENTIFIER}`;
|
|
53
|
+
break;
|
|
54
|
+
case 'session':
|
|
55
|
+
key = `session${KEY_SEPARATOR}${identifiers.sessionId || DEFAULT_IDENTIFIER}`;
|
|
56
|
+
break;
|
|
57
|
+
case 'user':
|
|
58
|
+
key = `user${KEY_SEPARATOR}${identifiers.userId || DEFAULT_IDENTIFIER}`;
|
|
59
|
+
break;
|
|
60
|
+
case 'action_type':
|
|
61
|
+
key = `action${KEY_SEPARATOR}${identifiers.actionType || DEFAULT_IDENTIFIER}`;
|
|
62
|
+
break;
|
|
63
|
+
default:
|
|
64
|
+
key = 'unknown';
|
|
65
|
+
}
|
|
66
|
+
return prefix ? `${prefix}${KEY_SEPARATOR}${key}` : key;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Parse a bucket key to extract scope and identifier.
|
|
70
|
+
*
|
|
71
|
+
* @param key - The bucket key to parse
|
|
72
|
+
* @returns Object with scope and identifier, or null if invalid
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* parseBucketKey('rate-1:agent:agent-123')
|
|
77
|
+
* // { prefix: 'rate-1', scope: 'agent', identifier: 'agent-123' }
|
|
78
|
+
*
|
|
79
|
+
* parseBucketKey('global')
|
|
80
|
+
* // { prefix: undefined, scope: 'global', identifier: undefined }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export function parseBucketKey(key) {
|
|
84
|
+
if (!key)
|
|
85
|
+
return null;
|
|
86
|
+
const parts = key.split(KEY_SEPARATOR);
|
|
87
|
+
// Handle simple global key
|
|
88
|
+
if (parts.length === 1 && parts[0] === 'global') {
|
|
89
|
+
return { scope: 'global' };
|
|
90
|
+
}
|
|
91
|
+
// Handle keys without prefix: "scope:identifier"
|
|
92
|
+
if (parts.length === 2) {
|
|
93
|
+
const scopeMap = {
|
|
94
|
+
'agent': 'agent',
|
|
95
|
+
'session': 'session',
|
|
96
|
+
'user': 'user',
|
|
97
|
+
'action': 'action_type'
|
|
98
|
+
};
|
|
99
|
+
const scope = scopeMap[parts[0]];
|
|
100
|
+
if (scope) {
|
|
101
|
+
return { scope, identifier: parts[1] };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Handle keys with prefix: "prefix:scope:identifier" or "prefix:global"
|
|
105
|
+
if (parts.length >= 2) {
|
|
106
|
+
const prefix = parts[0];
|
|
107
|
+
const scopePart = parts[1];
|
|
108
|
+
if (scopePart === 'global') {
|
|
109
|
+
return { prefix, scope: 'global' };
|
|
110
|
+
}
|
|
111
|
+
const scopeMap = {
|
|
112
|
+
'agent': 'agent',
|
|
113
|
+
'session': 'session',
|
|
114
|
+
'user': 'user',
|
|
115
|
+
'action': 'action_type'
|
|
116
|
+
};
|
|
117
|
+
const scope = scopeMap[scopePart];
|
|
118
|
+
if (scope && parts.length >= 3) {
|
|
119
|
+
return { prefix, scope, identifier: parts.slice(2).join(KEY_SEPARATOR) };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { scope: 'unknown' };
|
|
123
|
+
}
|
|
124
|
+
// ============================================================================
|
|
125
|
+
// SLIDING WINDOW
|
|
126
|
+
// ============================================================================
|
|
127
|
+
/**
|
|
128
|
+
* SlidingWindow class for time-based window tracking.
|
|
129
|
+
*
|
|
130
|
+
* Supports both fixed and sliding window algorithms:
|
|
131
|
+
* - Fixed: Window resets at fixed boundaries (simpler, less memory)
|
|
132
|
+
* - Sliding: Window slides with time (more accurate, tracks individual requests)
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* // Create a window: 100 requests per minute
|
|
137
|
+
* const window = new SlidingWindow({
|
|
138
|
+
* windowMs: 60000,
|
|
139
|
+
* maxRequests: 100,
|
|
140
|
+
* algorithm: 'fixed'
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* // Check and record a request
|
|
144
|
+
* if (window.canAccept()) {
|
|
145
|
+
* window.record();
|
|
146
|
+
* // Process request
|
|
147
|
+
* } else {
|
|
148
|
+
* // Rate limited
|
|
149
|
+
* const stats = window.getStats();
|
|
150
|
+
* console.log(`Retry after ${stats.resetAt}`);
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export class SlidingWindow {
|
|
155
|
+
config;
|
|
156
|
+
// Fixed window state
|
|
157
|
+
count = 0;
|
|
158
|
+
burstCount = 0;
|
|
159
|
+
windowStart;
|
|
160
|
+
// Sliding window state (for sliding algorithm)
|
|
161
|
+
requestTimestamps = [];
|
|
162
|
+
constructor(config) {
|
|
163
|
+
this.config = {
|
|
164
|
+
windowMs: config.windowMs,
|
|
165
|
+
maxRequests: config.maxRequests,
|
|
166
|
+
burstLimit: config.burstLimit ?? config.maxRequests,
|
|
167
|
+
algorithm: config.algorithm ?? 'fixed'
|
|
168
|
+
};
|
|
169
|
+
this.windowStart = Date.now();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if the window has expired and needs reset.
|
|
173
|
+
*
|
|
174
|
+
* For fixed windows: Checks if current time is past window boundary.
|
|
175
|
+
* For sliding windows: Always returns false (sliding handles this differently).
|
|
176
|
+
*
|
|
177
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
178
|
+
* @returns Whether the window has expired
|
|
179
|
+
*/
|
|
180
|
+
isExpired(now = Date.now()) {
|
|
181
|
+
if (this.config.algorithm === 'sliding') {
|
|
182
|
+
return false; // Sliding windows don't expire in the same way
|
|
183
|
+
}
|
|
184
|
+
// Fixed window: expired when now - windowStart >= windowMs
|
|
185
|
+
return now - this.windowStart >= this.config.windowMs;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Reset the window to initial state.
|
|
189
|
+
*
|
|
190
|
+
* @param now - Timestamp to use as new window start (defaults to Date.now())
|
|
191
|
+
*/
|
|
192
|
+
reset(now = Date.now()) {
|
|
193
|
+
this.count = 0;
|
|
194
|
+
this.burstCount = 0;
|
|
195
|
+
this.windowStart = now;
|
|
196
|
+
this.requestTimestamps = [];
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Check if the window can accept another request.
|
|
200
|
+
* Automatically resets expired windows (for fixed algorithm).
|
|
201
|
+
*
|
|
202
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
203
|
+
* @returns Whether a request can be accepted
|
|
204
|
+
*/
|
|
205
|
+
canAccept(now = Date.now()) {
|
|
206
|
+
this.maybeResetWindow(now);
|
|
207
|
+
if (this.config.algorithm === 'sliding') {
|
|
208
|
+
return this.getSlidingCount(now) < this.config.maxRequests;
|
|
209
|
+
}
|
|
210
|
+
// Fixed window
|
|
211
|
+
if (this.count >= this.config.maxRequests) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
if (this.burstCount >= this.config.burstLimit) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check if the window can accept based on burst limit only.
|
|
221
|
+
*
|
|
222
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
223
|
+
* @returns Whether burst limit allows acceptance
|
|
224
|
+
*/
|
|
225
|
+
canAcceptBurst(now = Date.now()) {
|
|
226
|
+
this.maybeResetWindow(now);
|
|
227
|
+
if (this.config.algorithm === 'sliding') {
|
|
228
|
+
// For sliding, burst is same as regular limit
|
|
229
|
+
return this.getSlidingCount(now) < this.config.burstLimit;
|
|
230
|
+
}
|
|
231
|
+
return this.burstCount < this.config.burstLimit;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Record a request in the window.
|
|
235
|
+
*
|
|
236
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
237
|
+
*/
|
|
238
|
+
record(now = Date.now()) {
|
|
239
|
+
this.maybeResetWindow(now);
|
|
240
|
+
if (this.config.algorithm === 'sliding') {
|
|
241
|
+
this.requestTimestamps.push(now);
|
|
242
|
+
// Clean up old timestamps to prevent memory growth
|
|
243
|
+
this.cleanupOldTimestamps(now);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.count++;
|
|
247
|
+
this.burstCount++;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Get current window statistics.
|
|
252
|
+
*
|
|
253
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
254
|
+
* @returns WindowStats object with current state
|
|
255
|
+
*/
|
|
256
|
+
getStats(now = Date.now()) {
|
|
257
|
+
this.maybeResetWindow(now);
|
|
258
|
+
const count = this.config.algorithm === 'sliding'
|
|
259
|
+
? this.getSlidingCount(now)
|
|
260
|
+
: this.count;
|
|
261
|
+
const remaining = Math.max(0, this.config.maxRequests - count);
|
|
262
|
+
const resetAt = this.windowStart + this.config.windowMs;
|
|
263
|
+
return {
|
|
264
|
+
count,
|
|
265
|
+
remaining,
|
|
266
|
+
windowStart: this.windowStart,
|
|
267
|
+
resetAt,
|
|
268
|
+
resetAtISO: new Date(resetAt).toISOString(),
|
|
269
|
+
exceeded: count >= this.config.maxRequests,
|
|
270
|
+
usagePercent: Math.min(100, Math.round((count / this.config.maxRequests) * 100))
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get the current count of requests in the window.
|
|
275
|
+
*
|
|
276
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
277
|
+
* @returns Current request count
|
|
278
|
+
*/
|
|
279
|
+
getCount(now = Date.now()) {
|
|
280
|
+
this.maybeResetWindow(now);
|
|
281
|
+
return this.config.algorithm === 'sliding'
|
|
282
|
+
? this.getSlidingCount(now)
|
|
283
|
+
: this.count;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Get remaining requests before limit is hit.
|
|
287
|
+
*
|
|
288
|
+
* @param now - Current timestamp (defaults to Date.now())
|
|
289
|
+
* @returns Number of remaining requests
|
|
290
|
+
*/
|
|
291
|
+
getRemaining(now = Date.now()) {
|
|
292
|
+
return Math.max(0, this.config.maxRequests - this.getCount(now));
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Get timestamp when the window resets.
|
|
296
|
+
*
|
|
297
|
+
* @returns Reset timestamp in milliseconds since epoch
|
|
298
|
+
*/
|
|
299
|
+
getResetTime() {
|
|
300
|
+
return this.windowStart + this.config.windowMs;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get the window configuration.
|
|
304
|
+
*
|
|
305
|
+
* @returns The window configuration
|
|
306
|
+
*/
|
|
307
|
+
getConfig() {
|
|
308
|
+
return { ...this.config };
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Set internal state (useful for persistence/restoration).
|
|
312
|
+
*
|
|
313
|
+
* @param state - State to restore
|
|
314
|
+
*/
|
|
315
|
+
setState(state) {
|
|
316
|
+
this.count = state.count;
|
|
317
|
+
this.windowStart = state.windowStart;
|
|
318
|
+
this.burstCount = state.burstCount ?? 0;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Get internal state (useful for persistence).
|
|
322
|
+
*
|
|
323
|
+
* @returns Current internal state
|
|
324
|
+
*/
|
|
325
|
+
getState() {
|
|
326
|
+
return {
|
|
327
|
+
count: this.count,
|
|
328
|
+
windowStart: this.windowStart,
|
|
329
|
+
burstCount: this.burstCount
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
// Private methods
|
|
333
|
+
maybeResetWindow(now) {
|
|
334
|
+
if (this.config.algorithm === 'fixed' && this.isExpired(now)) {
|
|
335
|
+
this.reset(now);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
getSlidingCount(now) {
|
|
339
|
+
const windowStart = now - this.config.windowMs;
|
|
340
|
+
return this.requestTimestamps.filter(ts => ts > windowStart).length;
|
|
341
|
+
}
|
|
342
|
+
cleanupOldTimestamps(now) {
|
|
343
|
+
const windowStart = now - this.config.windowMs;
|
|
344
|
+
// Keep only timestamps within the window plus a small buffer
|
|
345
|
+
this.requestTimestamps = this.requestTimestamps.filter(ts => ts > windowStart - 1000);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// FACTORY FUNCTIONS
|
|
350
|
+
// ============================================================================
|
|
351
|
+
/**
|
|
352
|
+
* Create a sliding window with common presets.
|
|
353
|
+
*
|
|
354
|
+
* @param preset - Preset name
|
|
355
|
+
* @returns Configured SlidingWindow
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* ```typescript
|
|
359
|
+
* // 60 requests per minute
|
|
360
|
+
* const perMinute = createWindowPreset('per-minute');
|
|
361
|
+
*
|
|
362
|
+
* // 1000 requests per hour
|
|
363
|
+
* const perHour = createWindowPreset('per-hour');
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
export function createWindowPreset(preset) {
|
|
367
|
+
const presets = {
|
|
368
|
+
'per-second': { windowMs: 1000, maxRequests: 10, algorithm: 'fixed' },
|
|
369
|
+
'per-minute': { windowMs: 60000, maxRequests: 60, algorithm: 'fixed' },
|
|
370
|
+
'per-hour': { windowMs: 3600000, maxRequests: 1000, algorithm: 'fixed' },
|
|
371
|
+
'per-day': { windowMs: 86400000, maxRequests: 10000, algorithm: 'fixed' }
|
|
372
|
+
};
|
|
373
|
+
return new SlidingWindow(presets[preset]);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Create multiple bucket keys for different scopes from the same identifiers.
|
|
377
|
+
*
|
|
378
|
+
* @param identifiers - Identifiers to use
|
|
379
|
+
* @param prefix - Optional prefix for all keys
|
|
380
|
+
* @returns Object with keys for each scope
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* const keys = createBucketKeys({ agentId: 'a1', userId: 'u1' }, 'rate');
|
|
385
|
+
* // {
|
|
386
|
+
* // global: 'rate:global',
|
|
387
|
+
* // agent: 'rate:agent:a1',
|
|
388
|
+
* // user: 'rate:user:u1',
|
|
389
|
+
* // session: 'rate:session:unknown',
|
|
390
|
+
* // action_type: 'rate:action:unknown'
|
|
391
|
+
* // }
|
|
392
|
+
* ```
|
|
393
|
+
*/
|
|
394
|
+
export function createBucketKeys(identifiers, prefix) {
|
|
395
|
+
return {
|
|
396
|
+
global: buildBucketKey('global', identifiers, prefix),
|
|
397
|
+
agent: buildBucketKey('agent', identifiers, prefix),
|
|
398
|
+
session: buildBucketKey('session', identifiers, prefix),
|
|
399
|
+
user: buildBucketKey('user', identifiers, prefix),
|
|
400
|
+
action_type: buildBucketKey('action_type', identifiers, prefix)
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
//# sourceMappingURL=rate-limiting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiting.js","sourceRoot":"","sources":["../../src/utils/rate-limiting.ts"],"names":[],"mappings":"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"}
|