@firela/billclaw-core 0.1.4 → 0.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/LICENSE +21 -0
- package/dist/billclaw.d.ts +8 -0
- package/dist/billclaw.d.ts.map +1 -1
- package/dist/billclaw.js +51 -1
- package/dist/billclaw.js.map +1 -1
- package/dist/config/config-manager.d.ts +127 -0
- package/dist/config/config-manager.d.ts.map +1 -0
- package/dist/config/config-manager.js +304 -0
- package/dist/config/config-manager.js.map +1 -0
- package/dist/config/env-loader.d.ts +33 -0
- package/dist/config/env-loader.d.ts.map +1 -0
- package/dist/config/env-loader.js +115 -0
- package/dist/config/env-loader.js.map +1 -0
- package/dist/config/index.d.ts +14 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +14 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/models/config.d.ts +147 -0
- package/dist/models/config.d.ts.map +1 -1
- package/dist/models/config.js +36 -0
- package/dist/models/config.js.map +1 -1
- package/dist/oauth/index.d.ts +12 -0
- package/dist/oauth/index.d.ts.map +1 -0
- package/dist/oauth/index.js +13 -0
- package/dist/oauth/index.js.map +1 -0
- package/dist/oauth/providers/gmail.d.ts +63 -0
- package/dist/oauth/providers/gmail.d.ts.map +1 -0
- package/dist/oauth/providers/gmail.js +213 -0
- package/dist/oauth/providers/gmail.js.map +1 -0
- package/dist/oauth/providers/plaid.d.ts +40 -0
- package/dist/oauth/providers/plaid.d.ts.map +1 -0
- package/dist/oauth/providers/plaid.js +90 -0
- package/dist/oauth/providers/plaid.js.map +1 -0
- package/dist/oauth/types.d.ts +102 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/types.js +10 -0
- package/dist/oauth/types.js.map +1 -0
- package/dist/runtime/types.d.ts +2 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/storage/locking.d.ts +4 -0
- package/dist/storage/locking.d.ts.map +1 -1
- package/dist/storage/locking.js +4 -0
- package/dist/storage/locking.js.map +1 -1
- package/dist/test-fixtures.d.ts.map +1 -1
- package/dist/test-fixtures.js +5 -0
- package/dist/test-fixtures.js.map +1 -1
- package/dist/webhooks/deduplication.d.ts +117 -0
- package/dist/webhooks/deduplication.d.ts.map +1 -0
- package/dist/webhooks/deduplication.js +258 -0
- package/dist/webhooks/deduplication.js.map +1 -0
- package/dist/webhooks/handlers/gmail.d.ts +39 -0
- package/dist/webhooks/handlers/gmail.d.ts.map +1 -0
- package/dist/webhooks/handlers/gmail.js +56 -0
- package/dist/webhooks/handlers/gmail.js.map +1 -0
- package/dist/webhooks/handlers/gocardless.d.ts +39 -0
- package/dist/webhooks/handlers/gocardless.d.ts.map +1 -0
- package/dist/webhooks/handlers/gocardless.js +73 -0
- package/dist/webhooks/handlers/gocardless.js.map +1 -0
- package/dist/webhooks/handlers/index.d.ts +10 -0
- package/dist/webhooks/handlers/index.d.ts.map +1 -0
- package/dist/webhooks/handlers/index.js +10 -0
- package/dist/webhooks/handlers/index.js.map +1 -0
- package/dist/webhooks/handlers/plaid.d.ts +73 -0
- package/dist/webhooks/handlers/plaid.d.ts.map +1 -0
- package/dist/webhooks/handlers/plaid.js +169 -0
- package/dist/webhooks/handlers/plaid.js.map +1 -0
- package/dist/webhooks/index.d.ts +15 -0
- package/dist/webhooks/index.d.ts.map +1 -0
- package/dist/webhooks/index.js +17 -0
- package/dist/webhooks/index.js.map +1 -0
- package/dist/webhooks/processor.d.ts +76 -0
- package/dist/webhooks/processor.d.ts.map +1 -0
- package/dist/webhooks/processor.js +116 -0
- package/dist/webhooks/processor.js.map +1 -0
- package/dist/webhooks/router.d.ts +80 -0
- package/dist/webhooks/router.d.ts.map +1 -0
- package/dist/webhooks/router.js +107 -0
- package/dist/webhooks/router.js.map +1 -0
- package/dist/webhooks/security.d.ts +90 -0
- package/dist/webhooks/security.d.ts.map +1 -0
- package/dist/webhooks/security.js +138 -0
- package/dist/webhooks/security.js.map +1 -0
- package/dist/webhooks/sync-rate-limiter.d.ts +138 -0
- package/dist/webhooks/sync-rate-limiter.d.ts.map +1 -0
- package/dist/webhooks/sync-rate-limiter.js +228 -0
- package/dist/webhooks/sync-rate-limiter.js.map +1 -0
- package/dist/webhooks/types.d.ts +140 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +18 -0
- package/dist/webhooks/types.js.map +1 -0
- package/package.json +12 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webhooks/handlers/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaid webhook handler
|
|
3
|
+
*
|
|
4
|
+
* Processes webhooks from Plaid:
|
|
5
|
+
* - TRANSACTIONS.SYNC_UPDATES_AVAILABLE: Trigger sync for the item
|
|
6
|
+
* - ITEM.ERROR: Emit account error event
|
|
7
|
+
* - ITEM.LOGIN_REQUIRED: Notify user to re-authenticate
|
|
8
|
+
*/
|
|
9
|
+
import type { WebhookHandler, WebhookRequest, WebhookResponse } from "../types.js";
|
|
10
|
+
import type { Logger } from "../../errors/errors.js";
|
|
11
|
+
/**
|
|
12
|
+
* Plaid webhook handler configuration
|
|
13
|
+
*/
|
|
14
|
+
export interface PlaidWebhookHandlerConfig {
|
|
15
|
+
/**
|
|
16
|
+
* Logger instance
|
|
17
|
+
*/
|
|
18
|
+
logger: Logger;
|
|
19
|
+
/**
|
|
20
|
+
* Find account by Plaid item ID
|
|
21
|
+
*/
|
|
22
|
+
findAccountByItemId: (itemId: string) => Promise<any | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Trigger sync for an account
|
|
25
|
+
*/
|
|
26
|
+
triggerSync?: (accountId: string) => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Emit events to configured webhook endpoints
|
|
29
|
+
*/
|
|
30
|
+
emitEvent?: (eventType: string, data: unknown) => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Webhook configurations for event emission
|
|
33
|
+
*/
|
|
34
|
+
webhooks?: any[];
|
|
35
|
+
/**
|
|
36
|
+
* Rate limiter for sync operations
|
|
37
|
+
*/
|
|
38
|
+
rateLimiter?: {
|
|
39
|
+
isWebhookSyncAllowed: (accountId: string) => boolean;
|
|
40
|
+
recordWebhookSync: (accountId: string) => void;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Plaid webhook handler
|
|
45
|
+
*
|
|
46
|
+
* Handles inbound webhooks from Plaid.
|
|
47
|
+
*/
|
|
48
|
+
export declare class PlaidWebhookHandler implements WebhookHandler {
|
|
49
|
+
readonly source: "plaid";
|
|
50
|
+
private readonly logger;
|
|
51
|
+
private readonly findAccountByItemId;
|
|
52
|
+
private readonly triggerSync?;
|
|
53
|
+
private readonly emitEvent?;
|
|
54
|
+
private readonly webhooks?;
|
|
55
|
+
private readonly rateLimiter?;
|
|
56
|
+
constructor(config: PlaidWebhookHandlerConfig);
|
|
57
|
+
handle(request: WebhookRequest): Promise<WebhookResponse>;
|
|
58
|
+
verify(_request: WebhookRequest, _secret: string): boolean;
|
|
59
|
+
getSupportedEvents(): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Handle SYNC_UPDATES_AVAILABLE webhook
|
|
62
|
+
*/
|
|
63
|
+
private handleSyncUpdatesAvailable;
|
|
64
|
+
/**
|
|
65
|
+
* Handle ITEM.ERROR or ITEM.LOGIN_REQUIRED webhook
|
|
66
|
+
*/
|
|
67
|
+
private handleItemError;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create a Plaid webhook handler
|
|
71
|
+
*/
|
|
72
|
+
export declare function createPlaidWebhookHandler(config: PlaidWebhookHandlerConfig): PlaidWebhookHandler;
|
|
73
|
+
//# sourceMappingURL=plaid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plaid.d.ts","sourceRoot":"","sources":["../../../src/webhooks/handlers/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAgBpD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAA;IAE5D;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAElD;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAE/D;;OAEG;IACH,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAA;IAEhB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;QACpD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;KAC/C,CAAA;CACF;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACxD,QAAQ,CAAC,MAAM,EAAG,OAAO,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyC;IAC7E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAqD;IAChF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAO;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAG5B;gBAEW,MAAM,EAAE,yBAAyB;IASvC,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAyC/D,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAM1D,kBAAkB,IAAI,MAAM,EAAE;IAQ9B;;OAEG;YACW,0BAA0B;IAqExC;;OAEG;YACW,eAAe;CAkC9B;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,yBAAyB,GAChC,mBAAmB,CAErB"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plaid webhook handler
|
|
3
|
+
*
|
|
4
|
+
* Processes webhooks from Plaid:
|
|
5
|
+
* - TRANSACTIONS.SYNC_UPDATES_AVAILABLE: Trigger sync for the item
|
|
6
|
+
* - ITEM.ERROR: Emit account error event
|
|
7
|
+
* - ITEM.LOGIN_REQUIRED: Notify user to re-authenticate
|
|
8
|
+
*/
|
|
9
|
+
import { emitSyncStarted, emitAccountError } from "../../services/event-emitter.js";
|
|
10
|
+
/**
|
|
11
|
+
* Plaid webhook handler
|
|
12
|
+
*
|
|
13
|
+
* Handles inbound webhooks from Plaid.
|
|
14
|
+
*/
|
|
15
|
+
export class PlaidWebhookHandler {
|
|
16
|
+
source = "plaid";
|
|
17
|
+
logger;
|
|
18
|
+
findAccountByItemId;
|
|
19
|
+
triggerSync;
|
|
20
|
+
emitEvent;
|
|
21
|
+
webhooks;
|
|
22
|
+
rateLimiter;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.logger = config.logger;
|
|
25
|
+
this.findAccountByItemId = config.findAccountByItemId;
|
|
26
|
+
this.triggerSync = config.triggerSync;
|
|
27
|
+
this.emitEvent = config.emitEvent;
|
|
28
|
+
this.webhooks = config.webhooks;
|
|
29
|
+
this.rateLimiter = config.rateLimiter;
|
|
30
|
+
}
|
|
31
|
+
async handle(request) {
|
|
32
|
+
try {
|
|
33
|
+
const body = request.body;
|
|
34
|
+
const webhookType = body.webhook_type;
|
|
35
|
+
const webhookCode = body.webhook_code;
|
|
36
|
+
const itemId = body.item_id;
|
|
37
|
+
this.logger.info?.(`Received Plaid webhook: ${webhookType}.${webhookCode} for item ${itemId}`);
|
|
38
|
+
switch (webhookType) {
|
|
39
|
+
case "TRANSACTIONS":
|
|
40
|
+
if (webhookCode === "SYNC_UPDATES_AVAILABLE") {
|
|
41
|
+
return this.handleSyncUpdatesAvailable(itemId);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case "ITEM":
|
|
45
|
+
if (webhookCode === "ERROR" || webhookCode === "LOGIN_REQUIRED") {
|
|
46
|
+
return this.handleItemError(body);
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
this.logger.debug?.(`Unhandled Plaid webhook: ${webhookType}.${webhookCode}`);
|
|
51
|
+
}
|
|
52
|
+
return { status: 200, body: { received: true } };
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
this.logger.error?.(`Error handling Plaid webhook:`, error);
|
|
56
|
+
return {
|
|
57
|
+
status: 500,
|
|
58
|
+
body: {
|
|
59
|
+
received: false,
|
|
60
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
verify(_request, _secret) {
|
|
66
|
+
// Plaid uses headers: plaid-verification, plaid-timestamp
|
|
67
|
+
// Signature verification should be done by security layer
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
getSupportedEvents() {
|
|
71
|
+
return [
|
|
72
|
+
"TRANSACTIONS.SYNC_UPDATES_AVAILABLE",
|
|
73
|
+
"ITEM.ERROR",
|
|
74
|
+
"ITEM.LOGIN_REQUIRED",
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Handle SYNC_UPDATES_AVAILABLE webhook
|
|
79
|
+
*/
|
|
80
|
+
async handleSyncUpdatesAvailable(itemId) {
|
|
81
|
+
try {
|
|
82
|
+
// Find account associated with this item
|
|
83
|
+
const account = await this.findAccountByItemId(itemId);
|
|
84
|
+
if (!account) {
|
|
85
|
+
this.logger.warn?.(`No account found for Plaid item: ${itemId}`);
|
|
86
|
+
return { status: 200, body: { received: true, processed: false } };
|
|
87
|
+
}
|
|
88
|
+
if (!account.enabled) {
|
|
89
|
+
this.logger.debug?.(`Account ${account.id} is disabled, skipping sync`);
|
|
90
|
+
return { status: 200, body: { received: true, processed: false } };
|
|
91
|
+
}
|
|
92
|
+
// Check rate limiter
|
|
93
|
+
if (this.rateLimiter) {
|
|
94
|
+
if (!this.rateLimiter.isWebhookSyncAllowed(account.id)) {
|
|
95
|
+
this.logger.warn?.(`Webhook-triggered sync blocked for ${account.id}: rate limit exceeded`);
|
|
96
|
+
return {
|
|
97
|
+
status: 429,
|
|
98
|
+
body: {
|
|
99
|
+
received: true,
|
|
100
|
+
processed: false,
|
|
101
|
+
error: "Rate limit exceeded",
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
this.rateLimiter.recordWebhookSync(account.id);
|
|
106
|
+
}
|
|
107
|
+
// Emit sync started event
|
|
108
|
+
const syncId = `sync_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
109
|
+
if (this.emitEvent) {
|
|
110
|
+
await emitSyncStarted(this.logger, this.webhooks || [], account.id, syncId);
|
|
111
|
+
}
|
|
112
|
+
// Trigger async sync (don't wait for completion)
|
|
113
|
+
if (this.triggerSync) {
|
|
114
|
+
this.triggerSync(account.id).catch((error) => {
|
|
115
|
+
this.logger.error?.(`Webhook-triggered sync failed for ${account.id}:`, error);
|
|
116
|
+
// P1: Emit sync.failed event
|
|
117
|
+
if (this.emitEvent) {
|
|
118
|
+
emitAccountError(this.logger, this.webhooks || [], account.id, "plaid", error instanceof Error ? error.message : String(error)).catch((err) => this.logger.debug?.(`Event emission failed:`, err));
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return { status: 200, body: { received: true, processed: true } };
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
this.logger.error?.(`Error handling SYNC_UPDATES_AVAILABLE:`, error);
|
|
126
|
+
return {
|
|
127
|
+
status: 500,
|
|
128
|
+
body: {
|
|
129
|
+
received: false,
|
|
130
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Handle ITEM.ERROR or ITEM.LOGIN_REQUIRED webhook
|
|
137
|
+
*/
|
|
138
|
+
async handleItemError(body) {
|
|
139
|
+
try {
|
|
140
|
+
const error = body.error ?? {
|
|
141
|
+
error_code: body.webhook_code,
|
|
142
|
+
error_message: "Item login required",
|
|
143
|
+
};
|
|
144
|
+
this.logger.warn?.(`Plaid item error for ${body.item_id}: ${error.error_code} - ${error.error_message}`);
|
|
145
|
+
// Emit account error event
|
|
146
|
+
if (this.emitEvent) {
|
|
147
|
+
await emitAccountError(this.logger, this.webhooks || [], body.item_id, "plaid", JSON.stringify(error));
|
|
148
|
+
}
|
|
149
|
+
return { status: 200, body: { received: true } };
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
this.logger.error?.(`Error handling item error:`, error);
|
|
153
|
+
return {
|
|
154
|
+
status: 500,
|
|
155
|
+
body: {
|
|
156
|
+
received: false,
|
|
157
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Create a Plaid webhook handler
|
|
165
|
+
*/
|
|
166
|
+
export function createPlaidWebhookHandler(config) {
|
|
167
|
+
return new PlaidWebhookHandler(config);
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=plaid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../../src/webhooks/handlers/plaid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook processing layer for BillClaw
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic inbound webhook processing with security and concurrency handling.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export * from "./types.js";
|
|
9
|
+
export * from "./processor.js";
|
|
10
|
+
export * from "./router.js";
|
|
11
|
+
export * from "./security.js";
|
|
12
|
+
export * from "./deduplication.js";
|
|
13
|
+
export * from "./sync-rate-limiter.js";
|
|
14
|
+
export * from "./handlers/index.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA;AAGtC,cAAc,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook processing layer for BillClaw
|
|
3
|
+
*
|
|
4
|
+
* Framework-agnostic inbound webhook processing with security and concurrency handling.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
// Public API exports
|
|
9
|
+
export * from "./types.js";
|
|
10
|
+
export * from "./processor.js";
|
|
11
|
+
export * from "./router.js";
|
|
12
|
+
export * from "./security.js";
|
|
13
|
+
export * from "./deduplication.js";
|
|
14
|
+
export * from "./sync-rate-limiter.js";
|
|
15
|
+
// Handlers
|
|
16
|
+
export * from "./handlers/index.js";
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/webhooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qBAAqB;AACrB,cAAc,YAAY,CAAA;AAC1B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA;AAEtC,WAAW;AACX,cAAc,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook processor interface
|
|
3
|
+
*
|
|
4
|
+
* Main interface for processing inbound webhooks from various sources.
|
|
5
|
+
*/
|
|
6
|
+
import type { Logger } from "../errors/errors.js";
|
|
7
|
+
import type { WebhookRequest, WebhookResponse, WebhookHandler } from "./types.js";
|
|
8
|
+
import type { WebhookSecurity } from "./security.js";
|
|
9
|
+
/**
|
|
10
|
+
* Webhook processor options
|
|
11
|
+
*/
|
|
12
|
+
export interface WebhookProcessorOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Logger instance
|
|
15
|
+
*/
|
|
16
|
+
logger: Logger;
|
|
17
|
+
/**
|
|
18
|
+
* Webhook secret for signature verification
|
|
19
|
+
*/
|
|
20
|
+
webhookSecret?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Security layer for replay protection and signature verification
|
|
23
|
+
*/
|
|
24
|
+
security?: WebhookSecurity;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Webhook processor
|
|
28
|
+
*
|
|
29
|
+
* Main entry point for processing inbound webhooks.
|
|
30
|
+
* Routes requests to appropriate handlers and applies security checks.
|
|
31
|
+
*/
|
|
32
|
+
export declare class WebhookProcessor {
|
|
33
|
+
private readonly handlers;
|
|
34
|
+
private readonly logger;
|
|
35
|
+
private readonly webhookSecret?;
|
|
36
|
+
private readonly security?;
|
|
37
|
+
constructor(options: WebhookProcessorOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Register a webhook handler for a specific source
|
|
40
|
+
*
|
|
41
|
+
* @param source - Webhook source identifier
|
|
42
|
+
* @param handler - Handler implementation
|
|
43
|
+
*/
|
|
44
|
+
registerHandler(source: string, handler: WebhookHandler): void;
|
|
45
|
+
/**
|
|
46
|
+
* Process incoming webhook request
|
|
47
|
+
*
|
|
48
|
+
* Applies security checks and routes to appropriate handler.
|
|
49
|
+
*
|
|
50
|
+
* @param request - Normalized webhook request
|
|
51
|
+
* @returns Processing response
|
|
52
|
+
*/
|
|
53
|
+
process(request: WebhookRequest): Promise<WebhookResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Get registered handler by source
|
|
56
|
+
*
|
|
57
|
+
* @param source - Webhook source identifier
|
|
58
|
+
* @returns Handler or undefined if not found
|
|
59
|
+
*/
|
|
60
|
+
getHandler(source: string): WebhookHandler | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Get all registered handlers
|
|
63
|
+
*
|
|
64
|
+
* @returns Map of source to handler
|
|
65
|
+
*/
|
|
66
|
+
getAllHandlers(): Map<string, WebhookHandler>;
|
|
67
|
+
/**
|
|
68
|
+
* Create error response
|
|
69
|
+
*/
|
|
70
|
+
private createErrorResponse;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a webhook processor with default configuration
|
|
74
|
+
*/
|
|
75
|
+
export declare function createWebhookProcessor(logger: Logger, options?: Partial<WebhookProcessorOptions>): WebhookProcessor;
|
|
76
|
+
//# sourceMappingURL=processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/webhooks/processor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,cAAc,EAEf,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;CAC3B;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAiB;gBAE/B,OAAO,EAAE,uBAAuB;IAM5C;;;;;OAKG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAK9D;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAsDhE;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAItD;;;;OAIG;IACH,cAAc,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAI7C;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAkB5B;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GACzC,gBAAgB,CAKlB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook processor interface
|
|
3
|
+
*
|
|
4
|
+
* Main interface for processing inbound webhooks from various sources.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Webhook processor
|
|
8
|
+
*
|
|
9
|
+
* Main entry point for processing inbound webhooks.
|
|
10
|
+
* Routes requests to appropriate handlers and applies security checks.
|
|
11
|
+
*/
|
|
12
|
+
export class WebhookProcessor {
|
|
13
|
+
handlers = new Map();
|
|
14
|
+
logger;
|
|
15
|
+
webhookSecret;
|
|
16
|
+
security;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.logger = options.logger;
|
|
19
|
+
this.webhookSecret = options.webhookSecret;
|
|
20
|
+
this.security = options.security;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a webhook handler for a specific source
|
|
24
|
+
*
|
|
25
|
+
* @param source - Webhook source identifier
|
|
26
|
+
* @param handler - Handler implementation
|
|
27
|
+
*/
|
|
28
|
+
registerHandler(source, handler) {
|
|
29
|
+
this.handlers.set(source, handler);
|
|
30
|
+
this.logger.info?.(`Registered webhook handler for source: ${source}`);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Process incoming webhook request
|
|
34
|
+
*
|
|
35
|
+
* Applies security checks and routes to appropriate handler.
|
|
36
|
+
*
|
|
37
|
+
* @param request - Normalized webhook request
|
|
38
|
+
* @returns Processing response
|
|
39
|
+
*/
|
|
40
|
+
async process(request) {
|
|
41
|
+
try {
|
|
42
|
+
// Security: Replay protection
|
|
43
|
+
if (this.security && request.timestamp && request.nonce) {
|
|
44
|
+
const isValid = await this.security.validateReplayProtection(request.timestamp, request.nonce);
|
|
45
|
+
if (!isValid) {
|
|
46
|
+
return this.createErrorResponse("REPLAY_DETECTED", 401, "Replay detected", false);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Security: Signature verification
|
|
50
|
+
if (this.security && request.signature && this.webhookSecret) {
|
|
51
|
+
const payload = JSON.stringify(request.body);
|
|
52
|
+
const isValid = this.security.verifySignature(payload, request.signature, this.webhookSecret);
|
|
53
|
+
if (!isValid) {
|
|
54
|
+
return this.createErrorResponse("INVALID_SIGNATURE", 401, "Invalid signature", false);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Get handler for source
|
|
58
|
+
const handler = this.handlers.get(request.source);
|
|
59
|
+
if (!handler) {
|
|
60
|
+
this.logger.warn?.(`No handler registered for source: ${request.source}`);
|
|
61
|
+
return this.createErrorResponse("INTERNAL_ERROR", 400, `No handler for source: ${request.source}`, false);
|
|
62
|
+
}
|
|
63
|
+
// Process with handler
|
|
64
|
+
this.logger.debug?.(`Processing webhook from ${request.source}`);
|
|
65
|
+
const response = await handler.handle(request);
|
|
66
|
+
return response;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
this.logger.error?.(`Error processing webhook from ${request.source}:`, error);
|
|
70
|
+
return this.createErrorResponse("INTERNAL_ERROR", 500, error instanceof Error ? error.message : "Unknown error", true);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get registered handler by source
|
|
75
|
+
*
|
|
76
|
+
* @param source - Webhook source identifier
|
|
77
|
+
* @returns Handler or undefined if not found
|
|
78
|
+
*/
|
|
79
|
+
getHandler(source) {
|
|
80
|
+
return this.handlers.get(source);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get all registered handlers
|
|
84
|
+
*
|
|
85
|
+
* @returns Map of source to handler
|
|
86
|
+
*/
|
|
87
|
+
getAllHandlers() {
|
|
88
|
+
return new Map(this.handlers);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create error response
|
|
92
|
+
*/
|
|
93
|
+
createErrorResponse(code, status, message, retryable) {
|
|
94
|
+
return {
|
|
95
|
+
status,
|
|
96
|
+
body: {
|
|
97
|
+
received: false,
|
|
98
|
+
error: {
|
|
99
|
+
code,
|
|
100
|
+
message,
|
|
101
|
+
retryable,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Create a webhook processor with default configuration
|
|
109
|
+
*/
|
|
110
|
+
export function createWebhookProcessor(logger, options) {
|
|
111
|
+
return new WebhookProcessor({
|
|
112
|
+
logger,
|
|
113
|
+
...options,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"processor.js","sourceRoot":"","sources":["../../src/webhooks/processor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA+BH;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACV,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAA;IAC5C,MAAM,CAAQ;IACd,aAAa,CAAS;IACtB,QAAQ,CAAkB;IAE3C,YAAY,OAAgC;QAC1C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAA;QAC1C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAClC,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAc,EAAE,OAAuB;QACrD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,0CAA0C,MAAM,EAAE,CAAC,CAAA;IACxE,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,OAAO,CAAC,OAAuB;QACnC,IAAI,CAAC;YACH,8BAA8B;YAC9B,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACxD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAC1D,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,KAAK,CACd,CAAA;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAA;gBACnF,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAC3C,OAAO,EACP,OAAO,CAAC,SAAS,EACjB,IAAI,CAAC,aAAa,CACnB,CAAA;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,GAAG,EAAE,mBAAmB,EAAE,KAAK,CAAC,CAAA;gBACvF,CAAC;YACH,CAAC;YAED,yBAAyB;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,qCAAqC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;gBACzE,OAAO,IAAI,CAAC,mBAAmB,CAC7B,gBAAgB,EAChB,GAAG,EACH,0BAA0B,OAAO,CAAC,MAAM,EAAE,EAC1C,KAAK,CACN,CAAA;YACH,CAAC;YAED,uBAAuB;YACvB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,2BAA2B,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;YAChE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAE9C,OAAO,QAAQ,CAAA;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,iCAAiC,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,CAAC,CAAA;YAC9E,OAAO,IAAI,CAAC,mBAAmB,CAC7B,gBAAgB,EAChB,GAAG,EACH,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EACxD,IAAI,CACL,CAAA;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;IAED;;;;OAIG;IACH,cAAc;QACZ,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC;IAED;;OAEG;IACK,mBAAmB,CACzB,IAAY,EACZ,MAAc,EACd,OAAe,EACf,SAAkB;QAElB,OAAO;YACL,MAAM;YACN,IAAI,EAAE;gBACJ,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE;oBACL,IAAI;oBACJ,OAAO;oBACP,SAAS;iBACV;aACF;SACF,CAAA;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAc,EACd,OAA0C;IAE1C,OAAO,IAAI,gBAAgB,CAAC;QAC1B,MAAM;QACN,GAAG,OAAO;KACX,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook router registry
|
|
3
|
+
*
|
|
4
|
+
* Registry pattern for managing webhook handlers.
|
|
5
|
+
* Provides handler registration and lookup functionality.
|
|
6
|
+
*/
|
|
7
|
+
import type { WebhookRequest, WebhookResponse, WebhookHandler, WebhookSource } from "./types.js";
|
|
8
|
+
import type { Logger } from "../errors/errors.js";
|
|
9
|
+
/**
|
|
10
|
+
* Webhook router options
|
|
11
|
+
*/
|
|
12
|
+
export interface WebhookRouterOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Logger instance
|
|
15
|
+
*/
|
|
16
|
+
logger: Logger;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Webhook router
|
|
20
|
+
*
|
|
21
|
+
* Registry for webhook handlers with routing functionality.
|
|
22
|
+
*/
|
|
23
|
+
export declare class WebhookRouter {
|
|
24
|
+
private readonly handlers;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
constructor(options: WebhookRouterOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Register a webhook handler for a specific source
|
|
29
|
+
*
|
|
30
|
+
* @param source - Webhook source identifier
|
|
31
|
+
* @param handler - Handler implementation
|
|
32
|
+
*/
|
|
33
|
+
register(source: WebhookSource, handler: WebhookHandler): void;
|
|
34
|
+
/**
|
|
35
|
+
* Unregister a handler for a specific source
|
|
36
|
+
*
|
|
37
|
+
* @param source - Webhook source identifier
|
|
38
|
+
*/
|
|
39
|
+
unregister(source: WebhookSource): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get handler by source
|
|
42
|
+
*
|
|
43
|
+
* @param source - Webhook source identifier
|
|
44
|
+
* @returns Handler or undefined if not found
|
|
45
|
+
*/
|
|
46
|
+
getHandler(source: WebhookSource): WebhookHandler | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Check if handler is registered for source
|
|
49
|
+
*
|
|
50
|
+
* @param source - Webhook source identifier
|
|
51
|
+
* @returns True if handler exists
|
|
52
|
+
*/
|
|
53
|
+
hasHandler(source: WebhookSource): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get all registered sources
|
|
56
|
+
*
|
|
57
|
+
* @returns Array of registered source identifiers
|
|
58
|
+
*/
|
|
59
|
+
getSources(): WebhookSource[];
|
|
60
|
+
/**
|
|
61
|
+
* Route request to appropriate handler
|
|
62
|
+
*
|
|
63
|
+
* @param request - Webhook request
|
|
64
|
+
* @returns Response from handler or error if not found
|
|
65
|
+
*/
|
|
66
|
+
route(request: WebhookRequest): Promise<WebhookResponse>;
|
|
67
|
+
/**
|
|
68
|
+
* Clear all registered handlers
|
|
69
|
+
*/
|
|
70
|
+
clear(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get number of registered handlers
|
|
73
|
+
*/
|
|
74
|
+
get size(): number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a webhook router with default configuration
|
|
78
|
+
*/
|
|
79
|
+
export declare function createWebhookRouter(logger: Logger): WebhookRouter;
|
|
80
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/webhooks/router.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAEjD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,OAAO,EAAE,oBAAoB;IAIzC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAS9D;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAMvC;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,GAAG,SAAS;IAI7D;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO;IAI1C;;;;OAIG;IACH,UAAU,IAAI,aAAa,EAAE;IAI7B;;;;;OAKG;IACG,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAiB9D;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAEjE"}
|