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.
- package/dist/{application-Cf9SER-i.js → application-Dg1jIKPe.js} +5 -7
- package/dist/{application-Cf9SER-i.js.map → application-Dg1jIKPe.js.map} +1 -1
- package/dist/application.d.ts +2 -2
- package/dist/application.js +1 -1
- package/dist/better-auth/apple-client-secret.d.ts +1 -1
- package/dist/better-auth/apple-client-secret.js +2 -2
- package/dist/better-auth/apple-client-secret.js.map +1 -1
- package/dist/better-auth/auth-client.js +1 -1
- package/dist/better-auth/rate-limit.d.ts +1 -1
- package/dist/better-auth/rate-limit.js +4 -6
- package/dist/better-auth/rate-limit.js.map +1 -1
- package/dist/better-auth.js +1 -1
- package/dist/billing/client.d.ts +86 -0
- package/dist/billing/client.d.ts.map +1 -0
- package/dist/billing/client.js +77 -0
- package/dist/billing/client.js.map +1 -0
- package/dist/cloudflare/auth-secondary-storage.d.ts +1 -1
- package/dist/cloudflare/auth-secondary-storage.js +1 -1
- package/dist/cloudflare/durable-object-client.js +1 -1
- package/dist/cloudflare/durable-object-errors.d.ts +1 -1
- package/dist/cloudflare/durable-object-errors.js +1 -1
- package/dist/cloudflare/kv-client.js +1 -1
- package/dist/cloudflare/kv-errors.d.ts +1 -1
- package/dist/cloudflare/kv-errors.js +1 -1
- package/dist/cloudflare/queue.d.ts +2 -2
- package/dist/cloudflare/queue.d.ts.map +1 -1
- package/dist/cloudflare/queue.js +10 -12
- package/dist/cloudflare/queue.js.map +1 -1
- package/dist/cloudflare/r2-client.d.ts +70 -0
- package/dist/cloudflare/r2-client.d.ts.map +1 -0
- package/dist/cloudflare/r2-client.js +153 -0
- package/dist/cloudflare/r2-client.js.map +1 -0
- package/dist/cloudflare/r2-errors.d.ts +34 -0
- package/dist/cloudflare/r2-errors.d.ts.map +1 -0
- package/dist/cloudflare/r2-errors.js +90 -0
- package/dist/cloudflare/r2-errors.js.map +1 -0
- package/dist/cloudflare/scheduled.d.ts +1 -1
- package/dist/cloudflare/scheduled.js +2 -2
- package/dist/cloudflare/scheduled.js.map +1 -1
- package/dist/cloudflare.d.ts +3 -3
- package/dist/cloudflare.js +3 -3
- package/dist/{core-ClSP5-V9.js → core-BT1dSEQI.js} +106 -195
- package/dist/core-BT1dSEQI.js.map +1 -0
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/http.d.ts +16 -8
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +51 -12
- package/dist/http.js.map +1 -1
- package/dist/{index-Cchdg2aQ.d.ts → index-CYHXOH08.d.ts} +2 -2
- package/dist/{index-Cchdg2aQ.d.ts.map → index-CYHXOH08.d.ts.map} +1 -1
- package/dist/{index-DvJUcSW1.d.ts → index-DUFS0SJ_.d.ts} +41 -102
- package/dist/index-DUFS0SJ_.d.ts.map +1 -0
- package/dist/{outbox-repository-options-ICOF8g2h.js → outbox-repository-options-B8TnAE1h.js} +2 -2
- package/dist/{outbox-repository-options-ICOF8g2h.js.map → outbox-repository-options-B8TnAE1h.js.map} +1 -1
- package/dist/{outbox-repository-options-AkihEaik.d.ts → outbox-repository-options-DjBgFhMi.d.ts} +3 -3
- package/dist/{outbox-repository-options-AkihEaik.d.ts.map → outbox-repository-options-DjBgFhMi.d.ts.map} +1 -1
- package/dist/postgres.d.ts +3 -3
- package/dist/postgres.js +3 -3
- package/dist/posthog/metrics.d.ts +1 -1
- package/dist/posthog/server.d.ts +2 -2
- package/dist/posthog/server.js +1 -1
- package/dist/resend.d.ts +5 -5
- package/dist/resend.d.ts.map +1 -1
- package/dist/resend.js +30 -57
- package/dist/resend.js.map +1 -1
- package/dist/sentry/client.d.ts +1 -1
- package/dist/sentry/client.d.ts.map +1 -1
- package/dist/sentry/client.js +10 -4
- package/dist/sentry/client.js.map +1 -1
- package/dist/sentry/server.d.ts +2 -2
- package/dist/sentry/server.js +5 -5
- package/dist/sentry/server.js.map +1 -1
- package/dist/stripe/payment-service.d.ts +52 -0
- package/dist/stripe/payment-service.d.ts.map +1 -0
- package/dist/stripe/payment-service.error.d.ts +13 -0
- package/dist/stripe/payment-service.error.d.ts.map +1 -0
- package/dist/stripe/payment-service.error.js +30 -0
- package/dist/stripe/payment-service.error.js.map +1 -0
- package/dist/stripe/payment-service.js +72 -0
- package/dist/stripe/payment-service.js.map +1 -0
- package/dist/stripe/payment-webhook.d.ts +18 -0
- package/dist/stripe/payment-webhook.d.ts.map +1 -0
- package/dist/stripe/payment-webhook.js +35 -0
- package/dist/stripe/payment-webhook.js.map +1 -0
- package/dist/tanstack.d.ts +1 -1
- package/dist/tanstack.js +4 -4
- package/dist/tanstack.js.map +1 -1
- package/dist/testing/outbox-repository.d.ts +2 -2
- package/dist/testing/payment-service.d.ts +10 -0
- package/dist/testing/payment-service.d.ts.map +1 -0
- package/dist/testing/payment-service.js +76 -0
- package/dist/testing/payment-service.js.map +1 -0
- package/dist/webhook-verification-D1c7BY4q.d.ts +21 -0
- package/dist/webhook-verification-D1c7BY4q.d.ts.map +1 -0
- package/dist/{webhook-verification-D6aGQfNi.js → webhook-verification-qSFXv5H3.js} +2 -2
- package/dist/webhook-verification-qSFXv5H3.js.map +1 -0
- package/package.json +13 -6
- package/src/application/outbox-relay.ts +3 -1
- package/src/core/console-log-sink.ts +61 -0
- package/src/core/index.ts +1 -4
- package/src/core/logger.ts +80 -281
- package/src/infrastructure/better-auth/apple-client-secret.ts +1 -1
- package/src/infrastructure/better-auth/rate-limit.ts +3 -1
- package/src/infrastructure/billing/client.ts +173 -0
- package/src/infrastructure/cloudflare/queue/queue-consumer.ts +8 -9
- package/src/infrastructure/cloudflare/r2-client.ts +162 -0
- package/src/infrastructure/cloudflare/r2-errors.ts +111 -0
- package/src/infrastructure/cloudflare/scheduled/scheduled-handler.ts +1 -1
- package/src/infrastructure/http/index.ts +2 -6
- package/src/infrastructure/http/webhook-handler.ts +69 -12
- package/src/infrastructure/http/webhook-verification.ts +6 -9
- package/src/infrastructure/resend/email-event.ts +14 -30
- package/src/infrastructure/resend/resend-webhook.ts +12 -22
- package/src/infrastructure/sentry/client.ts +6 -3
- package/src/infrastructure/sentry/server.ts +4 -4
- package/src/infrastructure/stripe/payment-service.error.ts +42 -0
- package/src/infrastructure/stripe/payment-service.ts +129 -0
- package/src/infrastructure/stripe/payment-webhook.ts +36 -0
- package/src/infrastructure/tanstack/resolve-failure.ts +3 -2
- package/src/infrastructure/testing/payment-service-contract.ts +91 -0
- package/dist/core-ClSP5-V9.js.map +0 -1
- package/dist/index-DvJUcSW1.d.ts.map +0 -1
- package/dist/webhook-verification-BcQQG-vY.d.ts +0 -29
- package/dist/webhook-verification-BcQQG-vY.d.ts.map +0 -1
- package/dist/webhook-verification-D6aGQfNi.js.map +0 -1
package/dist/http.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as WebhookVerificationError } from "./webhook-verification-
|
|
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
|
-
|
|
11
|
-
|
|
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,
|
|
20
|
-
const body = await
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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("
|
|
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<
|
|
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 {
|
|
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-
|
|
395
|
+
//# sourceMappingURL=index-CYHXOH08.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
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":";;;;;;KAMY,eAAe,iBAAiB,eAAe,MAAM,UAC/D,SAAS,UACT,MAAM,SACH,QAAQ;;;;;KAMD,aAAa,eAAe,aAAa,WAAW,UAC9D,OAAO,QACP,MAAM,cACH,QAAQ;;KAGD,aAAa,eAAe,aAAa,SACnD,OAAO,QACP,MAAM,SACH;;;;UCrBY,iBAAiB,eAAe,sBAAsB;;EAErE,SAAS,oBAAoB,aAAa;;EAE1C,MAAM,oBAAoB;;EAE1B,MAAM,OAAO,QAAQ,oBAAoB,WAAW;;EAEpD,eAAe,OAAO,QAAQ,oBAAoB,WAAW;;;cAIlD,gBAAgB;;;;KCdjB;;KAGA,mBAAmB,SAAS,eAAe;;UAGtC;WACN,aAAa;WACb;;;UAIM,eAAe;;EAE9B,MAAM,MAAM,OAAO,gBAAgB,UAAU;;EAE7C,MAAM,MAAM,OAAO,eAAe,UAAU;;EAE5C,UAAU,MAAM,OAAO,eAAe,UAAU;;;cAIrC,sBAAsB;;;;UCtBlB;WACN;;;UAIM;;EAEf,QAAQ,MAAM;;;UAIC,6BAA6B;;EAE5C,mBAAmB,GAAG,WAAW,OAAO,uBAAuB,IAAI,QAAQ,KAAK,QAAQ;;;;;KCX9E;;KAGA;WACD;WACA,kBAAkB;;WAElB,cAAc;;;;;;;KAQb;;WAED;WACA;WACA;WACA;;WAEA,iBAAiB;;WAEjB;WACA;;WAEA,OAAO,SAAS;WAChB,uBAAuB;;;KAItB;WAA2B;;;;;;UAMtB;;EAEf,UAAU,OAAO,gBAAgB,QAAQ;;;cAI9B,iCAAiC;;WAEnC,MAAM;;EAGT,UAAU,OAAO,gBAAgB,QAAQ;;;;;UCjDhC;EACf,KAAK,OAAO;EACZ,WAAW,cAAc;;;;;;;;UCCV;;EAEf,MAAM,WAAW,YAAY;;EAE7B,cAAc,QAAQ,cAAc,eAAe;;;;;KCPzC;WACD,SAAS;WACT;;;KAIC;WACD;WACA,UAAU,cAAc;;;KAIvB;;UAGK;;EAEf,sBAAsB,QAAQ,MAAM,oBAAoB;;EAExD,mBAAmB,QAAQ,MAAM,oBAAoB;;EAErD,qBAAqB,QAAQ,MAAM,oBAAoB;;;;;;UAOxC,0BAA0B;;EAEzC,aAAa,oBAAoB,QAAQ;;EAEzC,cAAc,OAAO,aAAa,UAAU,cAAc,iBAAiB;;EAE3E,aAAa,OAAO,aAAa,UAAU,cAAc,iBAAiB;;EAE1E,WACE,OAAO,aACP,UAAU,cAAc,gBACxB,QAAQ,kBACR,uBACC;;;;;;;;;UC9BY;EACf;;;UAIe;;EAEf,iBAAiB,UAAU,cAAc,eAAe,QAAQ,cAAc;;;KAIpE;WACD;WACA;WACA;;;;;;cASE;mBAIQ;mBACA;mBAJF;EAEjB,YACmB,WAAW,kBACX,YAAY,mBAC7B,UAAS;;EAUL,SAAS;;EA4BT,SAAS;UAWD;UAkBA;;;;;;;;;UCzGC,aAAa;EAC5B,YAAY,GAAG,OAAO,IAAI,OAAO,QAAQ,KAAK,QAAQ;;;;;;;;;UCOvC,YAAY;EAC3B,IAAI,GAAG,WAAW,WAAW,OAAO,OAAO,UAAU,QAAQ,KAAK,QAAQ;;KAGhE,eAAe,IAAI;WACpB,aAAa,aAAa;;WAE1B,eAAe,IAAI,OAAO;;WAE1B,qBAAqB,IAAI,OAAO;WAChC,gBAAgB;WAChB,OAAO;;;cAIL,WAAW,IAAI,kBAAkB,YAAY;mBAC3B;EAA7B,YAA6B,MAAM,eAAe,IAAI;EAEhD,IAAI,GAAG,WAAW,WAAW,OAAO,OAAO,UAAU,QAAQ,KAAK,QAAQ;;;;;KC1BtE;WACD,MAAM;WACN;;;;;;UAOM;;EAEf,aAAa,SAAS,cAAc,QAAQ,oBAAoB;;EAEhE,gBAAgB,SAAS,eAAe;;;KAI9B;WAAmC,qBAAqB;;;KAGxD;WAAkC,KAAK,YAAY;;;KAGnD,0BAA0B,gBAAgB;;;;;iBAMhC,iBACpB,SAAS,yBACT,MAAM,uBACL;;;;KChCS,gBAAgB,iBAAiB,eAAe,oBAChD,KAAK,YAAY,YAAY,eAAe,GAAG;;KAI/C,cAAc,eAAe,aAAa,yBAC1C,KAAK,UAAU,YAAY,aAAa,GAAG;;;;;KAO3C,cAAc,eAAe,aAAa,oBAC1C,KAAK,UAAU,aAAa,cAAc,aAAa,GAAG;;;;;;KAQ1D,gBAAgB,iBAAiB,eAAe,aAAa,WAAW;WACzE,UAAU,gBAAgB,QAAQ,UAAU,gBAAgB;WAC5D,SAAS,cAAc,QAAQ,UAAU,cAAc;WACvD,QAAQ,cAAc,QAAQ,UAAU,cAAc;;KAK5D,KAAK;EAAU,OAAO,SAAS,eAAe,MAAM,OAAO;;KAC3D,aAAa;EAAU,OAAO,OAAO,aAAa,MAAM,OAAO;;;;;;KAMxD,SAAS;WACV,UAAU,SAAS,eAAe,KAAK;WACvC,SAAS,SAAS,eAAe,KAAK;WACtC,QAAQ,SAAS,QAAQ,eAAe,cAAc,aAAa;;KAGzE,YAAY,UAAU,WAAW,QAAQ,aAAa,SAAS;KAE/D,oBAAoB,UACvB,YAAY,aAAa,iBAAiB,oBAAoB,iBAC1D,WAAW,QAAQ,eAAe;;KAI5B,gBAAgB,kBAAkB,mBAC1C,YAAY,yBACZ,YAAY,wBACZ,oBAAoB;KAEnB,UAAU,QAAQ,wBAAwB,oBAAoB,SAC/D,QAAQ,WAAW,QAAQ,OAAO,QAAQ;;KAIlC,cACV,iBAAiB,eACjB,kBAAkB,mBAChB,iBAAiB,gBACjB,UAAU,uBAAuB,oBACjC,iBAAiB,cACf,UAAU,sBAAsB;;;;UCvDrB,YAAY,kBAAkB;EAC7C,OAAO,iBAAiB,gBAAgB,gBAAgB,YACtD,SAAS,WACR,QAAQ,cAAc,UAAU;;;;;;cAOxB,WAAW,MAAM,kBAAkB,SAAS,kBAAkB,YAAY;mBAElE;mBACA;EAFnB,YACmB,MAAM,MACN,UAAU;;EAIvB,OAAO,iBAAiB,gBAAgB,gBAAgB,YAC5D,SAAS,WACR,QAAQ,cAAc,UAAU;UAM3B;UASA;UASA;;;;;;UAWM;;;;;KCpEJ;WACD;WACA;WACA;WACA;WACA;;;KAIC;WACD;WACA;WACA;;;cAIE;mBAIQ;mBAHF;EAEjB,YACmB,YAAY,4BAC7B,UAAS;;EAYL,MAAM,IAAI,OAAO,QAAQ;UAcjB;;;;;cC/CH,qCAAqC;WAKrC,WAAW;WAJb;WACA;EAET,YACW,WAAW,WACpB;aAAqB;;;SAMhB,KAAK,gBAAgB,WAAW,YAAY;;;;;cCZxC,qCAAqC;WACvC;WACA;EAET"}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
707
|
-
type
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
readonly
|
|
713
|
-
readonly
|
|
714
|
-
}
|
|
715
|
-
/** One
|
|
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
|
|
721
|
-
readonly
|
|
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
|
-
/**
|
|
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
|
|
758
|
-
readonly
|
|
722
|
+
readonly userId: string | undefined;
|
|
723
|
+
readonly attributes: LogFields;
|
|
759
724
|
}
|
|
760
|
-
/** A function that forwards one
|
|
725
|
+
/** A function that forwards one error to an error service. */
|
|
761
726
|
type LoggerErrorHook = (entry: ErrorCaptureEntry) => void;
|
|
762
|
-
/**
|
|
727
|
+
/** A destination for structured log records. */
|
|
763
728
|
type LogSink = (entry: LogEntry) => void;
|
|
764
|
-
/**
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
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
|
|
743
|
+
declare function createLogger(module: string): Logger;
|
|
805
744
|
//#endregion
|
|
806
|
-
export {
|
|
807
|
-
//# sourceMappingURL=index-
|
|
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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"}
|
package/dist/{outbox-repository-options-ICOF8g2h.js → outbox-repository-options-B8TnAE1h.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as UnitOfWorkAlreadyActiveError } from "./application-
|
|
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-
|
|
57
|
+
//# sourceMappingURL=outbox-repository-options-B8TnAE1h.js.map
|
package/dist/{outbox-repository-options-ICOF8g2h.js.map → outbox-repository-options-B8TnAE1h.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox-repository-options-
|
|
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"}
|
package/dist/{outbox-repository-options-AkihEaik.d.ts → outbox-repository-options-DjBgFhMi.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./index-
|
|
2
|
-
import { F as IEventCollector } from "./index-
|
|
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-
|
|
26
|
+
//# sourceMappingURL=outbox-repository-options-DjBgFhMi.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outbox-repository-options-
|
|
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"}
|
package/dist/postgres.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { A as IOutboxRepository, M as OutboxClaim, N as OutboxMessage, P as IMessageStore, k as DeadLetterReason, w as ITransaction } from "./index-
|
|
3
|
-
import { n as eventCollector, r as DrizzleSchema, t as OutboxRepositoryOptions } from "./outbox-repository-options-
|
|
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 {
|
|
2
|
-
import { o as MessageAlreadyProcessedError } from "./application-
|
|
3
|
-
import { i as runWithUnitOfWorkContext, r as eventCollector, t as OUTBOX_REPOSITORY_DEFAULTS } from "./outbox-repository-options-
|
|
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-
|
|
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. */
|
package/dist/posthog/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { X as AnalyticsService } from "../index-
|
|
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
|
package/dist/posthog/server.js
CHANGED
package/dist/resend.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { B as OutboundEmail, I as EmailAccepted, R as IEmailService } from "./index-
|
|
3
|
-
import {
|
|
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
|
|
69
|
-
verify(body: string, headers: Headers): Promise<
|
|
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 };
|
package/dist/resend.d.ts.map
CHANGED
|
@@ -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;;;;;
|
|
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 {
|
|
2
|
-
import { t as WebhookVerificationError } from "./webhook-verification-
|
|
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.
|
|
166
|
-
if (!header.
|
|
167
|
-
|
|
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.
|
|
174
|
+
occurredAt: header.created_at
|
|
181
175
|
};
|
|
182
176
|
switch (event.type) {
|
|
183
177
|
case "email.bounced": return {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
type: event.type,
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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
|
-
|
|
213
|
-
|
|
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
|
|
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)
|
|
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)
|
|
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
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
|