@nxuss/lemma 0.5.5 → 0.5.6

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 (49) hide show
  1. package/dist/cjs/cloud/BurstRateLimiter.d.ts +26 -0
  2. package/dist/cjs/cloud/BurstRateLimiter.d.ts.map +1 -0
  3. package/dist/cjs/cloud/BurstRateLimiter.js +63 -0
  4. package/dist/cjs/cloud/BurstRateLimiter.js.map +1 -0
  5. package/dist/cjs/cloud/KeyManager.d.ts +1 -0
  6. package/dist/cjs/cloud/KeyManager.d.ts.map +1 -1
  7. package/dist/cjs/cloud/KeyManager.js +28 -1
  8. package/dist/cjs/cloud/KeyManager.js.map +1 -1
  9. package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts +60 -0
  10. package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
  11. package/dist/cjs/cloud/PostgresQuotaLimiter.js +200 -0
  12. package/dist/cjs/cloud/PostgresQuotaLimiter.js.map +1 -0
  13. package/dist/cjs/cloud/TenantCache.d.ts +1 -1
  14. package/dist/cjs/cloud/TenantCache.d.ts.map +1 -1
  15. package/dist/cjs/cloud/TenantCache.js +21 -3
  16. package/dist/cjs/cloud/TenantCache.js.map +1 -1
  17. package/dist/cjs/cloud/server.d.ts +3 -1
  18. package/dist/cjs/cloud/server.d.ts.map +1 -1
  19. package/dist/cjs/cloud/server.js +42 -5
  20. package/dist/cjs/cloud/server.js.map +1 -1
  21. package/dist/cjs/cloud/types.d.ts +3 -0
  22. package/dist/cjs/cloud/types.d.ts.map +1 -1
  23. package/dist/cjs/cloud/types.js +3 -3
  24. package/dist/cjs/cloud/types.js.map +1 -1
  25. package/dist/esm/cloud/BurstRateLimiter.d.ts +26 -0
  26. package/dist/esm/cloud/BurstRateLimiter.d.ts.map +1 -0
  27. package/dist/esm/cloud/BurstRateLimiter.js +59 -0
  28. package/dist/esm/cloud/BurstRateLimiter.js.map +1 -0
  29. package/dist/esm/cloud/KeyManager.d.ts +1 -0
  30. package/dist/esm/cloud/KeyManager.d.ts.map +1 -1
  31. package/dist/esm/cloud/KeyManager.js +28 -1
  32. package/dist/esm/cloud/KeyManager.js.map +1 -1
  33. package/dist/esm/cloud/PostgresQuotaLimiter.d.ts +60 -0
  34. package/dist/esm/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
  35. package/dist/esm/cloud/PostgresQuotaLimiter.js +196 -0
  36. package/dist/esm/cloud/PostgresQuotaLimiter.js.map +1 -0
  37. package/dist/esm/cloud/TenantCache.d.ts +1 -1
  38. package/dist/esm/cloud/TenantCache.d.ts.map +1 -1
  39. package/dist/esm/cloud/TenantCache.js +21 -3
  40. package/dist/esm/cloud/TenantCache.js.map +1 -1
  41. package/dist/esm/cloud/server.d.ts +3 -1
  42. package/dist/esm/cloud/server.d.ts.map +1 -1
  43. package/dist/esm/cloud/server.js +41 -5
  44. package/dist/esm/cloud/server.js.map +1 -1
  45. package/dist/esm/cloud/types.d.ts +3 -0
  46. package/dist/esm/cloud/types.d.ts.map +1 -1
  47. package/dist/esm/cloud/types.js +3 -3
  48. package/dist/esm/cloud/types.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Lemma Cloud — Burst Rate Limiter
