@nestarc/webhook 0.12.1 → 0.13.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.
Files changed (61) hide show
  1. package/README.md +97 -0
  2. package/dist/adapters/fetch-http-client.d.ts +2 -2
  3. package/dist/adapters/fetch-http-client.d.ts.map +1 -1
  4. package/dist/adapters/fetch-http-client.js +165 -29
  5. package/dist/adapters/fetch-http-client.js.map +1 -1
  6. package/dist/adapters/prisma-delivery.repository.d.ts +9 -3
  7. package/dist/adapters/prisma-delivery.repository.d.ts.map +1 -1
  8. package/dist/adapters/prisma-delivery.repository.js +228 -19
  9. package/dist/adapters/prisma-delivery.repository.js.map +1 -1
  10. package/dist/adapters/prisma-endpoint.repository.js +1 -1
  11. package/dist/adapters/prisma-event.repository.d.ts +3 -1
  12. package/dist/adapters/prisma-event.repository.d.ts.map +1 -1
  13. package/dist/adapters/prisma-event.repository.js +36 -2
  14. package/dist/adapters/prisma-event.repository.js.map +1 -1
  15. package/dist/index.d.ts +5 -4
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/interfaces/webhook-delivery.interface.d.ts +26 -0
  20. package/dist/interfaces/webhook-delivery.interface.d.ts.map +1 -1
  21. package/dist/interfaces/webhook-options.interface.d.ts +27 -0
  22. package/dist/interfaces/webhook-options.interface.d.ts.map +1 -1
  23. package/dist/ports/webhook-delivery.repository.d.ts +6 -2
  24. package/dist/ports/webhook-delivery.repository.d.ts.map +1 -1
  25. package/dist/ports/webhook-event.repository.d.ts +6 -0
  26. package/dist/ports/webhook-event.repository.d.ts.map +1 -1
  27. package/dist/ports/webhook-http-client.d.ts +8 -1
  28. package/dist/ports/webhook-http-client.d.ts.map +1 -1
  29. package/dist/webhook.admin.service.d.ts +4 -2
  30. package/dist/webhook.admin.service.d.ts.map +1 -1
  31. package/dist/webhook.admin.service.js +8 -2
  32. package/dist/webhook.admin.service.js.map +1 -1
  33. package/dist/webhook.delivery-admin.service.d.ts +4 -2
  34. package/dist/webhook.delivery-admin.service.d.ts.map +1 -1
  35. package/dist/webhook.delivery-admin.service.js +14 -2
  36. package/dist/webhook.delivery-admin.service.js.map +1 -1
  37. package/dist/webhook.dispatcher.d.ts.map +1 -1
  38. package/dist/webhook.dispatcher.js +5 -2
  39. package/dist/webhook.dispatcher.js.map +1 -1
  40. package/dist/webhook.module.d.ts.map +1 -1
  41. package/dist/webhook.module.js +6 -2
  42. package/dist/webhook.module.js.map +1 -1
  43. package/dist/webhook.retention-admin.service.d.ts +10 -0
  44. package/dist/webhook.retention-admin.service.d.ts.map +1 -0
  45. package/dist/webhook.retention-admin.service.js +50 -0
  46. package/dist/webhook.retention-admin.service.js.map +1 -0
  47. package/dist/webhook.service.d.ts +7 -4
  48. package/dist/webhook.service.d.ts.map +1 -1
  49. package/dist/webhook.service.js +40 -10
  50. package/dist/webhook.service.js.map +1 -1
  51. package/dist/webhook.signer.d.ts +5 -0
  52. package/dist/webhook.signer.d.ts.map +1 -1
  53. package/dist/webhook.signer.js +14 -0
  54. package/dist/webhook.signer.js.map +1 -1
  55. package/dist/webhook.url-validator.d.ts +1 -1
  56. package/dist/webhook.url-validator.d.ts.map +1 -1
  57. package/dist/webhook.url-validator.js +145 -51
  58. package/dist/webhook.url-validator.js.map +1 -1
  59. package/package.json +9 -3
  60. package/src/sql/create-webhook-tables.sql +11 -5
  61. package/src/sql/migrations/v0.13.0.sql +11 -0
