@orgloop/connector-webhook 0.1.8 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/target.d.ts +2 -0
- package/dist/target.d.ts.map +1 -1
- package/dist/target.js +10 -2
- package/dist/target.js.map +1 -1
- package/package.json +2 -2
- package/dist/__tests__/webhook.test.d.ts +0 -2
- package/dist/__tests__/webhook.test.d.ts.map +0 -1
- package/dist/__tests__/webhook.test.js +0 -567
- package/dist/__tests__/webhook.test.js.map +0 -1
package/dist/target.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export declare class WebhookTarget implements ActorConnector {
|
|
|
9
9
|
private customHeaders;
|
|
10
10
|
private authHeader?;
|
|
11
11
|
private bodyTemplate?;
|
|
12
|
+
private httpAgent;
|
|
13
|
+
private keepAliveFetch;
|
|
12
14
|
init(config: ActorConfig): Promise<void>;
|
|
13
15
|
deliver(event: OrgLoopEvent, routeConfig: RouteDeliveryConfig): Promise<DeliveryResult>;
|
|
14
16
|
shutdown(): Promise<void>;
|
package/dist/target.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACX,WAAW,EACX,cAAc,EACd,cAAc,
|
|
1
|
+
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACX,WAAW,EACX,cAAc,EACd,cAAc,EAEd,YAAY,EACZ,mBAAmB,EACnB,MAAM,cAAc,CAAC;AAoEtB,qBAAa,aAAc,YAAW,cAAc;IACnD,QAAQ,CAAC,EAAE,aAAa;IACxB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAA0B;IAC/C,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,cAAc,CAA6C;IAE7D,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxC,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IA6DvF,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
|
package/dist/target.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generic webhook target connector — POSTs events to a configured URL.
|
|
3
3
|
*/
|
|
4
|
+
import { closeHttpAgent, createFetchWithKeepAlive, createHttpAgent } from '@orgloop/sdk';
|
|
4
5
|
/** Resolve env var references */
|
|
5
6
|
function resolveEnvVar(value) {
|
|
6
7
|
const match = value.match(/^\$\{(.+)\}$/);
|
|
@@ -58,6 +59,8 @@ export class WebhookTarget {
|
|
|
58
59
|
customHeaders = {};
|
|
59
60
|
authHeader;
|
|
60
61
|
bodyTemplate;
|
|
62
|
+
httpAgent = null;
|
|
63
|
+
keepAliveFetch = globalThis.fetch;
|
|
61
64
|
async init(config) {
|
|
62
65
|
const cfg = config.config;
|
|
63
66
|
this.url = cfg.url;
|
|
@@ -73,6 +76,8 @@ export class WebhookTarget {
|
|
|
73
76
|
this.authHeader = `Basic ${credentials}`;
|
|
74
77
|
}
|
|
75
78
|
}
|
|
79
|
+
this.httpAgent = createHttpAgent();
|
|
80
|
+
this.keepAliveFetch = createFetchWithKeepAlive(this.httpAgent);
|
|
76
81
|
}
|
|
77
82
|
async deliver(event, routeConfig) {
|
|
78
83
|
const headers = {
|
|
@@ -97,7 +102,7 @@ export class WebhookTarget {
|
|
|
97
102
|
};
|
|
98
103
|
}
|
|
99
104
|
try {
|
|
100
|
-
const response = await
|
|
105
|
+
const response = await this.keepAliveFetch(this.url, {
|
|
101
106
|
method: this.method,
|
|
102
107
|
headers,
|
|
103
108
|
body: JSON.stringify(body),
|
|
@@ -130,7 +135,10 @@ export class WebhookTarget {
|
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
137
|
async shutdown() {
|
|
133
|
-
|
|
138
|
+
if (this.httpAgent) {
|
|
139
|
+
await closeHttpAgent(this.httpAgent);
|
|
140
|
+
this.httpAgent = null;
|
|
141
|
+
}
|
|
134
142
|
}
|
|
135
143
|
}
|
|
136
144
|
//# sourceMappingURL=target.js.map
|
package/dist/target.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,iCAAiC;AACjC,SAAS,aAAa,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,gEAAgE;AAChE,SAAS,cAAc,CAAC,GAAY,EAAE,IAAY;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACrE,OAAO,GAAI,OAAmC,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,SAAS,cAAc,CAAC,QAAiB,EAAE,OAAgC;IAC1E,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,6EAA6E;QAC7E,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC7D,IAAI,SAAS,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,OAAO,KAAK,IAAI,EAAE,CAAC;QACpB,CAAC;QACD,0DAA0D;QAC1D,OAAO,QAAQ,CAAC,OAAO,CAAC,yBAAyB,EAAE,CAAC,MAAM,EAAE,IAAY,EAAE,EAAE;YAC3E,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5C,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAmC,CAAC,EAAE,CAAC;YAChF,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAeD,MAAM,OAAO,aAAa;IAChB,EAAE,GAAG,SAAS,CAAC;IAChB,GAAG,GAAG,EAAE,CAAC;IACT,MAAM,GAAmB,MAAM,CAAC;IAChC,aAAa,GAA2B,EAAE,CAAC;IAC3C,UAAU,CAAU;IACpB,YAAY,CAA2B;
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orgloop/connector-webhook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"description": "OrgLoop generic webhook connector — inbound and outbound",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@orgloop/sdk": "0.
|
|
9
|
+
"@orgloop/sdk": "0.7.6"
|
|
10
10
|
},
|
|
11
11
|
"orgloop": {
|
|
12
12
|
"type": "connector",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/webhook.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
import { createHmac } from 'node:crypto';
|
|
2
|
-
import { EventEmitter } from 'node:events';
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
-
import { tmpdir } from 'node:os';
|
|
5
|
-
import { join } from 'node:path';
|
|
6
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
-
import { WebhookSource } from '../source.js';
|
|
8
|
-
import { WebhookTarget } from '../target.js';
|
|
9
|
-
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
10
|
-
function createMockRequest(body, method = 'POST', headers = {}) {
|
|
11
|
-
const req = new EventEmitter();
|
|
12
|
-
req.method = method;
|
|
13
|
-
req.headers = headers;
|
|
14
|
-
setTimeout(() => {
|
|
15
|
-
req.emit('data', Buffer.from(body));
|
|
16
|
-
req.emit('end');
|
|
17
|
-
}, 0);
|
|
18
|
-
return req;
|
|
19
|
-
}
|
|
20
|
-
function createMockResponse() {
|
|
21
|
-
const res = {
|
|
22
|
-
statusCode: 200,
|
|
23
|
-
body: '',
|
|
24
|
-
writeHead(code, _headers) {
|
|
25
|
-
res.statusCode = code;
|
|
26
|
-
return res;
|
|
27
|
-
},
|
|
28
|
-
end(data) {
|
|
29
|
-
res.body = data ?? '';
|
|
30
|
-
return res;
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
return res;
|
|
34
|
-
}
|
|
35
|
-
function signPayload(body, secret) {
|
|
36
|
-
return `sha256=${createHmac('sha256', secret).update(body).digest('hex')}`;
|
|
37
|
-
}
|
|
38
|
-
// ─── WebhookSource ────────────────────────────────────────────────────────────
|
|
39
|
-
describe('WebhookSource', () => {
|
|
40
|
-
it('initializes and returns empty poll', async () => {
|
|
41
|
-
const source = new WebhookSource();
|
|
42
|
-
await source.init({
|
|
43
|
-
id: 'webhook',
|
|
44
|
-
connector: '@orgloop/connector-webhook',
|
|
45
|
-
config: { path: '/webhook' },
|
|
46
|
-
});
|
|
47
|
-
const result = await source.poll(null);
|
|
48
|
-
expect(result.events).toHaveLength(0);
|
|
49
|
-
});
|
|
50
|
-
it('receives webhook and normalizes to OrgLoop event', async () => {
|
|
51
|
-
const source = new WebhookSource();
|
|
52
|
-
await source.init({ id: 'webhook', connector: '@orgloop/connector-webhook', config: {} });
|
|
53
|
-
const handler = source.webhook();
|
|
54
|
-
const payload = { type: 'deployment', repo: 'my-app', status: 'success' };
|
|
55
|
-
const req = createMockRequest(JSON.stringify(payload));
|
|
56
|
-
const res = createMockResponse();
|
|
57
|
-
const events = await handler(req, res);
|
|
58
|
-
expect(res.statusCode).toBe(200);
|
|
59
|
-
expect(events).toHaveLength(1);
|
|
60
|
-
expect(events[0].type).toBe('resource.changed');
|
|
61
|
-
expect(events[0].source).toBe('webhook');
|
|
62
|
-
expect(events[0].provenance.platform).toBe('webhook');
|
|
63
|
-
expect(events[0].provenance.platform_event).toBe('deployment');
|
|
64
|
-
expect(events[0].payload).toEqual(payload);
|
|
65
|
-
// Drain via poll
|
|
66
|
-
const result = await source.poll(null);
|
|
67
|
-
expect(result.events).toHaveLength(1);
|
|
68
|
-
});
|
|
69
|
-
it('rejects non-POST', async () => {
|
|
70
|
-
const source = new WebhookSource();
|
|
71
|
-
await source.init({ id: 'webhook', connector: '@orgloop/connector-webhook', config: {} });
|
|
72
|
-
const handler = source.webhook();
|
|
73
|
-
const req = createMockRequest('', 'GET');
|
|
74
|
-
const res = createMockResponse();
|
|
75
|
-
const events = await handler(req, res);
|
|
76
|
-
expect(res.statusCode).toBe(405);
|
|
77
|
-
expect(events).toHaveLength(0);
|
|
78
|
-
});
|
|
79
|
-
it('rejects invalid JSON', async () => {
|
|
80
|
-
const source = new WebhookSource();
|
|
81
|
-
await source.init({ id: 'webhook', connector: '@orgloop/connector-webhook', config: {} });
|
|
82
|
-
const handler = source.webhook();
|
|
83
|
-
const req = createMockRequest('{invalid');
|
|
84
|
-
const res = createMockResponse();
|
|
85
|
-
const events = await handler(req, res);
|
|
86
|
-
expect(res.statusCode).toBe(400);
|
|
87
|
-
expect(events).toHaveLength(0);
|
|
88
|
-
});
|
|
89
|
-
it('clears pending events on shutdown', async () => {
|
|
90
|
-
const source = new WebhookSource();
|
|
91
|
-
await source.init({ id: 'webhook', connector: '@orgloop/connector-webhook', config: {} });
|
|
92
|
-
const handler = source.webhook();
|
|
93
|
-
const req = createMockRequest(JSON.stringify({ test: true }));
|
|
94
|
-
const res = createMockResponse();
|
|
95
|
-
await handler(req, res);
|
|
96
|
-
await source.shutdown();
|
|
97
|
-
const result = await source.poll(null);
|
|
98
|
-
expect(result.events).toHaveLength(0);
|
|
99
|
-
});
|
|
100
|
-
// ─── HMAC Validation ────────────────────────────────────────────────────
|
|
101
|
-
describe('HMAC validation', () => {
|
|
102
|
-
const SECRET = 'test-webhook-secret';
|
|
103
|
-
it('accepts valid HMAC-SHA256 signature via x-hub-signature-256', async () => {
|
|
104
|
-
const source = new WebhookSource();
|
|
105
|
-
await source.init({
|
|
106
|
-
id: 'webhook',
|
|
107
|
-
connector: '@orgloop/connector-webhook',
|
|
108
|
-
config: { secret: SECRET },
|
|
109
|
-
});
|
|
110
|
-
const handler = source.webhook();
|
|
111
|
-
const body = JSON.stringify({ type: 'push', ref: 'refs/heads/main' });
|
|
112
|
-
const signature = signPayload(body, SECRET);
|
|
113
|
-
const req = createMockRequest(body, 'POST', { 'x-hub-signature-256': signature });
|
|
114
|
-
const res = createMockResponse();
|
|
115
|
-
const events = await handler(req, res);
|
|
116
|
-
expect(res.statusCode).toBe(200);
|
|
117
|
-
expect(events).toHaveLength(1);
|
|
118
|
-
expect(events[0].provenance.platform_event).toBe('push');
|
|
119
|
-
});
|
|
120
|
-
it('accepts valid HMAC-SHA256 signature via x-signature header', async () => {
|
|
121
|
-
const source = new WebhookSource();
|
|
122
|
-
await source.init({
|
|
123
|
-
id: 'webhook',
|
|
124
|
-
connector: '@orgloop/connector-webhook',
|
|
125
|
-
config: { secret: SECRET },
|
|
126
|
-
});
|
|
127
|
-
const handler = source.webhook();
|
|
128
|
-
const body = JSON.stringify({ type: 'deploy', env: 'prod' });
|
|
129
|
-
const signature = signPayload(body, SECRET);
|
|
130
|
-
const req = createMockRequest(body, 'POST', { 'x-signature': signature });
|
|
131
|
-
const res = createMockResponse();
|
|
132
|
-
const events = await handler(req, res);
|
|
133
|
-
expect(res.statusCode).toBe(200);
|
|
134
|
-
expect(events).toHaveLength(1);
|
|
135
|
-
});
|
|
136
|
-
it('rejects invalid signature with 401', async () => {
|
|
137
|
-
const source = new WebhookSource();
|
|
138
|
-
await source.init({
|
|
139
|
-
id: 'webhook',
|
|
140
|
-
connector: '@orgloop/connector-webhook',
|
|
141
|
-
config: { secret: SECRET },
|
|
142
|
-
});
|
|
143
|
-
const handler = source.webhook();
|
|
144
|
-
const body = JSON.stringify({ type: 'push' });
|
|
145
|
-
const req = createMockRequest(body, 'POST', {
|
|
146
|
-
'x-hub-signature-256': 'sha256=invalid_signature_value',
|
|
147
|
-
});
|
|
148
|
-
const res = createMockResponse();
|
|
149
|
-
const events = await handler(req, res);
|
|
150
|
-
expect(res.statusCode).toBe(401);
|
|
151
|
-
expect(events).toHaveLength(0);
|
|
152
|
-
expect(JSON.parse(res.body).error).toBe('Invalid signature');
|
|
153
|
-
});
|
|
154
|
-
it('rejects missing signature when secret is configured with 401', async () => {
|
|
155
|
-
const source = new WebhookSource();
|
|
156
|
-
await source.init({
|
|
157
|
-
id: 'webhook',
|
|
158
|
-
connector: '@orgloop/connector-webhook',
|
|
159
|
-
config: { secret: SECRET },
|
|
160
|
-
});
|
|
161
|
-
const handler = source.webhook();
|
|
162
|
-
const body = JSON.stringify({ type: 'push' });
|
|
163
|
-
const req = createMockRequest(body, 'POST');
|
|
164
|
-
const res = createMockResponse();
|
|
165
|
-
const events = await handler(req, res);
|
|
166
|
-
expect(res.statusCode).toBe(401);
|
|
167
|
-
expect(events).toHaveLength(0);
|
|
168
|
-
expect(JSON.parse(res.body).error).toBe('Missing signature');
|
|
169
|
-
});
|
|
170
|
-
it('accepts all requests when no secret is configured', async () => {
|
|
171
|
-
const source = new WebhookSource();
|
|
172
|
-
await source.init({
|
|
173
|
-
id: 'webhook',
|
|
174
|
-
connector: '@orgloop/connector-webhook',
|
|
175
|
-
config: {},
|
|
176
|
-
});
|
|
177
|
-
const handler = source.webhook();
|
|
178
|
-
const body = JSON.stringify({ type: 'anything' });
|
|
179
|
-
const req = createMockRequest(body, 'POST');
|
|
180
|
-
const res = createMockResponse();
|
|
181
|
-
const events = await handler(req, res);
|
|
182
|
-
expect(res.statusCode).toBe(200);
|
|
183
|
-
expect(events).toHaveLength(1);
|
|
184
|
-
});
|
|
185
|
-
it('prefers x-hub-signature-256 over x-signature', async () => {
|
|
186
|
-
const source = new WebhookSource();
|
|
187
|
-
await source.init({
|
|
188
|
-
id: 'webhook',
|
|
189
|
-
connector: '@orgloop/connector-webhook',
|
|
190
|
-
config: { secret: SECRET },
|
|
191
|
-
});
|
|
192
|
-
const handler = source.webhook();
|
|
193
|
-
const body = JSON.stringify({ type: 'push' });
|
|
194
|
-
const validSig = signPayload(body, SECRET);
|
|
195
|
-
const req = createMockRequest(body, 'POST', {
|
|
196
|
-
'x-hub-signature-256': validSig,
|
|
197
|
-
'x-signature': 'sha256=wrong',
|
|
198
|
-
});
|
|
199
|
-
const res = createMockResponse();
|
|
200
|
-
const events = await handler(req, res);
|
|
201
|
-
// Should succeed because x-hub-signature-256 is valid (checked first)
|
|
202
|
-
expect(res.statusCode).toBe(200);
|
|
203
|
-
expect(events).toHaveLength(1);
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
// ─── Buffer Persistence ─────────────────────────────────────────────────
|
|
207
|
-
describe('buffer persistence', () => {
|
|
208
|
-
const bufferDir = join(tmpdir(), `webhook-test-${Date.now()}`);
|
|
209
|
-
afterEach(() => {
|
|
210
|
-
if (existsSync(bufferDir)) {
|
|
211
|
-
rmSync(bufferDir, { recursive: true });
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
it('persists events to JSONL file', async () => {
|
|
215
|
-
const source = new WebhookSource();
|
|
216
|
-
await source.init({
|
|
217
|
-
id: 'test-src',
|
|
218
|
-
connector: '@orgloop/connector-webhook',
|
|
219
|
-
config: { buffer_dir: bufferDir },
|
|
220
|
-
});
|
|
221
|
-
const handler = source.webhook();
|
|
222
|
-
const body = JSON.stringify({ type: 'deploy' });
|
|
223
|
-
const req = createMockRequest(body);
|
|
224
|
-
const res = createMockResponse();
|
|
225
|
-
await handler(req, res);
|
|
226
|
-
expect(res.statusCode).toBe(200);
|
|
227
|
-
// Verify the file exists with content
|
|
228
|
-
const bufferPath = join(bufferDir, 'webhook-test-src.jsonl');
|
|
229
|
-
expect(existsSync(bufferPath)).toBe(true);
|
|
230
|
-
const content = readFileSync(bufferPath, 'utf-8').trim();
|
|
231
|
-
const lines = content.split('\n');
|
|
232
|
-
expect(lines).toHaveLength(1);
|
|
233
|
-
const event = JSON.parse(lines[0]);
|
|
234
|
-
expect(event.type).toBe('resource.changed');
|
|
235
|
-
});
|
|
236
|
-
it('drains buffer on poll and truncates file', async () => {
|
|
237
|
-
const source = new WebhookSource();
|
|
238
|
-
await source.init({
|
|
239
|
-
id: 'test-src',
|
|
240
|
-
connector: '@orgloop/connector-webhook',
|
|
241
|
-
config: { buffer_dir: bufferDir },
|
|
242
|
-
});
|
|
243
|
-
const handler = source.webhook();
|
|
244
|
-
// Send two webhooks
|
|
245
|
-
for (let i = 0; i < 2; i++) {
|
|
246
|
-
const body = JSON.stringify({ type: 'event', index: i });
|
|
247
|
-
const req = createMockRequest(body);
|
|
248
|
-
const res = createMockResponse();
|
|
249
|
-
await handler(req, res);
|
|
250
|
-
}
|
|
251
|
-
// Poll should return both events
|
|
252
|
-
const result = await source.poll(null);
|
|
253
|
-
expect(result.events).toHaveLength(2);
|
|
254
|
-
// Buffer file should be empty after poll
|
|
255
|
-
const bufferPath = join(bufferDir, 'webhook-test-src.jsonl');
|
|
256
|
-
const content = readFileSync(bufferPath, 'utf-8');
|
|
257
|
-
expect(content).toBe('');
|
|
258
|
-
// Next poll should return zero events
|
|
259
|
-
const result2 = await source.poll(null);
|
|
260
|
-
expect(result2.events).toHaveLength(0);
|
|
261
|
-
});
|
|
262
|
-
it('creates buffer directory if it does not exist', async () => {
|
|
263
|
-
const nestedDir = join(bufferDir, 'nested', 'dir');
|
|
264
|
-
const source = new WebhookSource();
|
|
265
|
-
await source.init({
|
|
266
|
-
id: 'test-src',
|
|
267
|
-
connector: '@orgloop/connector-webhook',
|
|
268
|
-
config: { buffer_dir: nestedDir },
|
|
269
|
-
});
|
|
270
|
-
expect(existsSync(nestedDir)).toBe(true);
|
|
271
|
-
});
|
|
272
|
-
it('survives simulated restart by reading existing buffer', async () => {
|
|
273
|
-
// Create buffer directory and write events directly
|
|
274
|
-
mkdirSync(bufferDir, { recursive: true });
|
|
275
|
-
const bufferPath = join(bufferDir, 'webhook-persist.jsonl');
|
|
276
|
-
const fakeEvent = {
|
|
277
|
-
id: 'evt_test123',
|
|
278
|
-
timestamp: new Date().toISOString(),
|
|
279
|
-
source: 'webhook',
|
|
280
|
-
type: 'resource.changed',
|
|
281
|
-
provenance: { platform: 'webhook' },
|
|
282
|
-
payload: { survived: true },
|
|
283
|
-
};
|
|
284
|
-
writeFileSync(bufferPath, `${JSON.stringify(fakeEvent)}\n`);
|
|
285
|
-
// Init source — should pick up the pre-existing buffer
|
|
286
|
-
const source = new WebhookSource();
|
|
287
|
-
await source.init({
|
|
288
|
-
id: 'persist',
|
|
289
|
-
connector: '@orgloop/connector-webhook',
|
|
290
|
-
config: { buffer_dir: bufferDir },
|
|
291
|
-
});
|
|
292
|
-
const result = await source.poll(null);
|
|
293
|
-
expect(result.events).toHaveLength(1);
|
|
294
|
-
expect(result.events[0].payload).toEqual({ survived: true });
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
// ─── WebhookTarget ────────────────────────────────────────────────────────────
|
|
299
|
-
describe('WebhookTarget', () => {
|
|
300
|
-
let fetchMock;
|
|
301
|
-
beforeEach(() => {
|
|
302
|
-
fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 200, statusText: 'OK' });
|
|
303
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
304
|
-
});
|
|
305
|
-
afterEach(() => {
|
|
306
|
-
vi.restoreAllMocks();
|
|
307
|
-
});
|
|
308
|
-
it('delivers event to configured URL', async () => {
|
|
309
|
-
const target = new WebhookTarget();
|
|
310
|
-
await target.init({
|
|
311
|
-
id: 'webhook-target',
|
|
312
|
-
connector: '@orgloop/connector-webhook',
|
|
313
|
-
config: { url: 'https://example.com/hook' },
|
|
314
|
-
});
|
|
315
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
316
|
-
const event = createTestEvent();
|
|
317
|
-
const result = await target.deliver(event, {});
|
|
318
|
-
expect(result.status).toBe('delivered');
|
|
319
|
-
expect(fetchMock).toHaveBeenCalledOnce();
|
|
320
|
-
const [url] = fetchMock.mock.calls[0];
|
|
321
|
-
expect(url).toBe('https://example.com/hook');
|
|
322
|
-
});
|
|
323
|
-
it('sends event and launch_prompt in body', async () => {
|
|
324
|
-
const target = new WebhookTarget();
|
|
325
|
-
await target.init({
|
|
326
|
-
id: 'webhook-target',
|
|
327
|
-
connector: '@orgloop/connector-webhook',
|
|
328
|
-
config: { url: 'https://example.com/hook' },
|
|
329
|
-
});
|
|
330
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
331
|
-
const event = createTestEvent();
|
|
332
|
-
await target.deliver(event, { launch_prompt: 'Do the thing' });
|
|
333
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
334
|
-
expect(body.event.id).toBe(event.id);
|
|
335
|
-
expect(body.launch_prompt).toBe('Do the thing');
|
|
336
|
-
});
|
|
337
|
-
it('handles 429 rate limit', async () => {
|
|
338
|
-
fetchMock.mockResolvedValueOnce({ ok: false, status: 429, statusText: 'Too Many Requests' });
|
|
339
|
-
const target = new WebhookTarget();
|
|
340
|
-
await target.init({
|
|
341
|
-
id: 'webhook-target',
|
|
342
|
-
connector: '@orgloop/connector-webhook',
|
|
343
|
-
config: { url: 'https://example.com/hook' },
|
|
344
|
-
});
|
|
345
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
346
|
-
const result = await target.deliver(createTestEvent(), {});
|
|
347
|
-
expect(result.status).toBe('error');
|
|
348
|
-
expect(result.error?.message).toContain('429');
|
|
349
|
-
});
|
|
350
|
-
it('handles 4xx rejection', async () => {
|
|
351
|
-
fetchMock.mockResolvedValueOnce({ ok: false, status: 422, statusText: 'Unprocessable Entity' });
|
|
352
|
-
const target = new WebhookTarget();
|
|
353
|
-
await target.init({
|
|
354
|
-
id: 'webhook-target',
|
|
355
|
-
connector: '@orgloop/connector-webhook',
|
|
356
|
-
config: { url: 'https://example.com/hook' },
|
|
357
|
-
});
|
|
358
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
359
|
-
const result = await target.deliver(createTestEvent(), {});
|
|
360
|
-
expect(result.status).toBe('rejected');
|
|
361
|
-
});
|
|
362
|
-
it('handles network error', async () => {
|
|
363
|
-
fetchMock.mockRejectedValueOnce(new Error('ECONNREFUSED'));
|
|
364
|
-
const target = new WebhookTarget();
|
|
365
|
-
await target.init({
|
|
366
|
-
id: 'webhook-target',
|
|
367
|
-
connector: '@orgloop/connector-webhook',
|
|
368
|
-
config: { url: 'https://example.com/hook' },
|
|
369
|
-
});
|
|
370
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
371
|
-
const result = await target.deliver(createTestEvent(), {});
|
|
372
|
-
expect(result.status).toBe('error');
|
|
373
|
-
expect(result.error?.message).toContain('ECONNREFUSED');
|
|
374
|
-
});
|
|
375
|
-
// ─── Auth Tests ─────────────────────────────────────────────────────────
|
|
376
|
-
describe('authentication', () => {
|
|
377
|
-
it('sends Bearer token in Authorization header', async () => {
|
|
378
|
-
const target = new WebhookTarget();
|
|
379
|
-
await target.init({
|
|
380
|
-
id: 'webhook-target',
|
|
381
|
-
connector: '@orgloop/connector-webhook',
|
|
382
|
-
config: {
|
|
383
|
-
url: 'https://example.com/hook',
|
|
384
|
-
auth: { type: 'bearer', token: 'my-secret-token' },
|
|
385
|
-
},
|
|
386
|
-
});
|
|
387
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
388
|
-
await target.deliver(createTestEvent(), {});
|
|
389
|
-
const opts = fetchMock.mock.calls[0][1];
|
|
390
|
-
expect(opts.headers.Authorization).toBe('Bearer my-secret-token');
|
|
391
|
-
});
|
|
392
|
-
it('sends Basic auth with base64-encoded credentials', async () => {
|
|
393
|
-
const target = new WebhookTarget();
|
|
394
|
-
await target.init({
|
|
395
|
-
id: 'webhook-target',
|
|
396
|
-
connector: '@orgloop/connector-webhook',
|
|
397
|
-
config: {
|
|
398
|
-
url: 'https://example.com/hook',
|
|
399
|
-
auth: { type: 'basic', username: 'alice', password: 'secret123' },
|
|
400
|
-
},
|
|
401
|
-
});
|
|
402
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
403
|
-
await target.deliver(createTestEvent(), {});
|
|
404
|
-
const opts = fetchMock.mock.calls[0][1];
|
|
405
|
-
const expected = `Basic ${Buffer.from('alice:secret123').toString('base64')}`;
|
|
406
|
-
expect(opts.headers.Authorization).toBe(expected);
|
|
407
|
-
});
|
|
408
|
-
it('sends no Authorization header when no auth configured', async () => {
|
|
409
|
-
const target = new WebhookTarget();
|
|
410
|
-
await target.init({
|
|
411
|
-
id: 'webhook-target',
|
|
412
|
-
connector: '@orgloop/connector-webhook',
|
|
413
|
-
config: { url: 'https://example.com/hook' },
|
|
414
|
-
});
|
|
415
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
416
|
-
await target.deliver(createTestEvent(), {});
|
|
417
|
-
const opts = fetchMock.mock.calls[0][1];
|
|
418
|
-
expect(opts.headers.Authorization).toBeUndefined();
|
|
419
|
-
});
|
|
420
|
-
it('passes custom headers through', async () => {
|
|
421
|
-
const target = new WebhookTarget();
|
|
422
|
-
await target.init({
|
|
423
|
-
id: 'webhook-target',
|
|
424
|
-
connector: '@orgloop/connector-webhook',
|
|
425
|
-
config: {
|
|
426
|
-
url: 'https://example.com/hook',
|
|
427
|
-
headers: { 'X-Custom-Header': 'custom-value', 'X-Request-Id': 'req-123' },
|
|
428
|
-
},
|
|
429
|
-
});
|
|
430
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
431
|
-
await target.deliver(createTestEvent(), {});
|
|
432
|
-
const opts = fetchMock.mock.calls[0][1];
|
|
433
|
-
expect(opts.headers['X-Custom-Header']).toBe('custom-value');
|
|
434
|
-
expect(opts.headers['X-Request-Id']).toBe('req-123');
|
|
435
|
-
expect(opts.headers['Content-Type']).toBe('application/json');
|
|
436
|
-
});
|
|
437
|
-
});
|
|
438
|
-
// ─── Body Template Tests ────────────────────────────────────────────────
|
|
439
|
-
describe('body template', () => {
|
|
440
|
-
it('falls back to default body when no template configured', async () => {
|
|
441
|
-
const target = new WebhookTarget();
|
|
442
|
-
await target.init({
|
|
443
|
-
id: 'webhook-target',
|
|
444
|
-
connector: '@orgloop/connector-webhook',
|
|
445
|
-
config: { url: 'https://example.com/hook' },
|
|
446
|
-
});
|
|
447
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
448
|
-
const event = createTestEvent();
|
|
449
|
-
await target.deliver(event, { launch_prompt: 'Do something' });
|
|
450
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
451
|
-
expect(body.event.id).toBe(event.id);
|
|
452
|
-
expect(body.launch_prompt).toBe('Do something');
|
|
453
|
-
});
|
|
454
|
-
it('expands simple template with event fields', async () => {
|
|
455
|
-
const target = new WebhookTarget();
|
|
456
|
-
await target.init({
|
|
457
|
-
id: 'webhook-target',
|
|
458
|
-
connector: '@orgloop/connector-webhook',
|
|
459
|
-
config: {
|
|
460
|
-
url: 'https://hooks.slack.com/test',
|
|
461
|
-
body_template: {
|
|
462
|
-
text: '{{ event.provenance.platform_event }} by {{ event.provenance.author }}',
|
|
463
|
-
channel: '#engineering',
|
|
464
|
-
},
|
|
465
|
-
},
|
|
466
|
-
});
|
|
467
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
468
|
-
const event = createTestEvent({
|
|
469
|
-
provenance: {
|
|
470
|
-
platform: 'github',
|
|
471
|
-
platform_event: 'pull_request.opened',
|
|
472
|
-
author: 'alice',
|
|
473
|
-
},
|
|
474
|
-
});
|
|
475
|
-
await target.deliver(event, {});
|
|
476
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
477
|
-
expect(body.text).toBe('pull_request.opened by alice');
|
|
478
|
-
expect(body.channel).toBe('#engineering');
|
|
479
|
-
});
|
|
480
|
-
it('expands launch_prompt in template', async () => {
|
|
481
|
-
const target = new WebhookTarget();
|
|
482
|
-
await target.init({
|
|
483
|
-
id: 'webhook-target',
|
|
484
|
-
connector: '@orgloop/connector-webhook',
|
|
485
|
-
config: {
|
|
486
|
-
url: 'https://example.com/hook',
|
|
487
|
-
body_template: {
|
|
488
|
-
prompt: '{{ launch_prompt }}',
|
|
489
|
-
source: '{{ event.source }}',
|
|
490
|
-
},
|
|
491
|
-
},
|
|
492
|
-
});
|
|
493
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
494
|
-
const event = createTestEvent({ source: 'my-source' });
|
|
495
|
-
await target.deliver(event, { launch_prompt: 'Review this PR' });
|
|
496
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
497
|
-
expect(body.prompt).toBe('Review this PR');
|
|
498
|
-
expect(body.source).toBe('my-source');
|
|
499
|
-
});
|
|
500
|
-
it('handles missing template paths gracefully (empty string)', async () => {
|
|
501
|
-
const target = new WebhookTarget();
|
|
502
|
-
await target.init({
|
|
503
|
-
id: 'webhook-target',
|
|
504
|
-
connector: '@orgloop/connector-webhook',
|
|
505
|
-
config: {
|
|
506
|
-
url: 'https://example.com/hook',
|
|
507
|
-
body_template: {
|
|
508
|
-
text: '{{ event.nonexistent.field }}',
|
|
509
|
-
},
|
|
510
|
-
},
|
|
511
|
-
});
|
|
512
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
513
|
-
await target.deliver(createTestEvent(), {});
|
|
514
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
515
|
-
expect(body.text).toBe('');
|
|
516
|
-
});
|
|
517
|
-
it('expands nested template objects', async () => {
|
|
518
|
-
const target = new WebhookTarget();
|
|
519
|
-
await target.init({
|
|
520
|
-
id: 'webhook-target',
|
|
521
|
-
connector: '@orgloop/connector-webhook',
|
|
522
|
-
config: {
|
|
523
|
-
url: 'https://example.com/hook',
|
|
524
|
-
body_template: {
|
|
525
|
-
message: {
|
|
526
|
-
text: '{{ event.provenance.platform }}',
|
|
527
|
-
metadata: {
|
|
528
|
-
event_id: '{{ event.id }}',
|
|
529
|
-
},
|
|
530
|
-
},
|
|
531
|
-
},
|
|
532
|
-
},
|
|
533
|
-
});
|
|
534
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
535
|
-
const event = createTestEvent({
|
|
536
|
-
provenance: { platform: 'github' },
|
|
537
|
-
});
|
|
538
|
-
await target.deliver(event, {});
|
|
539
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
540
|
-
expect(body.message.text).toBe('github');
|
|
541
|
-
expect(body.message.metadata.event_id).toBe(event.id);
|
|
542
|
-
});
|
|
543
|
-
it('preserves literal values (non-template strings, numbers, booleans)', async () => {
|
|
544
|
-
const target = new WebhookTarget();
|
|
545
|
-
await target.init({
|
|
546
|
-
id: 'webhook-target',
|
|
547
|
-
connector: '@orgloop/connector-webhook',
|
|
548
|
-
config: {
|
|
549
|
-
url: 'https://example.com/hook',
|
|
550
|
-
body_template: {
|
|
551
|
-
text: '{{ event.source }}',
|
|
552
|
-
count: 42,
|
|
553
|
-
active: true,
|
|
554
|
-
static_text: 'hello world',
|
|
555
|
-
},
|
|
556
|
-
},
|
|
557
|
-
});
|
|
558
|
-
const { createTestEvent } = await import('@orgloop/sdk');
|
|
559
|
-
await target.deliver(createTestEvent(), {});
|
|
560
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
561
|
-
expect(body.count).toBe(42);
|
|
562
|
-
expect(body.active).toBe(true);
|
|
563
|
-
expect(body.static_text).toBe('hello world');
|
|
564
|
-
});
|
|
565
|
-
});
|
|
566
|
-
});
|
|
567
|
-
//# sourceMappingURL=webhook.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webhook.test.js","sourceRoot":"","sources":["../../src/__tests__/webhook.test.ts"],"names":[],"mappings":"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"}
|