@objectstack/plugin-webhooks 17.0.0-rc.1 → 17.0.0-rc.2

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/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkQUTQSOQCcjs = require('./chunk-QUTQSOQC.cjs');
3
+ var _chunkJQUVS5KKcjs = require('./chunk-JQUVS5KK.cjs');
4
4
 
5
5
  // src/auto-enqueuer.ts
6
6
  var AutoEnqueuer = class {
@@ -112,7 +112,7 @@ var AutoEnqueuer = class {
112
112
  const unknown = normalized.filter((t) => !DISPATCHABLE_WEBHOOK_TRIGGERS.has(t));
113
113
  if (unknown.length > 0) {
114
114
  _optionalChain([this, 'access', _15 => _15.logger, 'access', _16 => _16.warn, 'optionalCall', _17 => _17(
115
- `[webhook-auto-enqueuer] webhook '${_nullishCoalesce(row.name, () => ( row.id))}' declares trigger(s) the engine never emits: ${unknown.join(", ")} \u2014 ignored. Dispatchable triggers: create, update, delete.`,
115
+ `[webhook-auto-enqueuer] webhook '${_nullishCoalesce(row.name, () => ( row.id))}' declares trigger(s) the engine never emits: ${unknown.join(", ")} \u2014 ignored. Dispatchable triggers: ${[...DISPATCHABLE_WEBHOOK_TRIGGERS].join(", ")}.`,
116
116
  { id: row.id, unknown }
117
117
  )]);
118
118
  }
@@ -120,6 +120,10 @@ var AutoEnqueuer = class {
120
120
  normalized.filter((t) => DISPATCHABLE_WEBHOOK_TRIGGERS.has(t))
121
121
  );
122
122
  if (triggers.size === 0) {
123
+ _optionalChain([this, 'access', _18 => _18.logger, 'access', _19 => _19.warn, 'optionalCall', _20 => _20(
124
+ `[webhook-auto-enqueuer] webhook '${_nullishCoalesce(row.name, () => ( row.id))}' has no dispatchable triggers \u2014 it will NEVER fire (rule webhook/without-triggers): there is no manual fire path (#3196), so this row is dead while looking armed in Setup. Declare one of: ${[...DISPATCHABLE_WEBHOOK_TRIGGERS].join(", ")}, or set it inactive if it should be off.`,
125
+ { id: row.id }
126
+ )]);
123
127
  return null;
124
128
  }
125
129
  let defn = {};
@@ -154,9 +158,13 @@ var AutoEnqueuer = class {
154
158
  * webhook persistence.
155
159
  */
156
160
  handleEvent(event) {
157
- if (!_optionalChain([event, 'access', _18 => _18.type, 'optionalAccess', _19 => _19.startsWith, 'call', _20 => _20("data.record.")])) return;
158
161
  if (!event.object) return;
159
162
  if (event.object === this.subscriptionsObject) return;
163
+ if (_optionalChain([event, 'access', _21 => _21.type, 'optionalAccess', _22 => _22.startsWith, 'call', _23 => _23("data.records.")])) {
164
+ this.handleBulkEvent(event);
165
+ return;
166
+ }
167
+ if (!_optionalChain([event, 'access', _24 => _24.type, 'optionalAccess', _25 => _25.startsWith, 'call', _26 => _26("data.record.")])) return;
160
168
  const action = event.type.slice("data.record.".length);
161
169
  const trigger = mapActionToTrigger(action);
162
170
  if (!trigger) return;
@@ -166,7 +174,14 @@ var AutoEnqueuer = class {
166
174
  ];
167
175
  if (subs.length === 0) return;
168
176
  const payload = _nullishCoalesce(event.payload, () => ( {}));
169
- const recordId = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(payload.recordId, () => ( payload.id)), () => ( _optionalChain([payload, 'access', _21 => _21.after, 'optionalAccess', _22 => _22.id]))), () => ( _optionalChain([payload, 'access', _23 => _23.before, 'optionalAccess', _24 => _24.id]))), () => ( "unknown"));
177
+ const recordId = payload.recordId;
178
+ if (typeof recordId !== "string" || recordId === "") {
179
+ _optionalChain([this, 'access', _27 => _27.logger, 'access', _28 => _28.warn, 'optionalCall', _29 => _29(
180
+ "[webhook-auto-enqueuer] dropping off-contract data event: payload is not a DataEvent (no top-level string `recordId`) \u2014 fix the producer",
181
+ { type: event.type, object: event.object }
182
+ )]);
183
+ return;
184
+ }
170
185
  const eventId = `${event.object}:${recordId}:${action}:${event.timestamp}`;
171
186
  for (const sub of subs) {
172
187
  if (!sub.triggers.has(trigger)) continue;
@@ -182,12 +197,13 @@ var AutoEnqueuer = class {
182
197
  timeoutMs: sub.timeoutMs,
183
198
  // [#3946] Envelope keys are written LAST so the event payload
184
199
  // cannot rewrite them. Behaviour-neutral for the engine's own
185
- // publishers — `data.record.*` payloads are
186
- // `{ recordId, after, changes }`, with record fields nested
187
- // under `after`, so none of these four keys collide today. It
188
- // is the shape that was wrong: a publisher that flattened
189
- // record fields into the payload (the `payload.id` fallback
190
- // above suggests some do) would have silently rewritten the
200
+ // publishers — since #4626 a `data.record.*` payload is a
201
+ // `DataEvent` (`id`, `type`, `object`, `recordId`, `changes?`,
202
+ // `after?`, `userId?`, `timestamp`), whose `object` /
203
+ // `recordId` / `timestamp` carry the SAME values written here
204
+ // and whose record fields stay nested under `after`. It is the
205
+ // shape that was wrong: a publisher that flattened record
206
+ // fields into the payload would have silently rewritten the
191
207
  // `object` / `action` / `timestamp` a subscriber receives.
192
208
  payload: {
193
209
  ...payload,
@@ -197,19 +213,87 @@ var AutoEnqueuer = class {
197
213
  timestamp: event.timestamp
198
214
  }
199
215
  }).catch(
200
- (err) => _optionalChain([this, 'access', _25 => _25.logger, 'access', _26 => _26.warn, 'optionalCall', _27 => _27("[webhook-auto-enqueuer] enqueue failed", {
216
+ (err) => _optionalChain([this, 'access', _30 => _30.logger, 'access', _31 => _31.warn, 'optionalCall', _32 => _32("[webhook-auto-enqueuer] enqueue failed", {
217
+ webhook: sub.name,
218
+ eventId,
219
+ err: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _33 => _33.message]), () => ( err))
220
+ })])
221
+ );
222
+ }
223
+ }
224
+ /**
225
+ * Handler for aggregate `data.records.*` events — a predicate write
226
+ * (`multi: true`) that the driver reports only as an affected-row count
227
+ * (#4639).
228
+ *
229
+ * Deliberately NOT folded into {@link handleEvent}'s per-record path. The
230
+ * delivered body has no `recordId` and no record fields, so a subscriber
231
+ * to `update` that started receiving these would get a payload missing
232
+ * everything it reads — which is how the pre-#4626 `recordId: ''`
233
+ * fabrication broke consumers, just arriving from the other side. A
234
+ * webhook opts in with `bulk_update` / `bulk_delete`.
235
+ */
236
+ handleBulkEvent(event) {
237
+ const action = event.type.slice("data.records.".length);
238
+ const trigger = mapBulkActionToTrigger(action);
239
+ if (!trigger) return;
240
+ const subs = [
241
+ ..._nullishCoalesce(this.subscriptions.get(event.object), () => ( [])),
242
+ ..._nullishCoalesce(this.subscriptions.get("*"), () => ( []))
243
+ ];
244
+ if (subs.length === 0) return;
245
+ const payload = _nullishCoalesce(event.payload, () => ( {}));
246
+ const matched = payload.matched;
247
+ if (typeof matched !== "number" || !Number.isInteger(matched) || matched < 0) {
248
+ _optionalChain([this, 'access', _34 => _34.logger, 'access', _35 => _35.warn, 'optionalCall', _36 => _36(
249
+ "[webhook-auto-enqueuer] dropping off-contract bulk data event: payload is not a BulkDataEvent (no top-level non-negative integer `matched`) \u2014 fix the producer",
250
+ { type: event.type, object: event.object }
251
+ )]);
252
+ return;
253
+ }
254
+ const eventUuid = payload.id;
255
+ if (typeof eventUuid !== "string" || eventUuid === "") {
256
+ _optionalChain([this, 'access', _37 => _37.logger, 'access', _38 => _38.warn, 'optionalCall', _39 => _39(
257
+ "[webhook-auto-enqueuer] dropping off-contract bulk data event: payload has no top-level string `id` to dedup on \u2014 fix the producer",
258
+ { type: event.type, object: event.object }
259
+ )]);
260
+ return;
261
+ }
262
+ const eventId = `${event.object}:${event.type}:${eventUuid}`;
263
+ for (const sub of subs) {
264
+ if (!sub.triggers.has(trigger)) continue;
265
+ void this.enqueue({
266
+ source: "webhook",
267
+ refId: sub.id,
268
+ dedupKey: `${sub.id}:${eventId}`,
269
+ label: event.type,
270
+ url: sub.url,
271
+ method: sub.method,
272
+ headers: sub.headers,
273
+ signingSecret: sub.secret,
274
+ timeoutMs: sub.timeoutMs,
275
+ // [#3946] Envelope keys last so the payload cannot rewrite them.
276
+ payload: {
277
+ ...payload,
278
+ object: event.object,
279
+ matched,
280
+ action,
281
+ timestamp: event.timestamp
282
+ }
283
+ }).catch(
284
+ (err) => _optionalChain([this, 'access', _40 => _40.logger, 'access', _41 => _41.warn, 'optionalCall', _42 => _42("[webhook-auto-enqueuer] bulk enqueue failed", {
201
285
  webhook: sub.name,
202
286
  eventId,
203
- err: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _28 => _28.message]), () => ( err))
287
+ err: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _43 => _43.message]), () => ( err))
204
288
  })])
