@robinpath/webhook 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,91 +1,91 @@
1
- # @robinpath/webhook
2
-
3
- > Send webhooks with HMAC signatures, verify incoming webhook payloads, and prevent replay attacks
4
-
5
- ![Category](https://img.shields.io/badge/category-Web-blue) ![Functions](https://img.shields.io/badge/functions-8-green) ![Auth](https://img.shields.io/badge/auth-none-lightgrey) ![License](https://img.shields.io/badge/license-MIT-brightgreen)
6
-
7
- ## Why use this module?
8
-
9
- The `webhook` module lets you:
10
-
11
- - Send a webhook POST request with optional HMAC signature
12
- - Create an HMAC signature for a webhook payload
13
- - Verify a webhook HMAC signature using timing-safe comparison
14
- - Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks
15
- - Parse a raw webhook body based on content type
16
-
17
- All functions are callable directly from RobinPath scripts with a simple, consistent API.
18
-
19
- ## Installation
20
-
21
- ```bash
22
- npm install @robinpath/webhook
23
- ```
24
-
25
- ## Quick Start
26
-
27
- No credentials needed — start using it right away:
28
-
29
- ```robinpath
30
- webhook.sign $payload "whsec_abc"
31
- ```
32
-
33
- ## Available Functions
34
-
35
- | Function | Description |
36
- |----------|-------------|
37
- | `webhook.send` | Send a webhook POST request with optional HMAC signature |
38
- | `webhook.sign` | Create an HMAC signature for a webhook payload |
39
- | `webhook.verify` | Verify a webhook HMAC signature using timing-safe comparison |
40
- | `webhook.verifyTimestamp` | Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks |
41
- | `webhook.parsePayload` | Parse a raw webhook body based on content type |
42
- | `webhook.buildPayload` | Build a standardized webhook payload with event name, data, timestamp, and ID |
43
- | `webhook.headers` | Build webhook headers including signature and timestamp |
44
- | `webhook.isValidUrl` | Check if a string is a valid HTTP/HTTPS webhook URL |
45
-
46
- ## Examples
47
-
48
- ### Create an HMAC signature for a webhook payload
49
-
50
- ```robinpath
51
- webhook.sign $payload "whsec_abc"
52
- ```
53
-
54
- ### Verify a webhook HMAC signature using timing-safe comparison
55
-
56
- ```robinpath
57
- webhook.verify $body "whsec_abc" $signatureHeader
58
- ```
59
-
60
- ### Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks
61
-
62
- ```robinpath
63
- webhook.verifyTimestamp $timestamp 60000
64
- ```
65
-
66
- ## Integration with RobinPath
67
-
68
- ```typescript
69
- import { RobinPath } from "@wiredwp/robinpath";
70
- import Module from "@robinpath/webhook";
71
-
72
- const rp = new RobinPath();
73
- rp.registerModule(Module.name, Module.functions);
74
- rp.registerModuleMeta(Module.name, Module.functionMetadata);
75
-
76
- const result = await rp.executeScript(`
77
- webhook.sign $payload "whsec_abc"
78
- `);
79
- ```
80
-
81
- ## Full API Reference
82
-
83
- See [MODULE.md](./MODULE.md) for complete documentation including all parameters, return types, error handling, and advanced examples.
84
-
85
- ## Related Modules
86
-
87
- - [`@robinpath/json`](../json) — JSON module for complementary functionality
88
-
89
- ## License
90
-
91
- MIT
1
+ # @robinpath/webhook
2
+
3
+ > Send webhooks with HMAC signatures, verify incoming webhook payloads, and prevent replay attacks
4
+
5
+ ![Category](https://img.shields.io/badge/category-Web-blue) ![Functions](https://img.shields.io/badge/functions-8-green) ![Auth](https://img.shields.io/badge/auth-none-lightgrey) ![License](https://img.shields.io/badge/license-MIT-brightgreen)
6
+
7
+ ## Why use this module?
8
+
9
+ The `webhook` module lets you:
10
+
11
+ - Send a webhook POST request with optional HMAC signature
12
+ - Create an HMAC signature for a webhook payload
13
+ - Verify a webhook HMAC signature using timing-safe comparison
14
+ - Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks
15
+ - Parse a raw webhook body based on content type
16
+
17
+ All functions are callable directly from RobinPath scripts with a simple, consistent API.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @robinpath/webhook
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ No credentials needed — start using it right away:
28
+
29
+ ```robinpath
30
+ webhook.sign $payload "whsec_abc"
31
+ ```
32
+
33
+ ## Available Functions
34
+
35
+ | Function | Description |
36
+ |----------|-------------|
37
+ | `webhook.send` | Send a webhook POST request with optional HMAC signature |
38
+ | `webhook.sign` | Create an HMAC signature for a webhook payload |
39
+ | `webhook.verify` | Verify a webhook HMAC signature using timing-safe comparison |
40
+ | `webhook.verifyTimestamp` | Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks |
41
+ | `webhook.parsePayload` | Parse a raw webhook body based on content type |
42
+ | `webhook.buildPayload` | Build a standardized webhook payload with event name, data, timestamp, and ID |
43
+ | `webhook.headers` | Build webhook headers including signature and timestamp |
44
+ | `webhook.isValidUrl` | Check if a string is a valid HTTP/HTTPS webhook URL |
45
+
46
+ ## Examples
47
+
48
+ ### Create an HMAC signature for a webhook payload
49
+
50
+ ```robinpath
51
+ webhook.sign $payload "whsec_abc"
52
+ ```
53
+
54
+ ### Verify a webhook HMAC signature using timing-safe comparison
55
+
56
+ ```robinpath
57
+ webhook.verify $body "whsec_abc" $signatureHeader
58
+ ```
59
+
60
+ ### Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks
61
+
62
+ ```robinpath
63
+ webhook.verifyTimestamp $timestamp 60000
64
+ ```
65
+
66
+ ## Integration with RobinPath
67
+
68
+ ```typescript
69
+ import { RobinPath } from "@wiredwp/robinpath";
70
+ import Module from "@robinpath/webhook";
71
+
72
+ const rp = new RobinPath();
73
+ rp.registerModule(Module.name, Module.functions);
74
+ rp.registerModuleMeta(Module.name, Module.functionMetadata);
75
+
76
+ const result = await rp.executeScript(`
77
+ webhook.sign $payload "whsec_abc"
78
+ `);
79
+ ```
80
+
81
+ ## Full API Reference
82
+
83
+ See [MODULE.md](./MODULE.md) for complete documentation including all parameters, return types, error handling, and advanced examples.
84
+
85
+ ## Related Modules
86
+
87
+ - [`@robinpath/json`](../json) — JSON module for complementary functionality
88
+
89
+ ## License
90
+
91
+ MIT
package/package.json CHANGED
@@ -1,14 +1,43 @@
1
1
  {
2
2
  "name": "@robinpath/webhook",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Send and verify webhooks with HMAC signatures for RobinPath",
5
- "publishConfig": { "access": "public" },
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
6
8
  "type": "module",
7
9
  "main": "dist/index.js",
8
10
  "types": "dist/index.d.ts",
9
- "exports": { ".": { "import": "./dist/index.js", "types": "./dist/index.d.ts" } },
10
- "files": ["dist"],
11
- "scripts": { "build": "tsc", "test": "node --import tsx --test tests/*.test.ts" },
12
- "peerDependencies": { "@wiredwp/robinpath": ">=0.20.0" },
13
- "devDependencies": { "@wiredwp/robinpath": "^0.30.1", "tsx": "^4.19.0", "typescript": "^5.6.0" }
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "test": "node --import tsx --test tests/*.test.ts"
23
+ },
24
+ "peerDependencies": {
25
+ "@robinpath/core": ">=0.20.0"
26
+ },
27
+ "devDependencies": {
28
+ "@robinpath/core": "^0.30.1",
29
+ "tsx": "^4.19.0",
30
+ "typescript": "^5.6.0"
31
+ },
32
+ "keywords": [
33
+ "webhook",
34
+ "web"
35
+ ],
36
+ "license": "MIT",
37
+ "robinpath": {
38
+ "category": "web",
39
+ "type": "utility",
40
+ "auth": "none",
41
+ "functionCount": 8
42
+ }
14
43
  }
package/dist/index.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import type { ModuleAdapter } from "@wiredwp/robinpath";
2
- declare const WebhookModule: ModuleAdapter;
3
- export default WebhookModule;
4
- export { WebhookModule };
5
- export { WebhookFunctions, WebhookFunctionMetadata, WebhookModuleMetadata } from "./webhook.js";
6
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,QAAA,MAAM,aAAa,EAAE,aAMpB,CAAC;AAEF,eAAe,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js DELETED
@@ -1,12 +0,0 @@
1
- import { WebhookFunctions, WebhookFunctionMetadata, WebhookModuleMetadata } from "./webhook.js";
2
- const WebhookModule = {
3
- name: "webhook",
4
- functions: WebhookFunctions,
5
- functionMetadata: WebhookFunctionMetadata,
6
- moduleMetadata: WebhookModuleMetadata,
7
- global: false,
8
- }; // as ModuleAdapter
9
- export default WebhookModule;
10
- export { WebhookModule };
11
- export { WebhookFunctions, WebhookFunctionMetadata, WebhookModuleMetadata } from "./webhook.js";
12
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAEhG,MAAM,aAAa,GAAkB;IACnC,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,gBAAgB;IAC3B,gBAAgB,EAAE,uBAA8B;IAChD,cAAc,EAAE,qBAA4B;IAC5C,MAAM,EAAE,KAAK;CACd,CAAC,CAAC,mBAAmB;AAEtB,eAAe,aAAa,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC"}
package/dist/webhook.d.ts DELETED
@@ -1,113 +0,0 @@
1
- import type { BuiltinHandler } from "@wiredwp/robinpath";
2
- export declare const WebhookFunctions: Record<string, BuiltinHandler>;
3
- export declare const WebhookFunctionMetadata: {
4
- send: {
5
- description: string;
6
- parameters: {
7
- name: string;
8
- dataType: string;
9
- description: string;
10
- formInputType: string;
11
- required: boolean;
12
- }[];
13
- returnType: string;
14
- returnDescription: string;
15
- example: string;
16
- };
17
- sign: {
18
- description: string;
19
- parameters: {
20
- name: string;
21
- dataType: string;
22
- description: string;
23
- formInputType: string;
24
- required: boolean;
25
- }[];
26
- returnType: string;
27
- returnDescription: string;
28
- example: string;
29
- };
30
- verify: {
31
- description: string;
32
- parameters: {
33
- name: string;
34
- dataType: string;
35
- description: string;
36
- formInputType: string;
37
- required: boolean;
38
- }[];
39
- returnType: string;
40
- returnDescription: string;
41
- example: string;
42
- };
43
- verifyTimestamp: {
44
- description: string;
45
- parameters: {
46
- name: string;
47
- dataType: string;
48
- description: string;
49
- formInputType: string;
50
- required: boolean;
51
- }[];
52
- returnType: string;
53
- returnDescription: string;
54
- example: string;
55
- };
56
- parsePayload: {
57
- description: string;
58
- parameters: {
59
- name: string;
60
- dataType: string;
61
- description: string;
62
- formInputType: string;
63
- required: boolean;
64
- }[];
65
- returnType: string;
66
- returnDescription: string;
67
- example: string;
68
- };
69
- buildPayload: {
70
- description: string;
71
- parameters: {
72
- name: string;
73
- dataType: string;
74
- description: string;
75
- formInputType: string;
76
- required: boolean;
77
- }[];
78
- returnType: string;
79
- returnDescription: string;
80
- example: string;
81
- };
82
- headers: {
83
- description: string;
84
- parameters: {
85
- name: string;
86
- dataType: string;
87
- description: string;
88
- formInputType: string;
89
- required: boolean;
90
- }[];
91
- returnType: string;
92
- returnDescription: string;
93
- example: string;
94
- };
95
- isValidUrl: {
96
- description: string;
97
- parameters: {
98
- name: string;
99
- dataType: string;
100
- description: string;
101
- formInputType: string;
102
- required: boolean;
103
- }[];
104
- returnType: string;
105
- returnDescription: string;
106
- example: string;
107
- };
108
- };
109
- export declare const WebhookModuleMetadata: {
110
- description: string;
111
- methods: string[];
112
- };
113
- //# sourceMappingURL=webhook.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA2C,MAAM,oBAAoB,CAAC;AAiLlG,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAE3D,CAAC;AAEF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsEnC,CAAC;AAEF,eAAO,MAAM,qBAAqB;;;CAGjC,CAAC"}
package/dist/webhook.js DELETED
@@ -1,228 +0,0 @@
1
- import { createHmac, timingSafeEqual } from "node:crypto";
2
- // ── Function Handlers ───────────────────────────────────────────────
3
- const send = async (args) => {
4
- const url = String(args[0] ?? "");
5
- const payload = args[1];
6
- const opts = (typeof args[2] === "object" && args[2] !== null ? args[2] : {});
7
- if (!url)
8
- throw new Error("URL is required");
9
- const secret = opts.secret != null ? String(opts.secret) : undefined;
10
- const method = String(opts.method ?? "POST").toUpperCase();
11
- const contentType = String(opts.contentType ?? "application/json");
12
- const headers = {
13
- "Content-Type": contentType,
14
- "User-Agent": "RobinPath-Webhook/1.0",
15
- };
16
- // Merge custom headers
17
- if (typeof opts.headers === "object" && opts.headers !== null) {
18
- for (const [k, v] of Object.entries(opts.headers)) {
19
- headers[k] = String(v);
20
- }
21
- }
22
- const body = contentType.includes("json") ? JSON.stringify(payload) : String(payload);
23
- // Sign the payload if secret is provided
24
- if (secret) {
25
- const algorithm = String(opts.algorithm ?? "sha256");
26
- const signature = createHmac(algorithm, secret).update(body).digest("hex");
27
- const headerName = String(opts.signatureHeader ?? "X-Webhook-Signature");
28
- headers[headerName] = `${algorithm}=${signature}`;
29
- }
30
- // Add timestamp
31
- const timestamp = Date.now().toString();
32
- headers["X-Webhook-Timestamp"] = timestamp;
33
- // Add custom event type
34
- if (opts.event) {
35
- headers["X-Webhook-Event"] = String(opts.event);
36
- }
37
- const response = await fetch(url, { method, headers, body });
38
- return {
39
- status: response.status,
40
- statusText: response.statusText,
41
- ok: response.ok,
42
- headers: Object.fromEntries(response.headers.entries()),
43
- body: response.headers.get("content-type")?.includes("json")
44
- ? await response.json()
45
- : await response.text(),
46
- };
47
- };
48
- const sign = (args) => {
49
- const payload = typeof args[0] === "string" ? args[0] : JSON.stringify(args[0]);
50
- const secret = String(args[1] ?? "");
51
- const algorithm = String(args[2] ?? "sha256");
52
- const signature = createHmac(algorithm, secret).update(payload).digest("hex");
53
- return `${algorithm}=${signature}`;
54
- };
55
- const verify = (args) => {
56
- const payload = typeof args[0] === "string" ? args[0] : JSON.stringify(args[0]);
57
- const secret = String(args[1] ?? "");
58
- const signature = String(args[2] ?? "");
59
- const algorithm = String(args[3] ?? "sha256");
60
- // Parse the signature format "algorithm=hex"
61
- let expectedAlgo = algorithm;
62
- let sigHex = signature;
63
- if (signature.includes("=")) {
64
- const parts = signature.split("=");
65
- expectedAlgo = parts[0];
66
- sigHex = parts.slice(1).join("=");
67
- }
68
- const expected = createHmac(expectedAlgo, secret).update(payload).digest("hex");
69
- if (expected.length !== sigHex.length)
70
- return false;
71
- try {
72
- return timingSafeEqual(Buffer.from(expected), Buffer.from(sigHex));
73
- }
74
- catch {
75
- return false;
76
- }
77
- };
78
- const verifyTimestamp = (args) => {
79
- const timestamp = parseInt(String(args[0] ?? "0"), 10);
80
- const toleranceMs = parseInt(String(args[1] ?? "300000"), 10); // default 5 minutes
81
- const now = Date.now();
82
- const diff = Math.abs(now - timestamp);
83
- return {
84
- valid: diff <= toleranceMs,
85
- ageMs: diff,
86
- toleranceMs,
87
- };
88
- };
89
- const parsePayload = (args) => {
90
- const body = args[0];
91
- const contentType = String(args[1] ?? "application/json");
92
- if (contentType.includes("json")) {
93
- if (typeof body === "string")
94
- return JSON.parse(body);
95
- return body;
96
- }
97
- if (contentType.includes("x-www-form-urlencoded")) {
98
- const params = new URLSearchParams(String(body));
99
- const result = {};
100
- for (const [key, value] of params.entries()) {
101
- result[key] = value;
102
- }
103
- return result;
104
- }
105
- return String(body);
106
- };
107
- const buildPayload = (args) => {
108
- const event = String(args[0] ?? "");
109
- const data = args[1];
110
- const opts = (typeof args[2] === "object" && args[2] !== null ? args[2] : {});
111
- return {
112
- event,
113
- data,
114
- timestamp: new Date().toISOString(),
115
- id: opts.id ?? `wh_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`,
116
- ...(opts.metadata ? { metadata: opts.metadata } : {}),
117
- };
118
- };
119
- const headers = (args) => {
120
- const secret = String(args[0] ?? "");
121
- const payload = typeof args[1] === "string" ? args[1] : JSON.stringify(args[1]);
122
- const event = args[2] != null ? String(args[2]) : undefined;
123
- const algorithm = String(args[3] ?? "sha256");
124
- const timestamp = Date.now().toString();
125
- const result = {
126
- "Content-Type": "application/json",
127
- "User-Agent": "RobinPath-Webhook/1.0",
128
- "X-Webhook-Timestamp": timestamp,
129
- };
130
- if (secret) {
131
- const signature = createHmac(algorithm, secret).update(payload).digest("hex");
132
- result["X-Webhook-Signature"] = `${algorithm}=${signature}`;
133
- }
134
- if (event) {
135
- result["X-Webhook-Event"] = event;
136
- }
137
- return result;
138
- };
139
- const isValidUrl = (args) => {
140
- const url = String(args[0] ?? "");
141
- try {
142
- const parsed = new URL(url);
143
- return parsed.protocol === "https:" || parsed.protocol === "http:";
144
- }
145
- catch {
146
- return false;
147
- }
148
- };
149
- // ── Exports ─────────────────────────────────────────────────────────
150
- export const WebhookFunctions = {
151
- send, sign, verify, verifyTimestamp, parsePayload, buildPayload, headers, isValidUrl,
152
- };
153
- export const WebhookFunctionMetadata = {
154
- send: {
155
- description: "Send a webhook POST request with optional HMAC signature",
156
- parameters: [
157
- { name: "url", dataType: "string", description: "Target webhook URL", formInputType: "text", required: true },
158
- { name: "payload", dataType: "any", description: "Data to send", formInputType: "text", required: true },
159
- { name: "options", dataType: "object", description: "{secret, method, contentType, headers, algorithm, signatureHeader, event}", formInputType: "text", required: false },
160
- ],
161
- returnType: "object", returnDescription: "{status, statusText, ok, headers, body}", example: 'webhook.send "https://example.com/hook" $data {"secret": "whsec_abc"}',
162
- },
163
- sign: {
164
- description: "Create an HMAC signature for a webhook payload",
165
- parameters: [
166
- { name: "payload", dataType: "any", description: "The payload to sign (string or object)", formInputType: "text", required: true },
167
- { name: "secret", dataType: "string", description: "The webhook secret", formInputType: "text", required: true },
168
- { name: "algorithm", dataType: "string", description: "Hash algorithm (default: sha256)", formInputType: "text", required: false },
169
- ],
170
- returnType: "string", returnDescription: "Signature in format 'algorithm=hex'", example: 'webhook.sign $payload "whsec_abc"',
171
- },
172
- verify: {
173
- description: "Verify a webhook HMAC signature using timing-safe comparison",
174
- parameters: [
175
- { name: "payload", dataType: "any", description: "The received payload", formInputType: "text", required: true },
176
- { name: "secret", dataType: "string", description: "The webhook secret", formInputType: "text", required: true },
177
- { name: "signature", dataType: "string", description: "The received signature", formInputType: "text", required: true },
178
- { name: "algorithm", dataType: "string", description: "Hash algorithm (default: sha256)", formInputType: "text", required: false },
179
- ],
180
- returnType: "boolean", returnDescription: "True if signature is valid", example: 'webhook.verify $body "whsec_abc" $signatureHeader',
181
- },
182
- verifyTimestamp: {
183
- description: "Verify a webhook timestamp is within acceptable tolerance to prevent replay attacks",
184
- parameters: [
185
- { name: "timestamp", dataType: "number", description: "Timestamp in milliseconds", formInputType: "text", required: true },
186
- { name: "toleranceMs", dataType: "number", description: "Tolerance in ms (default 300000 = 5min)", formInputType: "text", required: false },
187
- ],
188
- returnType: "object", returnDescription: "{valid, ageMs, toleranceMs}", example: 'webhook.verifyTimestamp $timestamp 60000',
189
- },
190
- parsePayload: {
191
- description: "Parse a raw webhook body based on content type",
192
- parameters: [
193
- { name: "body", dataType: "any", description: "Raw request body", formInputType: "text", required: true },
194
- { name: "contentType", dataType: "string", description: "Content-Type header (default: application/json)", formInputType: "text", required: false },
195
- ],
196
- returnType: "any", returnDescription: "Parsed payload", example: 'webhook.parsePayload $rawBody "application/json"',
197
- },
198
- buildPayload: {
199
- description: "Build a standardized webhook payload with event name, data, timestamp, and ID",
200
- parameters: [
201
- { name: "event", dataType: "string", description: "Event type name", formInputType: "text", required: true },
202
- { name: "data", dataType: "any", description: "Event data", formInputType: "text", required: true },
203
- { name: "options", dataType: "object", description: "{id, metadata}", formInputType: "text", required: false },
204
- ],
205
- returnType: "object", returnDescription: "{event, data, timestamp, id}", example: 'webhook.buildPayload "order.created" $orderData',
206
- },
207
- headers: {
208
- description: "Build webhook headers including signature and timestamp",
209
- parameters: [
210
- { name: "secret", dataType: "string", description: "Webhook secret for signing", formInputType: "text", required: true },
211
- { name: "payload", dataType: "any", description: "The payload being sent", formInputType: "text", required: true },
212
- { name: "event", dataType: "string", description: "Event type header (optional)", formInputType: "text", required: false },
213
- ],
214
- returnType: "object", returnDescription: "Headers object ready for HTTP request", example: 'webhook.headers "whsec_abc" $payload "order.created"',
215
- },
216
- isValidUrl: {
217
- description: "Check if a string is a valid HTTP/HTTPS webhook URL",
218
- parameters: [
219
- { name: "url", dataType: "string", description: "URL to validate", formInputType: "text", required: true },
220
- ],
221
- returnType: "boolean", returnDescription: "True if valid HTTP(S) URL", example: 'webhook.isValidUrl "https://example.com/hook"',
222
- },
223
- };
224
- export const WebhookModuleMetadata = {
225
- description: "Send webhooks with HMAC signatures, verify incoming webhook payloads, and prevent replay attacks",
226
- methods: ["send", "sign", "verify", "verifyTimestamp", "parsePayload", "buildPayload", "headers", "isValidUrl"],
227
- };
228
- //# sourceMappingURL=webhook.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE1D,uEAAuE;AAEvE,MAAM,IAAI,GAAmB,KAAK,EAAE,IAAI,EAAE,EAAE;IAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;IAEzG,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAE7C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,kBAAkB,CAAC,CAAC;IACnE,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,WAAW;QAC3B,YAAY,EAAE,uBAAuB;KACtC,CAAC;IAEF,uBAAuB;IACvB,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9D,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAkC,CAAC,EAAE,CAAC;YAC7E,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEtF,yCAAyC;IACzC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC;QACrD,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,IAAI,qBAAqB,CAAC,CAAC;QACzE,OAAO,CAAC,UAAU,CAAC,GAAG,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC;IACpD,CAAC;IAED,gBAAgB;IAChB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACxC,OAAO,CAAC,qBAAqB,CAAC,GAAG,SAAS,CAAC;IAE3C,wBAAwB;IACxB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7D,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACvD,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC;YAC1D,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE;YACvB,CAAC,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE;KAC1B,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,IAAI,GAAmB,CAAC,IAAI,EAAE,EAAE;IACpC,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,OAAO,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,MAAM,GAAmB,CAAC,IAAI,EAAE,EAAE;IACtC,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;IAE9C,6CAA6C;IAC7C,IAAI,YAAY,GAAG,SAAS,CAAC;IAC7B,IAAI,MAAM,GAAG,SAAS,CAAC;IACvB,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACzB,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhF,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC;QACH,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAmB,CAAC,IAAI,EAAE,EAAE;IAC/C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;IACnF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC;IACvC,OAAO;QACL,KAAK,EAAE,IAAI,IAAI,WAAW;QAC1B,KAAK,EAAE,IAAI;QACX,WAAW;KACZ,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,YAAY,GAAmB,CAAC,IAAI,EAAE,EAAE;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,CAAC;IAE1D,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,WAAW,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAA2B,EAAE,CAAC;QAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,YAAY,GAAmB,CAAC,IAAI,EAAE,EAAE;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAA4B,CAAC;IAEzG,OAAO;QACL,KAAK;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QAC/E,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,OAAO,GAAmB,CAAC,IAAI,EAAE,EAAE;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;IAE9C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACxC,MAAM,MAAM,GAA2B;QACrC,cAAc,EAAE,kBAAkB;QAClC,YAAY,EAAE,uBAAuB;QACrC,qBAAqB,EAAE,SAAS;KACjC,CAAC;IAEF,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,CAAC,qBAAqB,CAAC,GAAG,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC;IAC9D,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,iBAAiB,CAAC,GAAG,KAAK,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAmB,CAAC,IAAI,EAAE,EAAE;IAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,uEAAuE;AAEvE,MAAM,CAAC,MAAM,gBAAgB,GAAmC;IAC9D,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU;CACrF,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE;QACJ,WAAW,EAAE,0DAA0D;QACvE,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC7G,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACxG,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,2EAA2E,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC1K;QACD,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,yCAAyC,EAAE,OAAO,EAAE,uEAAuE;KACrK;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,gDAAgD;QAC7D,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,wCAAwC,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAClI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAChH,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnI;QACD,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,qCAAqC,EAAE,OAAO,EAAE,mCAAmC;KAC7H;IACD,MAAM,EAAE;QACN,WAAW,EAAE,8DAA8D;QAC3E,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAChH,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAChH,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACvH,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnI;QACD,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,OAAO,EAAE,mDAAmD;KACrI;IACD,eAAe,EAAE;QACf,WAAW,EAAE,qFAAqF;QAClG,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC1H,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC5I;QACD,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,6BAA6B,EAAE,OAAO,EAAE,0CAA0C;KAC5H;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,gDAAgD;QAC7D,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACzG,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,iDAAiD,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SACpJ;QACD,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,OAAO,EAAE,kDAAkD;KACpH;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,+EAA+E;QAC5F,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC5G,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACnG,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC/G;QACD,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,8BAA8B,EAAE,OAAO,EAAE,iDAAiD;KACpI;IACD,OAAO,EAAE;QACP,WAAW,EAAE,yDAAyD;QACtE,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,4BAA4B,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YACxH,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;YAClH,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;SAC3H;QACD,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,uCAAuC,EAAE,OAAO,EAAE,sDAAsD;KAClJ;IACD,UAAU,EAAE;QACV,WAAW,EAAE,qDAAqD;QAClE,UAAU,EAAE;YACV,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;SAC3G;QACD,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,OAAO,EAAE,+CAA+C;KAChI;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,WAAW,EAAE,kGAAkG;IAC/G,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,CAAC;CAChH,CAAC"}