3
+ *
4
+ * Highly optimized, in-memory sliding window rate limiter.
5
+ * Caps requests at 10 RPS per API Key.
6
+ * Adds <50 microseconds overhead (0.05ms) to the critical path.
7
+ */
8
+ export declare class BurstRateLimiter {
9
+ private windows;
10
+ private maxRequestsPerSecond;
11
+ private windowSizeMs;
12
+ constructor(maxRps?: number, windowSizeMs?: number);
13
+ /**
14
+ * Check if a request is allowed under the rate limit
15
+ * @param keyId The unique identifier for the rate limit window (e.g. API key)
16
+ */
17
+ check(keyId: string): {
18
+ allowed: boolean;
19
+ remaining: number;
20
+ };
21
+ /**
22
+ * Helper to manually clear a rate limit window (useful for unit tests)
23
+ */
24
+ clear(keyId: string): void;
25
+ }
26
+ //# sourceMappingURL=BurstRateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BurstRateLimiter.d.ts","sourceRoot":"","sources":["../../../src/cloud/BurstRateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,YAAY,CAAS;gBAEjB,MAAM,SAAK,EAAE,YAAY,SAAO;IAoB5C;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IA0B7D;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAG3B"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ /**
3
+ * Lemma Cloud — Burst Rate Limiter
4
+ *
5
+ * Highly optimized, in-memory sliding window rate limiter.
6
+ * Caps requests at 10 RPS per API Key.
7
+ * Adds <50 microseconds overhead (0.05ms) to the critical path.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.BurstRateLimiter = void 0;
11
+ class BurstRateLimiter {
12
+ constructor(maxRps = 10, windowSizeMs = 1000) {
13
+ this.windows = new Map();
14
+ this.maxRequestsPerSecond = maxRps;
15
+ this.windowSizeMs = windowSizeMs;
16
+ // Periodic sweep to prevent memory leak (runs every minute)
17
+ setInterval(() => {
18
+ const now = Date.now();
19
+ const expirationTime = now - this.windowSizeMs;
20
+ for (const [key, timestamps] of this.windows.entries()) {
21
+ const active = timestamps.filter(t => t > expirationTime);
22
+ if (active.length === 0) {
23
+ this.windows.delete(key);
24
+ }
25
+ else {
26
+ this.windows.set(key, active);
27
+ }
28
+ }
29
+ }, 60000).unref();
30
+ }
31
+ /**
32
+ * Check if a request is allowed under the rate limit
33
+ * @param keyId The unique identifier for the rate limit window (e.g. API key)
34
+ */
35
+ check(keyId) {
36
+ const now = Date.now();
37
+ const expirationTime = now - this.windowSizeMs;
38
+ let timestamps = this.windows.get(keyId) || [];
39
+ // Prune expired timestamps (older than 1 second)
40
+ timestamps = timestamps.filter(t => t > expirationTime);
41
+ if (timestamps.length >= this.maxRequestsPerSecond) {
42
+ return {
43
+ allowed: false,
44
+ remaining: 0,
45
+ };
46
+ }
47
+ // Register current request
48
+ timestamps.push(now);
49
+ this.windows.set(keyId, timestamps);
50
+ return {
51
+ allowed: true,
52
+ remaining: this.maxRequestsPerSecond - timestamps.length,
53
+ };
54
+ }
55
+ /**
56
+ * Helper to manually clear a rate limit window (useful for unit tests)
57
+ */
58
+ clear(keyId) {
59
+ this.windows.delete(keyId);
60
+ }
61
+ }
62
+ exports.BurstRateLimiter = BurstRateLimiter;
63
+ //# sourceMappingURL=BurstRateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BurstRateLimiter.js","sourceRoot":"","sources":["../../../src/cloud/BurstRateLimiter.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,MAAa,gBAAgB;IAK3B,YAAY,MAAM,GAAG,EAAE,EAAE,YAAY,GAAG,IAAI;QAJpC,YAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;QAK5C,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QAEjC,4DAA4D;QAC5D,WAAW,CAAC,GAAG,EAAE;YACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;YAE/C,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;gBACvD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;gBAC1D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAa;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,cAAc,GAAG,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;QAE/C,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAE/C,iDAAiD;QACjD,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC;QAExD,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACnD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,CAAC;aACb,CAAC;QACJ,CAAC;QAED,2BAA2B;QAC3B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAEpC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI,CAAC,oBAAoB,GAAG,UAAU,CAAC,MAAM;SACzD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACF;AA7DD,4CA6DC"}
@@ -22,6 +22,7 @@ export declare class KeyManager {
22
22
  getByTenant(tenantId: string): ApiKey[];
23
23
  get(keyId: string): ApiKey | undefined;
24
24
  private maybeResetDaily;
25
+ private maybeResetMonthly;
25
26
  private scheduleSave;
26
27
  private save;
27
28
  private load;
@@ -1 +1 @@
1
- {"version":3,"file":"KeyManager.d.ts","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAE9C,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA+B;gBAEpC,SAAS,SAAqB;IAO1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,CAAU,GAAG,MAAM;IAkB/E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA4B1E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAUlC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO;IAQzD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAQ9B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,IAAI;CAYb"}
1
+ {"version":3,"file":"KeyManager.d.ts","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAE9C,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA+B;gBAEpC,SAAS,SAAqB;IAO1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,CAAU,GAAG,MAAM;IAkB/E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAsC1E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWlC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO;IAQzD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAQ9B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIvC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,IAAI;CAiBb"}
@@ -31,7 +31,7 @@ class KeyManager {
31
31
  plan,
32
32
  createdAt: Date.now(),
33
33
  active: true,
34
- usage: { today: 0, total: 0, lastReset: Date.now() },
34
+ usage: { today: 0, monthly: 0, total: 0, lastReset: Date.now(), lastMonthlyReset: Date.now() },
35
35
  };
36
36
  this.keys.set(id, key);
37
37
  this.scheduleSave();
@@ -49,6 +49,8 @@ class KeyManager {
49
49
  }
50
50
  // Reset daily counter if needed
51
51
  this.maybeResetDaily(key);
52
+ // Reset monthly counter if needed
53
+ this.maybeResetMonthly(key);
52
54
  // Check plan limits
53
55
  const limits = types_1.PLAN_LIMITS[key.plan];
54
56
  if (key.usage.today >= limits.dailyRequests) {
@@ -59,6 +61,12 @@ class KeyManager {
59
61
  : 'Daily request limit reached. Contact support to increase limits.',
60
62
  };
61
63
  }
64
+ if (!process.env.DATABASE_URL && key.usage.monthly >= limits.monthlyRequests) {
65
+ return {
66
+ valid: false,
67
+ reason: 'Monthly Cloud Quota Exceeded. Please upgrade your plan.',
68
+ };
69
+ }
62
70
  return { valid: true, key };
63
71
  }