205
289
  );
206
290
  }
207
291
  }
208
292
  handleSelfHealEvent(event) {
209
293
  if (event.object !== this.subscriptionsObject) return;
210
- if (!_optionalChain([event, 'access', _29 => _29.type, 'optionalAccess', _30 => _30.startsWith, 'call', _31 => _31("data.record.")])) return;
294
+ if (!_optionalChain([event, 'access', _44 => _44.type, 'optionalAccess', _45 => _45.startsWith, 'call', _46 => _46("data.record.")]) && !_optionalChain([event, 'access', _47 => _47.type, 'optionalAccess', _48 => _48.startsWith, 'call', _49 => _49("data.records.")])) return;
211
295
  this.refresh().catch(
212
- (err) => _optionalChain([this, 'access', _32 => _32.logger, 'access', _33 => _33.warn, 'optionalCall', _34 => _34("[webhook-auto-enqueuer] self-heal refresh failed", err)])
296
+ (err) => _optionalChain([this, 'access', _50 => _50.logger, 'access', _51 => _51.warn, 'optionalCall', _52 => _52("[webhook-auto-enqueuer] self-heal refresh failed", err)])
213
297
  );
214
298
  }
215
299
  /** Test / admin accessor. */
@@ -229,29 +313,45 @@ function mapActionToTrigger(action) {
229
313
  return null;
230
314
  }
