paygate-mcp 1.0.0 → 1.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/README.md +73 -1
- package/dist/audit.d.ts +102 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +165 -0
- package/dist/audit.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +262 -16
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +91 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +202 -0
- package/dist/session.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,6 +40,8 @@ Agent → PayGate (auth + billing) → Your MCP Server (stdio or HTTP)
|
|
|
40
40
|
- **Usage Quotas** — Daily/monthly call and credit limits per key (with UTC auto-reset)
|
|
41
41
|
- **Dynamic Pricing** — Charge extra credits based on input size (`creditsPerKbInput`)
|
|
42
42
|
- **OAuth 2.1** — Full authorization server with PKCE, client registration, Bearer tokens
|
|
43
|
+
- **SSE Streaming** — Full MCP Streamable HTTP transport (POST SSE, GET notifications, DELETE sessions)
|
|
44
|
+
- **Audit Log** — Structured audit trail with retention policies, query API, CSV/JSON export
|
|
43
45
|
- **Refund on Failure** — Automatically refund credits when downstream tool calls fail
|
|
44
46
|
- **Webhook Events** — POST batched usage events to any URL for external billing/alerting
|
|
45
47
|
- **Config File Mode** — Load all settings from a JSON file (`--config`)
|
|
@@ -247,7 +249,9 @@ A real-time admin UI for managing keys, viewing usage, and monitoring tool calls
|
|
|
247
249
|
|
|
248
250
|
| Endpoint | Method | Auth | Description |
|
|
249
251
|
|----------|--------|------|-------------|
|
|
250
|
-
| `/mcp` | POST | `X-API-Key` or `Bearer` | JSON-RPC 2.0 proxy
|
|
252
|
+
| `/mcp` | POST | `X-API-Key` or `Bearer` | JSON-RPC 2.0 proxy (returns JSON or SSE) |
|
|
253
|
+
| `/mcp` | GET | `X-API-Key` or `Bearer` | SSE notification stream (Streamable HTTP) |
|
|
254
|
+
| `/mcp` | DELETE | `Mcp-Session-Id` | Terminate an MCP session |
|
|
251
255
|
| `/balance` | GET | `X-API-Key` | Client self-service — check credits, quota, ACL, expiry |
|
|
252
256
|
| `/keys` | POST | `X-Admin-Key` | Create API key (with ACL, expiry, quota, credits) |
|
|
253
257
|
| `/keys` | GET | `X-Admin-Key` | List all keys (masked, with expiry status) |
|
|
@@ -267,6 +271,9 @@ A real-time admin UI for managing keys, viewing usage, and monitoring tool calls
|
|
|
267
271
|
| `/oauth/token` | POST | None | Token endpoint (code exchange + refresh) |
|
|
268
272
|
| `/oauth/revoke` | POST | None | Token revocation (RFC 7009) |
|
|
269
273
|
| `/oauth/clients` | GET | `X-Admin-Key` | List registered OAuth clients |
|
|
274
|
+
| `/audit` | GET | `X-Admin-Key` | Query audit log (filter by type, actor, time) |
|
|
275
|
+
| `/audit/export` | GET | `X-Admin-Key` | Export full audit log (JSON or CSV) |
|
|
276
|
+
| `/audit/stats` | GET | `X-Admin-Key` | Audit log statistics |
|
|
270
277
|
| `/` | GET | None | Health check |
|
|
271
278
|
|
|
272
279
|
### Free Methods
|
|
@@ -527,6 +534,64 @@ curl -X POST http://localhost:3402/oauth/token \
|
|
|
527
534
|
|
|
528
535
|
OAuth tokens are backed by API keys — each token maps to an API key for billing. The `/mcp` endpoint accepts both `X-API-Key` and `Authorization: Bearer` headers.
|
|
529
536
|
|
|
537
|
+
### SSE Streaming (MCP Streamable HTTP)
|
|
538
|
+
|
|
539
|
+
PayGate implements the full MCP Streamable HTTP transport with SSE support:
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
# POST /mcp with SSE response (add Accept header)
|
|
543
|
+
curl -N -X POST http://localhost:3402/mcp \
|
|
544
|
+
-H "Content-Type: application/json" \
|
|
545
|
+
-H "Accept: text/event-stream" \
|
|
546
|
+
-H "X-API-Key: YOUR_KEY" \
|
|
547
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"analyze","arguments":{}}}'
|
|
548
|
+
# Response: SSE stream with event: message + data: {jsonrpc response}
|
|
549
|
+
|
|
550
|
+
# GET /mcp — Open SSE notification stream
|
|
551
|
+
curl -N http://localhost:3402/mcp \
|
|
552
|
+
-H "Accept: text/event-stream" \
|
|
553
|
+
-H "Mcp-Session-Id: mcp_sess_..."
|
|
554
|
+
# Receives server-initiated notifications as SSE events
|
|
555
|
+
|
|
556
|
+
# DELETE /mcp — Terminate session
|
|
557
|
+
curl -X DELETE http://localhost:3402/mcp \
|
|
558
|
+
-H "Mcp-Session-Id: mcp_sess_..."
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
**Session Management:**
|
|
562
|
+
- Every POST `/mcp` response includes an `Mcp-Session-Id` header
|
|
563
|
+
- Clients reuse sessions by sending `Mcp-Session-Id` on subsequent requests
|
|
564
|
+
- GET `/mcp` opens a long-lived SSE connection for server-to-client notifications
|
|
565
|
+
- DELETE `/mcp` terminates a session and closes all SSE connections
|
|
566
|
+
- Sessions auto-expire after 30 minutes of inactivity
|
|
567
|
+
|
|
568
|
+
**Transport modes:**
|
|
569
|
+
- `POST /mcp` without `Accept: text/event-stream` → standard JSON response (backward compatible)
|
|
570
|
+
- `POST /mcp` with `Accept: text/event-stream` → SSE-wrapped JSON-RPC response
|
|
571
|
+
- `GET /mcp` with `Accept: text/event-stream` → long-lived notification stream
|
|
572
|
+
|
|
573
|
+
### Audit Log
|
|
574
|
+
|
|
575
|
+
Every significant operation is recorded in a structured audit trail:
|
|
576
|
+
|
|
577
|
+
```bash
|
|
578
|
+
# Query audit events (with filtering)
|
|
579
|
+
curl http://localhost:3402/audit?types=key.created,gate.deny&limit=50 \
|
|
580
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
581
|
+
|
|
582
|
+
# Export full audit log as CSV
|
|
583
|
+
curl http://localhost:3402/audit/export?format=csv \
|
|
584
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY" > audit.csv
|
|
585
|
+
|
|
586
|
+
# Get audit statistics
|
|
587
|
+
curl http://localhost:3402/audit/stats \
|
|
588
|
+
-H "X-Admin-Key: YOUR_ADMIN_KEY"
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**Tracked events:** `key.created`, `key.revoked`, `key.topup`, `key.acl_updated`, `key.expiry_updated`, `key.quota_updated`, `key.limit_updated`, `gate.allow`, `gate.deny`, `session.created`, `session.destroyed`, `oauth.client_registered`, `oauth.token_issued`, `oauth.token_revoked`, `admin.auth_failed`, `billing.refund`.
|
|
592
|
+
|
|
593
|
+
**Retention:** Ring buffer (default 10,000 events), age-based cleanup (default 30 days), automatic periodic enforcement.
|
|
594
|
+
|
|
530
595
|
### Config File Mode
|
|
531
596
|
|
|
532
597
|
Load all settings from a JSON file instead of CLI flags:
|
|
@@ -624,6 +689,9 @@ const result = await client.callTool('search', { query: 'hello' });
|
|
|
624
689
|
- OAuth 2.1 with PKCE (S256) — no implicit grant, no plain challenge
|
|
625
690
|
- OAuth tokens are opaque hex strings (no JWT data leakage)
|
|
626
691
|
- Quota counters reset atomically at UTC boundaries
|
|
692
|
+
- SSE sessions auto-expire (30 min), max 1000 concurrent, max 3 SSE per session
|
|
693
|
+
- Audit log with retention policies (ring buffer, age-based cleanup)
|
|
694
|
+
- API keys masked in audit events (only first 7 + last 4 chars visible)
|
|
627
695
|
- Red-teamed with 101 adversarial security tests across 14 passes
|
|
628
696
|
|
|
629
697
|
## Current Limitations
|
|
@@ -651,6 +719,10 @@ const result = await client.callTool('search', { query: 'hello' });
|
|
|
651
719
|
- [x] Usage quotas — daily/monthly call and credit limits per key
|
|
652
720
|
- [x] Dynamic pricing — charge by input size (`creditsPerKbInput`)
|
|
653
721
|
- [x] OAuth 2.1 — PKCE, client registration, Bearer tokens, token refresh/revocation
|
|
722
|
+
- [x] SSE streaming — Full MCP Streamable HTTP transport with session management
|
|
723
|
+
- [x] Audit log — Structured audit trail with retention, query API, CSV/JSON export
|
|
724
|
+
- [ ] Registry/discovery — Agent-discoverable paid tools
|
|
725
|
+
- [ ] Horizontal scaling — Redis-backed state for multi-process deployments
|
|
654
726
|
|
|
655
727
|
## Requirements
|
|
656
728
|
|
package/dist/audit.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuditLogger — Structured audit trail with retention policies.
|
|
3
|
+
*
|
|
4
|
+
* Logs every significant event: key management, gate decisions, billing,
|
|
5
|
+
* session lifecycle, and admin operations. Ring buffer with configurable
|
|
6
|
+
* max size and age-based retention. Zero external dependencies.
|
|
7
|
+
*/
|
|
8
|
+
export type AuditEventType = 'key.created' | 'key.revoked' | 'key.topup' | 'key.acl_updated' | 'key.expiry_updated' | 'key.quota_updated' | 'key.limit_updated' | 'gate.allow' | 'gate.deny' | 'session.created' | 'session.destroyed' | 'oauth.client_registered' | 'oauth.token_issued' | 'oauth.token_revoked' | 'admin.auth_failed' | 'billing.refund';
|
|
9
|
+
export interface AuditEvent {
|
|
10
|
+
/** Monotonically increasing ID */
|
|
11
|
+
id: number;
|
|
12
|
+
/** ISO 8601 timestamp */
|
|
13
|
+
timestamp: string;
|
|
14
|
+
/** Event type (dot-separated category.action) */
|
|
15
|
+
type: AuditEventType;
|
|
16
|
+
/** Actor: API key (masked), admin, system, or null */
|
|
17
|
+
actor: string;
|
|
18
|
+
/** Human-readable description */
|
|
19
|
+
message: string;
|
|
20
|
+
/** Structured metadata (varies by event type) */
|
|
21
|
+
metadata: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface AuditLogConfig {
|
|
24
|
+
/** Maximum number of events to retain. Default: 10000. */
|
|
25
|
+
maxEvents: number;
|
|
26
|
+
/** Maximum age of events in hours. 0 = no age limit. Default: 720 (30 days). */
|
|
27
|
+
maxAgeHours: number;
|
|
28
|
+
/** How often to run retention cleanup in ms. Default: 60000 (1 min). */
|
|
29
|
+
cleanupIntervalMs: number;
|
|
30
|
+
}
|
|
31
|
+
export interface AuditQuery {
|
|
32
|
+
/** Filter by event type(s). */
|
|
33
|
+
types?: AuditEventType[];
|
|
34
|
+
/** Filter by actor (partial match). */
|
|
35
|
+
actor?: string;
|
|
36
|
+
/** Return events since this ISO date. */
|
|
37
|
+
since?: string;
|
|
38
|
+
/** Return events until this ISO date. */
|
|
39
|
+
until?: string;
|
|
40
|
+
/** Max events to return. Default: 100. */
|
|
41
|
+
limit?: number;
|
|
42
|
+
/** Offset for pagination. Default: 0. */
|
|
43
|
+
offset?: number;
|
|
44
|
+
}
|
|
45
|
+
export interface AuditQueryResult {
|
|
46
|
+
total: number;
|
|
47
|
+
offset: number;
|
|
48
|
+
limit: number;
|
|
49
|
+
events: AuditEvent[];
|
|
50
|
+
}
|
|
51
|
+
export declare class AuditLogger {
|
|
52
|
+
private events;
|
|
53
|
+
private nextId;
|
|
54
|
+
private readonly config;
|
|
55
|
+
private cleanupTimer;
|
|
56
|
+
constructor(config?: Partial<AuditLogConfig>);
|
|
57
|
+
/**
|
|
58
|
+
* Log an audit event.
|
|
59
|
+
*/
|
|
60
|
+
log(type: AuditEventType, actor: string, message: string, metadata?: Record<string, unknown>): AuditEvent;
|
|
61
|
+
/**
|
|
62
|
+
* Query events with optional filters.
|
|
63
|
+
*/
|
|
64
|
+
query(q?: AuditQuery): AuditQueryResult;
|
|
65
|
+
/**
|
|
66
|
+
* Get summary statistics of the audit log.
|
|
67
|
+
*/
|
|
68
|
+
stats(): {
|
|
69
|
+
totalEvents: number;
|
|
70
|
+
oldestEvent: string | null;
|
|
71
|
+
newestEvent: string | null;
|
|
72
|
+
eventsByType: Record<string, number>;
|
|
73
|
+
eventsLastHour: number;
|
|
74
|
+
eventsLast24h: number;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Export all events (for backup/external systems).
|
|
78
|
+
*/
|
|
79
|
+
exportAll(): AuditEvent[];
|
|
80
|
+
/**
|
|
81
|
+
* Export events as CSV string.
|
|
82
|
+
*/
|
|
83
|
+
exportCsv(q?: AuditQuery): string;
|
|
84
|
+
/**
|
|
85
|
+
* Get event count.
|
|
86
|
+
*/
|
|
87
|
+
get size(): number;
|
|
88
|
+
/**
|
|
89
|
+
* Enforce retention policy: remove events older than maxAgeHours.
|
|
90
|
+
*/
|
|
91
|
+
enforceRetention(): number;
|
|
92
|
+
/**
|
|
93
|
+
* Clear all events.
|
|
94
|
+
*/
|
|
95
|
+
clear(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Stop cleanup timer.
|
|
98
|
+
*/
|
|
99
|
+
destroy(): void;
|
|
100
|
+
}
|
|
101
|
+
export declare function maskKeyForAudit(key: string): string;
|
|
102
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,cAAc,GAEtB,aAAa,GACb,aAAa,GACb,WAAW,GACX,iBAAiB,GACjB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,GAEnB,YAAY,GACZ,WAAW,GAEX,iBAAiB,GACjB,mBAAmB,GAEnB,yBAAyB,GACzB,oBAAoB,GACpB,qBAAqB,GAErB,mBAAmB,GAEnB,gBAAgB,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,IAAI,EAAE,cAAc,CAAC;IACrB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAUD,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,YAAY,CAA+C;gBAEvD,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAU5C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,UAAU;IAoB7G;;OAEG;IACH,KAAK,CAAC,CAAC,GAAE,UAAe,GAAG,gBAAgB;IAoC3C;;OAEG;IACH,KAAK,IAAI;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;KACvB;IA0BD;;OAEG;IACH,SAAS,IAAI,UAAU,EAAE;IAIzB;;OAEG;IACH,SAAS,CAAC,CAAC,GAAE,UAAe,GAAG,MAAM;IASrC;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAS1B;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB;AAID,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD"}
|
package/dist/audit.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AuditLogger — Structured audit trail with retention policies.
|
|
4
|
+
*
|
|
5
|
+
* Logs every significant event: key management, gate decisions, billing,
|
|
6
|
+
* session lifecycle, and admin operations. Ring buffer with configurable
|
|
7
|
+
* max size and age-based retention. Zero external dependencies.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.AuditLogger = void 0;
|
|
11
|
+
exports.maskKeyForAudit = maskKeyForAudit;
|
|
12
|
+
const DEFAULT_AUDIT_CONFIG = {
|
|
13
|
+
maxEvents: 10_000,
|
|
14
|
+
maxAgeHours: 720, // 30 days
|
|
15
|
+
cleanupIntervalMs: 60_000, // 1 minute
|
|
16
|
+
};
|
|
17
|
+
// ─── AuditLogger Class ───────────────────────────────────────────────────────
|
|
18
|
+
class AuditLogger {
|
|
19
|
+
events = [];
|
|
20
|
+
nextId = 1;
|
|
21
|
+
config;
|
|
22
|
+
cleanupTimer = null;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = { ...DEFAULT_AUDIT_CONFIG, ...config };
|
|
25
|
+
// Start retention cleanup timer
|
|
26
|
+
if (this.config.cleanupIntervalMs > 0) {
|
|
27
|
+
this.cleanupTimer = setInterval(() => this.enforceRetention(), this.config.cleanupIntervalMs);
|
|
28
|
+
this.cleanupTimer.unref(); // Don't prevent process exit
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Log an audit event.
|
|
33
|
+
*/
|
|
34
|
+
log(type, actor, message, metadata = {}) {
|
|
35
|
+
const event = {
|
|
36
|
+
id: this.nextId++,
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
type,
|
|
39
|
+
actor,
|
|
40
|
+
message,
|
|
41
|
+
metadata,
|
|
42
|
+
};
|
|
43
|
+
this.events.push(event);
|
|
44
|
+
// Enforce max size immediately (ring buffer behavior)
|
|
45
|
+
if (this.events.length > this.config.maxEvents) {
|
|
46
|
+
this.events = this.events.slice(-this.config.maxEvents);
|
|
47
|
+
}
|
|
48
|
+
return event;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Query events with optional filters.
|
|
52
|
+
*/
|
|
53
|
+
query(q = {}) {
|
|
54
|
+
let filtered = this.events;
|
|
55
|
+
// Filter by type(s)
|
|
56
|
+
if (q.types && q.types.length > 0) {
|
|
57
|
+
const typeSet = new Set(q.types);
|
|
58
|
+
filtered = filtered.filter(e => typeSet.has(e.type));
|
|
59
|
+
}
|
|
60
|
+
// Filter by actor (partial match, case-insensitive)
|
|
61
|
+
if (q.actor) {
|
|
62
|
+
const actorLower = q.actor.toLowerCase();
|
|
63
|
+
filtered = filtered.filter(e => e.actor.toLowerCase().includes(actorLower));
|
|
64
|
+
}
|
|
65
|
+
// Filter by time range
|
|
66
|
+
if (q.since) {
|
|
67
|
+
const sinceDate = new Date(q.since).getTime();
|
|
68
|
+
filtered = filtered.filter(e => new Date(e.timestamp).getTime() >= sinceDate);
|
|
69
|
+
}
|
|
70
|
+
if (q.until) {
|
|
71
|
+
const untilDate = new Date(q.until).getTime();
|
|
72
|
+
filtered = filtered.filter(e => new Date(e.timestamp).getTime() <= untilDate);
|
|
73
|
+
}
|
|
74
|
+
const total = filtered.length;
|
|
75
|
+
const offset = Math.max(0, q.offset || 0);
|
|
76
|
+
const limit = Math.min(1000, Math.max(1, q.limit || 100));
|
|
77
|
+
// Return newest first (reverse chronological) — copy to avoid mutating
|
|
78
|
+
const reversed = [...filtered].reverse();
|
|
79
|
+
const page = reversed.slice(offset, offset + limit);
|
|
80
|
+
return { total, offset, limit, events: page };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get summary statistics of the audit log.
|
|
84
|
+
*/
|
|
85
|
+
stats() {
|
|
86
|
+
const now = Date.now();
|
|
87
|
+
const oneHourAgo = now - 3_600_000;
|
|
88
|
+
const oneDayAgo = now - 86_400_000;
|
|
89
|
+
const eventsByType = {};
|
|
90
|
+
let eventsLastHour = 0;
|
|
91
|
+
let eventsLast24h = 0;
|
|
92
|
+
for (const e of this.events) {
|
|
93
|
+
eventsByType[e.type] = (eventsByType[e.type] || 0) + 1;
|
|
94
|
+
const ts = new Date(e.timestamp).getTime();
|
|
95
|
+
if (ts >= oneHourAgo)
|
|
96
|
+
eventsLastHour++;
|
|
97
|
+
if (ts >= oneDayAgo)
|
|
98
|
+
eventsLast24h++;
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
totalEvents: this.events.length,
|
|
102
|
+
oldestEvent: this.events.length > 0 ? this.events[0].timestamp : null,
|
|
103
|
+
newestEvent: this.events.length > 0 ? this.events[this.events.length - 1].timestamp : null,
|
|
104
|
+
eventsByType,
|
|
105
|
+
eventsLastHour,
|
|
106
|
+
eventsLast24h,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Export all events (for backup/external systems).
|
|
111
|
+
*/
|
|
112
|
+
exportAll() {
|
|
113
|
+
return [...this.events];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Export events as CSV string.
|
|
117
|
+
*/
|
|
118
|
+
exportCsv(q = {}) {
|
|
119
|
+
const result = this.query({ ...q, limit: q.limit || 10_000 });
|
|
120
|
+
const header = 'id,timestamp,type,actor,message';
|
|
121
|
+
const rows = result.events.map(e => `${e.id},${e.timestamp},${e.type},"${e.actor.replace(/"/g, '""')}","${e.message.replace(/"/g, '""')}"`);
|
|
122
|
+
return [header, ...rows].join('\n');
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get event count.
|
|
126
|
+
*/
|
|
127
|
+
get size() {
|
|
128
|
+
return this.events.length;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Enforce retention policy: remove events older than maxAgeHours.
|
|
132
|
+
*/
|
|
133
|
+
enforceRetention() {
|
|
134
|
+
if (this.config.maxAgeHours <= 0)
|
|
135
|
+
return 0;
|
|
136
|
+
const cutoff = Date.now() - (this.config.maxAgeHours * 3_600_000);
|
|
137
|
+
const before = this.events.length;
|
|
138
|
+
this.events = this.events.filter(e => new Date(e.timestamp).getTime() >= cutoff);
|
|
139
|
+
return before - this.events.length;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Clear all events.
|
|
143
|
+
*/
|
|
144
|
+
clear() {
|
|
145
|
+
this.events = [];
|
|
146
|
+
this.nextId = 1;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Stop cleanup timer.
|
|
150
|
+
*/
|
|
151
|
+
destroy() {
|
|
152
|
+
if (this.cleanupTimer) {
|
|
153
|
+
clearInterval(this.cleanupTimer);
|
|
154
|
+
this.cleanupTimer = null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.AuditLogger = AuditLogger;
|
|
159
|
+
// ─── Helper: Mask API key for audit ──────────────────────────────────────────
|
|
160
|
+
function maskKeyForAudit(key) {
|
|
161
|
+
if (!key || key.length < 10)
|
|
162
|
+
return '***';
|
|
163
|
+
return key.slice(0, 7) + '...' + key.slice(-4);
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,10 @@ export { WebhookEmitter } from './webhook';
|
|
|
27
27
|
export { QuotaTracker } from './quota';
|
|
28
28
|
export { OAuthProvider } from './oauth';
|
|
29
29
|
export type { OAuthClientRecord, OAuthTokenRecord, OAuthServerMetadata, OAuthConfig } from './oauth';
|
|
30
|
+
export { SessionManager, writeSseHeaders, writeSseEvent, writeSseKeepAlive } from './session';
|
|
31
|
+
export { AuditLogger, maskKeyForAudit } from './audit';
|
|
32
|
+
export type { AuditEvent, AuditEventType, AuditLogConfig, AuditQuery, AuditQueryResult } from './audit';
|
|
33
|
+
export type { McpSession, SessionManagerConfig } from './session';
|
|
30
34
|
export { getDashboardHtml } from './dashboard';
|
|
31
35
|
export { PayGateClient, PayGateError } from './client';
|
|
32
36
|
export type { PayGateClientConfig, CreditsNeededInfo, BalanceInfo } from './client';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpF,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACxG,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpF,YAAY,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.DEFAULT_CONFIG = exports.PayGateError = exports.PayGateClient = exports.getDashboardHtml = exports.OAuthProvider = exports.QuotaTracker = exports.WebhookEmitter = exports.StripeWebhookHandler = exports.RateLimiter = exports.UsageMeter = exports.KeyStore = exports.MultiServerRouter = exports.HttpMcpProxy = exports.McpProxy = exports.Gate = exports.PayGateServer = void 0;
|
|
19
|
+
exports.DEFAULT_CONFIG = exports.PayGateError = exports.PayGateClient = exports.getDashboardHtml = exports.maskKeyForAudit = exports.AuditLogger = exports.writeSseKeepAlive = exports.writeSseEvent = exports.writeSseHeaders = exports.SessionManager = exports.OAuthProvider = exports.QuotaTracker = exports.WebhookEmitter = exports.StripeWebhookHandler = exports.RateLimiter = exports.UsageMeter = exports.KeyStore = exports.MultiServerRouter = exports.HttpMcpProxy = exports.McpProxy = exports.Gate = exports.PayGateServer = void 0;
|
|
20
20
|
var server_1 = require("./server");
|
|
21
21
|
Object.defineProperty(exports, "PayGateServer", { enumerable: true, get: function () { return server_1.PayGateServer; } });
|
|
22
22
|
var gate_1 = require("./gate");
|
|
@@ -41,6 +41,14 @@ var quota_1 = require("./quota");
|
|
|
41
41
|
Object.defineProperty(exports, "QuotaTracker", { enumerable: true, get: function () { return quota_1.QuotaTracker; } });
|
|
42
42
|
var oauth_1 = require("./oauth");
|
|
43
43
|
Object.defineProperty(exports, "OAuthProvider", { enumerable: true, get: function () { return oauth_1.OAuthProvider; } });
|
|
44
|
+
var session_1 = require("./session");
|
|
45
|
+
Object.defineProperty(exports, "SessionManager", { enumerable: true, get: function () { return session_1.SessionManager; } });
|
|
46
|
+
Object.defineProperty(exports, "writeSseHeaders", { enumerable: true, get: function () { return session_1.writeSseHeaders; } });
|
|
47
|
+
Object.defineProperty(exports, "writeSseEvent", { enumerable: true, get: function () { return session_1.writeSseEvent; } });
|
|
48
|
+
Object.defineProperty(exports, "writeSseKeepAlive", { enumerable: true, get: function () { return session_1.writeSseKeepAlive; } });
|
|
49
|
+
var audit_1 = require("./audit");
|
|
50
|
+
Object.defineProperty(exports, "AuditLogger", { enumerable: true, get: function () { return audit_1.AuditLogger; } });
|
|
51
|
+
Object.defineProperty(exports, "maskKeyForAudit", { enumerable: true, get: function () { return audit_1.maskKeyForAudit; } });
|
|
44
52
|
var dashboard_1 = require("./dashboard");
|
|
45
53
|
Object.defineProperty(exports, "getDashboardHtml", { enumerable: true, get: function () { return dashboard_1.getDashboardHtml; } });
|
|
46
54
|
var client_1 = require("./client");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAC1B,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,iCAAuC;AAA9B,qGAAA,YAAY,OAAA;AACrB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AAEtB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AACzB,mCAAuD;AAA9C,uGAAA,aAAa,OAAA;AAAE,sGAAA,YAAY,OAAA;AAmBpC,iCAAyC;AAAhC,uGAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AACtB,+BAA8B;AAArB,4FAAA,IAAI,OAAA;AACb,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AACrB,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAC1B,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AACjB,iCAAqC;AAA5B,mGAAA,UAAU,OAAA;AACnB,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,iCAAuC;AAA9B,qGAAA,YAAY,OAAA;AACrB,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AAEtB,qCAA8F;AAArF,yGAAA,cAAc,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,4GAAA,iBAAiB,OAAA;AAC1E,iCAAuD;AAA9C,oGAAA,WAAW,OAAA;AAAE,wGAAA,eAAe,OAAA;AAGrC,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AACzB,mCAAuD;AAA9C,uGAAA,aAAa,OAAA;AAAE,sGAAA,YAAY,OAAA;AAmBpC,iCAAyC;AAAhC,uGAAA,cAAc,OAAA"}
|
package/dist/server.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ import { McpProxy } from './proxy';
|
|
|
17
17
|
import { HttpMcpProxy } from './http-proxy';
|
|
18
18
|
import { MultiServerRouter } from './router';
|
|
19
19
|
import { OAuthProvider } from './oauth';
|
|
20
|
+
import { SessionManager } from './session';
|
|
21
|
+
import { AuditLogger } from './audit';
|
|
20
22
|
/** Union type for both proxy backends */
|
|
21
23
|
type ProxyBackend = McpProxy | HttpMcpProxy;
|
|
22
24
|
export declare class PayGateServer {
|
|
@@ -31,6 +33,10 @@ export declare class PayGateServer {
|
|
|
31
33
|
private stripeHandler;
|
|
32
34
|
/** OAuth 2.1 provider (null if OAuth is not enabled) */
|
|
33
35
|
readonly oauth: OAuthProvider | null;
|
|
36
|
+
/** Session manager for Streamable HTTP transport */
|
|
37
|
+
readonly sessions: SessionManager;
|
|
38
|
+
/** Structured audit log */
|
|
39
|
+
readonly audit: AuditLogger;
|
|
34
40
|
/** The active request handler — either proxy or router */
|
|
35
41
|
private get handler();
|
|
36
42
|
constructor(config: Partial<PayGateConfig> & {
|
|
@@ -42,6 +48,19 @@ export declare class PayGateServer {
|
|
|
42
48
|
}>;
|
|
43
49
|
private handleRequest;
|
|
44
50
|
private handleMcp;
|
|
51
|
+
/**
|
|
52
|
+
* GET /mcp — Open an SSE stream for server-to-client notifications.
|
|
53
|
+
* The connection stays open until the client disconnects or session is deleted.
|
|
54
|
+
*/
|
|
55
|
+
private handleMcpSseStream;
|
|
56
|
+
/**
|
|
57
|
+
* DELETE /mcp — Terminate a session.
|
|
58
|
+
*/
|
|
59
|
+
private handleMcpDeleteSession;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve API key from X-API-Key header or OAuth Bearer token.
|
|
62
|
+
*/
|
|
63
|
+
private resolveApiKey;
|
|
45
64
|
private handleRoot;
|
|
46
65
|
private handleStatus;
|
|
47
66
|
private handleCreateKey;
|
|
@@ -68,6 +87,9 @@ export declare class PayGateServer {
|
|
|
68
87
|
private handleOAuthRevoke;
|
|
69
88
|
/** GET /oauth/clients — List registered OAuth clients (admin only) */
|
|
70
89
|
private handleOAuthClients;
|
|
90
|
+
private handleAudit;
|
|
91
|
+
private handleAuditExport;
|
|
92
|
+
private handleAuditStats;
|
|
71
93
|
private checkAdmin;
|
|
72
94
|
private readBody;
|
|
73
95
|
stop(): Promise<void>;
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,aAAa,EAAkB,mBAAmB,EAAkB,MAAM,SAAS,CAAC;AAS7F,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAE,aAAa,EAAkB,mBAAmB,EAAkB,MAAM,SAAS,CAAC;AAS7F,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,cAAc,EAAqD,MAAM,WAAW,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAmB,MAAM,SAAS,CAAC;AAMvD,yCAAyC;AACzC,KAAK,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;AAY5C,qBAAa,aAAa;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACpC,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,aAAa,CAAqC;IAC1D,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAQ;IAC5C,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,2BAA2B;IAC3B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAE5B,0DAA0D;IAC1D,OAAO,KAAK,OAAO,GAElB;gBAGC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,EAC1D,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,mBAAmB,CAAC,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,mBAAmB,EAAE;IAwC3B,KAAK,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;YAuB5C,aAAa;YA2Eb,SAAS;IA8EvB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA+C1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAyB9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,UAAU;IAsClB,OAAO,CAAC,YAAY;YASN,eAAe;IAuE7B,OAAO,CAAC,cAAc;YASR,WAAW;YAoDX,eAAe;YAyCf,YAAY;YAiDZ,eAAe;YAuDf,cAAc;IA6D5B,OAAO,CAAC,aAAa;YAqDP,YAAY;IAiD1B,OAAO,CAAC,WAAW;YA8CL,mBAAmB;IAmCjC,OAAO,CAAC,eAAe;IAYvB,+EAA+E;IAC/E,OAAO,CAAC,mBAAmB;IAU3B,oEAAoE;YACtD,mBAAmB;IA4DjC,yDAAyD;YAC3C,oBAAoB;IAuFlC,yCAAyC;YAC3B,gBAAgB;IA8E9B,uDAAuD;YACzC,iBAAiB;IAiC/B,sEAAsE;IACtE,OAAO,CAAC,kBAAkB;IAqB1B,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,QAAQ;IAkBV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAY5B"}
|