better-ship 0.17.0 → 0.19.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 (126) hide show
  1. package/dist/{application-Cf9SER-i.js → application-Dg1jIKPe.js} +5 -7
  2. package/dist/{application-Cf9SER-i.js.map → application-Dg1jIKPe.js.map} +1 -1
  3. package/dist/application.d.ts +2 -2
  4. package/dist/application.js +1 -1
  5. package/dist/better-auth/apple-client-secret.d.ts +1 -1
  6. package/dist/better-auth/apple-client-secret.js +2 -2
  7. package/dist/better-auth/apple-client-secret.js.map +1 -1
  8. package/dist/better-auth/auth-client.js +1 -1
  9. package/dist/better-auth/rate-limit.d.ts +1 -1
  10. package/dist/better-auth/rate-limit.js +4 -6
  11. package/dist/better-auth/rate-limit.js.map +1 -1
  12. package/dist/better-auth.js +1 -1
  13. package/dist/billing/client.d.ts +86 -0
  14. package/dist/billing/client.d.ts.map +1 -0
  15. package/dist/billing/client.js +77 -0
  16. package/dist/billing/client.js.map +1 -0
  17. package/dist/cloudflare/auth-secondary-storage.d.ts +1 -1
  18. package/dist/cloudflare/auth-secondary-storage.js +1 -1
  19. package/dist/cloudflare/durable-object-client.js +1 -1
  20. package/dist/cloudflare/durable-object-errors.d.ts +1 -1
  21. package/dist/cloudflare/durable-object-errors.js +1 -1
  22. package/dist/cloudflare/kv-client.js +1 -1
  23. package/dist/cloudflare/kv-errors.d.ts +1 -1
  24. package/dist/cloudflare/kv-errors.js +1 -1
  25. package/dist/cloudflare/queue.d.ts +2 -2
  26. package/dist/cloudflare/queue.d.ts.map +1 -1
  27. package/dist/cloudflare/queue.js +10 -12
  28. package/dist/cloudflare/queue.js.map +1 -1
  29. package/dist/cloudflare/r2-client.d.ts +70 -0
  30. package/dist/cloudflare/r2-client.d.ts.map +1 -0
  31. package/dist/cloudflare/r2-client.js +153 -0
  32. package/dist/cloudflare/r2-client.js.map +1 -0
  33. package/dist/cloudflare/r2-errors.d.ts +34 -0
  34. package/dist/cloudflare/r2-errors.d.ts.map +1 -0
  35. package/dist/cloudflare/r2-errors.js +90 -0
  36. package/dist/cloudflare/r2-errors.js.map +1 -0
  37. package/dist/cloudflare/scheduled.d.ts +1 -1
  38. package/dist/cloudflare/scheduled.js +2 -2
  39. package/dist/cloudflare/scheduled.js.map +1 -1
  40. package/dist/cloudflare.d.ts +3 -3
  41. package/dist/cloudflare.js +3 -3
  42. package/dist/{core-ClSP5-V9.js → core-BT1dSEQI.js} +106 -195
  43. package/dist/core-BT1dSEQI.js.map +1 -0
  44. package/dist/core.d.ts +2 -2
  45. package/dist/core.js +2 -2
  46. package/dist/http.d.ts +16 -8
  47. package/dist/http.d.ts.map +1 -1
  48. package/dist/http.js +51 -12
  49. package/dist/http.js.map +1 -1
  50. package/dist/{index-Cchdg2aQ.d.ts → index-CYHXOH08.d.ts} +2 -2
  51. package/dist/{index-Cchdg2aQ.d.ts.map → index-CYHXOH08.d.ts.map} +1 -1
  52. package/dist/{index-DvJUcSW1.d.ts → index-DUFS0SJ_.d.ts} +41 -102
  53. package/dist/index-DUFS0SJ_.d.ts.map +1 -0
  54. package/dist/{outbox-repository-options-ICOF8g2h.js → outbox-repository-options-B8TnAE1h.js} +2 -2
  55. package/dist/{outbox-repository-options-ICOF8g2h.js.map → outbox-repository-options-B8TnAE1h.js.map} +1 -1
  56. package/dist/{outbox-repository-options-AkihEaik.d.ts → outbox-repository-options-DjBgFhMi.d.ts} +3 -3
  57. package/dist/{outbox-repository-options-AkihEaik.d.ts.map → outbox-repository-options-DjBgFhMi.d.ts.map} +1 -1
  58. package/dist/postgres.d.ts +3 -3
  59. package/dist/postgres.js +3 -3
  60. package/dist/posthog/metrics.d.ts +1 -1
  61. package/dist/posthog/server.d.ts +2 -2
  62. package/dist/posthog/server.js +1 -1
  63. package/dist/resend.d.ts +5 -5
  64. package/dist/resend.d.ts.map +1 -1
  65. package/dist/resend.js +30 -57
  66. package/dist/resend.js.map +1 -1
  67. package/dist/sentry/client.d.ts +1 -1
  68. package/dist/sentry/client.d.ts.map +1 -1
  69. package/dist/sentry/client.js +10 -4
  70. package/dist/sentry/client.js.map +1 -1
  71. package/dist/sentry/server.d.ts +2 -2
  72. package/dist/sentry/server.js +5 -5
  73. package/dist/sentry/server.js.map +1 -1
  74. package/dist/stripe/payment-service.d.ts +52 -0
  75. package/dist/stripe/payment-service.d.ts.map +1 -0
  76. package/dist/stripe/payment-service.error.d.ts +13 -0
  77. package/dist/stripe/payment-service.error.d.ts.map +1 -0
  78. package/dist/stripe/payment-service.error.js +30 -0
  79. package/dist/stripe/payment-service.error.js.map +1 -0
  80. package/dist/stripe/payment-service.js +72 -0
  81. package/dist/stripe/payment-service.js.map +1 -0
  82. package/dist/stripe/payment-webhook.d.ts +18 -0
  83. package/dist/stripe/payment-webhook.d.ts.map +1 -0
  84. package/dist/stripe/payment-webhook.js +35 -0
  85. package/dist/stripe/payment-webhook.js.map +1 -0
  86. package/dist/tanstack.d.ts +1 -1
  87. package/dist/tanstack.js +4 -4
  88. package/dist/tanstack.js.map +1 -1
  89. package/dist/testing/outbox-repository.d.ts +2 -2
  90. package/dist/testing/payment-service.d.ts +10 -0
  91. package/dist/testing/payment-service.d.ts.map +1 -0
  92. package/dist/testing/payment-service.js +76 -0
  93. package/dist/testing/payment-service.js.map +1 -0
  94. package/dist/webhook-verification-D1c7BY4q.d.ts +21 -0
  95. package/dist/webhook-verification-D1c7BY4q.d.ts.map +1 -0
  96. package/dist/{webhook-verification-D6aGQfNi.js → webhook-verification-qSFXv5H3.js} +2 -2
  97. package/dist/webhook-verification-qSFXv5H3.js.map +1 -0
  98. package/package.json +13 -6
  99. package/src/application/outbox-relay.ts +3 -1
  100. package/src/core/console-log-sink.ts +61 -0
  101. package/src/core/index.ts +1 -4
  102. package/src/core/logger.ts +80 -281
  103. package/src/infrastructure/better-auth/apple-client-secret.ts +1 -1
  104. package/src/infrastructure/better-auth/rate-limit.ts +3 -1
  105. package/src/infrastructure/billing/client.ts +173 -0
  106. package/src/infrastructure/cloudflare/queue/queue-consumer.ts +8 -9
  107. package/src/infrastructure/cloudflare/r2-client.ts +162 -0
  108. package/src/infrastructure/cloudflare/r2-errors.ts +111 -0
  109. package/src/infrastructure/cloudflare/scheduled/scheduled-handler.ts +1 -1
  110. package/src/infrastructure/http/index.ts +2 -6
  111. package/src/infrastructure/http/webhook-handler.ts +69 -12
  112. package/src/infrastructure/http/webhook-verification.ts +6 -9
  113. package/src/infrastructure/resend/email-event.ts +14 -30
  114. package/src/infrastructure/resend/resend-webhook.ts +12 -22
  115. package/src/infrastructure/sentry/client.ts +6 -3
  116. package/src/infrastructure/sentry/server.ts +4 -4
  117. package/src/infrastructure/stripe/payment-service.error.ts +42 -0
  118. package/src/infrastructure/stripe/payment-service.ts +129 -0
  119. package/src/infrastructure/stripe/payment-webhook.ts +36 -0
  120. package/src/infrastructure/tanstack/resolve-failure.ts +3 -2
  121. package/src/infrastructure/testing/payment-service-contract.ts +91 -0
  122. package/dist/core-ClSP5-V9.js.map +0 -1
  123. package/dist/index-DvJUcSW1.d.ts.map +0 -1
  124. package/dist/webhook-verification-BcQQG-vY.d.ts +0 -29
  125. package/dist/webhook-verification-BcQQG-vY.d.ts.map +0 -1
  126. package/dist/webhook-verification-D6aGQfNi.js.map +0 -1