package/README.md CHANGED
@@ -13,6 +13,7 @@ Outbound webhook delivery for NestJS — HMAC signing, exponential retry, circui
13
13
  ## Features
14
14
 
15
15
  - **Fan-out delivery** — one event to many endpoints
16
+ - **Idempotent publish** — deduplicate producer retries with application keys
16
17
  - **HMAC-SHA256 signing** — Standard Webhooks compatible headers
17
18
  - **Secret rotation overlap** — sign with both old and new secrets during rotation windows
18
19
  - **Exponential backoff** — 30s, 5m, 30m, 2h, 24h (with jitter)
@@ -20,6 +21,8 @@ Outbound webhook delivery for NestJS — HMAC signing, exponential retry, circui
20
21
  - **Dead letter queue** — failed deliveries tracked for manual retry
21
22
  - **Delivery logs** — full audit trail (status code, latency, response body)
22
23
  - **Per-attempt audit log** — every attempt recorded with status, latency, response body, and errors
24
+ - **Replay and bulk retry** — requeue failed deliveries or replay an event to active endpoints
25
+ - **Retention and redaction controls** — purge stored payloads/response bodies and sanitize data before persistence
23
26
  - **Endpoint snapshotting** — queued deliveries keep their original URL and signing secret during retries
24
27
  - **Multi-instance safe** — `FOR UPDATE SKIP LOCKED` prevents duplicate delivery
25
28
  - **Graceful shutdown** — waits for in-flight deliveries on process exit
@@ -62,6 +65,14 @@ psql -d your_database -f node_modules/@nestarc/webhook/src/sql/migrations/v0.9.0
62
65
 
63
66
  See [CHANGELOG.md](./CHANGELOG.md) for release-specific migration notes.
64
67
 
68
+ ### Upgrading from versions before 0.13.0
69
+
70
+ Existing databases need the v0.13.0 additive migration for idempotent publish keys, correlation IDs, and payload purge metadata:
71
+
72
+ ```bash
73
+ psql -d your_database -f node_modules/@nestarc/webhook/src/sql/migrations/v0.13.0.sql
74
+ ```
75
+
65
76
  ## Quick Start
66
77
 
67
78
  ### 1. Register the module
@@ -143,6 +154,17 @@ export class OrderService {
143
154
  }
144
155
  ```
145
156
 
157
+ Use an idempotency key when the producer may retry the same business operation:
158
+
159
+ ```typescript
160
+ await this.webhooks.send(new OrderCreatedEvent(order.id, order.total), {
161
+ idempotencyKey: `order:${order.id}:created`,
162
+ correlationId: requestId,
163
+ });
164
+ ```
165
+
166
+ Duplicate sends with the same tenant, event type, and idempotency key return the existing event ID and do not enqueue duplicate deliveries.
167
+
146
168
  ### 4. Manage endpoints
147
169
 
148
170
  ```typescript
