@getstrata/core 0.5.37 → 0.5.38

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.
@@ -9,5 +9,6 @@ declare class DispatchWebhookJob extends Job<DispatchWebhookPayload> {
9
9
  readonly backoffMs = 2000;
10
10
  handle(payload: DispatchWebhookPayload): Promise<void>;
11
11
  }
12
+ export { DispatchWebhookJob };
12
13
  export default DispatchWebhookJob;
13
14
  export type { DispatchWebhookPayload };
@@ -8,5 +8,6 @@ declare class InvalidateCacheTagsJob extends Job<InvalidateCacheTagsPayload> {
8
8
  constructor(cache: CacheLike);
9
9
  handle(payload: InvalidateCacheTagsPayload): Promise<void>;
10
10
  }
11
+ export { InvalidateCacheTagsJob };
11
12
  export default InvalidateCacheTagsJob;
12
13
  export type { InvalidateCacheTagsPayload };
@@ -1,4 +1,7 @@
1
1
  // @bun
2
+ // ../../src/core/jobs/dispatchWebhookJob.ts
3
+ import { createHmac } from "crypto";
4
+
2
5
  // ../../src/config/app.ts
3
6
  var appConfig = {
4
7
  name: "WorkHub",
@@ -316,3 +319,65 @@ async function safeFetch(input, init = {}, options = {}) {
316
319
  clearTimeout(timeout);
317
320
  }
318
321
  }
322
+
323
+ // ../../src/core/jobs/dispatchWebhookJob.ts
324
+ class DispatchWebhookJob extends Job {
325
+ maxAttempts = 3;
326
+ backoffMs = 2000;
327
+ async handle(payload) {
328
+ const rows = await repositoryConnection`
329
+ SELECT id, url, secret
330
+ FROM webhook
331
+ WHERE id = ${payload.webhookId} AND active = TRUE
332
+ LIMIT 1
333
+ `;
334
+ const webhook = rows[0];
335
+ if (!webhook) {
336
+ return;
337
+ }
338
+ const body = JSON.stringify({ event: payload.event, payload: payload.payload });
339
+ const signature = createHmac("sha256", webhook.secret).update(body).digest("hex");
340
+ assertSafeOutboundUrl(webhook.url, { allowHttp: appConfig.env !== "production" });
341
+ let responseStatus = null;
342
+ let errorMessage = null;
343
+ try {
344
+ const response = await safeFetch(webhook.url, {
345
+ method: "POST",
346
+ headers: {
347
+ "content-type": "application/json",
348
+ "x-workhub-signature": signature
349
+ },
350
+ body
351
+ }, { allowHttp: appConfig.env !== "production" });
352
+ responseStatus = response.status;
353
+ if (!response.ok) {
354
+ throw new Error(`Webhook delivery failed with status ${response.status}.`);
355
+ }
356
+ } catch (error) {
357
+ errorMessage = error instanceof Error ? error.message : String(error);
358
+ await repositoryConnection`
359
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status, error)
360
+ VALUES (
361
+ ${webhook.id},
362
+ ${payload.event},
363
+ ${JSON.stringify(payload.payload)}::jsonb,
364
+ ${responseStatus},
365
+ ${errorMessage}
366
+ )
367
+ `;
368
+ throw error instanceof Error ? error : new Error(errorMessage);
369
+ }
370
+ await repositoryConnection`
371
+ INSERT INTO webhook_delivery (webhook_id, event, payload, response_status)
372
+ VALUES (
373
+ ${webhook.id},
374
+ ${payload.event},
375
+ ${JSON.stringify(payload.payload)}::jsonb,
376
+ ${responseStatus}
377
+ )
378
+ `;
379
+ }
380
+ }
381
+ export {
382
+ DispatchWebhookJob
383
+ };
@@ -24,3 +24,18 @@ class AsyncQueue {
24
24
  function createQueue(driver) {
25
25
  return driver === "async" ? new AsyncQueue : new SyncQueue;
26
26
  }
27
+
28
+ // ../../src/core/jobs/invalidateCacheTagsJob.ts
29
+ class InvalidateCacheTagsJob extends Job {
30
+ cache;
31
+ constructor(cache) {
32
+ super();
33
+ this.cache = cache;
34
+ }
35
+ async handle(payload) {
36
+ await this.cache.tags(...payload.tags).flush();
37
+ }
38
+ }
39
+ export {
40
+ InvalidateCacheTagsJob
41
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getstrata/core",
3
- "version": "0.5.37",
3
+ "version": "0.5.38",
4
4
  "description": "Strata — Laravel-inspired Bun framework public API",
5
5
  "type": "module",
6
6
  "license": "MIT",