sovr-mcp-proxy 7.0.0 → 7.2.0
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/dist/auditDashboard.d.mts +208 -0
- package/dist/auditDashboard.d.ts +208 -0
- package/dist/auditDashboard.js +398 -0
- package/dist/auditDashboard.mjs +370 -0
- package/dist/mcpProxyInterceptor.d.mts +256 -0
- package/dist/mcpProxyInterceptor.d.ts +256 -0
- package/dist/mcpProxyInterceptor.js +579 -0
- package/dist/mcpProxyInterceptor.mjs +552 -0
- package/dist/semanticAnalyzer.d.mts +247 -0
- package/dist/semanticAnalyzer.d.ts +247 -0
- package/dist/semanticAnalyzer.js +911 -0
- package/dist/semanticAnalyzer.mjs +874 -0
- package/dist/teamPolicyManager.d.mts +202 -0
- package/dist/teamPolicyManager.d.ts +202 -0
- package/dist/teamPolicyManager.js +529 -0
- package/dist/teamPolicyManager.mjs +502 -0
- package/package.json +2 -2
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/auditDashboard.ts
|
|
21
|
+
var auditDashboard_exports = {};
|
|
22
|
+
__export(auditDashboard_exports, {
|
|
23
|
+
AuditDashboard: () => AuditDashboard,
|
|
24
|
+
createAuditDashboard: () => createAuditDashboard,
|
|
25
|
+
createFreeTierDashboard: () => createFreeTierDashboard,
|
|
26
|
+
createProDashboard: () => createProDashboard
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(auditDashboard_exports);
|
|
29
|
+
var AuditDashboard = class {
|
|
30
|
+
entries = [];
|
|
31
|
+
config;
|
|
32
|
+
saveTimer = null;
|
|
33
|
+
quotaCounter = 0;
|
|
34
|
+
quotaPeriodStart = Date.now();
|
|
35
|
+
constructor(config = {}) {
|
|
36
|
+
this.config = {
|
|
37
|
+
maxEntries: config.maxEntries ?? 5e4,
|
|
38
|
+
persistPath: config.persistPath,
|
|
39
|
+
autoSaveInterval: config.autoSaveInterval ?? 6e4,
|
|
40
|
+
quotaLimit: config.quotaLimit ?? 1e4,
|
|
41
|
+
quotaPeriod: config.quotaPeriod ?? 30 * 24 * 60 * 60 * 1e3,
|
|
42
|
+
// 30 days
|
|
43
|
+
redactPatterns: config.redactPatterns ?? [
|
|
44
|
+
/password/i,
|
|
45
|
+
/secret/i,
|
|
46
|
+
/token/i,
|
|
47
|
+
/api.?key/i,
|
|
48
|
+
/credential/i,
|
|
49
|
+
/authorization/i,
|
|
50
|
+
/cookie/i,
|
|
51
|
+
/session/i
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
if (this.config.persistPath && this.config.autoSaveInterval > 0) {
|
|
55
|
+
this.saveTimer = setInterval(() => this.persist(), this.config.autoSaveInterval);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ─── Core Operations ───────────────────────────────────────────────────
|
|
59
|
+
/** Record a new audit entry */
|
|
60
|
+
record(entry) {
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const fullEntry = {
|
|
63
|
+
...entry,
|
|
64
|
+
id: `ae_${now}_${Math.random().toString(36).slice(2, 8)}`,
|
|
65
|
+
timestamp: new Date(now).toISOString(),
|
|
66
|
+
epochMs: now,
|
|
67
|
+
arguments: this.redactSensitive(entry.arguments)
|
|
68
|
+
};
|
|
69
|
+
this.entries.push(fullEntry);
|
|
70
|
+
this.quotaCounter++;
|
|
71
|
+
if (this.entries.length > this.config.maxEntries) {
|
|
72
|
+
this.entries = this.entries.slice(-this.config.maxEntries);
|
|
73
|
+
}
|
|
74
|
+
return fullEntry;
|
|
75
|
+
}
|
|
76
|
+
/** Get entries with optional filters */
|
|
77
|
+
query(filters = {}) {
|
|
78
|
+
let filtered = this.entries;
|
|
79
|
+
if (filters.from) filtered = filtered.filter((e) => e.epochMs >= filters.from);
|
|
80
|
+
if (filters.to) filtered = filtered.filter((e) => e.epochMs <= filters.to);
|
|
81
|
+
if (filters.toolName) filtered = filtered.filter((e) => e.toolName === filters.toolName);
|
|
82
|
+
if (filters.decision) filtered = filtered.filter((e) => e.decision === filters.decision);
|
|
83
|
+
if (filters.riskLevel) filtered = filtered.filter((e) => e.riskLevel === filters.riskLevel);
|
|
84
|
+
if (filters.sessionId) filtered = filtered.filter((e) => e.sessionId === filters.sessionId);
|
|
85
|
+
if (filters.agentId) filtered = filtered.filter((e) => e.agentId === filters.agentId);
|
|
86
|
+
const total = filtered.length;
|
|
87
|
+
const offset = filters.offset ?? 0;
|
|
88
|
+
const limit = filters.limit ?? 100;
|
|
89
|
+
const paged = filtered.slice(offset, offset + limit);
|
|
90
|
+
return { entries: paged, total };
|
|
91
|
+
}
|
|
92
|
+
/** Get a single entry by ID */
|
|
93
|
+
getById(id) {
|
|
94
|
+
return this.entries.find((e) => e.id === id);
|
|
95
|
+
}
|
|
96
|
+
// ─── Statistics ────────────────────────────────────────────────────────
|
|
97
|
+
/** Get dashboard statistics for a time range */
|
|
98
|
+
getStats(from, to) {
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
const rangeFrom = from ?? now - 24 * 60 * 60 * 1e3;
|
|
101
|
+
const rangeTo = to ?? now;
|
|
102
|
+
const filtered = this.entries.filter((e) => e.epochMs >= rangeFrom && e.epochMs <= rangeTo);
|
|
103
|
+
const byDecision = {};
|
|
104
|
+
const byRiskLevel = {};
|
|
105
|
+
const byTool = {};
|
|
106
|
+
const byType = {};
|
|
107
|
+
const policyCount = {};
|
|
108
|
+
const blockedTools = {};
|
|
109
|
+
const latencies = [];
|
|
110
|
+
for (const entry of filtered) {
|
|
111
|
+
byDecision[entry.decision] = (byDecision[entry.decision] || 0) + 1;
|
|
112
|
+
byRiskLevel[entry.riskLevel] = (byRiskLevel[entry.riskLevel] || 0) + 1;
|
|
113
|
+
byTool[entry.toolName] = (byTool[entry.toolName] || 0) + 1;
|
|
114
|
+
byType[entry.type] = (byType[entry.type] || 0) + 1;
|
|
115
|
+
latencies.push(entry.durationMs);
|
|
116
|
+
if (entry.policyId) {
|
|
117
|
+
policyCount[entry.policyId] = (policyCount[entry.policyId] || 0) + 1;
|
|
118
|
+
}
|
|
119
|
+
if (entry.decision === "block") {
|
|
120
|
+
blockedTools[entry.toolName] = (blockedTools[entry.toolName] || 0) + 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const sortedLatencies = latencies.sort((a, b) => a - b);
|
|
124
|
+
const p95Index = Math.floor(sortedLatencies.length * 0.95);
|
|
125
|
+
const p99Index = Math.floor(sortedLatencies.length * 0.99);
|
|
126
|
+
const topBlocked = Object.entries(blockedTools).sort(([, a], [, b]) => b - a).slice(0, 10).map(([tool, count]) => ({ tool, count }));
|
|
127
|
+
const topPolicies = Object.entries(policyCount).sort(([, a], [, b]) => b - a).slice(0, 10).map(([policyId, count]) => ({ policyId, count }));
|
|
128
|
+
const riskHistogram = [
|
|
129
|
+
{ range: "0-20", count: filtered.filter((e) => e.riskScore < 20).length },
|
|
130
|
+
{ range: "20-40", count: filtered.filter((e) => e.riskScore >= 20 && e.riskScore < 40).length },
|
|
131
|
+
{ range: "40-60", count: filtered.filter((e) => e.riskScore >= 40 && e.riskScore < 60).length },
|
|
132
|
+
{ range: "60-80", count: filtered.filter((e) => e.riskScore >= 60 && e.riskScore < 80).length },
|
|
133
|
+
{ range: "80-100", count: filtered.filter((e) => e.riskScore >= 80).length }
|
|
134
|
+
];
|
|
135
|
+
const durationMinutes = Math.max(1, (rangeTo - rangeFrom) / 6e4);
|
|
136
|
+
const allowed = byDecision["allow"] || 0;
|
|
137
|
+
return {
|
|
138
|
+
timeRange: { from: new Date(rangeFrom).toISOString(), to: new Date(rangeTo).toISOString() },
|
|
139
|
+
totalEvents: filtered.length,
|
|
140
|
+
byDecision,
|
|
141
|
+
byRiskLevel,
|
|
142
|
+
byTool,
|
|
143
|
+
byType,
|
|
144
|
+
successRate: filtered.length > 0 ? Math.round(allowed / filtered.length * 1e4) / 100 : 100,
|
|
145
|
+
avgLatencyMs: latencies.length > 0 ? Math.round(latencies.reduce((a, b) => a + b, 0) / latencies.length) : 0,
|
|
146
|
+
p95LatencyMs: sortedLatencies[p95Index] ?? 0,
|
|
147
|
+
p99LatencyMs: sortedLatencies[p99Index] ?? 0,
|
|
148
|
+
eventsPerMinute: Math.round(filtered.length / durationMinutes * 100) / 100,
|
|
149
|
+
topBlocked,
|
|
150
|
+
topPolicies,
|
|
151
|
+
riskHistogram
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// ─── Trends ────────────────────────────────────────────────────────────
|
|
155
|
+
/** Get time-series trend data */
|
|
156
|
+
getTrends(granularity = "hourly", from, to) {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
const rangeFrom = from ?? now - 7 * 24 * 60 * 60 * 1e3;
|
|
159
|
+
const rangeTo = to ?? now;
|
|
160
|
+
const bucketSize = granularity === "hourly" ? 36e5 : granularity === "daily" ? 864e5 : 6048e5;
|
|
161
|
+
const filtered = this.entries.filter((e) => e.epochMs >= rangeFrom && e.epochMs <= rangeTo);
|
|
162
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const entry of filtered) {
|
|
164
|
+
const bucketStart = Math.floor(entry.epochMs / bucketSize) * bucketSize;
|
|
165
|
+
if (!buckets.has(bucketStart)) buckets.set(bucketStart, []);
|
|
166
|
+
buckets.get(bucketStart).push(entry);
|
|
167
|
+
}
|
|
168
|
+
const points = [];
|
|
169
|
+
let current = Math.floor(rangeFrom / bucketSize) * bucketSize;
|
|
170
|
+
while (current <= rangeTo) {
|
|
171
|
+
const entries = buckets.get(current) || [];
|
|
172
|
+
const allowed = entries.filter((e) => e.decision === "allow" || e.decision === "transform").length;
|
|
173
|
+
const blocked = entries.filter((e) => e.decision === "block" || e.decision === "rate-limited").length;
|
|
174
|
+
points.push({
|
|
175
|
+
label: this.formatBucketLabel(current, granularity),
|
|
176
|
+
epochMs: current,
|
|
177
|
+
total: entries.length,
|
|
178
|
+
allowed,
|
|
179
|
+
blocked,
|
|
180
|
+
avgRisk: entries.length > 0 ? Math.round(entries.reduce((sum, e) => sum + e.riskScore, 0) / entries.length) : 0,
|
|
181
|
+
avgLatency: entries.length > 0 ? Math.round(entries.reduce((sum, e) => sum + e.durationMs, 0) / entries.length) : 0
|
|
182
|
+
});
|
|
183
|
+
current += bucketSize;
|
|
184
|
+
}
|
|
185
|
+
return points;
|
|
186
|
+
}
|
|
187
|
+
// ─── Quota ─────────────────────────────────────────────────────────────
|
|
188
|
+
/** Get current quota status with prediction */
|
|
189
|
+
getQuotaStatus() {
|
|
190
|
+
const now = Date.now();
|
|
191
|
+
if (now - this.quotaPeriodStart > this.config.quotaPeriod) {
|
|
192
|
+
this.quotaCounter = 0;
|
|
193
|
+
this.quotaPeriodStart = now;
|
|
194
|
+
}
|
|
195
|
+
const elapsed = now - this.quotaPeriodStart;
|
|
196
|
+
const elapsedDays = Math.max(1, elapsed / (24 * 60 * 60 * 1e3));
|
|
197
|
+
const dailyAverage = Math.round(this.quotaCounter / elapsedDays);
|
|
198
|
+
const remaining = this.config.quotaLimit - this.quotaCounter;
|
|
199
|
+
const daysRemaining = dailyAverage > 0 ? Math.round(remaining / dailyAverage) : void 0;
|
|
200
|
+
let predictedExhaustion;
|
|
201
|
+
if (daysRemaining !== void 0 && daysRemaining > 0) {
|
|
202
|
+
predictedExhaustion = new Date(now + daysRemaining * 24 * 60 * 60 * 1e3).toISOString();
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
used: this.quotaCounter,
|
|
206
|
+
limit: this.config.quotaLimit,
|
|
207
|
+
percentage: Math.round(this.quotaCounter / this.config.quotaLimit * 1e4) / 100,
|
|
208
|
+
predictedExhaustion,
|
|
209
|
+
dailyAverage,
|
|
210
|
+
daysRemaining
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// ─── Export ────────────────────────────────────────────────────────────
|
|
214
|
+
/** Export audit log as CSV */
|
|
215
|
+
exportCSV(filters) {
|
|
216
|
+
const { entries } = this.query({ from: filters?.from, to: filters?.to, limit: this.config.maxEntries });
|
|
217
|
+
const headers = [
|
|
218
|
+
"id",
|
|
219
|
+
"timestamp",
|
|
220
|
+
"type",
|
|
221
|
+
"toolName",
|
|
222
|
+
"decision",
|
|
223
|
+
"riskScore",
|
|
224
|
+
"riskLevel",
|
|
225
|
+
"policyId",
|
|
226
|
+
"reason",
|
|
227
|
+
"durationMs",
|
|
228
|
+
"sessionId",
|
|
229
|
+
"agentId",
|
|
230
|
+
"error"
|
|
231
|
+
];
|
|
232
|
+
const rows = entries.map((e) => [
|
|
233
|
+
e.id,
|
|
234
|
+
e.timestamp,
|
|
235
|
+
e.type,
|
|
236
|
+
e.toolName,
|
|
237
|
+
e.decision,
|
|
238
|
+
e.riskScore,
|
|
239
|
+
e.riskLevel,
|
|
240
|
+
e.policyId || "",
|
|
241
|
+
`"${(e.reason || "").replace(/"/g, '""')}"`,
|
|
242
|
+
e.durationMs,
|
|
243
|
+
e.sessionId || "",
|
|
244
|
+
e.agentId || "",
|
|
245
|
+
e.error ? `"${e.error.replace(/"/g, '""')}"` : ""
|
|
246
|
+
].join(","));
|
|
247
|
+
return [headers.join(","), ...rows].join("\n");
|
|
248
|
+
}
|
|
249
|
+
/** Export audit log as JSON */
|
|
250
|
+
exportJSON(filters) {
|
|
251
|
+
const { entries } = this.query({ from: filters?.from, to: filters?.to, limit: this.config.maxEntries });
|
|
252
|
+
return JSON.stringify({
|
|
253
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
254
|
+
totalEntries: entries.length,
|
|
255
|
+
entries
|
|
256
|
+
}, null, 2);
|
|
257
|
+
}
|
|
258
|
+
/** Export Trust Bundle (evidence package) */
|
|
259
|
+
exportTrustBundle(sessionId) {
|
|
260
|
+
const { entries } = sessionId ? this.query({ sessionId, limit: this.config.maxEntries }) : this.query({ limit: 1e3 });
|
|
261
|
+
const stats = this.getStats();
|
|
262
|
+
const dataStr = JSON.stringify(entries);
|
|
263
|
+
let hash = 0;
|
|
264
|
+
for (let i = 0; i < dataStr.length; i++) {
|
|
265
|
+
const char = dataStr.charCodeAt(i);
|
|
266
|
+
hash = (hash << 5) - hash + char;
|
|
267
|
+
hash |= 0;
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
bundleId: `tb_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
|
271
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272
|
+
entries,
|
|
273
|
+
stats,
|
|
274
|
+
integrity: `sha256:${Math.abs(hash).toString(16).padStart(16, "0")}`
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
// ─── Session Management ────────────────────────────────────────────────
|
|
278
|
+
/** Start a new audit session */
|
|
279
|
+
startSession(agentId) {
|
|
280
|
+
const sessionId = `ses_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
281
|
+
this.record({
|
|
282
|
+
type: "session_start",
|
|
283
|
+
toolName: "__session__",
|
|
284
|
+
arguments: {},
|
|
285
|
+
decision: "allow",
|
|
286
|
+
riskScore: 0,
|
|
287
|
+
riskLevel: "safe",
|
|
288
|
+
reason: "Session started",
|
|
289
|
+
durationMs: 0,
|
|
290
|
+
sessionId,
|
|
291
|
+
agentId
|
|
292
|
+
});
|
|
293
|
+
return sessionId;
|
|
294
|
+
}
|
|
295
|
+
/** End an audit session */
|
|
296
|
+
endSession(sessionId) {
|
|
297
|
+
this.record({
|
|
298
|
+
type: "session_end",
|
|
299
|
+
toolName: "__session__",
|
|
300
|
+
arguments: {},
|
|
301
|
+
decision: "allow",
|
|
302
|
+
riskScore: 0,
|
|
303
|
+
riskLevel: "safe",
|
|
304
|
+
reason: "Session ended",
|
|
305
|
+
durationMs: 0,
|
|
306
|
+
sessionId
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
// ─── Lifecycle ─────────────────────────────────────────────────────────
|
|
310
|
+
/** Get total entry count */
|
|
311
|
+
get size() {
|
|
312
|
+
return this.entries.length;
|
|
313
|
+
}
|
|
314
|
+
/** Clear all entries */
|
|
315
|
+
clear() {
|
|
316
|
+
this.entries = [];
|
|
317
|
+
}
|
|
318
|
+
/** Destroy and cleanup */
|
|
319
|
+
destroy() {
|
|
320
|
+
if (this.saveTimer) {
|
|
321
|
+
clearInterval(this.saveTimer);
|
|
322
|
+
this.saveTimer = null;
|
|
323
|
+
}
|
|
324
|
+
this.persist();
|
|
325
|
+
}
|
|
326
|
+
// ─── Private ─────────────────────────────────────────────────────────────
|
|
327
|
+
redactSensitive(args) {
|
|
328
|
+
const result = JSON.parse(JSON.stringify(args));
|
|
329
|
+
const redact = (obj) => {
|
|
330
|
+
for (const key of Object.keys(obj)) {
|
|
331
|
+
if (this.config.redactPatterns.some((p) => p.test(key))) {
|
|
332
|
+
obj[key] = "[REDACTED]";
|
|
333
|
+
} else if (typeof obj[key] === "object" && obj[key] !== null) {
|
|
334
|
+
redact(obj[key]);
|
|
335
|
+
} else if (typeof obj[key] === "string") {
|
|
336
|
+
let val = obj[key];
|
|
337
|
+
for (const pattern of this.config.redactPatterns) {
|
|
338
|
+
if (pattern.test(val)) {
|
|
339
|
+
obj[key] = "[REDACTED]";
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
redact(result);
|
|
347
|
+
return result;
|
|
348
|
+
}
|
|
349
|
+
formatBucketLabel(epochMs, granularity) {
|
|
350
|
+
const d = new Date(epochMs);
|
|
351
|
+
switch (granularity) {
|
|
352
|
+
case "hourly":
|
|
353
|
+
return `${d.getUTCMonth() + 1}/${d.getUTCDate()} ${d.getUTCHours().toString().padStart(2, "0")}:00`;
|
|
354
|
+
case "daily":
|
|
355
|
+
return `${d.getUTCFullYear()}-${(d.getUTCMonth() + 1).toString().padStart(2, "0")}-${d.getUTCDate().toString().padStart(2, "0")}`;
|
|
356
|
+
case "weekly":
|
|
357
|
+
return `Week of ${d.getUTCMonth() + 1}/${d.getUTCDate()}`;
|
|
358
|
+
default:
|
|
359
|
+
return d.toISOString();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
persist() {
|
|
363
|
+
if (!this.config.persistPath) return;
|
|
364
|
+
try {
|
|
365
|
+
const data = JSON.stringify({
|
|
366
|
+
entries: this.entries.slice(-this.config.maxEntries),
|
|
367
|
+
quotaCounter: this.quotaCounter,
|
|
368
|
+
quotaPeriodStart: this.quotaPeriodStart
|
|
369
|
+
});
|
|
370
|
+
void data;
|
|
371
|
+
} catch {
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
function createAuditDashboard(overrides = {}) {
|
|
376
|
+
return new AuditDashboard(overrides);
|
|
377
|
+
}
|
|
378
|
+
function createFreeTierDashboard() {
|
|
379
|
+
return new AuditDashboard({
|
|
380
|
+
maxEntries: 1e3,
|
|
381
|
+
quotaLimit: 500,
|
|
382
|
+
quotaPeriod: 30 * 24 * 60 * 60 * 1e3
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
function createProDashboard() {
|
|
386
|
+
return new AuditDashboard({
|
|
387
|
+
maxEntries: 5e4,
|
|
388
|
+
quotaLimit: 5e4,
|
|
389
|
+
quotaPeriod: 30 * 24 * 60 * 60 * 1e3
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
393
|
+
0 && (module.exports = {
|
|
394
|
+
AuditDashboard,
|
|
395
|
+
createAuditDashboard,
|
|
396
|
+
createFreeTierDashboard,
|
|
397
|
+
createProDashboard
|
|
398
|
+
});
|