@@ -174,6 +196,8 @@ export class WebhookController {
174
196
  | `sendToTenant(tenantId, event)` | Publish to tenant-specific endpoints only |
175
197
  | `sendToEndpoints(endpointIds, event)` | Publish to specific endpoint IDs only |
176
198
 
199
+ All publish methods accept optional `WebhookPublishOptions` with `idempotencyKey` and `correlationId`.
200
+
177
201
  ### WebhookEndpointAdminService
178
202
 
179
203
  | Method | Description |
@@ -193,6 +217,14 @@ export class WebhookController {
193
217
  | `getDeliveryLogs(endpointId, filters?)` | Query delivery history |
194
218
  | `getDeliveryAttempts(deliveryId)` | Query per-attempt audit records for a delivery |
195
219
  | `retryDelivery(deliveryId)` | Manually retry a failed delivery |
220
+ | `retryFailedDeliveries(filters, options?)` | Requeue matching failed deliveries in bulk |
221
+ | `replayEvent(eventId, options?)` | Create new delivery rows for an existing event and currently active endpoints |
222
+
223
+ ### WebhookRetentionAdminService
224
+
225
+ | Method | Description |
226
+ |--------|-------------|
227
+ | `purgeExpiredData(now?)` | Apply configured retention policy and return purge counts |
196
228
 
197
229
  ### WebhookSigner
198
230
 
@@ -201,6 +233,7 @@ export class WebhookController {
201
233
  | `sign(eventId, timestamp, body, secret)` | Generate Standard Webhooks signature headers |
202
234
  | `signAll(eventId, timestamp, body, secrets[])` | Generate multi-signature headers for secret rotation overlap |
203
235
  | `verify(eventId, timestamp, body, secret, signature)` | Verify a webhook signature |
236
+ | `verifyWithTolerance(eventId, timestamp, body, secret, signature, options)` | Verify a signature and reject timestamps outside `options.toleranceSeconds` |
204
237
  | `generateSecret()` | Generate a random base64 signing secret |
205
238
 
206
239
  > **Deprecated:** `WebhookAdminService` is a facade that delegates to `WebhookEndpointAdminService` and `WebhookDeliveryAdminService`. It has been deprecated since `v0.2.0` and will be removed in `v1.0.0`.
@@ -224,6 +257,11 @@ export class WebhookController {
224
257
  | `polling.drainWhileBacklogged` | `false` | Keep claiming additional batches inside one poll while backlog and capacity remain |
225
258
  | `polling.maxDrainLoopsPerPoll` | `1`, or `10` when drain mode is enabled | Max claim loops inside one poll cycle |
226
259
  | `polling.drainLoopDelayMs` | `0` | Optional delay between drain loops |
260
+ | `retention.eventPayloadRetentionDays` | — | Replace terminal event payloads with `{}` after this many days. Disabled unless set. |
261
+ | `retention.deliveryResponseBodyRetentionDays` | — | Clear terminal delivery response bodies after this many days. Disabled unless set. |
262
+ | `retention.attemptResponseBodyRetentionDays` | — | Clear attempt response bodies after this many days. Disabled unless set. |
263
+ | `redaction.sanitizePayload` | — | Minimize payload before persistence and delivery. This changes delivered content. |
264
+ | `redaction.sanitizeResponseBody` | — | Sanitize or suppress response bodies before storing delivery and attempt rows. |
227
265
  | `allowPrivateUrls` | `false` | Allow private/internal URLs (dev/test only) |
228
266
  | `secretVault` | `PlaintextSecretVault` | Custom vault for encrypting/decrypting endpoint secrets at rest |
229
267
  | `onDeliveryFailed` | — | Fire-and-forget callback when a delivery exhausts retries or receives a non-retryable response. Receives `DeliveryFailedContext` (`tenantId` is `null` for global endpoints). See **Delivery failure classification** below. |
@@ -274,6 +312,52 @@ const summary = await deliveryRepository.getBacklogSummary?.();
274
312
 
275
313
  The summary includes `pendingCount`, `sendingCount`, `runnablePendingCount`, `oldestPendingAgeMs`, and `oldestRunnableAgeMs`.
276
314
 
315
+ ### Manual Retry, Bulk Retry, And Replay
316
+
317
+ ```ts
318
+ await deliveryAdmin.retryDelivery(deliveryId, {
319
+ reason: 'customer requested retry',
320
+ });
321
+
322
+ await deliveryAdmin.retryFailedDeliveries({
323
+ endpointId,
324
+ eventType: 'order.created',
325
+ limit: 100,
326
+ });
327
+
328
+ await deliveryAdmin.replayEvent(eventId, {
329
+ tenantId: 'tenant_123',
330
+ reason: 'customer support replay',
331
+ });
332
+ ```
333
+
334
+ Manual retries only requeue failed deliveries. Event replay reuses the original event ID and creates new delivery rows for currently active matching endpoints using their current URL and signing secret snapshots.
335
+
336
+ ### Retention And Redaction
337
+
338
+ Retention is disabled unless configured. Applications can call `WebhookRetentionAdminService.purgeExpiredData()` from their own scheduler:
339
+
340
+ ```ts
341
+ WebhookModule.forRoot({
342
+ prisma,
343
+ retention: {
344
+ eventPayloadRetentionDays: 30,
345
+ deliveryResponseBodyRetentionDays: 14,
346
+ attemptResponseBodyRetentionDays: 7,
347
+ },
348
+ redaction: {
349
+ sanitizePayload(payload) {
350
+ return { ...payload, email: undefined };
351
+ },
352
+ sanitizeResponseBody() {
353
+ return null;
354
+ },
355
+ },
356
+ });
357
+ ```
358
+
359
+ `sanitizePayload` runs before persistence and dispatch, so it changes the delivered webhook payload. Review retention and redaction policies with your security and legal teams before storing sensitive data.
360
+
277
361
  Webhook receiver responses are classified before scheduling another attempt:
278
362
 
279
363
  | Response | Behavior |
@@ -412,6 +496,19 @@ const isValid = signer.verify(
412
496
  );
413
497
  ```
414
498
 
499
+ To reject replayed signatures, use an explicit timestamp tolerance:
500
+
501
+ ```ts
502
+ const isValidFreshRequest = signer.verifyWithTolerance(
503
+ headers['webhook-id'],
504
+ Number(headers['webhook-timestamp']),
505
+ rawBody,
506
+ signingSecret,
507
+ headers['webhook-signature'],
508
+ { toleranceSeconds: 300 },
509
+ );
510
+ ```
511
+
415
512
  ### Delivery audit data
416
513
 
417
514
  Delivery logs expose the snapshotted destination URL through `DeliveryRecord.destinationUrl`. Per-attempt audit records are available through `WebhookDeliveryAdminService.getDeliveryAttempts(deliveryId)`:
@@ -1,6 +1,6 @@
1
- import { WebhookHttpClient } from '../ports/webhook-http-client';
1
+ import { WebhookHttpClient, WebhookHttpClientRequestOptions } from '../ports/webhook-http-client';
2
2
  import { DeliveryResult } from '../interfaces/webhook-delivery.interface';
3
3
  export declare class FetchHttpClient implements WebhookHttpClient {
4
- post(url: string, headers: Record<string, string>, body: string, timeout: number): Promise<DeliveryResult>;
4
+ post(url: string, headers: Record<string, string>, body: string, timeout: number, options?: WebhookHttpClientRequestOptions): Promise<DeliveryResult>;
5
5
  }
6
6
  //# sourceMappingURL=fetch-http-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-http-client.d.ts","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAM1E,qBACa,eAAgB,YAAW,iBAAiB;IACjD,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC;CAuC3B"}
1
+ {"version":3,"file":"fetch-http-client.d.ts","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,+BAA+B,EAChC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAW1E,qBACa,eAAgB,YAAW,iBAAiB;IACjD,IAAI,CACR,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,+BAA+B,GACxC,OAAO,CAAC,cAAc,CAAC;CAgF3B"}
@@ -1,56 +1,192 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  Object.defineProperty(exports, "__esModule", { value: true });
9
42
  exports.FetchHttpClient = void 0;
10
43
  const common_1 = require("@nestjs/common");
44
+ const http = __importStar(require("http"));
45
+ const https = __importStar(require("https"));
46
+ const net = __importStar(require("net"));
11
47
  const webhook_constants_1 = require("../webhook.constants");
12
48
  let FetchHttpClient = class FetchHttpClient {
13
- async post(url, headers, body, timeout) {
14
- const controller = new AbortController();
15
- const timeoutId = setTimeout(() => controller.abort(), timeout);
49
+ async post(url, headers, body, timeout, options) {
16
50
  const start = Date.now();
17
- try {
18
- const response = await fetch(url, {
51
+ return new Promise((resolve) => {
52
+ let settled = false;
53
+ let timeoutId;
54
+ const parsed = new URL(url);
55
+ const isHttps = parsed.protocol === 'https:';
56
+ const transport = isHttps ? https : http;
57
+ const hostname = parsed.hostname.replace(/^\[|\]$/g, '');
58
+ const lookup = createPinnedLookup(options?.resolvedIpAddresses);
59
+ const finish = (result) => {
60
+ if (settled) {
61
+ return;
62
+ }
63
+ settled = true;
64
+ if (timeoutId) {
65
+ clearTimeout(timeoutId);
66
+ }
67
+ resolve(result);
68
+ };
69
+ const request = transport.request({
70
+ protocol: parsed.protocol,
71
+ hostname,
72
+ port: parsed.port,
73
+ path: `${parsed.pathname}${parsed.search}`,
19
74
  method: 'POST',
20
75
  headers: {
21
76
  'Content-Type': 'application/json',
22
77
  'User-Agent': webhook_constants_1.DEFAULT_USER_AGENT,
23
78
  ...headers,
24
79
  },
25
- body,
26
- signal: controller.signal,
27
- redirect: 'manual',
80
+ lookup,
81
+ servername: isHttps ? hostname : undefined,
82
+ }, (response) => {
83
+ const latencyMs = Date.now() - start;
84
+ readLimitedResponseBody(response)
85
+ .then((responseBody) => {
86
+ finish({
87
+ success: response.statusCode !== undefined &&
88
+ response.statusCode >= 200 &&
89
+ response.statusCode < 300,
90
+ statusCode: response.statusCode,
91
+ body: responseBody,
92
+ latencyMs,
93
+ });
94
+ })
95
+ .catch((error) => {
96
+ finish({
97
+ success: false,
98
+ latencyMs,
99
+ error: error instanceof Error ? error.message : String(error),
100
+ });
101
+ });
28
102
  });
29
- const latencyMs = Date.now() - start;
30
- const responseBody = await response.text();
31
- return {
32
- success: response.status >= 200 && response.status < 300,
33
- statusCode: response.status,
34
- body: responseBody.slice(0, webhook_constants_1.RESPONSE_BODY_MAX_LENGTH),
35
- latencyMs,
36
- };
37
- }
38
- catch (error) {
39
- const latencyMs = Date.now() - start;
40
- const message = error instanceof Error ? error.message : String(error);
41
- return {
42
- success: false,
43
- latencyMs,
44
- error: message,
45
- };
46
- }
47
- finally {
48
- clearTimeout(timeoutId);
49
- }
103
+ request.on('error', (error) => {
104
+ finish({
105
+ success: false,
106
+ latencyMs: Date.now() - start,
107
+ error: error.message,
108
+ });
109
+ });
110
+ request.setTimeout(timeout, () => {
111
+ request.destroy(new Error('Request timed out'));
112
+ });
113
+ timeoutId = setTimeout(() => {
114
+ request.destroy(new Error('Request timed out'));
115
+ }, timeout);
116
+ request.write(body);
117
+ request.end();
118
+ });
50
119
  }
51
120
  };
52
121
  exports.FetchHttpClient = FetchHttpClient;
53
122
  exports.FetchHttpClient = FetchHttpClient = __decorate([
54
123
  (0, common_1.Injectable)()
55
124
  ], FetchHttpClient);
125
+ function createPinnedLookup(addresses) {
126
+ const pinned = (addresses ?? [])
127
+ .map((address) => {
128
+ const family = net.isIP(address);
129
+ return family === 4 || family === 6 ? { address, family } : null;
130
+ })
131
+ .filter((address) => address !== null);
132
+ if (pinned.length === 0) {
133
+ return undefined;
134
+ }
135
+ return (_hostname, lookupOptions, callback) => {
136
+ const options = typeof lookupOptions === 'number'
137
+ ? { family: lookupOptions, all: false }
138
+ : lookupOptions;
139
+ const family = options?.family === 4 || options?.family === 6
140
+ ? options.family
141
+ : undefined;
142
+ const matches = family
143
+ ? pinned.filter((address) => address.family === family)
144
+ : pinned;
145
+ if (matches.length === 0) {
146
+ const error = new Error('No prevalidated address matches requested family');
147
+ error.code = 'ENOTFOUND';
148
+ callback(error, '', family ?? 0);
149
+ return;
150
+ }
151
+ if (typeof options === 'object' && options.all) {
152
+ callback(null, matches, 0);
153
+ return;
154
+ }
155
+ callback(null, matches[0].address, matches[0].family);
156
+ };
157
+ }
158
+ function readLimitedResponseBody(response) {
159
+ return new Promise((resolve, reject) => {
160
+ let body = '';
161
+ let settled = false;
162
+ const finish = (result) => {
163
+ if (settled) {
164
+ return;
165
+ }
166
+ settled = true;
167
+ resolve(result);
168
+ };
169
+ response.setEncoding('utf8');
170
+ response.on('data', (chunk) => {
171
+ if (settled) {
172
+ return;
173
+ }
174
+ const remaining = webhook_constants_1.RESPONSE_BODY_MAX_LENGTH - body.length;
175
+ if (remaining > 0) {
176
+ body += chunk.slice(0, remaining);
177
+ }
178
+ if (body.length >= webhook_constants_1.RESPONSE_BODY_MAX_LENGTH) {
179
+ finish(body);
180
+ response.destroy();
181
+ }
182
+ });
183
+ response.on('end', () => finish(body));
184
+ response.on('error', (error) => {
185
+ if (!settled) {
186
+ settled = true;
187
+ reject(error);
188
+ }
189
+ });
190
+ });
191
+ }
56
192
  //# sourceMappingURL=fetch-http-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-http-client.js","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAG5C,4DAG8B;AAGvB,IAAM,eAAe,GAArB,MAAM,eAAe;IAC1B,KAAK,CAAC,IAAI,CACR,GAAW,EACX,OAA+B,EAC/B,IAAY,EACZ,OAAe;QAEf,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,YAAY,EAAE,sCAAkB;oBAChC,GAAG,OAAO;iBACX;gBACD,IAAI;gBACJ,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAE3C,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG;gBACxD,UAAU,EAAE,QAAQ,CAAC,MAAM;gBAC3B,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,4CAAwB,CAAC;gBACrD,SAAS;aACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,SAAS;gBACT,KAAK,EAAE,OAAO;aACf,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;CACF,CAAA;AA7CY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;GACA,eAAe,CA6C3B"}
1
+ {"version":3,"file":"fetch-http-client.js","sourceRoot":"","sources":["../../src/adapters/fetch-http-client.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { ClaimedDelivery, DeliveryBacklogSummary, PendingDelivery, WebhookDeliveryRepository, WebhookTransaction } from '../ports/webhook-delivery.repository';
2
- import { DeliveryAttemptRecord, DeliveryLogFilters, DeliveryRecord, DeliveryResult } from '../interfaces/webhook-delivery.interface';
2
+ import { DeliveryAttemptRecord, DeliveryLogFilters, DeliveryRecord, DeliveryResult, ReplayEventOptions, ReplayEventResult, RetryDeliveryOptions, RetryFailedDeliveriesFilters, RetryFailedDeliveriesResult, WebhookRetentionPurgeResult } from '../interfaces/webhook-delivery.interface';
3
+ import { WebhookRedactionOptions, WebhookRetentionOptions } from '../interfaces/webhook-options.interface';
3
4
  import { WebhookSecretVault } from '../ports/webhook-secret-vault';
4
5
  type AttemptLogClient = {
5
6
  $executeRaw: <T = unknown>(strings: TemplateStringsArray, ...values: unknown[]) => Promise<T>;
@@ -7,7 +8,8 @@ type AttemptLogClient = {
7
8
  export declare class PrismaDeliveryRepository implements WebhookDeliveryRepository {
8
9
  protected readonly prisma: any;
9
10
  protected readonly vault?: WebhookSecretVault | undefined;
10
- constructor(prisma: any, vault?: WebhookSecretVault | undefined);
11
+ protected readonly redaction?: WebhookRedactionOptions | undefined;
12
+ constructor(prisma: any, vault?: WebhookSecretVault | undefined, redaction?: WebhookRedactionOptions | undefined);
11
13
  createDeliveriesInTransaction(tx: any, eventId: string, endpointIds: string[], maxAttempts: number): Promise<void>;
12
14
  runInTransaction<T>(fn: (tx: WebhookTransaction) => Promise<T>): Promise<T>;
13
15
  claimPendingDeliveries(batchSize: number): Promise<ClaimedDelivery[]>;
@@ -19,9 +21,13 @@ export declare class PrismaDeliveryRepository implements WebhookDeliveryReposito
19
21
  getBacklogSummary(): Promise<DeliveryBacklogSummary>;
20
22
  getDeliveryLogs(endpointId: string, filters?: DeliveryLogFilters): Promise<DeliveryRecord[]>;
21
23
  getDeliveryAttempts(deliveryId: string): Promise<DeliveryAttemptRecord[]>;
22
- retryDelivery(deliveryId: string): Promise<boolean>;
24
+ retryDelivery(deliveryId: string, _options?: RetryDeliveryOptions): Promise<boolean>;
25
+ retryFailedDeliveries(filters: RetryFailedDeliveriesFilters, _options?: RetryDeliveryOptions): Promise<RetryFailedDeliveriesResult>;
26
+ replayEvent(eventId: string, options?: ReplayEventOptions): Promise<ReplayEventResult>;
27
+ purgeExpiredData(options: WebhookRetentionOptions, now?: Date): Promise<WebhookRetentionPurgeResult>;
23
28
  createTestDelivery(eventId: string, endpointId: string): Promise<void>;
24
29
  protected appendAttemptLog(client: AttemptLogClient, deliveryId: string, attempts: number, status: 'PENDING' | 'SENT' | 'FAILED', result: DeliveryResult): Promise<void>;
30
+ private sanitizeDeliveryResult;
25
31
  }
26
32
  export {};
27
33
  //# sourceMappingURL=prisma-delivery.repository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prisma-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,yBAAyB,EACzB,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACf,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE,CAAC,CAAC,GAAG,OAAO,EACvB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,KACjB,OAAO,CAAC,CAAC,CAAC,CAAC;CACjB,CAAC;AA4CF,qBACa,wBAAyB,YAAW,yBAAyB;IAEtE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG;IAC9B,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB;gBAD1B,MAAM,EAAE,GAAG,EACX,KAAK,CAAC,EAAE,kBAAkB,YAAA;IAGzC,6BAA6B,CACjC,EAAE,EAAE,GAAG,EACP,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAqCV,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI3E,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAqBrE,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4CnE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvF,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;IAeV,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2D9D,iBAAiB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAwEpD,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAmDtB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAkBzE,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQnD,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;cA+B5D,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,EACxB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,EACrC,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC;CA0BjB"}
1
+ {"version":3,"file":"prisma-delivery.repository.d.ts","sourceRoot":"","sources":["../../src/adapters/prisma-delivery.repository.ts"],"names":[],"mappings":"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"}