231
315
  }
232
- var DISPATCHABLE_WEBHOOK_TRIGGERS = /* @__PURE__ */ new Set(["create", "update", "delete"]);
316
+ function mapBulkActionToTrigger(action) {
317
+ switch (action) {
318
+ case "updated":
319
+ return "bulk_update";
320
+ case "deleted":
321
+ return "bulk_delete";
322
+ default:
323
+ return null;
324
+ }
325
+ }
326
+ var DISPATCHABLE_WEBHOOK_TRIGGERS = /* @__PURE__ */ new Set([
327
+ "create",
328
+ "update",
329
+ "delete",
330
+ "bulk_update",
331
+ "bulk_delete"
332
+ ]);
233
333
 
234
334
  // src/bootstrap-declared-webhooks.ts
235
335
  var _automation = require('@objectstack/spec/automation');
236
336
  var SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] };
237
337
  function uid(prefix) {
238
338
  const g = globalThis;
239
- if (_optionalChain([g, 'access', _35 => _35.crypto, 'optionalAccess', _36 => _36.randomUUID])) return `${prefix}_${g.crypto.randomUUID()}`;
339
+ if (_optionalChain([g, 'access', _53 => _53.crypto, 'optionalAccess', _54 => _54.randomUUID])) return `${prefix}_${g.crypto.randomUUID()}`;
240
340
  return `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
241
341
  }
242
342
  function readDeclared(engine, metadataService, type) {
243
343
  try {
244
- const reg = _optionalChain([engine, 'optionalAccess', _37 => _37._registry]);
245
- if (_optionalChain([reg, 'optionalAccess', _38 => _38.listItems])) {
246
- const items = (_nullishCoalesce(reg.listItems(type), () => ( []))).map((i) => _nullishCoalesce(_optionalChain([i, 'optionalAccess', _39 => _39.content]), () => ( i))).filter(Boolean);
344
+ const reg = _optionalChain([engine, 'optionalAccess', _55 => _55._registry]);
345
+ if (_optionalChain([reg, 'optionalAccess', _56 => _56.listItems])) {
346
+ const items = (_nullishCoalesce(reg.listItems(type), () => ( []))).map((i) => _nullishCoalesce(_optionalChain([i, 'optionalAccess', _57 => _57.content]), () => ( i))).filter(Boolean);
247
347
  if (items.length > 0) return items;
248
348
  }
249
349
  } catch (e3) {
250
350
  }
251
351
  try {
252
- const listed = _optionalChain([metadataService, 'optionalAccess', _40 => _40.list, 'optionalCall', _41 => _41(type)]);
253
- const arr = typeof _optionalChain([listed, 'optionalAccess', _42 => _42.then]) === "function" ? [] : _nullishCoalesce(listed, () => ( []));
254
- return Array.isArray(arr) ? arr.map((i) => _nullishCoalesce(_optionalChain([i, 'optionalAccess', _43 => _43.content]), () => ( i))).filter(Boolean) : [];
352
+ const listed = _optionalChain([metadataService, 'optionalAccess', _58 => _58.list, 'optionalCall', _59 => _59(type)]);
353
+ const arr = typeof _optionalChain([listed, 'optionalAccess', _60 => _60.then]) === "function" ? [] : _nullishCoalesce(listed, () => ( []));
354
+ return Array.isArray(arr) ? arr.map((i) => _nullishCoalesce(_optionalChain([i, 'optionalAccess', _61 => _61.content]), () => ( i))).filter(Boolean) : [];
255
355
  } catch (e4) {
256
356
  return [];
257
357
  }
@@ -267,9 +367,9 @@ async function bootstrapDeclaredWebhooks(engine, metadataService, logger, subscr
267
367
  try {
268
368
  wh = _automation.WebhookSchema.parse(raw);
269
369
  } catch (err) {
270
- _optionalChain([logger, 'optionalAccess', _44 => _44.warn, 'optionalCall', _45 => _45("[webhook] declared webhook failed validation \u2014 skipped", {
271
- name: _optionalChain([raw, 'optionalAccess', _46 => _46.name]),
272
- error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _47 => _47.message]), () => ( String(err)))
370
+ _optionalChain([logger, 'optionalAccess', _62 => _62.warn, 'optionalCall', _63 => _63("[webhook] declared webhook failed validation \u2014 skipped", {
371
+ name: _optionalChain([raw, 'optionalAccess', _64 => _64.name]),
372
+ error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _65 => _65.message]), () => ( String(err)))
273
373
  })]);
274
374
  skipped += 1;
275
375
  continue;
@@ -283,7 +383,7 @@ async function bootstrapDeclaredWebhooks(engine, metadataService, logger, subscr
283
383
  const row = Array.isArray(existing) ? existing[0] : void 0;
284
384
  if (row) {
285
385
  if (row.managed_by === "admin") {
286
- _optionalChain([logger, 'optionalAccess', _48 => _48.warn, 'optionalCall', _49 => _49("[webhook] declared name collides with an admin-authored row \u2014 seed skipped", {
386
+ _optionalChain([logger, 'optionalAccess', _66 => _66.warn, 'optionalCall', _67 => _67("[webhook] declared name collides with an admin-authored row \u2014 seed skipped", {
287
387
  name: wh.name
288
388
  })]);
289
389
  skipped += 1;
@@ -316,14 +416,14 @@ async function bootstrapDeclaredWebhooks(engine, metadataService, logger, subscr
316
416
  await engine.insert(subscriptionsObject, newRow, { context: SYSTEM_CTX });
317
417
  seeded += 1;
318
418
  } catch (err) {
319
- _optionalChain([logger, 'optionalAccess', _50 => _50.warn, 'optionalCall', _51 => _51("[webhook] declared webhook seed failed", {
419
+ _optionalChain([logger, 'optionalAccess', _68 => _68.warn, 'optionalCall', _69 => _69("[webhook] declared webhook seed failed", {
320
420
  name: wh.name,
321
- error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _52 => _52.message]), () => ( String(err)))
421
+ error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _70 => _70.message]), () => ( String(err)))
322
422
  })]);
323
423
  skipped += 1;
324
424
  }
325
425
  }
326
- _optionalChain([logger, 'optionalAccess', _53 => _53.info, 'optionalCall', _54 => _54("[webhook] declared webhooks materialized into sys_webhook", {
426
+ _optionalChain([logger, 'optionalAccess', _71 => _71.info, 'optionalCall', _72 => _72("[webhook] declared webhooks materialized into sys_webhook", {
327
427
  seeded,
328
428
  skipped,
329
429
  total: declared.length
@@ -350,14 +450,14 @@ function mapWebhookToRow(wh) {
350
450
  var WEBHOOK_PROVENANCE_PACKAGE = "plugin-webhooks:provenance";
351
451
  var SYSTEM_CTX2 = { isSystem: true, positions: [], permissions: [] };
352
452
  function bindWebhookProvenanceStamp(engine, logger) {
353
- if (typeof _optionalChain([engine, 'optionalAccess', _55 => _55.registerHook]) !== "function") return;
453
+ if (typeof _optionalChain([engine, 'optionalAccess', _73 => _73.registerHook]) !== "function") return;
354
454
  engine.registerHook(
355
455
  "beforeUpdate",
356
456
  async (ctx) => {
357
- if (_optionalChain([ctx, 'optionalAccess', _56 => _56.session, 'optionalAccess', _57 => _57.isSystem])) return;
358
- const id = _nullishCoalesce(_optionalChain([ctx, 'optionalAccess', _58 => _58.input, 'optionalAccess', _59 => _59.id]), () => ( _optionalChain([ctx, 'optionalAccess', _60 => _60.input, 'optionalAccess', _61 => _61.data, 'optionalAccess', _62 => _62.id])));
457
+ if (_optionalChain([ctx, 'optionalAccess', _74 => _74.session, 'optionalAccess', _75 => _75.isSystem])) return;
458
+ const id = _nullishCoalesce(_optionalChain([ctx, 'optionalAccess', _76 => _76.input, 'optionalAccess', _77 => _77.id]), () => ( _optionalChain([ctx, 'optionalAccess', _78 => _78.input, 'optionalAccess', _79 => _79.data, 'optionalAccess', _80 => _80.id])));
359
459
  if (!id) return;
360
- const data = _optionalChain([ctx, 'optionalAccess', _63 => _63.input, 'optionalAccess', _64 => _64.data]);
460
+ const data = _optionalChain([ctx, 'optionalAccess', _81 => _81.input, 'optionalAccess', _82 => _82.data]);
361
461
  if (!data || typeof data !== "object") return;
362
462
  try {
363
463
  const rows = await engine.find("sys_webhook", {
@@ -372,18 +472,18 @@ function bindWebhookProvenanceStamp(engine, logger) {
372
472
  data.customized = true;
373
473
  }
374
474
  } catch (err) {
375
- _optionalChain([logger, 'optionalAccess', _65 => _65.warn, 'optionalCall', _66 => _66("[webhook] provenance stamp failed (edit proceeds unstamped)", {
475
+ _optionalChain([logger, 'optionalAccess', _83 => _83.warn, 'optionalCall', _84 => _84("[webhook] provenance stamp failed (edit proceeds unstamped)", {
376
476
  id,
377
- error: _optionalChain([err, 'optionalAccess', _67 => _67.message])
477
+ error: _optionalChain([err, 'optionalAccess', _85 => _85.message])
378
478
  })]);
379
479
  }
380
480
  },
381
481
  { object: "sys_webhook", packageId: WEBHOOK_PROVENANCE_PACKAGE, priority: 150 }
382
482
  );
383
- _optionalChain([logger, 'optionalAccess', _68 => _68.info, 'optionalCall', _69 => _69("[webhook] provenance stamp hook bound")]);
483
+ _optionalChain([logger, 'optionalAccess', _86 => _86.info, 'optionalCall', _87 => _87("[webhook] provenance stamp hook bound")]);
384
484
  }
385
485
  function unbindWebhookProvenanceStamp(engine) {
386
- if (typeof _optionalChain([engine, 'optionalAccess', _70 => _70.unregisterHooksByPackage]) === "function") {
486
+ if (typeof _optionalChain([engine, 'optionalAccess', _88 => _88.unregisterHooksByPackage]) === "function") {
387
487
  engine.unregisterHooksByPackage(WEBHOOK_PROVENANCE_PACKAGE);
388
488
  }
389
489
  }
@@ -418,7 +518,7 @@ var WebhookOutboxPlugin = class {
418
518
  scope: "system",
419
519
  name: "Webhook Schemas",
420
520
  description: "Registers sys_webhook (configuration). Deliveries use messaging's sys_http_delivery outbox.",
421
- objects: [_chunkQUTQSOQCcjs.SysWebhook],
521
+ objects: [_chunkJQUVS5KKcjs.SysWebhook],
422
522
  navigationContributions: [
423
523
  {
424
524
  app: "setup",
@@ -432,7 +532,7 @@ var WebhookOutboxPlugin = class {
432
532
  ]
433
533
  });
434
534
  } else {
435
- _optionalChain([ctx, 'access', _71 => _71.logger, 'access', _72 => _72.warn, 'optionalCall', _73 => _73(
535
+ _optionalChain([ctx, 'access', _89 => _89.logger, 'access', _90 => _90.warn, 'optionalCall', _91 => _91(
436
536
  "[webhook-outbox] manifest service unavailable \u2014 sys_webhook will NOT appear in REST or Studio nav. Register MetadataService before WebhookOutboxPlugin."
437
537
  )]);
438
538
  }
@@ -441,7 +541,7 @@ var WebhookOutboxPlugin = class {
441
541
  try {
442
542
  const i18n = ctx.getService("i18n");
443
543
  if (i18n && typeof i18n.loadTranslations === "function") {
444
- const { WebhooksTranslations } = await Promise.resolve().then(() => _interopRequireWildcard(require("./translations-CBQRUIS5.cjs")));
544
+ const { WebhooksTranslations } = await Promise.resolve().then(() => _interopRequireWildcard(require("./translations-BWS57U2V.cjs")));
445
545
  for (const [locale, data] of Object.entries(WebhooksTranslations)) {
446
546
  i18n.loadTranslations(locale, data);
447
547
  }
@@ -458,12 +558,12 @@ var WebhookOutboxPlugin = class {
458
558
  this.registerAdminRoutes(ctx);
459
559
  });
460
560
  }
461
- _optionalChain([ctx, 'access', _74 => _74.logger, 'access', _75 => _75.info, 'optionalCall', _76 => _76("[webhook-outbox] initialised (delivery via shared messaging HTTP outbox)", {
561
+ _optionalChain([ctx, 'access', _92 => _92.logger, 'access', _93 => _93.info, 'optionalCall', _94 => _94("[webhook-outbox] initialised (delivery via shared messaging HTTP outbox)", {
462
562
  autoEnqueue: autoEnqueueOpt !== false
463
563
  })]);
464
564
  }
465
565
  async dispose() {
466
- await _optionalChain([this, 'access', _77 => _77.autoEnqueuer, 'optionalAccess', _78 => _78.stop, 'call', _79 => _79()]);
566
+ await _optionalChain([this, 'access', _95 => _95.autoEnqueuer, 'optionalAccess', _96 => _96.stop, 'call', _97 => _97()]);
467
567
  if (this.boundEngine) {
468
568
  try {
469
569
  unbindWebhookProvenanceStamp(this.boundEngine);
@@ -491,7 +591,7 @@ var WebhookOutboxPlugin = class {
491
591
  async bootDeclaredWebhooks(ctx) {
492
592
  const engine = this.tryGetService(ctx, ["objectql", "data"]);
493
593
  if (!engine) {
494
- _optionalChain([ctx, 'access', _80 => _80.logger, 'access', _81 => _81.warn, 'optionalCall', _82 => _82("[webhook] declared-webhook bootstrap skipped \u2014 no data engine available")]);
594
+ _optionalChain([ctx, 'access', _98 => _98.logger, 'access', _99 => _99.warn, 'optionalCall', _100 => _100("[webhook] declared-webhook bootstrap skipped \u2014 no data engine available")]);
495
595
  return;
496
596
  }
497
597
  this.boundEngine = engine;
@@ -504,8 +604,8 @@ var WebhookOutboxPlugin = class {
504
604
  try {
505
605
  await bootstrapDeclaredWebhooks(engine, metadataService, ctx.logger);
506
606
  } catch (err) {
507
- _optionalChain([ctx, 'access', _83 => _83.logger, 'access', _84 => _84.warn, 'optionalCall', _85 => _85("[webhook] declared-webhook bootstrap failed (dispatcher still serves admin rows)", {
508
- error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _86 => _86.message]), () => ( String(err)))
607
+ _optionalChain([ctx, 'access', _101 => _101.logger, 'access', _102 => _102.warn, 'optionalCall', _103 => _103("[webhook] declared-webhook bootstrap failed (dispatcher still serves admin rows)", {
608
+ error: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _104 => _104.message]), () => ( String(err)))
509
609
  })]);
510
610
  }
511
611
  }
@@ -515,14 +615,14 @@ var WebhookOutboxPlugin = class {
515
615
  const realtime = this.tryGetService(ctx, ["realtime"]);
516
616
  const messaging = this.getMessaging(ctx);
517
617
  if (!engine || !realtime || !messaging) {
518
- _optionalChain([ctx, 'access', _87 => _87.logger, 'access', _88 => _88.warn, 'optionalCall', _89 => _89(
618
+ _optionalChain([ctx, 'access', _105 => _105.logger, 'access', _106 => _106.warn, 'optionalCall', _107 => _107(
519
619
  "[webhook-auto-enqueuer] disabled \u2014 ObjectQL, Realtime, or Messaging service not available",
520
620
  { hasEngine: !!engine, hasRealtime: !!realtime, hasMessaging: !!messaging }
521
621
  )]);
522
622
  return;
523
623
  }
524
624
  if (!messaging.isHttpDeliveryReady()) {
525
- _optionalChain([ctx, 'access', _90 => _90.logger, 'access', _91 => _91.warn, 'optionalCall', _92 => _92(
625
+ _optionalChain([ctx, 'access', _108 => _108.logger, 'access', _109 => _109.warn, 'optionalCall', _110 => _110(
526
626
  "[webhook-auto-enqueuer] messaging HTTP outbox not ready (no data engine / reliableDelivery off) \u2014 webhook deliveries will not be durable"
527
627
  )]);
528
628
  }
@@ -535,7 +635,7 @@ var WebhookOutboxPlugin = class {
535
635
  );
536
636
  await this.autoEnqueuer.start();
537
637
  ctx.registerService("webhook.autoEnqueuer", this.autoEnqueuer);
538
- _optionalChain([ctx, 'access', _93 => _93.logger, 'access', _94 => _94.info, 'optionalCall', _95 => _95("[webhook-auto-enqueuer] started (enqueues source=webhook onto sys_http_delivery)")]);
638
+ _optionalChain([ctx, 'access', _111 => _111.logger, 'access', _112 => _112.info, 'optionalCall', _113 => _113("[webhook-auto-enqueuer] started (enqueues source=webhook onto sys_http_delivery)")]);
539
639
  }
540
640
  tryGetService(ctx, names) {
541
641
  for (const n of names) {
@@ -555,7 +655,7 @@ var WebhookOutboxPlugin = class {
555
655
  registerAdminRoutes(ctx) {
556
656
  const http = this.tryGetService(ctx, ["http-server"]);
557
657
  if (!http || typeof http.getRawApp !== "function") {
558
- _optionalChain([ctx, 'access', _96 => _96.logger, 'access', _97 => _97.debug, 'optionalCall', _98 => _98("[webhook-outbox] HTTP server not available; redeliver endpoint not mounted")]);
658
+ _optionalChain([ctx, 'access', _114 => _114.logger, 'access', _115 => _115.debug, 'optionalCall', _116 => _116("[webhook-outbox] HTTP server not available; redeliver endpoint not mounted")]);
559
659
  return;
560
660
  }
561
661
  const rawApp = http.getRawApp();
@@ -575,7 +675,7 @@ var WebhookOutboxPlugin = class {
575
675
  } catch (e9) {
576
676
  return c.json({ success: false, error: { code: "INVALID_REQUEST", message: "Request body must be JSON." } }, 400);
577
677
  }
578
- const deliveryId = typeof _optionalChain([body, 'optionalAccess', _99 => _99.deliveryId]) === "string" ? body.deliveryId.trim() : "";
678
+ const deliveryId = typeof _optionalChain([body, 'optionalAccess', _117 => _117.deliveryId]) === "string" ? body.deliveryId.trim() : "";
579
679
  if (!deliveryId) {
580
680
  return c.json(
581
681
  { success: false, error: { code: "MISSING_REQUIRED_FIELD", message: "Body must include `deliveryId: string`." } },
@@ -584,24 +684,24 @@ var WebhookOutboxPlugin = class {
584
684
  }
585
685
  try {
586
686
  const row = await messaging.redeliverHttp(deliveryId);
587
- _optionalChain([ctx, 'access', _100 => _100.logger, 'access', _101 => _101.info, 'optionalCall', _102 => _102("[webhook-outbox] redelivered", { deliveryId, requestedBy: userId })]);
687
+ _optionalChain([ctx, 'access', _118 => _118.logger, 'access', _119 => _119.info, 'optionalCall', _120 => _120("[webhook-outbox] redelivered", { deliveryId, requestedBy: userId })]);
588
688
  return c.json({ success: true, data: { id: row.id, status: row.status } });
589
689
  } catch (err) {
590
- const code = _optionalChain([err, 'optionalAccess', _103 => _103.code]);
690
+ const code = _optionalChain([err, 'optionalAccess', _121 => _121.code]);
591
691
  if (code === "RESOURCE_NOT_FOUND") {
592
692
  return c.json({ success: false, error: { code, message: err.message } }, 404);
593
693
  }
594
694
  if (code === "DELIVERY_NOT_ELIGIBLE") {
595
695
  return c.json({ success: false, error: { code, message: err.message } }, 409);
596
696
  }
597
- _optionalChain([ctx, 'access', _104 => _104.logger, 'access', _105 => _105.error, 'optionalCall', _106 => _106("[webhook-outbox] redeliver failed", err)]);
697
+ _optionalChain([ctx, 'access', _122 => _122.logger, 'access', _123 => _123.error, 'optionalCall', _124 => _124("[webhook-outbox] redeliver failed", err)]);
598
698
  return c.json(
599
- { success: false, error: { code: "INTERNAL_ERROR", message: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _107 => _107.message]), () => ( String(err))) } },
699
+ { success: false, error: { code: "INTERNAL_ERROR", message: _nullishCoalesce(_optionalChain([err, 'optionalAccess', _125 => _125.message]), () => ( String(err))) } },
600
700
  500
601
701
  );
602
702
  }
603
703
  });
604
- _optionalChain([ctx, 'access', _108 => _108.logger, 'access', _109 => _109.info, 'optionalCall', _110 => _110("[webhook-outbox] redeliver endpoint mounted at POST /api/v1/webhooks/redeliver")]);
704
+ _optionalChain([ctx, 'access', _126 => _126.logger, 'access', _127 => _127.info, 'optionalCall', _128 => _128("[webhook-outbox] redeliver endpoint mounted at POST /api/v1/webhooks/redeliver")]);
605
705
  }
606
706
  async resolveSessionUserId(ctx, c) {
607
707
  try {
@@ -611,9 +711,9 @@ var WebhookOutboxPlugin = class {
611
711
  if (!api && typeof authService.getApi === "function") {
612
712
  api = await authService.getApi();
613
713
  }
614
- if (!_optionalChain([api, 'optionalAccess', _111 => _111.getSession])) return void 0;
714
+ if (!_optionalChain([api, 'optionalAccess', _129 => _129.getSession])) return void 0;
615
715
  const session = await api.getSession({ headers: c.req.raw.headers });
616
- const uid2 = _optionalChain([session, 'optionalAccess', _112 => _112.user, 'optionalAccess', _113 => _113.id]);
716
+ const uid2 = _optionalChain([session, 'optionalAccess', _130 => _130.user, 'optionalAccess', _131 => _131.id]);
617
717
  return typeof uid2 === "string" && uid2.length > 0 ? uid2 : void 0;
618
718
  } catch (e10) {
619
719
  return void 0;
@@ -624,5 +724,5 @@ var WebhookOutboxPlugin = class {
624
724
 
625
725
 
626
726
 
627
- exports.AutoEnqueuer = AutoEnqueuer; exports.SysWebhook = _chunkQUTQSOQCcjs.SysWebhook; exports.WebhookOutboxPlugin = WebhookOutboxPlugin;
727
+ exports.AutoEnqueuer = AutoEnqueuer; exports.SysWebhook = _chunkJQUVS5KKcjs.SysWebhook; exports.WebhookOutboxPlugin = WebhookOutboxPlugin;
628
728
  //# sourceMappingURL=index.cjs.map