64
72
  // ─── Usage Tracking ─────────────────────────────────────────────────────────
@@ -67,6 +75,7 @@ class KeyManager {
67
75
  if (!key)
68
76
  return;
69
77
  key.usage.today++;
78
+ key.usage.monthly++;
70
79
  key.usage.total++;
71
80
  this.scheduleSave();
72
81
  }
@@ -103,6 +112,17 @@ class KeyManager {
103
112
  key.usage.lastReset = now;
104
113
  }
105
114
  }
115
+ maybeResetMonthly(key) {
116
+ const now = Date.now();
117
+ const currentDate = new Date(now);
118
+ const lastResetDate = new Date(key.usage.lastMonthlyReset || 0);
119
+ if (currentDate.getUTCMonth() !== lastResetDate.getUTCMonth() ||
120
+ currentDate.getUTCFullYear() !== lastResetDate.getUTCFullYear()) {
121
+ key.usage.monthly = 0;
122
+ key.usage.lastMonthlyReset = now;
123
+ this.scheduleSave();
124
+ }
125
+ }
106
126
  scheduleSave() {
107
127
  if (this.saveTimer)
108
128
  return;
@@ -129,6 +149,13 @@ class KeyManager {
129
149
  return;
130
150
  const data = JSON.parse(fs_1.default.readFileSync(this.storePath, 'utf-8'));
131
151
  for (const [id, key] of data) {
152
+ // Upgrade legacy schema key attributes
153
+ if (key && key.usage) {
154
+ if (key.usage.monthly === undefined)
155
+ key.usage.monthly = 0;
156
+ if (key.usage.lastMonthlyReset === undefined)
157
+ key.usage.lastMonthlyReset = key.usage.lastReset || Date.now();
158
+ }
132
159
  this.keys.set(id, key);
133
160
  }
134
161
  console.log(`[KeyManager] Loaded ${this.keys.size} keys`);
@@ -1 +1 @@
1
- {"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../src/cloud/KeyManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { Pool } from 'pg';
2
+ export interface TenantQuota {
3
+ tenantId: string;
4
+ totalRequestsThisMonth: number;
5
+ quotaLimit: number;
6
+ billingCycleResetDate: Date;
7
+ }
8
+ export declare class PostgresQuotaLimiter {
9
+ private pool;
10
+ private inMemoryQuotas;
11
+ private pendingIncrements;
12
+ private flushIntervalMs;
13
+ private flushTimer;
14
+ private isFlushing;
15
+ constructor(pool: Pool, flushIntervalMs?: number);
16
+ /**
17
+ * Start the background flush timer
18
+ */
19
+ start(): void;
20
+ /**
21
+ * Stop the background flush timer and flush any remaining increments
22
+ */
23
+ stop(): Promise<void>;
24
+ /**
25
+ * Synchronously validate a tenant's request against in-memory limits.
26
+ * If a cache miss occurs, initializes with default limits and lazily loads from Postgres in the background.
27
+ */
28
+ checkQuota(tenantId: string, defaultLimit?: number): {
29
+ allowed: boolean;
30
+ reason?: string;
31
+ };
32
+ /**
33
+ * Lazily loads tenant quota details from PostgreSQL in the background.
34
+ * Merges loaded DB counts with any in-memory increments that accumulated in the meantime.
35
+ */
36
+ private lazyLoadTenantQuota;
37
+ /**
38
+ * Queue increments in memory to await bulk batch flush
39
+ */
40
+ private enqueueIncrement;
41
+ /**
42
+ * Performs an atomic database bulk UPSERT of all pending in-memory increments.
43
+ * If a database error occurs, pending increments are safely rolled back and merged
44
+ * into the in-memory map to try again in the next batch flush cycle.
45
+ */
46
+ flushPendingIncrements(): Promise<void>;
47
+ /**
48
+ * Helper to calculate the 1st of the next calendar month at midnight UTC
49
+ */
50
+ private calculateNextResetDate;
51
+ /**
52
+ * For test harness only: directly seed an in-memory quota entry
53
+ */
54
+ seedQuotaForTest(tenantId: string, quota: TenantQuota): void;
55
+ /**
56
+ * For test harness only: check in-memory status
57
+ */
58
+ getInMemoryQuota(tenantId: string): TenantQuota | undefined;
59
+ }
60
+ //# sourceMappingURL=PostgresQuotaLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresQuotaLimiter.d.ts","sourceRoot":"","sources":["../../../src/cloud/PostgresQuotaLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE1B,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB,EAAE,IAAI,CAAC;CAC7B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,EAAE,IAAI,EAAE,eAAe,SAAO;IAK9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,SAAQ,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA6CzF;;;OAGG;YACW,mBAAmB;IA8CjC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;OAIG;IACG,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD7C;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAQ9B;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI;IAI5D;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;CAG5D"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostgresQuotaLimiter = void 0;
4
+ class PostgresQuotaLimiter {
5
+ constructor(pool, flushIntervalMs = 5000) {
6
+ this.inMemoryQuotas = new Map();
7
+ this.pendingIncrements = new Map();
8
+ this.flushTimer = null;
9
+ this.isFlushing = false;
10
+ this.pool = pool;
11
+ this.flushIntervalMs = flushIntervalMs;
12
+ }
13
+ /**
14
+ * Start the background flush timer
15
+ */
16
+ start() {
17
+ if (this.flushTimer)
18
+ return;
19
+ this.flushTimer = setInterval(() => {
20
+ this.flushPendingIncrements().catch(err => {
21
+ console.error('[PostgresQuotaLimiter] Background flush failed:', err);
22
+ });
23
+ }, this.flushIntervalMs).unref();
24
+ console.log(`[PostgresQuotaLimiter] Asynchronous batch flusher started (interval: ${this.flushIntervalMs}ms)`);
25
+ }
26
+ /**
27
+ * Stop the background flush timer and flush any remaining increments
28
+ */
29
+ async stop() {
30
+ if (this.flushTimer) {
31
+ clearInterval(this.flushTimer);
32
+ this.flushTimer = null;
33
+ }
34
+ console.log('[PostgresQuotaLimiter] Stopping flusher, performing final flush...');
35
+ await this.flushPendingIncrements();
36
+ }
37
+ /**
38
+ * Synchronously validate a tenant's request against in-memory limits.
39
+ * If a cache miss occurs, initializes with default limits and lazily loads from Postgres in the background.
40
+ */
41
+ checkQuota(tenantId, defaultLimit = 50000) {
42
+ let quota = this.inMemoryQuotas.get(tenantId);
43
+ if (!quota) {
44
+ // 1. First-time seen in this memory session: initialize with sensible default
45
+ const nextReset = this.calculateNextResetDate();
46
+ quota = {
47
+ tenantId,
48
+ totalRequestsThisMonth: 0,
49
+ quotaLimit: defaultLimit,
50
+ billingCycleResetDate: nextReset,
51
+ };
52
+ this.inMemoryQuotas.set(tenantId, quota);
53
+ // 2. Trigger asynchronous, non-blocking load from PostgreSQL
54
+ this.lazyLoadTenantQuota(tenantId, defaultLimit).catch(err => {
55
+ console.error(`[PostgresQuotaLimiter] Failed to lazy load quota for ${tenantId}:`, err);
56
+ });
57
+ }
58
+ const now = Date.now();
59
+ // 3. Handle calendar reset boundary checking
60
+ if (now >= quota.billingCycleResetDate.getTime()) {
61
+ quota.totalRequestsThisMonth = 0;
62
+ quota.billingCycleResetDate = this.calculateNextResetDate();
63
+ // Record a zero-increment upsert to sync the new reset date to Postgres
64
+ this.enqueueIncrement(tenantId, 0);
65
+ }
66
+ // 4. Validate quota limit
67
+ if (quota.totalRequestsThisMonth >= quota.quotaLimit) {
68
+ return {
69
+ allowed: false,
70
+ reason: 'Monthly Cloud Quota Exceeded. Please upgrade your plan.',
71
+ };
72
+ }
73
+ // 5. Allow request, increment counter locally, and queue the increment
74
+ quota.totalRequestsThisMonth++;
75
+ this.enqueueIncrement(tenantId, 1);
76
+ return { allowed: true };
77
+ }
78
+ /**
79
+ * Lazily loads tenant quota details from PostgreSQL in the background.
80
+ * Merges loaded DB counts with any in-memory increments that accumulated in the meantime.
81
+ */
82
+ async lazyLoadTenantQuota(tenantId, defaultLimit) {
83
+ try {
84
+ const result = await this.pool.query('SELECT total_requests_this_month, quota_limit, billing_cycle_reset_date FROM tenant_quotas WHERE tenant_id = $1', [tenantId]);
85
+ const nextReset = this.calculateNextResetDate();
86
+ if (result.rows.length > 0) {
87
+ const row = result.rows[0];
88
+ const dbQuota = {
89
+ tenantId,
90
+ totalRequestsThisMonth: parseInt(row.total_requests_this_month, 10),
91
+ quotaLimit: parseInt(row.quota_limit, 10),
92
+ billingCycleResetDate: new Date(row.billing_cycle_reset_date),
93
+ };
94
+ const currentQuota = this.inMemoryQuotas.get(tenantId);
95
+ if (currentQuota) {
96
+ // Check if DB stored reset date has expired in the real world
97
+ if (Date.now() >= dbQuota.billingCycleResetDate.getTime()) {
98
+ dbQuota.totalRequestsThisMonth = 0;
99
+ dbQuota.billingCycleResetDate = nextReset;
100
+ }
101
+ // Merge: Add currently accumulated pending increments onto DB count
102
+ const pending = this.pendingIncrements.get(tenantId) || 0;
103
+ currentQuota.totalRequestsThisMonth = dbQuota.totalRequestsThisMonth + pending;
104
+ currentQuota.quotaLimit = dbQuota.quotaLimit;
105
+ currentQuota.billingCycleResetDate = dbQuota.billingCycleResetDate;
106
+ }
107
+ }
108
+ else {
109
+ // First-time tenant insertion in Postgres (UPSERT to initialize)
110
+ await this.pool.query(`INSERT INTO tenant_quotas (tenant_id, total_requests_this_month, quota_limit, billing_cycle_reset_date)
111
+ VALUES ($1, 0, $2, $3)
112
+ ON CONFLICT (tenant_id) DO NOTHING`, [tenantId, defaultLimit, nextReset]);
113
+ }
114
+ }
115
+ catch (err) {
116
+ console.error(`[PostgresQuotaLimiter] Database load error for tenant ${tenantId}:`, err);
117
+ }
118
+ }
119
+ /**
120
+ * Queue increments in memory to await bulk batch flush
121
+ */
122
+ enqueueIncrement(tenantId, amount) {
123
+ const current = this.pendingIncrements.get(tenantId) || 0;
124
+ this.pendingIncrements.set(tenantId, current + amount);
125
+ }
126
+ /**
127
+ * Performs an atomic database bulk UPSERT of all pending in-memory increments.
128
+ * If a database error occurs, pending increments are safely rolled back and merged
129
+ * into the in-memory map to try again in the next batch flush cycle.
130
+ */
131
+ async flushPendingIncrements() {
132
+ if (this.isFlushing || this.pendingIncrements.size === 0)
133
+ return;
134
+ this.isFlushing = true;
135
+ // Shallow copy and clear the queue immediately to avoid race conditions
136
+ // with new inbound requests accumulating during database I/O
137
+ const incrementsToFlush = new Map(this.pendingIncrements);
138
+ this.pendingIncrements.clear();
139
+ try {
140
+ const client = await this.pool.connect();
141
+ try {
142
+ await client.query('BEGIN');
143
+ for (const [tenantId, increment] of incrementsToFlush.entries()) {
144
+ const quota = this.inMemoryQuotas.get(tenantId);
145
+ const limit = quota ? quota.quotaLimit : 50000;
146
+ const resetDate = quota ? quota.billingCycleResetDate : this.calculateNextResetDate();
147
+ await client.query(`INSERT INTO tenant_quotas (tenant_id, total_requests_this_month, quota_limit, billing_cycle_reset_date)
148
+ VALUES ($1, $2, $3, $4)
149
+ ON CONFLICT (tenant_id) DO UPDATE
150
+ SET total_requests_this_month = tenant_quotas.total_requests_this_month + EXCLUDED.total_requests_this_month,
151
+ billing_cycle_reset_date = EXCLUDED.billing_cycle_reset_date,
152
+ updated_at = CURRENT_TIMESTAMP`, [tenantId, increment, limit, resetDate]);
153
+ }
154
+ await client.query('COMMIT');
155
+ }
156
+ catch (err) {
157
+ await client.query('ROLLBACK');
158
+ throw err;
159
+ }
160
+ finally {
161
+ client.release();
162
+ }
163
+ }
164
+ catch (err) {
165
+ console.error('[PostgresQuotaLimiter] Batch flush database error. Restoring increments:', err);
166
+ // Restore increments back to pending list so they are retried on the next run
167
+ for (const [tenantId, increment] of incrementsToFlush.entries()) {
168
+ const current = this.pendingIncrements.get(tenantId) || 0;
169
+ this.pendingIncrements.set(tenantId, current + increment);
170
+ }
171
+ }
172
+ finally {
173
+ this.isFlushing = false;
174
+ }
175
+ }
176
+ /**
177
+ * Helper to calculate the 1st of the next calendar month at midnight UTC
178
+ */
179
+ calculateNextResetDate() {
180
+ const d = new Date();
181
+ d.setUTCMonth(d.getUTCMonth() + 1);
182
+ d.setUTCDate(1);
183
+ d.setUTCHours(0, 0, 0, 0);
184
+ return d;
185
+ }
186
+ /**
187
+ * For test harness only: directly seed an in-memory quota entry
188
+ */
189
+ seedQuotaForTest(tenantId, quota) {
190
+ this.inMemoryQuotas.set(tenantId, quota);
191
+ }
192
+ /**
193
+ * For test harness only: check in-memory status
194
+ */
195
+ getInMemoryQuota(tenantId) {
196
+ return this.inMemoryQuotas.get(tenantId);
197
+ }
198
+ }
199
+ exports.PostgresQuotaLimiter = PostgresQuotaLimiter;
200
+ //# sourceMappingURL=PostgresQuotaLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PostgresQuotaLimiter.js","sourceRoot":"","sources":["../../../src/cloud/PostgresQuotaLimiter.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@ export declare class TenantCache {
23
23
  data?: any;
24
24
  similarity?: number;
25
25
  }>;
26
- store(key: string, input: string, data: any, ttl: number): Promise<void>;
26
+ store(key: string, input: string, data: any, ttl: number, maxEntries?: number): Promise<void>;
27
27
  getStats(): Promise<TenantStats>;
28
28
  private embed;
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TenantCache.d.ts","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAuD,MAAM,SAAS,CAAC;AAU3F,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,SAAS,CAAa;IAE9B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAS3E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA0CvD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBxE,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;YAyBxB,KAAK;CAyCpB"}
1
+ {"version":3,"file":"TenantCache.d.ts","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,WAAW,EAAuD,MAAM,SAAS,CAAC;AAU3F,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,SAAS,CAAa;IAE9B,OAAO,CAAC,KAAK,CAA0B;gBAE3B,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAS3E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,KAAK,CACT,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAuDvD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B5F,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;YAyBxB,KAAK;CAyCpB"}
@@ -85,9 +85,21 @@ class TenantCache {
85
85
  return { hit: false };
86
86
  }
87
87
  const meta = results.metadatas[0][0];
88
- // Check TTL
89
- if (meta.ttl > 0 && Date.now() - meta.createdAt > meta.ttl) {
88
+ const age = Date.now() - meta.createdAt;
89
+ // 1. Enforce strict 7-day TTL cache eviction policy (Pro/SaaS tier)
90
+ const MAX_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
91
+ if (age > MAX_TTL_MS) {
90
92
  this.stats.misses++;
93
+ // Evict expired entry from vector database in background
94
+ const expiredId = results.ids[0][0];
95
+ this.chromaCollection.delete({ ids: [expiredId] }).catch(() => { });
96
+ return { hit: false };
97
+ }
98
+ // 2. Check custom entry TTL
99
+ if (meta.ttl > 0 && age > meta.ttl) {
100
+ this.stats.misses++;
101
+ const expiredId = results.ids[0][0];
102
+ this.chromaCollection.delete({ ids: [expiredId] }).catch(() => { });
91
103
  return { hit: false };
92
104
  }
93
105
  this.stats.hits++;
@@ -99,10 +111,16 @@ class TenantCache {
99
111
  }
100
112
  }
101
113
  // ─── Store ──────────────────────────────────────────────────────────────────
102
- async store(key, input, data, ttl) {
114
+ async store(key, input, data, ttl, maxEntries = 10000) {
103
115
  if (!this.chromaCollection)
104
116
  await this.initialize();
105
117
  try {
118
+ // Enforce maximum cache entries constraint to prevent storage bloat
119
+ const count = await this.chromaCollection.count();
120
+ if (count >= maxEntries) {
121
+ console.warn(`⚠️ [TenantCache:${this.tenantId}] Vector cache limit reached (${count}/${maxEntries} entries). Skipping store to prevent storage bloat.`);
122
+ return;
123
+ }
106
124
  const embedding = await this.embed(input);
107
125
  await this.chromaCollection.upsert({
108
126
  ids: [key],
@@ -1 +1 @@
1
- {"version":3,"file":"TenantCache.js","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TenantCache.js","sourceRoot":"","sources":["../../../src/cloud/TenantCache.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGH,mCAA2F;AAU3F,MAAa,WAAW;IActB,YAAY,QAAgB,EAAE,SAAiB,EAAE,SAAiB,EAAE,KAAa;QAPzE,iBAAY,GAAQ,IAAI,CAAC;QACzB,qBAAgB,GAAQ,IAAI,CAAC;QAC7B,mBAAc,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC7C,cAAS,GAAQ,IAAI,CAAC;QAEtB,UAAK,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAGrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,iDAAiD;QACjD,IAAI,CAAC,cAAc,GAAG,SAAS,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,EAAE,YAAY,EAAE,GAAG,wDAAa,UAAU,GAAC,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC;YACpE,IAAI,EAAE,IAAI,CAAC,cAAc;YACzB,QAAQ,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE;SAC5D,CAAC,CAAC;IACL,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CACT,KAAa,EACb,SAAiB;QAEjB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAEpD,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBAChD,eAAe,EAAE,CAAC,SAAS,CAAC;gBAC5B,QAAQ,EAAE,CAAC;gBACX,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC;aACpC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,CAAC;YAEhC,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAQ,CAAC;YAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YAExC,oEAAoE;YACpE,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;YACrD,IAAI,GAAG,GAAG,UAAU,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,yDAAyD;gBACzD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,4BAA4B;YAC5B,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACxB,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,QAAQ,gBAAgB,EAAE,GAAG,CAAC,CAAC;YAClE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CAAC,GAAW,EAAE,KAAa,EAAE,IAAS,EAAE,GAAW,EAAE,UAAU,GAAG,KAAK;QAChF,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAEpD,IAAI,CAAC;YACH,oEAAoE;YACpE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAClD,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,QAAQ,iCAAiC,KAAK,IAAI,UAAU,qDAAqD,CAAC,CAAC;gBACzJ,OAAO;YACT,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;gBACjC,GAAG,EAAE,CAAC,GAAG,CAAC;gBACV,UAAU,EAAE,CAAC,SAAS,CAAC;gBACvB,SAAS,EAAE,CAAC,KAAK,CAAC;gBAClB,SAAS,EAAE,CAAC;wBACV,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;wBAC1B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;wBACrB,GAAG;wBACH,MAAM,EAAE,IAAI,CAAC,QAAQ;qBACtB,CAAC;aACH,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,QAAQ,gBAAgB,EAAE,GAAG,CAAC,CAAC;YAClE,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,+EAA+E;IAE/E,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAClD,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,8BAAsB,CAAC;QAC7D,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,gBAAgB;gBAAE,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QAEV,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,KAAK,EAAE,yBAAyB;YACtC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;YACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,aAAa,EAAE,KAAK;YACpB,OAAO;YACP,oBAAoB,EAAE,WAAW;YACjC,kBAAkB,EAAE,UAAU,CAAC,CAAC,WAAW,GAAG,sBAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACzE,SAAS;SACV,CAAC;IACJ,CAAC;IAED,+EAA+E;IAEvE,KAAK,CAAC,KAAK,CAAC,IAAY;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAErF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,CAAC;QAC5D,IAAI,SAAS,GAAa,EAAE,CAAC;QAE7B,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,CAAC,wDAAa,OAAO,GAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAC1B,sCAAsC,EACtC,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,EAChD;gBACE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE;gBAClE,OAAO,EAAE,KAAK;aACf,CACF,CAAC;YACF,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACzC,CAAC;aAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,aAAa;YACb,MAAM,EAAE,QAAQ,EAAE,GAAG,wDAAa,sBAAsB,GAAC,CAAC;YAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC7E,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAa,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,CAAC,wDAAa,OAAO,GAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAC1B,GAAG,IAAI,CAAC,SAAS,iBAAiB,EAClC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EACnC,EAAE,OAAO,EAAE,KAAK,EAAE,CACnB,CAAC;YACF,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,IAAI;YAAE,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QACjE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AA7LD,kCA6LC"}
@@ -10,8 +10,10 @@
10
10
  */
11
11
  import { KeyManager } from './KeyManager';
12
12
  import { TenantCache } from './TenantCache';
13
+ import { PostgresQuotaLimiter } from './PostgresQuotaLimiter';
13
14
  declare const app: import("express-serve-static-core").Express;
14
15
  declare const keyManager: KeyManager;
15
16
  declare const tenantCaches: Map<string, TenantCache>;
16
- export { app, keyManager, tenantCaches };
17
+ declare let postgresQuotaLimiter: PostgresQuotaLimiter | null;
18
+ export { app, keyManager, tenantCaches, postgresQuotaLimiter };
17
19
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cloud/server.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,QAAA,MAAM,GAAG,6CAAY,CAAC;AAYtB,QAAA,MAAM,UAAU,YAAmB,CAAC;AACpC,QAAA,MAAM,YAAY,0BAAiC,CAAC;AAySpD,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cloud/server.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,QAAA,MAAM,GAAG,6CAAY,CAAC;AAYtB,QAAA,MAAM,UAAU,YAAmB,CAAC;AACpC,QAAA,MAAM,YAAY,0BAAiC,CAAC;AAIpD,QAAA,IAAI,oBAAoB,EAAE,oBAAoB,GAAG,IAAW,CAAC;AA6U7D,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC"}