package/dist/http.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as createLogger } from "./core-ClSP5-V9.js";
2
- import { t as WebhookVerificationError } from "./webhook-verification-D6aGQfNi.js";
1
+ import { r as createLogger } from "./core-BT1dSEQI.js";
2
+ import { t as WebhookVerificationError } from "./webhook-verification-qSFXv5H3.js";
3
3
  import { StatusCodes } from "http-status-codes";
4
4
 
5
5
  //#region src/infrastructure/http/webhook-handler.ts
@@ -7,24 +7,63 @@ import { StatusCodes } from "http-status-codes";
7
7
  var WebhookHandler = class {
8
8
  verifier;
9
9
  logger;
10
- /** Inject provider verification and an optional logger with the application's module name. */
11
- constructor(verifier, logger = createLogger("webhook")) {
10
+ maxBodyBytes;
11
+ /** Inject provider verification, the application body limit, and optional diagnostics. */
12
+ constructor(verifier, options) {
12
13
  this.verifier = verifier;
13
- this.logger = logger;
14
+ this.logger = options.logger ?? createLogger("webhook");
15
+ this.maxBodyBytes = options.maxBodyBytes;
14
16
  }
15
17
  /**
16
- * Return 401 for authentication failure, 400 for invalid content, and 200 after callback completion or an ignored event.
18
+ * Return 413 for large content, 401 for authentication failure, 400 for invalid content, and 200 after callback completion or an ignored event.
17
19
  * Operational and callback failures propagate to the route's error boundary without an acknowledgment.
18
20
  */
19
- async handle(request, onEvent) {
20
- const body = await request.text();
21
- const result = await this.verifier.verify(body, request.headers);
22
- if (result.outcome === "rejected") return this.reject(result.error);
23
- if (result.outcome === "event") await onEvent(result.event);
21
+ async handle(request, onVerified) {
22
+ const body = await this.readBody(request);
23
+ if (body === null) return this.rejectBodyTooLarge();
24
+ let verified;
25
+ try {
26
+ verified = await this.verifier.verify(body, request.headers);
27
+ } catch (cause) {
28
+ if (cause instanceof WebhookVerificationError) return this.reject(cause);
29
+ throw cause;
30
+ }
31
+ if (verified !== null) await onVerified(verified);
24
32
  return new Response(null, { status: StatusCodes.OK });
25
33
  }
34
+ async readBody(request) {
35
+ const contentLength = request.headers.get("content-length");
36
+ if (contentLength !== null && /^\d+$/.test(contentLength)) {
37
+ if (Number(contentLength) > this.maxBodyBytes) return null;
38
+ }
39
+ if (request.body === null) return "";
40
+ const reader = request.body.getReader();
41
+ const decoder = new TextDecoder();
42
+ let body = "";
43
+ let byteCount = 0;
44
+ try {
45
+ while (true) {
46
+ const chunk = await reader.read();
47
+ if (chunk.done) return body + decoder.decode();
48
+ byteCount += chunk.value.byteLength;
49
+ if (byteCount > this.maxBodyBytes) {
50
+ try {
51
+ await reader.cancel();
52
+ } catch {}
53
+ return null;
54
+ }
55
+ body += decoder.decode(chunk.value, { stream: true });
56
+ }
57
+ } finally {
58
+ reader.releaseLock();
59
+ }
60
+ }
61
+ rejectBodyTooLarge() {
62
+ this.logger.warn("webhook_rejected", { reason: "body_too_large" });
63
+ return new Response(null, { status: StatusCodes.REQUEST_TOO_LONG });
64
+ }
26
65
  reject(error) {
27
- this.logger.warn("Webhook rejected", { reason: error.reason });
66
+ this.logger.warn("webhook_rejected", { reason: error.reason });
28
67
  const status = error.reason === "missing_headers" || error.reason === "invalid_signature" ? StatusCodes.UNAUTHORIZED : StatusCodes.BAD_REQUEST;
29
68
  return new Response(null, { status });
30
69
  }
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","names":[],"sources":["../src/infrastructure/http/webhook-handler.ts"],"sourcesContent":["import { StatusCodes } from 'http-status-codes'\n\nimport { createLogger, type Logger } from '@/core'\n\nimport { WebhookVerificationError, type WebhookVerifier } from './webhook-verification.ts'\n\n/** Read raw webhook requests and acknowledge effects only after the callback completes. */\nexport class WebhookHandler<Event> {\n /** Inject provider verification and an optional logger with the application's module name. */\n constructor(\n private readonly verifier: WebhookVerifier<Event>,\n private readonly logger: Pick<Logger, 'warn'> = createLogger('webhook'),\n ) {}\n\n /**\n * Return 401 for authentication failure, 400 for invalid content, and 200 after callback completion or an ignored event.\n * Operational and callback failures propagate to the route's error boundary without an acknowledgment.\n */\n async handle(request: Request, onEvent: (event: Event) => Promise<void>): Promise<Response> {\n const body = await request.text()\n const result = await this.verifier.verify(body, request.headers)\n if (result.outcome === 'rejected') return this.reject(result.error)\n if (result.outcome === 'event') await onEvent(result.event)\n return new Response(null, { status: StatusCodes.OK })\n }\n\n private reject(error: WebhookVerificationError): Response {\n this.logger.warn('Webhook rejected', { reason: error.reason })\n const status =\n error.reason === 'missing_headers' || error.reason === 'invalid_signature'\n ? StatusCodes.UNAUTHORIZED\n : StatusCodes.BAD_REQUEST\n return new Response(null, { status })\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,iBAAb,MAAmC;CAGd;CACA;;CAFnB,YACE,AAAiB,UACjB,AAAiB,SAA+B,aAAa,SAAS,GACtE;EAFiB;EACA;CAChB;;;;;CAMH,MAAM,OAAO,SAAkB,SAA6D;EAC1F,MAAM,OAAO,MAAM,QAAQ,KAAK;EAChC,MAAM,SAAS,MAAM,KAAK,SAAS,OAAO,MAAM,QAAQ,OAAO;EAC/D,IAAI,OAAO,YAAY,YAAY,OAAO,KAAK,OAAO,OAAO,KAAK;EAClE,IAAI,OAAO,YAAY,SAAS,MAAM,QAAQ,OAAO,KAAK;EAC1D,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,YAAY,GAAG,CAAC;CACtD;CAEA,AAAQ,OAAO,OAA2C;EACxD,KAAK,OAAO,KAAK,oBAAoB,EAAE,QAAQ,MAAM,OAAO,CAAC;EAC7D,MAAM,SACJ,MAAM,WAAW,qBAAqB,MAAM,WAAW,sBACnD,YAAY,eACZ,YAAY;EAClB,OAAO,IAAI,SAAS,MAAM,EAAE,OAAO,CAAC;CACtC;AACF"}
1
+ {"version":3,"file":"http.js","names":[],"sources":["../src/infrastructure/http/webhook-handler.ts"],"sourcesContent":["import { StatusCodes } from 'http-status-codes'\n\nimport { createLogger, type Logger } from '@/core'\n\nimport { WebhookVerificationError, type WebhookVerifier } from './webhook-verification.ts'\n\n/** Application policy and diagnostics for one webhook body. */\nexport type WebhookHandlerOptions = {\n readonly maxBodyBytes: number\n readonly logger?: Pick<Logger, 'warn'>\n}\n\n/** Read raw webhook requests and acknowledge effects only after the callback completes. */\nexport class WebhookHandler<Verified> {\n private readonly logger: Pick<Logger, 'warn'>\n private readonly maxBodyBytes: number\n\n /** Inject provider verification, the application body limit, and optional diagnostics. */\n constructor(\n private readonly verifier: WebhookVerifier<Verified>,\n options: WebhookHandlerOptions,\n ) {\n this.logger = options.logger ?? createLogger('webhook')\n this.maxBodyBytes = options.maxBodyBytes\n }\n\n /**\n * Return 413 for large content, 401 for authentication failure, 400 for invalid content, and 200 after callback completion or an ignored event.\n * Operational and callback failures propagate to the route's error boundary without an acknowledgment.\n */\n async handle(\n request: Request,\n onVerified: (value: Verified) => Promise<void>,\n ): Promise<Response> {\n const body = await this.readBody(request)\n if (body === null) return this.rejectBodyTooLarge()\n let verified: Verified | null\n try {\n verified = await this.verifier.verify(body, request.headers)\n } catch (cause) {\n if (cause instanceof WebhookVerificationError) return this.reject(cause)\n throw cause\n }\n if (verified !== null) await onVerified(verified)\n return new Response(null, { status: StatusCodes.OK })\n }\n\n private async readBody(request: Request): Promise<string | null> {\n const contentLength = request.headers.get('content-length')\n if (contentLength !== null && /^\\d+$/.test(contentLength)) {\n if (Number(contentLength) > this.maxBodyBytes) return null\n }\n if (request.body === null) return ''\n\n const reader = request.body.getReader()\n const decoder = new TextDecoder()\n let body = ''\n let byteCount = 0\n try {\n while (true) {\n const chunk = await reader.read()\n if (chunk.done) return body + decoder.decode()\n byteCount += chunk.value.byteLength\n if (byteCount > this.maxBodyBytes) {\n try {\n await reader.cancel()\n } catch {\n // A cancellation failure must not replace the body-size rejection.\n }\n return null\n }\n body += decoder.decode(chunk.value, { stream: true })\n }\n } finally {\n reader.releaseLock()\n }\n }\n\n private rejectBodyTooLarge(): Response {\n this.logger.warn('webhook_rejected', { reason: 'body_too_large' })\n return new Response(null, { status: StatusCodes.REQUEST_TOO_LONG })\n }\n\n private reject(error: WebhookVerificationError): Response {\n this.logger.warn('webhook_rejected', { reason: error.reason })\n const status =\n error.reason === 'missing_headers' || error.reason === 'invalid_signature'\n ? StatusCodes.UNAUTHORIZED\n : StatusCodes.BAD_REQUEST\n return new Response(null, { status })\n }\n}\n"],"mappings":";;;;;;AAaA,IAAa,iBAAb,MAAsC;CAMjB;CALnB,AAAiB;CACjB,AAAiB;;CAGjB,YACE,AAAiB,UACjB,SACA;EAFiB;EAGjB,KAAK,SAAS,QAAQ,UAAU,aAAa,SAAS;EACtD,KAAK,eAAe,QAAQ;CAC9B;;;;;CAMA,MAAM,OACJ,SACA,YACmB;EACnB,MAAM,OAAO,MAAM,KAAK,SAAS,OAAO;EACxC,IAAI,SAAS,MAAM,OAAO,KAAK,mBAAmB;EAClD,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,KAAK,SAAS,OAAO,MAAM,QAAQ,OAAO;EAC7D,SAAS,OAAO;GACd,IAAI,iBAAiB,0BAA0B,OAAO,KAAK,OAAO,KAAK;GACvE,MAAM;EACR;EACA,IAAI,aAAa,MAAM,MAAM,WAAW,QAAQ;EAChD,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,YAAY,GAAG,CAAC;CACtD;CAEA,MAAc,SAAS,SAA0C;EAC/D,MAAM,gBAAgB,QAAQ,QAAQ,IAAI,gBAAgB;EAC1D,IAAI,kBAAkB,QAAQ,QAAQ,KAAK,aAAa,GACtD;OAAI,OAAO,aAAa,IAAI,KAAK,cAAc,OAAO;EAAG;EAE3D,IAAI,QAAQ,SAAS,MAAM,OAAO;EAElC,MAAM,SAAS,QAAQ,KAAK,UAAU;EACtC,MAAM,UAAU,IAAI,YAAY;EAChC,IAAI,OAAO;EACX,IAAI,YAAY;EAChB,IAAI;GACF,OAAO,MAAM;IACX,MAAM,QAAQ,MAAM,OAAO,KAAK;IAChC,IAAI,MAAM,MAAM,OAAO,OAAO,QAAQ,OAAO;IAC7C,aAAa,MAAM,MAAM;IACzB,IAAI,YAAY,KAAK,cAAc;KACjC,IAAI;MACF,MAAM,OAAO,OAAO;KACtB,QAAQ,CAER;KACA,OAAO;IACT;IACA,QAAQ,QAAQ,OAAO,MAAM,OAAO,EAAE,QAAQ,KAAK,CAAC;GACtD;EACF,UAAU;GACR,OAAO,YAAY;EACrB;CACF;CAEA,AAAQ,qBAA+B;EACrC,KAAK,OAAO,KAAK,oBAAoB,EAAE,QAAQ,iBAAiB,CAAC;EACjE,OAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,YAAY,iBAAiB,CAAC;CACpE;CAEA,AAAQ,OAAO,OAA2C;EACxD,KAAK,OAAO,KAAK,oBAAoB,EAAE,QAAQ,MAAM,OAAO,CAAC;EAC7D,MAAM,SACJ,MAAM,WAAW,qBAAqB,MAAM,WAAW,sBACnD,YAAY,eACZ,YAAY;EAClB,OAAO,IAAI,SAAS,MAAM,EAAE,OAAO,CAAC;CACtC;AACF"}
@@ -1,4 +1,4 @@
1
- import { $t as AppError, J as DomainMessage, Jt as AnalyticsEventIdentity, K as DomainCommand, Mt as RecordEmailEventPayload, Pt as BounceType, Vt as EmailIdempotencyKey, Wt as EmailAddress, X as MessageId, Xt as AnalyticsProperties, Y as DomainQuery, Yt as AnalyticsEventInput, q as DomainEvent } from "./index-DvJUcSW1.js";
1
+ import { G as DomainMessage, Gt as AnalyticsEventIdentity, K as DomainQuery, Kt as AnalyticsEventInput, Rt as EmailIdempotencyKey, U as DomainCommand, Vt as EmailAddress, W as DomainEvent, Xt as AppError, jt as BounceType, kt as RecordEmailEventPayload, q as MessageId, qt as AnalyticsProperties } from "./index-DUFS0SJ_.js";
2
2
  //#region src/application/handlers.d.ts
3
3
  /**
4
4
  * Handles one command with the dependency container and returns the caller's value.
@@ -392,4 +392,4 @@ declare class UnitOfWorkAlreadyActiveError extends AppError {
392
392
  }
393
393
  //#endregion
394
394
  export { EventHandler as $, IOutboxRepository as A, OutboundEmail as B, UnitOfWorkDeps as C, OutboxRelay as D, IOutboxRelay as E, IEventCollector as F, MetricAttributeValue as G, ObservabilityScope as H, EmailAccepted as I, MetricsService as J, MetricAttributes as K, EmailAttachment as L, OutboxClaim as M, OutboxMessage as N, OutboxRelayOptions as O, IMessageStore as P, CommandHandler as Q, IEmailService as R, UnitOfWork as S, IOutboxPublisher as T, ObservabilityService as U, RecordingEmailService as V, ObservabilityUser as W, AnalyticsService as X, NULL_METRICS_SERVICE as Y, NULL_ANALYTICS as Z, RecordEmailEventCommand as _, OutboxRetentionResult as a, recordEmailEvent as b, CommandRegistry as c, MessageRegistry as d, QueryHandler as et, MessageResult as f, IEmailDeliverabilityStore as g, EmailBounceRecord as h, OutboxRetentionOptions as i, IOutboxRetentionRepository as j, DeadLetterReason as k, EventRegistry as l, RegistryMessage as m, MessageAlreadyProcessedError as n, IMessageBus as o, QueryRegistry as p, MetricOptions as q, OutboxRetention as r, MessageBus as s, UnitOfWorkAlreadyActiveError as t, Handlers as u, RecordEmailEventDeps as v, ITransaction as w, IUnitOfWork as x, RecordEmailEventRepos as y, MimeType as z };
395
- //# sourceMappingURL=index-Cchdg2aQ.d.ts.map
395
+ //# sourceMappingURL=index-CYHXOH08.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-Cchdg2aQ.d.ts","names":[],"sources":["../src/application/handlers.ts","../src/application/analytics-service.ts","../src/application/metrics-service.ts","../src/application/observability-service.ts","../src/application/email-service.ts","../src/application/event-collector.ts","../src/application/message-store.ts","../src/application/outbox-repository.ts","../src/application/outbox-relay.ts","../src/application/transaction.ts","../src/application/unit-of-work.ts","../src/application/record-email-event.ts","../src/application/registry.ts","../src/application/message-bus.ts","../src/application/outbox-retention.ts","../src/application/message-already-processed.error.ts","../src/application/unit-of-work.errors.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index-CYHXOH08.d.ts","names":[],"sources":["../src/application/handlers.ts","../src/application/analytics-service.ts","../src/application/metrics-service.ts","../src/application/observability-service.ts","../src/application/email-service.ts","../src/application/event-collector.ts","../src/application/message-store.ts","../src/application/outbox-repository.ts","../src/application/outbox-relay.ts","../src/application/transaction.ts","../src/application/unit-of-work.ts","../src/application/record-email-event.ts","../src/application/registry.ts","../src/application/message-bus.ts","../src/application/outbox-retention.ts","../src/application/message-already-processed.error.ts","../src/application/unit-of-work.errors.ts"],"mappings":"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"}
@@ -678,24 +678,18 @@ declare function exponentialEqualJitterMs(baseDelayMs: number, maxDelayMs: numbe
678
678
  /** Capped exponential delay for a durable retry recorded in storage. */
679
679
  declare function exponentialDelayCapMs(baseDelayMs: number, maxDelayMs: number, attempt: number): number;
680
680
  //#endregion
681
+ //#region src/core/console-log-sink.d.ts
682
+ /** Write one structured record or one readable development entry to `console`. */
683
+ declare const consoleSink: LogSink;
684
+ //#endregion
681
685
  //#region src/core/logger.d.ts
682
- /**
683
- * Module-scoped logging for every host.
684
- *
685
- * A logger emits one plain-data entry per log. The default sink hands it to `console` as an
686
- * entry object for a log service or as a colored line for a person, selected at startup.
687
- */
688
- /** A value a log entry may carry. Errors enter only through `Logger.error`. */
689
- type LogValue = string | number | boolean | null | undefined | ReadonlyArray<LogValue> | LogFields;
690
- /** Named log values. */
691
- type LogFields = {
686
+ /** One JSON-compatible value in a normal log field. */
687
+ type LogValue = string | number | boolean | null | readonly LogValue[] | {
692
688
  readonly [key: string]: LogValue;
693
689
  };
694
- /**
695
- * The supported log severity levels, in ascending order.
696
- *
697
- * A const object, not an enum, so a parsed environment value typed `'INFO'` is a `LogLevel`.
698
- */
690
+ /** Flat fields for one log call. Only `error` can contain an arbitrary value. */
691
+ type LogFields = Readonly<Record<string, unknown>>;
692
+ /** Supported log levels in ascending order. */
699
693
  declare const LogLevel: {
700
694
  readonly DEBUG: 'DEBUG';
701
695
  readonly INFO: 'INFO';
@@ -703,105 +697,50 @@ declare const LogLevel: {
703
697
  readonly ERROR: 'ERROR';
704
698
  };
705
699
  type LogLevel = (typeof LogLevel)[keyof typeof LogLevel];
706
- /** An error as plain data, including diagnostics, causes, and aggregate members. */
707
- type SerializedError = {
708
- readonly name: string;
709
- readonly message: string;
710
- readonly stack?: string;
711
- readonly fields?: LogFields;
712
- readonly cause?: SerializedError;
713
- readonly errors?: ReadonlyArray<SerializedError>;
714
- };
715
- /** One log, as the sink receives it. Plain data, safe to stringify. */
700
+ /** The minimum emitted level, or `OFF` for no console output. */
701
+ type LogThreshold = LogLevel | 'OFF';
702
+ /** Explicit output formats for production, browser development, and terminal development. */
703
+ type LogFormat = 'json' | 'pretty-browser' | 'pretty-terminal';
704
+ /** Process-wide logger settings supplied at startup. */
705
+ interface LoggerSettings {
706
+ readonly level?: LogThreshold;
707
+ readonly format?: LogFormat;
708
+ }
709
+ /** One structured record sent to a log sink. */
716
710
  type LogEntry = {
717
711
  readonly timestamp: string;
718
712
  readonly level: LogLevel;
719
713
  readonly module: string;
720
- readonly message: string;
721
- readonly details: LogFields;
714
+ readonly event: string;
715
+ readonly attributes: LogFields;
722
716
  readonly userId?: string;
723
- /** Present on `Logger.error` entries that carried an error. */
724
- readonly error?: SerializedError;
725
- };
726
- /** The context an error log carries. */
727
- type ErrorLogContext = {
728
717
  readonly error?: unknown;
729
- readonly userId?: string;
730
- readonly details?: LogFields;
731
718
  };
732
- /** What a logger lets through: a level and everything above it, or nothing. */
733
- type LogThreshold = LogLevel | 'OFF';
734
- /** Overrides the application settings for one logger. */
735
- interface LoggerConfig {
736
- readonly level?: LogThreshold;
737
- }
738
- /** `json` writes the entry object. `pretty` writes one readable line for a person. */
739
- type LogFormat = 'json' | 'pretty';
740
- /**
741
- * The application settings, set once at the composition root.
742
- *
743
- * An omitted field keeps its default. An explicit `undefined` is a compile error, so the root
744
- * parses an environment value before passing it. The logger reads no environment itself.
745
- */
746
- interface LoggerSettings extends LoggerConfig {
747
- readonly format?: LogFormat;
748
- }
749
- /**
750
- * Set application settings, including for existing loggers. Per-logger overrides take priority.
751
- * Call at startup, never per request. An omitted field resets to INFO and JSON output.
752
- */
753
- declare function configureLogger(config: LoggerSettings): void;
754
- /** The error data sent to the configured error hook. */
719
+ /** The original error and fields sent to an error service. */
755
720
  interface ErrorCaptureEntry {
756
721
  readonly error: unknown;
757
- readonly distinctId: string | undefined;
758
- readonly context: LogFields;
722
+ readonly userId: string | undefined;
723
+ readonly attributes: LogFields;
759
724
  }
760
- /** A function that forwards one logged error to an error service. */
725
+ /** A function that forwards one error to an error service. */
761
726
  type LoggerErrorHook = (entry: ErrorCaptureEntry) => void;
762
- /** Where every log entry goes. */
727
+ /** A destination for structured log records. */
763
728
  type LogSink = (entry: LogEntry) => void;
764
- /**
765
- * Register the function that receives each logged error.
766
- *
767
- * Set once at the process entry point. A later call replaces the earlier hook.
768
- */
769
- declare function setLoggerErrorHook(fn: LoggerErrorHook): void;
770
- /**
771
- * JSON format writes the entry object. Pretty format writes one line, then the details,
772
- * the error, and the stack as separate console arguments.
773
- */
774
- declare const consoleSink: LogSink;
775
- /**
776
- * Send every log entry somewhere other than `console`.
777
- *
778
- * Set once at the process entry point, never per module. A logger is created
779
- * by name and nothing else, so its destination is a fact about the process.
780
- */
781
- declare function setLogSink(fn: LogSink): void;
782
- /** Write module-scoped logs with application defaults and optional overrides. */
783
- declare class Logger {
784
- private readonly module;
785
- private readonly config;
786
- /** Create a logger for one module. */
787
- constructor(module: string, overrideConfig?: LoggerConfig);
788
- private log;
789
- /** Write a debug log. */
790
- debug(message: string, details?: LogFields): void;
791
- /** Write an information log. */
792
- info(message: string, details?: LogFields): void;
793
- /** Write a warning log. */
794
- warn(message: string, details?: LogFields): void;
795
- /**
796
- * Write an error log and send the error to the configured hook.
797
- *
798
- * The details say which call this was, and the error says what went wrong
799
- * inside it. Both the entry and the error hook receive the supplied user ID.
800
- */
801
- error(message: string, context?: ErrorLogContext): void;
729
+ /** The common flat logger API for all levels. */
730
+ interface Logger {
731
+ debug(event: string, fields?: LogFields): void;
732
+ info(event: string, fields?: LogFields): void;
733
+ warn(event: string, fields?: LogFields): void;
734
+ error(event: string, fields?: LogFields): void;
802
735
  }
736
+ /** Set the process-wide level and output format. Omitted fields restore production defaults. */
737
+ declare function configureLogger(settings: LoggerSettings): void;
738
+ /** Set the process-wide log destination. */
739
+ declare function setLogSink(sink: LogSink): void;
740
+ /** Set or clear the process-wide error service hook. */
741
+ declare function setLoggerErrorHook(hook: LoggerErrorHook | null): void;
803
742
  /** Create a logger for one module. */
804
- declare function createLogger(module: string, config?: LoggerConfig): Logger;
743
+ declare function createLogger(module: string): Logger;
805
744
  //#endregion
806
- export { IdOf as $, AppError as $t, isCloudflareRetryableError as A, RateLimitError as At, MessageDefinition as B, EmailServiceError as Bt, BoundaryErrorClassifier as C, ValidationProblemDetailsSchema as Ct, CLOUDFLARE_TRANSIENT_ERROR_PATTERNS as D, ServiceUnavailableError as Dt, retryAfterSecondsOf as E, InternalServerError as Et, EntityData as F, BounceTypeSchema as Ft, defineMessages as G, EmailAddressSchema as Gt, PayloadSchemas as H, InvalidEmailIdempotencyKeyError as Ht, CommandOf as I, isEmailDeliverable as It, DomainMessage as J, AnalyticsEventIdentity as Jt, DomainCommand as K, AnalyticsEventId as Kt, DuplicateMessageNameError as L, parseBounceType as Lt, isAbortError as M, RecordEmailEventPayload as Mt, isTransientTransportError as N, RecordEmailEventPayloadSchema as Nt, isCloudflareObjectResetError as O, NotAuthorizedError as Ot, Entity as P, BounceType as Pt, IdDefinition as Q, MissingConfigurationError as Qt, EventOf as R, shouldUpdateBounce as Rt, spreadJitterMs as S, ValidationProblemDetails as St, classifyFailure as T, ValidationProblemErrorSchema as Tt, QueryOf as U, emailIdempotencyKey as Ut, MessageOf as V, EmailIdempotencyKey as Vt, combineMessages as W, EmailAddress as Wt, MessageId as X, AnalyticsProperties as Xt, DomainQuery as Y, AnalyticsEventInput as Yt, Id as Z, AnalyticsProperty as Zt, createLogger as _, UpgradeRequiredError as _t, LogFormat as a, DatabaseFailure as at, exponentialDelayCapMs as b, ProblemDetails as bt, LogThreshold as c, ErrorPayloadOf as ct, LoggerConfig as d, ResolvedError as dt, FailureClassification as en, defineId as et, LoggerErrorHook as f, defineErrors as ft, consoleSink as g, ResourceNotFoundError as gt, configureLogger as h, RequestTimeoutError as ht, LogFields as i, DatabaseError as it, isTransientCloudflareRuntimeError as j, AuthenticationError as jt, isCloudflareOverloadedError as k, StaleSessionError as kt, LogValue as l, ErrorTable as lt, SerializedError as m, MalformedRequestError as mt, ErrorLogContext as n, shouldRetryFailure as nn, unreachable as nt, LogLevel as o, ErrorEntries as ot, LoggerSettings as p, sharedErrors as pt, DomainEvent as q, AnalyticsEventIdSchema as qt, LogEntry as r, D1ConstraintKind as rt, LogSink as s, ErrorEntry as st, ErrorCaptureEntry as t, RetryOwner as tn, notImplemented as tt, Logger as u, ErrorTagOf as ut, setLogSink as v, ValidationError as vt, classifyBoundaryError as w, ValidationProblemError as wt, exponentialEqualJitterMs as x, ProblemDetailsSchema as xt, setLoggerErrorHook as y, ValidationIssue as yt, MessageCollection as z, EmailSendFailureReason as zt };
807
- //# sourceMappingURL=index-DvJUcSW1.d.ts.map
745
+ export { unreachable as $, shouldRetryFailure as $t, isTransientTransportError as A, RecordEmailEventPayloadSchema as At, QueryOf as B, emailIdempotencyKey as Bt, retryAfterSecondsOf as C, InternalServerError as Ct, isCloudflareRetryableError as D, RateLimitError as Dt, isCloudflareOverloadedError as E, StaleSessionError as Et, EventOf as F, shouldUpdateBounce as Ft, DomainMessage as G, AnalyticsEventIdentity as Gt, defineMessages as H, EmailAddressSchema as Ht, MessageCollection as I, EmailSendFailureReason as It, Id as J, AnalyticsProperty as Jt, DomainQuery as K, AnalyticsEventInput as Kt, MessageDefinition as L, EmailServiceError as Lt, EntityData as M, BounceTypeSchema as Mt, CommandOf as N, isEmailDeliverable as Nt, isTransientCloudflareRuntimeError as O, AuthenticationError as Ot, DuplicateMessageNameError as P, parseBounceType as Pt, notImplemented as Q, RetryOwner as Qt, MessageOf as R, EmailIdempotencyKey as Rt, classifyFailure as S, ValidationProblemErrorSchema as St, isCloudflareObjectResetError as T, NotAuthorizedError as Tt, DomainCommand as U, AnalyticsEventId as Ut, combineMessages as V, EmailAddress as Vt, DomainEvent as W, AnalyticsEventIdSchema as Wt, IdOf as X, AppError as Xt, IdDefinition as Y, MissingConfigurationError as Yt, defineId as Z, FailureClassification as Zt, exponentialDelayCapMs as _, ProblemDetails as _t, LogLevel as a, ErrorPayloadOf as at, BoundaryErrorClassifier as b, ValidationProblemDetailsSchema as bt, LogValue as c, ResolvedError as ct, LoggerSettings as d, MalformedRequestError as dt, D1ConstraintKind as et, configureLogger as f, RequestTimeoutError as ft, consoleSink as g, ValidationIssue as gt, setLoggerErrorHook as h, ValidationError as ht, LogFormat as i, ErrorEntry as it, Entity as j, BounceType as jt, isAbortError as k, RecordEmailEventPayload as kt, Logger as l, defineErrors as lt, setLogSink as m, UpgradeRequiredError as mt, LogEntry as n, DatabaseFailure as nt, LogSink as o, ErrorTable as ot, createLogger as p, ResourceNotFoundError as pt, MessageId as q, AnalyticsProperties as qt, LogFields as r, ErrorEntries as rt, LogThreshold as s, ErrorTagOf as st, ErrorCaptureEntry as t, DatabaseError as tt, LoggerErrorHook as u, sharedErrors as ut, exponentialEqualJitterMs as v, ProblemDetailsSchema as vt, CLOUDFLARE_TRANSIENT_ERROR_PATTERNS as w, ServiceUnavailableError as wt, classifyBoundaryError as x, ValidationProblemError as xt, spreadJitterMs as y, ValidationProblemDetails as yt, PayloadSchemas as z, InvalidEmailIdempotencyKeyError as zt };
746
+ //# sourceMappingURL=index-DUFS0SJ_.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DUFS0SJ_.d.ts","names":[],"sources":["../src/core/failure-classification.ts","../src/core/app-error.ts","../src/core/missing-configuration.error.ts","../src/core/analytics-event.ts","../src/core/email-address.ts","../src/core/email-idempotency-key.ts","../src/core/email-service.error.ts","../src/core/email-deliverability.ts","../src/core/record-email-event.ts","../src/core/authentication.error.ts","../src/core/rate-limit.error.ts","../src/core/stale-session.error.ts","../src/core/not-authorized.error.ts","../src/core/internal.errors.ts","../src/core/problem-details.ts","../src/core/request.errors.ts","../src/core/error-table.ts","../src/core/database.error.ts","../src/core/defects.ts","../src/core/identity.ts","../src/core/messages.ts","../src/core/define-messages.ts","../src/core/entity.ts","../src/core/transport-classification.ts","../src/core/cloudflare-classification.ts","../src/core/classify-failure.ts","../src/core/backoff.ts","../src/core/console-log-sink.ts","../src/core/logger.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { t as UnitOfWorkAlreadyActiveError } from "./application-Cf9SER-i.js";
1
+ import { t as UnitOfWorkAlreadyActiveError } from "./application-Dg1jIKPe.js";
2
2
  import { panic } from "better-result";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
 
@@ -54,4 +54,4 @@ const OUTBOX_REPOSITORY_DEFAULTS = {
54
54
 
55
55
  //#endregion
56
56
  export { stageD1Statement as a, runWithUnitOfWorkContext as i, collectD1Statements as n, eventCollector as r, OUTBOX_REPOSITORY_DEFAULTS as t };
57
- //# sourceMappingURL=outbox-repository-options-ICOF8g2h.js.map
57
+ //# sourceMappingURL=outbox-repository-options-B8TnAE1h.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"outbox-repository-options-ICOF8g2h.js","names":[],"sources":["../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { panic } from 'better-result'\nimport type { BatchItem } from 'drizzle-orm/batch'\n\nimport { UnitOfWorkAlreadyActiveError, type IEventCollector } from '@/application'\nimport type { DomainEvent } from '@/core'\n\ntype UnitOfWorkContext = { readonly events: DomainEvent[] } & (\n | { readonly database: 'd1'; readonly statements: BatchItem<'sqlite'>[] }\n | { readonly database: 'postgres' }\n)\n\n// One async scope isolates events and D1 statements and rejects nesting across both adapters.\nconst storage = new AsyncLocalStorage<UnitOfWorkContext>()\n\n/** Reject nested transactions before database work starts; preserve independent concurrent execution. */\nexport async function runWithUnitOfWorkContext<T>(\n database: UnitOfWorkContext['database'],\n work: () => Promise<T>,\n): Promise<T> {\n if (storage.getStore() !== undefined) throw new UnitOfWorkAlreadyActiveError()\n const context: UnitOfWorkContext =\n database === 'd1' ? { database, events: [], statements: [] } : { database, events: [] }\n return storage.run(context, work)\n}\n\n/** Inject this shared scope into the unit of work and expose its emitter to application handlers. */\nexport const eventCollector: IEventCollector = {\n emit(event) {\n currentContext().events.push(event)\n },\n collect() {\n return [...currentContext().events]\n },\n}\n\n/** Queue one native D1 statement for the active batch; other contexts cannot accept D1 writes. */\nexport function stageD1Statement(statement: BatchItem<'sqlite'>): void {\n d1Context().statements.push(statement)\n}\n\n/** Read the active D1 batch in staging order for commit. */\nexport function collectD1Statements(): ReadonlyArray<BatchItem<'sqlite'>> {\n return [...d1Context().statements]\n}\n\nfunction d1Context(): Extract<UnitOfWorkContext, { database: 'd1' }> {\n const context = currentContext()\n if (context.database !== 'd1') return panic('D1 statements require a D1 unit of work')\n return context\n}\n\nfunction currentContext(): UnitOfWorkContext {\n return storage.getStore() ?? panic('operation requires an active unit of work')\n}\n","/** Shared lease and delay defaults for both database adapters. */\nexport const OUTBOX_REPOSITORY_DEFAULTS = {\n leaseMs: 60_000,\n retryBaseDelayMs: 1_000,\n retryMaxDelayMs: 60_000,\n}\n\n/** Override lease and delay limits at the composition root. */\nexport type OutboxRepositoryOptions = Readonly<Partial<typeof OUTBOX_REPOSITORY_DEFAULTS>>\n"],"mappings":";;;;;AAcA,MAAM,UAAU,IAAI,kBAAqC;;AAGzD,eAAsB,yBACpB,UACA,MACY;CACZ,IAAI,QAAQ,SAAS,MAAM,QAAW,MAAM,IAAI,6BAA6B;CAC7E,MAAM,UACJ,aAAa,OAAO;EAAE;EAAU,QAAQ,CAAC;EAAG,YAAY,CAAC;CAAE,IAAI;EAAE;EAAU,QAAQ,CAAC;CAAE;CACxF,OAAO,QAAQ,IAAI,SAAS,IAAI;AAClC;;AAGA,MAAa,iBAAkC;CAC7C,KAAK,OAAO;EACV,eAAe,CAAC,CAAC,OAAO,KAAK,KAAK;CACpC;CACA,UAAU;EACR,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC,MAAM;CACpC;AACF;;AAGA,SAAgB,iBAAiB,WAAsC;CACrE,UAAU,CAAC,CAAC,WAAW,KAAK,SAAS;AACvC;;AAGA,SAAgB,sBAA0D;CACxE,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,UAAU;AACnC;AAEA,SAAS,YAA4D;CACnE,MAAM,UAAU,eAAe;CAC/B,IAAI,QAAQ,aAAa,MAAM,OAAO,MAAM,yCAAyC;CACrF,OAAO;AACT;AAEA,SAAS,iBAAoC;CAC3C,OAAO,QAAQ,SAAS,KAAK,MAAM,2CAA2C;AAChF;;;;;ACtDA,MAAa,6BAA6B;CACxC,SAAS;CACT,kBAAkB;CAClB,iBAAiB;AACnB"}
1
+ {"version":3,"file":"outbox-repository-options-B8TnAE1h.js","names":[],"sources":["../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { panic } from 'better-result'\nimport type { BatchItem } from 'drizzle-orm/batch'\n\nimport { UnitOfWorkAlreadyActiveError, type IEventCollector } from '@/application'\nimport type { DomainEvent } from '@/core'\n\ntype UnitOfWorkContext = { readonly events: DomainEvent[] } & (\n | { readonly database: 'd1'; readonly statements: BatchItem<'sqlite'>[] }\n | { readonly database: 'postgres' }\n)\n\n// One async scope isolates events and D1 statements and rejects nesting across both adapters.\nconst storage = new AsyncLocalStorage<UnitOfWorkContext>()\n\n/** Reject nested transactions before database work starts; preserve independent concurrent execution. */\nexport async function runWithUnitOfWorkContext<T>(\n database: UnitOfWorkContext['database'],\n work: () => Promise<T>,\n): Promise<T> {\n if (storage.getStore() !== undefined) throw new UnitOfWorkAlreadyActiveError()\n const context: UnitOfWorkContext =\n database === 'd1' ? { database, events: [], statements: [] } : { database, events: [] }\n return storage.run(context, work)\n}\n\n/** Inject this shared scope into the unit of work and expose its emitter to application handlers. */\nexport const eventCollector: IEventCollector = {\n emit(event) {\n currentContext().events.push(event)\n },\n collect() {\n return [...currentContext().events]\n },\n}\n\n/** Queue one native D1 statement for the active batch; other contexts cannot accept D1 writes. */\nexport function stageD1Statement(statement: BatchItem<'sqlite'>): void {\n d1Context().statements.push(statement)\n}\n\n/** Read the active D1 batch in staging order for commit. */\nexport function collectD1Statements(): ReadonlyArray<BatchItem<'sqlite'>> {\n return [...d1Context().statements]\n}\n\nfunction d1Context(): Extract<UnitOfWorkContext, { database: 'd1' }> {\n const context = currentContext()\n if (context.database !== 'd1') return panic('D1 statements require a D1 unit of work')\n return context\n}\n\nfunction currentContext(): UnitOfWorkContext {\n return storage.getStore() ?? panic('operation requires an active unit of work')\n}\n","/** Shared lease and delay defaults for both database adapters. */\nexport const OUTBOX_REPOSITORY_DEFAULTS = {\n leaseMs: 60_000,\n retryBaseDelayMs: 1_000,\n retryMaxDelayMs: 60_000,\n}\n\n/** Override lease and delay limits at the composition root. */\nexport type OutboxRepositoryOptions = Readonly<Partial<typeof OUTBOX_REPOSITORY_DEFAULTS>>\n"],"mappings":";;;;;AAcA,MAAM,UAAU,IAAI,kBAAqC;;AAGzD,eAAsB,yBACpB,UACA,MACY;CACZ,IAAI,QAAQ,SAAS,MAAM,QAAW,MAAM,IAAI,6BAA6B;CAC7E,MAAM,UACJ,aAAa,OAAO;EAAE;EAAU,QAAQ,CAAC;EAAG,YAAY,CAAC;CAAE,IAAI;EAAE;EAAU,QAAQ,CAAC;CAAE;CACxF,OAAO,QAAQ,IAAI,SAAS,IAAI;AAClC;;AAGA,MAAa,iBAAkC;CAC7C,KAAK,OAAO;EACV,eAAe,CAAC,CAAC,OAAO,KAAK,KAAK;CACpC;CACA,UAAU;EACR,OAAO,CAAC,GAAG,eAAe,CAAC,CAAC,MAAM;CACpC;AACF;;AAGA,SAAgB,iBAAiB,WAAsC;CACrE,UAAU,CAAC,CAAC,WAAW,KAAK,SAAS;AACvC;;AAGA,SAAgB,sBAA0D;CACxE,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC,UAAU;AACnC;AAEA,SAAS,YAA4D;CACnE,MAAM,UAAU,eAAe;CAC/B,IAAI,QAAQ,aAAa,MAAM,OAAO,MAAM,yCAAyC;CACrF,OAAO;AACT;AAEA,SAAS,iBAAoC;CAC3C,OAAO,QAAQ,SAAS,KAAK,MAAM,2CAA2C;AAChF;;;;;ACtDA,MAAa,6BAA6B;CACxC,SAAS;CACT,kBAAkB;CAClB,iBAAiB;AACnB"}
@@ -1,5 +1,5 @@
1
- import "./index-DvJUcSW1.js";
2
- import { F as IEventCollector } from "./index-Cchdg2aQ.js";
1
+ import "./index-DUFS0SJ_.js";
2
+ import { F as IEventCollector } from "./index-CYHXOH08.js";
3
3
  import { BatchItem } from "drizzle-orm/batch";
4
4
  //#region src/infrastructure/drizzle-schema.d.ts
5
5
  /**
@@ -23,4 +23,4 @@ declare const OUTBOX_REPOSITORY_DEFAULTS: {
23
23
  type OutboxRepositoryOptions = Readonly<Partial<typeof OUTBOX_REPOSITORY_DEFAULTS>>;
24
24
  //#endregion
25
25
  export { eventCollector as n, DrizzleSchema as r, OutboxRepositoryOptions as t };
26
- //# sourceMappingURL=outbox-repository-options-AkihEaik.d.ts.map
26
+ //# sourceMappingURL=outbox-repository-options-DjBgFhMi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"outbox-repository-options-AkihEaik.d.ts","names":[],"sources":["../src/infrastructure/drizzle-schema.ts","../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"mappings":";;;;;;;;KAKY,gBAAgB;;;;cCuBf,gBAAgB;;;;cC3BhB;EACX;EACA;EACA;;;KAIU,0BAA0B,SAAS,eAAe"}
1
+ {"version":3,"file":"outbox-repository-options-DjBgFhMi.d.ts","names":[],"sources":["../src/infrastructure/drizzle-schema.ts","../src/infrastructure/unit-of-work-context.ts","../src/infrastructure/outbox-repository-options.ts"],"mappings":";;;;;;;;KAKY,gBAAgB;;;;cCuBf,gBAAgB;;;;cC3BhB;EACX;EACA;EACA;;;KAIU,0BAA0B,SAAS,eAAe"}
@@ -1,6 +1,6 @@
1
- import { X as MessageId, at as DatabaseFailure, it as DatabaseError, q as DomainEvent } from "./index-DvJUcSW1.js";
2
- import { A as IOutboxRepository, M as OutboxClaim, N as OutboxMessage, P as IMessageStore, k as DeadLetterReason, w as ITransaction } from "./index-Cchdg2aQ.js";
3
- import { n as eventCollector, r as DrizzleSchema, t as OutboxRepositoryOptions } from "./outbox-repository-options-AkihEaik.js";
1
+ import { W as DomainEvent, nt as DatabaseFailure, q as MessageId, tt as DatabaseError } from "./index-DUFS0SJ_.js";
2
+ import { A as IOutboxRepository, M as OutboxClaim, N as OutboxMessage, P as IMessageStore, k as DeadLetterReason, w as ITransaction } from "./index-CYHXOH08.js";
3
+ import { n as eventCollector, r as DrizzleSchema, t as OutboxRepositoryOptions } from "./outbox-repository-options-DjBgFhMi.js";
4
4
  import { ExtractTablesWithRelations } from "drizzle-orm";
5
5
  import { PostgresJsDatabase, PostgresJsTransaction, drizzle } from "drizzle-orm/postgres-js";
6
6
  //#region src/infrastructure/postgres/postgres-database-types.d.ts
package/dist/postgres.js CHANGED
@@ -1,6 +1,6 @@
1
- import { c as exponentialDelayCapMs, k as DatabaseError, rt as AppError } from "./core-ClSP5-V9.js";
2
- import { o as MessageAlreadyProcessedError } from "./application-Cf9SER-i.js";
3
- import { i as runWithUnitOfWorkContext, r as eventCollector, t as OUTBOX_REPOSITORY_DEFAULTS } from "./outbox-repository-options-ICOF8g2h.js";
1
+ import { O as DatabaseError, nt as AppError, s as exponentialDelayCapMs } from "./core-BT1dSEQI.js";
2
+ import { o as MessageAlreadyProcessedError } from "./application-Dg1jIKPe.js";
3
+ import { i as runWithUnitOfWorkContext, r as eventCollector, t as OUTBOX_REPOSITORY_DEFAULTS } from "./outbox-repository-options-B8TnAE1h.js";
4
4
  import { Result } from "better-result";
5
5
  import { DrizzleQueryError } from "drizzle-orm/errors";
6
6
  import { and, asc, eq, inArray, isNull, lt, lte, or, sql } from "drizzle-orm";
@@ -1,4 +1,4 @@
1
- import { J as MetricsService, q as MetricOptions } from "../index-Cchdg2aQ.js";
1
+ import { J as MetricsService, q as MetricOptions } from "../index-CYHXOH08.js";
2
2
  import { PostHog } from "posthog-node";
3
3
  //#region src/infrastructure/posthog/metrics.d.ts
4
4
  /** PostHog Metrics with Worker lifetime management, ported from Typist's metrics-service.ts. */
@@ -1,5 +1,5 @@
1
- import { Jt as AnalyticsEventIdentity, Xt as AnalyticsProperties, Yt as AnalyticsEventInput } from "../index-DvJUcSW1.js";
2
- import { X as AnalyticsService } from "../index-Cchdg2aQ.js";
1
+ import { Gt as AnalyticsEventIdentity, Kt as AnalyticsEventInput, qt as AnalyticsProperties } from "../index-DUFS0SJ_.js";
2
+ import { X as AnalyticsService } from "../index-CYHXOH08.js";
3
3
  import { PostHogMetricsService } from "./metrics.js";
4
4
  import { PostHog, PostHogOptions } from "posthog-node";
5
5
  //#region src/infrastructure/posthog/server.d.ts
@@ -1,4 +1,4 @@
1
- import { nt as MissingConfigurationError } from "../core-ClSP5-V9.js";
1
+ import { tt as MissingConfigurationError } from "../core-BT1dSEQI.js";
2
2
  import { PostHogMetricsService } from "./metrics.js";
3
3
  import { PostHog } from "posthog-node";
4
4
 
package/dist/resend.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { Pt as BounceType } from "./index-DvJUcSW1.js";
2
- import { B as OutboundEmail, I as EmailAccepted, R as IEmailService } from "./index-Cchdg2aQ.js";
3
- import { r as WebhookVerifier, t as WebhookVerification } from "./webhook-verification-BcQQG-vY.js";
1
+ import { jt as BounceType } from "./index-DUFS0SJ_.js";
2
+ import { B as OutboundEmail, I as EmailAccepted, R as IEmailService } from "./index-CYHXOH08.js";
3
+ import { n as WebhookVerifier } from "./webhook-verification-D1c7BY4q.js";
4
4
  import { Resend } from "resend";
5
5
  //#region src/infrastructure/resend/resend-email-service.d.ts
6
6
  /** The SDK operations required by the adapter; a test factory can return a plain object. */
@@ -65,8 +65,8 @@ export declare class ResendWebhook implements WebhookVerifier<EmailEvent> {
65
65
  private client;
66
66
  /** Inject the local SDK verifier when testing. */
67
67
  constructor(webhookSecret: string, verifier: () => Promise<ResendWebhookClient>);
68
- /** Verify the raw body and Svix headers. Invalid requests return rejected; configuration and SDK defects propagate. */
69
- verify(body: string, headers: Headers): Promise<WebhookVerification<EmailEvent>>;
68
+ /** Verify the raw body and Svix headers. Invalid requests throw typed errors; other failures propagate. */
69
+ verify(body: string, headers: Headers): Promise<EmailEvent | null>;
70
70
  }
71
71
  //#endregion
72
72
  export type { EmailEvent, EmailEventType, ResendEmailClient, ResendWebhookClient };
@@ -1 +1 @@
1
- {"version":3,"file":"resend.d.ts","names":[],"sources":["../src/infrastructure/resend/resend-email-service.ts","../src/infrastructure/resend/email-event.ts","../src/infrastructure/resend/resend-webhook.ts"],"mappings":";;;;;;KAsEY;WAA+B,QAAQ,KAAK;;;;;;qBAM3C,8BAA8B;mBAatB;mBACA;;SAZZ,OAAO,gBAAgB,sBAAsB;UAO5C;;EAGR,YACmB,oBAAoB,QAAQ,oBAC5B;;EAIb,UAAU,OAAO,gBAAgB,QAAQ;;;;cCzF3C;;KAYM,yBACA;KAgDP;WACM;WACA;WACA;WACA;WACA,MAAM,SAAS;WACf;;;KAIC,cACP;WACU;WACA;aACE,MAAM;aACN;aACA;;MAGZ;WAA4B;WAA+B;MAC3D;WAA4B;WAAgC;MAC5D;WAA4B,cAAc;;;;;KCvEnC,sBAAsB,KAAK;;qBAG1B,yBAAyB,gBAAgB;mBAcjC;mBACA;;SAbZ,OAAO,wBAAwB;UAQ9B;;EAGR,YACmB,uBACA,gBAAgB,QAAQ;;EAIrC,OAAO,cAAc,SAAS,UAAU,QAAQ,oBAAoB"}
1
+ {"version":3,"file":"resend.d.ts","names":[],"sources":["../src/infrastructure/resend/resend-email-service.ts","../src/infrastructure/resend/email-event.ts","../src/infrastructure/resend/resend-webhook.ts"],"mappings":";;;;;;KAsEY;WAA+B,QAAQ,KAAK;;;;;;qBAM3C,8BAA8B;mBAatB;mBACA;;SAZZ,OAAO,gBAAgB,sBAAsB;UAO5C;;EAGR,YACmB,oBAAoB,QAAQ,oBAC5B;;EAIb,UAAU,OAAO,gBAAgB,QAAQ;;;;cCzF3C;;KAYM,yBACA;KAgDP;WACM;WACA;WACA;WACA;WACA,MAAM,SAAS;WACf;;;KAIC,cACP;WACU;WACA;aACE,MAAM;aACN;aACA;;MAGZ;WAA4B;WAA+B;MAC3D;WAA4B;WAAgC;MAC5D;WAA4B,cAAc;;;;;KC3EnC,sBAAsB,KAAK;;qBAG1B,yBAAyB,gBAAgB;mBAcjC;mBACA;;SAbZ,OAAO,wBAAwB;UAQ9B;;EAGR,YACmB,uBACA,gBAAgB,QAAQ;;EAIrC,OAAO,cAAc,SAAS,UAAU,QAAQ"}
package/dist/resend.js CHANGED
@@ -1,5 +1,5 @@
1
- import { Y as parseBounceType, Z as EmailServiceError, et as EmailAddressSchema } from "./core-ClSP5-V9.js";
2
- import { t as WebhookVerificationError } from "./webhook-verification-D6aGQfNi.js";
1
+ import { $ as EmailAddressSchema, J as parseBounceType, X as EmailServiceError } from "./core-BT1dSEQI.js";
2
+ import { t as WebhookVerificationError } from "./webhook-verification-qSFXv5H3.js";
3
3
  import { z } from "zod";
4
4
  import { Buffer } from "node:buffer";
5
5
 
@@ -162,58 +162,40 @@ const EventHeaderSchema = z.object({
162
162
  });
163
163
  /** Validate signed provider data before projecting it into the public event contract. */
164
164
  function parseEmailEvent(payload, id) {
165
- const header = EventHeaderSchema.safeParse(payload);
166
- if (!header.success) return { outcome: "invalid" };
167
- if (!Object.hasOwn(EMAIL_TYPES, header.data.type)) return {
168
- outcome: "ignored",
169
- type: header.data.type
170
- };
171
- const parsed = EmailPayloadSchema.safeParse(payload);
172
- if (!parsed.success) return { outcome: "invalid" };
173
- const event = parsed.data;
165
+ const header = EventHeaderSchema.parse(payload);
166
+ if (!Object.hasOwn(EMAIL_TYPES, header.type)) return null;
167
+ const event = EmailPayloadSchema.parse(payload);
174
168
  const base = {
175
169
  id,
176
170
  emailId: event.data.email_id,
177
171
  recipients: event.data.to,
178
172
  subject: event.data.subject,
179
173
  tags: event.data.tags,
180
- occurredAt: header.data.created_at
174
+ occurredAt: header.created_at
181
175
  };
182
176
  switch (event.type) {
183
177
  case "email.bounced": return {
184
- outcome: "event",
185
- event: {
186
- ...base,
187
- type: event.type,
188
- bounce: {
189
- type: parseBounceType(event.data.bounce.type),
190
- subType: event.data.bounce.subType ?? null,
191
- message: event.data.bounce.message
192
- }
178
+ ...base,
179
+ type: event.type,
180
+ bounce: {
181
+ type: parseBounceType(event.data.bounce.type),
182
+ subType: event.data.bounce.subType ?? null,
183
+ message: event.data.bounce.message
193
184
  }
194
185
  };
195
186
  case "email.failed": return {
196
- outcome: "event",
197
- event: {
198
- ...base,
199
- type: event.type,
200
- reason: event.data.failed.reason
201
- }
187
+ ...base,
188
+ type: event.type,
189
+ reason: event.data.failed.reason
202
190
  };
203
191
  case "email.clicked": return {
204
- outcome: "event",
205
- event: {
206
- ...base,
207
- type: event.type,
208
- link: event.data.click.link
209
- }
192
+ ...base,
193
+ type: event.type,
194
+ link: event.data.click.link
210
195
  };
211
196
  default: return {
212
- outcome: "event",
213
- event: {
214
- ...base,
215
- type: event.type
216
- }
197
+ ...base,
198
+ type: event.type
217
199
  };
218
200
  }
219
201
  }
@@ -238,15 +220,12 @@ var ResendWebhook = class ResendWebhook {
238
220
  this.webhookSecret = webhookSecret;
239
221
  this.verifier = verifier;
240
222
  }
241
- /** Verify the raw body and Svix headers. Invalid requests return rejected; configuration and SDK defects propagate. */
223
+ /** Verify the raw body and Svix headers. Invalid requests throw typed errors; other failures propagate. */
242
224
  async verify(body, headers) {
243
225
  const id = headers.get("svix-id");
244
226
  const timestamp = headers.get("svix-timestamp");
245
227
  const signature = headers.get("svix-signature");
246
- if (!id || !timestamp || !signature) return {
247
- outcome: "rejected",
248
- error: new WebhookVerificationError("missing_headers")
249
- };
228
+ if (!id || !timestamp || !signature) throw new WebhookVerificationError("missing_headers");
250
229
  const client = await (this.client ??= this.verifier());
251
230
  let payload;
252
231
  try {
@@ -260,22 +239,16 @@ var ResendWebhook = class ResendWebhook {
260
239
  webhookSecret: this.webhookSecret
261
240
  });
262
241
  } catch (cause) {
263
- if (cause instanceof SyntaxError) return {
264
- outcome: "rejected",
265
- error: new WebhookVerificationError("invalid_payload", cause)
266
- };
242
+ if (cause instanceof SyntaxError) throw new WebhookVerificationError("invalid_payload", cause);
267
243
  if (!SignatureErrorSchema.safeParse(cause).success) throw cause;
268
- return {
269
- outcome: "rejected",
270
- error: new WebhookVerificationError("invalid_signature", cause)
271
- };
244
+ throw new WebhookVerificationError("invalid_signature", cause);
245
+ }
246
+ try {
247
+ return parseEmailEvent(payload, id);
248
+ } catch (cause) {
249
+ if (cause instanceof z.ZodError) throw new WebhookVerificationError("invalid_payload", cause);
250
+ throw cause;
272
251
  }
273
- const result = parseEmailEvent(payload, id);
274
- if (result.outcome === "invalid") return {
275
- outcome: "rejected",
276
- error: new WebhookVerificationError("invalid_payload")
277
- };
278
- return result;
279
252
  }
280
253
  };
281
254