better-ship 0.8.0 → 0.11.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-DYfcAy-Q.js → application-CIxo_BpK.js} +32 -3
- package/dist/application-CIxo_BpK.js.map +1 -0
- package/dist/application.d.ts +3 -3
- package/dist/application.js +2 -2
- package/dist/better-auth/apple-client-secret.d.ts +11 -4
- package/dist/better-auth/apple-client-secret.d.ts.map +1 -1
- package/dist/better-auth/apple-client-secret.js +39 -11
- 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 +21 -2
- package/dist/better-auth/rate-limit.d.ts.map +1 -1
- package/dist/better-auth/rate-limit.js +38 -2
- package/dist/better-auth/rate-limit.js.map +1 -1
- package/dist/better-auth.js +1 -1
- package/dist/cloudflare/auth-secondary-storage.d.ts +1 -1
- package/dist/cloudflare/auth-secondary-storage.js +1 -1
- package/dist/cloudflare/queue.d.ts +1 -1
- package/dist/cloudflare/queue.js +2 -2
- package/dist/cloudflare/scheduled.d.ts +36 -0
- package/dist/cloudflare/scheduled.d.ts.map +1 -0
- package/dist/cloudflare/scheduled.js +37 -0
- package/dist/cloudflare/scheduled.js.map +1 -0
- package/dist/cloudflare.d.ts +3 -3
- package/dist/cloudflare.js +3 -3
- package/dist/{core-DC_4pOrI.js → core-DG_cC8YT.js} +110 -2
- package/dist/{core-DC_4pOrI.js.map → core-DG_cC8YT.js.map} +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/http.d.ts +19 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +35 -0
- package/dist/http.js.map +1 -0
- package/dist/{index-6XMPJu7u.d.ts → index-Bl0K1RQW.d.ts} +90 -2
- package/dist/index-Bl0K1RQW.d.ts.map +1 -0
- package/dist/{index-_Cihfq1J.d.ts → index-DgDyeR5s.d.ts} +135 -55
- package/dist/index-DgDyeR5s.d.ts.map +1 -0
- package/dist/postgres.d.ts +3 -3
- package/dist/postgres.js +3 -3
- package/dist/resend.d.ts +73 -0
- package/dist/resend.d.ts.map +1 -0
- package/dist/resend.js +284 -0
- package/dist/resend.js.map +1 -0
- package/dist/tanstack/server.d.ts +8 -0
- package/dist/tanstack/server.d.ts.map +1 -0
- package/dist/tanstack/server.js +16 -0
- package/dist/tanstack/server.js.map +1 -0
- package/dist/tanstack.d.ts +18 -14
- package/dist/tanstack.d.ts.map +1 -1
- package/dist/tanstack.js +17 -23
- package/dist/tanstack.js.map +1 -1
- package/dist/{unit-of-work-context-BFCmU92Z.js → unit-of-work-context-BPE1In2f.js} +2 -2
- package/dist/{unit-of-work-context-BFCmU92Z.js.map → unit-of-work-context-BPE1In2f.js.map} +1 -1
- package/dist/{unit-of-work-context-BWTJfYPW.d.ts → unit-of-work-context-BzmnjlDa.d.ts} +3 -3
- package/dist/{unit-of-work-context-BWTJfYPW.d.ts.map → unit-of-work-context-BzmnjlDa.d.ts.map} +1 -1
- package/dist/webhook-verification-BQ9qZnVK.js +18 -0
- package/dist/webhook-verification-BQ9qZnVK.js.map +1 -0
- package/dist/webhook-verification-sZtwTI5n.d.ts +29 -0
- package/dist/webhook-verification-sZtwTI5n.d.ts.map +1 -0
- package/package.json +11 -6
- package/src/application/email-service.ts +55 -0
- package/src/application/index.ts +16 -0
- package/src/application/record-email-event.ts +53 -0
- package/src/core/email-address.ts +7 -0
- package/src/core/email-deliverability.ts +31 -0
- package/src/core/email-idempotency-key.ts +34 -0
- package/src/core/email-service.error.ts +51 -0
- package/src/core/index.ts +18 -0
- package/src/core/record-email-event.ts +23 -0
- package/src/infrastructure/better-auth/apple-client-secret.ts +41 -14
- package/src/infrastructure/better-auth/rate-limit.ts +44 -1
- package/src/infrastructure/cloudflare/scheduled/index.ts +8 -0
- package/src/infrastructure/cloudflare/scheduled/scheduled-handler.ts +62 -0
- package/src/infrastructure/http/index.ts +6 -0
- package/src/infrastructure/http/webhook-handler.ts +35 -0
- package/src/infrastructure/http/webhook-verification.ts +27 -0
- package/src/infrastructure/resend/email-event.ts +142 -0
- package/src/infrastructure/resend/index.ts +3 -0
- package/src/infrastructure/resend/resend-email-service.ts +125 -0
- package/src/infrastructure/resend/resend-webhook.ts +70 -0
- package/src/infrastructure/tanstack/auth.middleware.ts +14 -6
- package/src/infrastructure/tanstack/error.middleware.ts +7 -8
- package/src/infrastructure/tanstack/index.ts +0 -1
- package/src/infrastructure/tanstack/request-context.ts +11 -0
- package/src/infrastructure/tanstack/server.ts +7 -0
- package/src/infrastructure/tanstack/session-cookies.ts +6 -4
- package/dist/application-DYfcAy-Q.js.map +0 -1
- package/dist/index-6XMPJu7u.d.ts.map +0 -1
- package/dist/index-_Cihfq1J.d.ts.map +0 -1
|
@@ -36,6 +36,94 @@ declare abstract class AppError extends Error {
|
|
|
36
36
|
get name(): string;
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
|
+
//#region src/core/email-address.d.ts
|
|
40
|
+
/** A parsed email address for message payloads and webhook recipients. Ported from Typist's `EmailSchema`. */
|
|
41
|
+
declare const EmailAddressSchema: z.core.$ZodBranded<z.ZodEmail, "EmailAddress", "out">;
|
|
42
|
+
/** An address the schema accepted. */
|
|
43
|
+
type EmailAddress = z.infer<typeof EmailAddressSchema>;
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/core/email-idempotency-key.d.ts
|
|
46
|
+
/** A key only `emailIdempotencyKey` mints, so every send carries one built by its rules. */
|
|
47
|
+
type EmailIdempotencyKey = string & z.core.$brand<'EmailIdempotencyKey'>;
|
|
48
|
+
/** A key outside 1 to 256 characters. Keys come from stable ids, so this is a defect, not a retry. */
|
|
49
|
+
declare class InvalidEmailIdempotencyKeyError extends AppError {
|
|
50
|
+
readonly length: number;
|
|
51
|
+
readonly _tag = "InvalidEmailIdempotencyKeyError";
|
|
52
|
+
readonly classification = "terminal";
|
|
53
|
+
constructor(length: number);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `<scope>/<id>` for one logical send. Resend deduplicates it for 24 hours.
|
|
57
|
+
* Derive `id` from a stable identity: a message id, a job id, a user id with a template name.
|
|
58
|
+
* The same key must map to an identical payload; a changed body is rejected as terminal.
|
|
59
|
+
* A random `id` means every request is a deliberate new send, as a sign-in code resend is.
|
|
60
|
+
* Source: https://resend.com/docs/dashboard/emails/idempotency-keys
|
|
61
|
+
*/
|
|
62
|
+
declare function emailIdempotencyKey(scope: string, id: string): EmailIdempotencyKey;
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/core/email-service.error.d.ts
|
|
65
|
+
/** Why the provider rejected a send. The reason owns the classification, so the two never disagree. */
|
|
66
|
+
type EmailSendFailureReason = 'rate_limited' | 'idempotency_conflict' | 'provider_error' | 'quota_exceeded' | 'invalid_request' | 'configuration';
|
|
67
|
+
/**
|
|
68
|
+
* The provider rejected a send. The boundary that awaited the send logs once; the adapter never does.
|
|
69
|
+
* `retryAfter` is the server's delay in seconds when it sent one, so `retryAfterSecondsOf` reads it.
|
|
70
|
+
*/
|
|
71
|
+
declare class EmailServiceError extends AppError {
|
|
72
|
+
readonly _tag = "EmailServiceError";
|
|
73
|
+
readonly classification: FailureClassification;
|
|
74
|
+
readonly reason: EmailSendFailureReason;
|
|
75
|
+
readonly provider: string;
|
|
76
|
+
readonly providerCode: string;
|
|
77
|
+
readonly statusCode: number | null;
|
|
78
|
+
readonly retryAfter: number | null;
|
|
79
|
+
constructor(args: {
|
|
80
|
+
readonly reason: EmailSendFailureReason;
|
|
81
|
+
readonly provider: string;
|
|
82
|
+
readonly providerCode: string;
|
|
83
|
+
readonly statusCode: number | null;
|
|
84
|
+
readonly retryAfter: number | null;
|
|
85
|
+
readonly cause: unknown;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/core/email-deliverability.d.ts
|
|
90
|
+
/** The bounce classes Resend reports, ported from Typist's comm-eligibility.ts. */
|
|
91
|
+
declare const BounceTypeSchema: z.ZodEnum<{
|
|
92
|
+
Permanent: "Permanent";
|
|
93
|
+
Transient: "Transient";
|
|
94
|
+
Undetermined: "Undetermined";
|
|
95
|
+
}>;
|
|
96
|
+
/** One bounce class. */
|
|
97
|
+
type BounceType = z.infer<typeof BounceTypeSchema>;
|
|
98
|
+
/** Parse a provider's bounce type. An unknown value is `Undetermined`, which suppresses. */
|
|
99
|
+
declare function parseBounceType(value: string | undefined): BounceType;
|
|
100
|
+
/** Keep the higher severity. Equal severity permits replacement; callers own timestamp ordering. */
|
|
101
|
+
declare function shouldUpdateBounce(incoming: BounceType, current: BounceType | null): boolean;
|
|
102
|
+
/** Typist's send policy: no complaint, and either no bounce or a transient one. Delivery is not guaranteed. */
|
|
103
|
+
declare function isEmailDeliverable(bounceType: BounceType | null, complained: boolean): boolean;
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/core/record-email-event.d.ts
|
|
106
|
+
/**
|
|
107
|
+
* The payload of the command an application registers to record a bounce or a complaint.
|
|
108
|
+
* Register it under a name of the application's choice in `defineMessages`; `recordEmailEvent` handles it.
|
|
109
|
+
*/
|
|
110
|
+
declare const RecordEmailEventPayloadSchema: z.ZodObject<{
|
|
111
|
+
recipients: z.ZodArray<z.core.$ZodBranded<z.ZodEmail, "EmailAddress", "out">>;
|
|
112
|
+
event: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
113
|
+
type: z.ZodLiteral<"bounced">;
|
|
114
|
+
bounceType: z.ZodEnum<{
|
|
115
|
+
Permanent: "Permanent";
|
|
116
|
+
Transient: "Transient";
|
|
117
|
+
Undetermined: "Undetermined";
|
|
118
|
+
}>;
|
|
119
|
+
bounceSubType: z.ZodNullable<z.ZodString>;
|
|
120
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
121
|
+
type: z.ZodLiteral<"complained">;
|
|
122
|
+
}, z.core.$strip>], "type">;
|
|
123
|
+
}, z.core.$strip>;
|
|
124
|
+
/** A parsed payload. */
|
|
125
|
+
type RecordEmailEventPayload = z.infer<typeof RecordEmailEventPayloadSchema>;
|
|
126
|
+
//#endregion
|
|
39
127
|
//#region src/core/authentication.error.d.ts
|
|
40
128
|
/** A protected operation requires a session that the caller did not provide. */
|
|
41
129
|
declare class AuthenticationError extends AppError {
|
|
@@ -627,5 +715,5 @@ declare class Logger {
|
|
|
627
715
|
/** Create a logger for one module. */
|
|
628
716
|
declare function createLogger(module: string, config?: LoggerConfig): Logger;
|
|
629
717
|
//#endregion
|
|
630
|
-
export { unreachable as $, isTransientCloudflareRuntimeError as A,
|
|
631
|
-
//# sourceMappingURL=index-
|
|
718
|
+
export { unreachable as $, isTransientCloudflareRuntimeError as A, RecordEmailEventPayloadSchema as At, PayloadSchemas as B, emailIdempotencyKey as Bt, classifyBoundaryError as C, InternalServerError as Ct, isCloudflareObjectResetError as D, RateLimitError as Dt, CLOUDFLARE_TRANSIENT_ERROR_PATTERNS as E, StaleSessionError as Et, AppMessages as F, shouldUpdateBounce as Ft, DomainMessage as G, RetryOwner as Gt, defineMessages as H, EmailAddressSchema as Ht, CommandOf as I, EmailSendFailureReason as It, Id as J, DomainQuery as K, shouldRetryFailure as Kt, EventOf as L, EmailServiceError as Lt, isTransientTransportError as M, BounceTypeSchema as Mt, Entity as N, isEmailDeliverable as Nt, isCloudflareOverloadedError as O, AuthenticationError as Ot, EntityData as P, parseBounceType as Pt, notImplemented as Q, MessageDefinition as R, EmailIdempotencyKey as Rt, BoundaryErrorClassifier as S, ValidationProblemErrorSchema as St, retryAfterSecondsOf as T, NotAuthorizedError as Tt, DomainCommand as U, AppError as Ut, QueryOf as V, EmailAddress as Vt, DomainEvent as W, FailureClassification as Wt, IdOf as X, IdDefinition as Y, defineId as Z, createLogger as _, ProblemDetails as _t, LogFormat as a, ErrorPayloadOf as at, exponentialEqualJitterMs as b, ValidationProblemDetailsSchema as bt, LogThreshold as c, ResolvedError as ct, LoggerConfig as d, MalformedRequestError as dt, D1ConstraintKind as et, LoggerErrorHook as f, RequestTimeoutError as ft, consoleSink as g, ValidationIssue as gt, configureLogger as h, ValidationError as ht, LogFields as i, ErrorEntry as it, isAbortError as j, BounceType as jt, isCloudflareRetryableError as k, RecordEmailEventPayload as kt, LogValue as l, defineErrors as lt, SerializedError as m, UpgradeRequiredError as mt, ErrorLogContext as n, DatabaseFailure as nt, LogLevel as o, ErrorTable as ot, LoggerSettings as p, ResourceNotFoundError as pt, MessageId as q, LogEntry as r, ErrorEntries as rt, LogSink as s, ErrorTagOf as st, ErrorCaptureEntry as t, DatabaseError as tt, Logger as u, sharedErrors as ut, setLogSink as v, ProblemDetailsSchema as vt, classifyFailure as w, ServiceUnavailableError as wt, spreadJitterMs as x, ValidationProblemError as xt, setLoggerErrorHook as y, ValidationProblemDetails as yt, MessageOf as z, InvalidEmailIdempotencyKeyError as zt };
|
|
719
|
+
//# sourceMappingURL=index-Bl0K1RQW.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-Bl0K1RQW.d.ts","names":[],"sources":["../src/core/failure-classification.ts","../src/core/app-error.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/logger.ts"],"mappings":";;;;;;;;KAMY;;;;;;;KAQA;;iBAGI,mBAAmB;WACxB,gBAAgB;WAChB;WACA,OAAO;;;;;;;;;;;;uBCVI,iBAAiB;oBACnB;oBACA,gBAAgB;MAErB;;;;;cCXF,oBAAkB,EAAA,KAAA,YAAA,EAAA;;KAGnB,eAAe,EAAE,aAAa;;;;KCD9B,+BAA+B,EAAE,KAAK;;cAMrC,wCAAwC;WAI9B;WAHZ;WACA;EAET,YAAqB;;;;;;;;;iBAYP,oBAAoB,eAAe,aAAa;;;;KCvBpD;;;;;cAqBC,0BAA0B;WAC5B;WACA,gBAAgB;WAChB,QAAQ;WACR;WACA;WACA;WACA;EAET,YAAY;aACD,QAAQ;aACR;aACA;aACA;aACA;aACA;;;;;;cCrCA,kBAAgB,EAAA;;;;;;KAGjB,aAAa,EAAE,aAAa;;iBAGxB,gBAAgB,4BAA4B;;iBAY5C,mBAAmB,UAAU,YAAY,SAAS;;iBAMlD,mBAAmB,YAAY,mBAAmB;;;;;;;cClBrD,+BAA6B,EAAA;;;;;;;;;;;;;GAUxC,EAAA,KAAA;;KAGU,0BAA0B,EAAE,aAAa;;;;cCnBxC,4BAA4B;WAC9B;WACA;EAET;;;;;cCJW,uBAAuB;WAKb;WAJZ;WACA;WACA;EAET,YAAqB;;;;;cCLV,0BAA0B;WAC5B;WACA;EAET;;;;;cCJW,2BAA2B;WAC7B;WACA;EAET;;;;;cCJW,4BAA4B;WAC9B;WACA;EAET;;;cAMW,gCAAgC;WAClC;WACA;EAET;;;;;;;;;cCVW,sBAAoB,EAAA;;;;;GAqB/B,EAAA,KAAA;;KAGU,iBAAiB,EAAE,aAAa;;cAG/B,8BAA4B,EAAA;;;GAWvC,EAAA,KAAA;;KAGU,yBAAyB,EAAE,aAAa;;cAGvC,gCAA8B,EAAA;;;;;;;;;GAEzC,EAAA,KAAA;;KAGU,2BAA2B,EAAE,aAAa;;;;KClD1C;WACD;WACA,eAAe;;;cAIb,wBAAwB;WAKxB,iBAAiB;WAJnB;WACA;EAET,YACW,iBAAiB,0BAC1B;;SAMK,QAAQ,OAAO,EAAE,UAAU,mBAAmB;;SAK9C,WAAW,iBAAiB,mBAAmB,mBAAmB;;;cAS9D,8BAA8B;WAChC;WACA;EAET,YAAY;IAAQ;;;;cAMT,8BAA8B;WAChC;WACA;EAET;;;cAMW,6BAA6B;WAC/B;WACA;EAET;;;cAMW,4BAA4B;WAC9B;WACA;EAET;;;;KCtDG,eAAe,EAAE;;;;;KAMV,WAAW,oBAAoB,eAAe,eAAe;WAC9D,wBAAwB,kBAAkB;aAAsB,MAAM;;WACtE;WACA,SAAS;;;KAMR,aAAa,uBACb,aAAa,mBAAmB,WAAW;KAGlD,aAAa,oBAAoB,SAAS;WACpC,cAAc,eAAe,EAAE;;WAE3B,MAAM;WAAc;IAAoB,EAAE,OAAO;WACjD,MAAM;WAAc;;KAE9B,iBAAiB,cACnB,aAAa,mBAAmB,aAAa,KAAK,QAAQ,eACrD;;KAGI,cAAc;WACf;WACA,SAAS;;;;;;KAOR,WAAW;WACZ,SAAS;;WAET,eAAe,EAAE,QAAQ,iBAAiB;;WAE1C,SAAS,iBAAiB;;EAEnC,MAAM,iBAAiB,iBAAiB;;EAExC,GAAG,kBAAkB,kBACnB,gBACA,KAAK,MACJ,SAAS,QAAQ,iBAAiB;aAAqB,MAAM;;;EAEhE,QAAQ,iBAAiB,cAAc,iBAAiB;;EAExD,SAAS,iBAAiB,cAAc,iBAAiB;;;KAI/C,eAAe,SACzB,cAAc,iBAAiB,WAAW,iBAAiB;;KAGjD,WAAW,SACrB,cAAc,iBAAiB,iBAAiB;;cAUrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAcR,cAAc,WAAW,YAAY,oBAAoB,WAAW;;;;;iBA4BzD,mBAAmB,gBAAgB,aAAa,UAC9D,SAAS,UACR,WAAW,cAAc;;;;KCpIhB;;KAGA;WAEG;WACA;WACA,MAAM;WACN;WACA;WACA;;WAGA;WACA;WACA;WACA;WACA;;;cAIF,sBAAsB;WAItB;WACA,gBAAgB;WAChB,SAAS;WALX;EAET,YACW,mBACA,gBAAgB,uBAChB,SAAS,iBAClB;aAAoB;;;;;;;;;;iBCzBR,YAAY;;;;;;;iBAUZ,eAAe;;;;KCbnB,GAAG,iCAAiC,EAAE,KAAK,OAAO;;KAGlD,aAAa;WACd,QAAQ,EAAE,KAAK,YAAY,EAAE,SAAS;;EAE/C,UAAU,GAAG;;;KAIH,KAAK,mBAAmB,wBAAwB,EAAE,OAAO;;;;;iBAMrD,eAAe,sBAAsB,OAAO,QAAQ,aAAa;;;;;;;;;;KCbrE;;KAGA,cAAc;WACf;WACA,MAAM;WACN,IAAI;;;KAIH,YAAY;WACb;WACA,MAAM;;;KAIL,YAAY;WACb;WACA,MAAM;WACN,IAAI;;;KAIH,gBAAgB,gBAAgB,cAAc;;;;KCxB9C,iBAAiB,SAAS,eAAe,EAAE;;KAG3C;WACD,UAAU;WACV,QAAQ;WACR,SAAS;;KAGf;WAAyB,YAAY;;KACrC,IAAI,iBAAiB,eAAe;KACpC,QAAQ,gBAAgB,gBAAgB,mBAAmB,WAAW,EAAE,OAAO,QAAQ;;KAGhF,UAAU,iBAAiB,kBACpC,cAAc,IAAI,iCAAiC,cAAc,QAChE,QAAQ,IAAI,uBAAuB,eAC/B,IAAI;;KAGA,QAAQ,iBAAiB,kBAClC,cAAc,IAAI,+BAA+B,YAAY,QAC5D,QAAQ,IAAI,qBAAqB,eAC7B,IAAI;;KAGA,QAAQ,iBAAiB,kBAClC,cAAc,IAAI,gCAAgC,YAAY,QAC7D,QAAQ,IAAI,sBAAsB,eAC9B,IAAI;;KAGA,UAAU,iBAAiB,eACnC,UAAU,YACV,QAAQ,YACR,QAAQ;;;;;KAMA,YAAY,mBAAmB;WAChC,YAAY;;EAErB,cAAc,mBAAmB,iCAC/B,MAAM,MACN,SAAS,QAAQ,wBAAwB,OACzC,KAAK,YACJ,cAAc,QAAQ,QAAQ,wBAAwB;;EAEzD,YAAY,mBAAmB,+BAC7B,MAAM,MACN,SAAS,QAAQ,sBAAsB,OACvC,KAAK,YACJ,YAAY,QAAQ,QAAQ,sBAAsB;;EAErD,YAAY,mBAAmB,gCAC7B,MAAM,MACN,SAAS,QAAQ,uBAAuB,QACvC,YAAY,QAAQ,QAAQ,uBAAuB;WAC7C,eAAe,EAAE,QAAQ,UAAU,YAAY;WAC/C,aAAa,EAAE,QAAQ,QAAQ,YAAY;WAC3C,aAAa,EAAE,QAAQ,QAAQ,YAAY;;WAE3C,aAAa,EAAE,QACtB,UAAU,YAAY,eAAe,QAAQ,YAAY;;KAIxD;;KAGA,qBAAqB,gBAAgB,8BAC9B,cAAc,gBAAgB,EAAE,OAAO,QAAQ,SAAS,6BAC9D,QAAQ;;KAKT,gBAAgB,mBAAmB;WAC7B,UAAU,qBAAqB;WAC/B,QAAQ,qBAAqB;WAC7B,SAAS,qBAAqB;;;;;;iBA6BzB,qBAAqB,mBAAmB,mBACtD,YAAY,aAAa,gBAAgB,cACxC,YAAY;;;;KCpHH;WAAwB;;;;;;;uBAOd,OAAO,aAAa,YAAY,eAAe,cAAc;UACzE;oBAEU,IAAI;;YAGZ,SAAS,OAAO;;EAK1B,iBAAiB,cAAc;;EAK/B;;WAKS,iBAAiB;;;;;iBCbZ,aAAa;;iBAKb,0BAA0B;;;;cCpB7B;WACX,uBAAqB;WACrB,aAAW;WACX,iBAAe;WACf,aAAW;WACX,mBAAiB;;;iBAgBH,2BAA2B;;iBAK3B,4BAA4B;;iBAK5B,6BAA6B;;iBAK7B,kCAAkC;;;;KC3BtC,2BAA2B,mBAAmB;;;;;iBAM1C,sBAAsB;WAC3B;WACA,kBAAkB;WAClB;IACP;;;;;iBAwBY,gBAAgB,iBAAiB;;iBAUjC,oBAAoB;;;;iBCrDpB,eAAe;;;;;iBAWf,yBACd,qBACA,oBACA;;;;;;;;;;KCTU,0DAMR,cAAc,YACd;;KAGQ;YAAwB,cAAc;;;;;;;cAOrC;WACX;WACA;WACA;WACA;;KAEU,mBAAmB,uBAAuB;;KAG1C;WACD;WACA;WACA;WACA,SAAS;WACT,QAAQ;WACR,SAAS,cAAc;;;KAItB;WACD;WACA,OAAO;WACP;WACA;WACA,SAAS;WACT;;WAEA,QAAQ;;;KAIP;WACD;WACA;WACA,UAAU;;;KAIT,eAAe;;UAGV;WACN,QAAQ;;;KAIP;;;;;;;UAQK,uBAAuB;WAC7B,SAAS;;;;;;iBAgBJ,gBAAgB,QAAQ;;UAQvB;WACN;WACA;WACA,SAAS;;;KAIR,mBAAmB,OAAO;;KAG1B,WAAW,OAAO;;;;;;iBASd,mBAAmB,IAAI;;;;;cA0C1B,aAAa;;;;;;;iBA6BV,WAAW,IAAI;;cAyDlB;mBAKQ;mBAJF;;EAGjB,YACmB,gBACjB,iBAAiB;UAKX;;EAuBR,MAAM,iBAAiB,UAAS;;EAKhC,KAAK,iBAAiB,UAAS;;EAK/B,KAAK,iBAAiB,UAAS;;;;;;;EAU/B,MAAM,iBAAiB,UAAS;;;iBAyBlB,aAAa,gBAAgB,SAAS,eAAe"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as DomainMessage, K as DomainQuery, U as DomainCommand, W as DomainEvent, kt as
|
|
1
|
+
import { G as DomainMessage, K as DomainQuery, Rt as EmailIdempotencyKey, U as DomainCommand, Ut as AppError, Vt as EmailAddress, W as DomainEvent, jt as BounceType, kt as RecordEmailEventPayload, q as MessageId } from "./index-Bl0K1RQW.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.
|
|
@@ -13,6 +13,61 @@ type QueryHandler<TQuery extends DomainQuery, QueryDeps, Value> = (query: TQuery
|
|
|
13
13
|
/** Completes one subscriber's work for an event. Failures throw. */
|
|
14
14
|
type EventHandler<TEvent extends DomainEvent, Deps> = (event: TEvent, deps: Deps) => Promise<void>;
|
|
15
15
|
//#endregion
|
|
16
|
+
//#region src/application/email-service.d.ts
|
|
17
|
+
/** A media type such as `application/pdf`. */
|
|
18
|
+
type MimeType = `${string}/${string}`;
|
|
19
|
+
/** A file to attach. Binary content is bytes; the adapter encodes it for the provider. */
|
|
20
|
+
type EmailAttachment = {
|
|
21
|
+
readonly filename: string;
|
|
22
|
+
readonly content: string | Uint8Array;
|
|
23
|
+
/** Optional MIME metadata; Resend accepts filename and content without it. */
|
|
24
|
+
readonly contentType?: MimeType;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* One transactional email. Resend accepts 50 recipients, 75 tags with ASCII names and values,
|
|
28
|
+
* and 40 MB of attachments after base64. Sources: https://resend.com/docs/api-reference/emails/send-email
|
|
29
|
+
* and https://resend.com/docs/dashboard/emails/tags
|
|
30
|
+
*/
|
|
31
|
+
type OutboundEmail = {
|
|
32
|
+
readonly to: string | readonly string[];
|
|
33
|
+
readonly subject: string;
|
|
34
|
+
readonly html: string;
|
|
35
|
+
/** The stable identity of this send. Resend deduplicates it for 24 hours. */
|
|
36
|
+
readonly idempotencyKey: EmailIdempotencyKey;
|
|
37
|
+
/** Resend generates plain text from html when omitted. An empty string disables that generation. */
|
|
38
|
+
readonly text?: string;
|
|
39
|
+
readonly replyTo?: string;
|
|
40
|
+
/** Labels the provider stores with the email and returns on every delivery event. */
|
|
41
|
+
readonly tags?: Readonly<Record<string, string>>;
|
|
42
|
+
readonly attachments?: readonly EmailAttachment[];
|
|
43
|
+
};
|
|
44
|
+
/** The provider accepted the email and assigned its id. */
|
|
45
|
+
type EmailAccepted = {
|
|
46
|
+
readonly providerId: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* The port a handler sends through. The adapter owns the sender address and the provider error mapping.
|
|
50
|
+
* A provider rejection throws `EmailServiceError`; unexpected SDK rejections propagate unchanged.
|
|
51
|
+
*/
|
|
52
|
+
interface IEmailService {
|
|
53
|
+
/** Resolve after provider acceptance; this does not confirm delivery to the recipient. */
|
|
54
|
+
sendEmail(email: OutboundEmail): Promise<EmailAccepted>;
|
|
55
|
+
}
|
|
56
|
+
/** Records every send for a test. Provider ids count up as `recorded-1`, `recorded-2`. */
|
|
57
|
+
declare class RecordingEmailService implements IEmailService {
|
|
58
|
+
/** Sends in call order, including repeated idempotency keys. */
|
|
59
|
+
readonly sent: OutboundEmail[];
|
|
60
|
+
/** Record the send before returning its provider id. */
|
|
61
|
+
sendEmail(email: OutboundEmail): Promise<EmailAccepted>;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/application/event-collector.d.ts
|
|
65
|
+
/** Records events in the current unit of work; the unit of work collects a snapshot for outbox persistence. */
|
|
66
|
+
interface IEventCollector {
|
|
67
|
+
emit(event: DomainEvent): void;
|
|
68
|
+
collect(): ReadonlyArray<DomainEvent>;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
16
71
|
//#region src/application/message-store.d.ts
|
|
17
72
|
/**
|
|
18
73
|
* Stores processed messages and outgoing events in the same transaction as application writes.
|
|
@@ -25,6 +80,83 @@ interface IMessageStore {
|
|
|
25
80
|
persistEvents(events: ReadonlyArray<DomainEvent>): Promise<void>;
|
|
26
81
|
}
|
|
27
82
|
//#endregion
|
|
83
|
+
//#region src/application/outbox-relay.d.ts
|
|
84
|
+
/**
|
|
85
|
+
* Delivers committed outbox rows. The unit of work only wakes it after a commit that wrote
|
|
86
|
+
* events; the app decides what a wake is: `waitUntil`, a Durable Object alarm, nothing.
|
|
87
|
+
* The sweep is the source of truth, so a lost wake loses no events.
|
|
88
|
+
*/
|
|
89
|
+
interface IOutboxRelay {
|
|
90
|
+
wake(): void;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/application/transaction.d.ts
|
|
94
|
+
/**
|
|
95
|
+
* Supplies `Tx` to participating repositories and resolves after their writes commit. Failure rolls back or discards writes.
|
|
96
|
+
* Nested calls reject with `UnitOfWorkAlreadyActiveError` before opening another boundary.
|
|
97
|
+
* Independent concurrent calls are allowed.
|
|
98
|
+
*/
|
|
99
|
+
interface ITransaction<Tx> {
|
|
100
|
+
transaction<T>(work: (tx: Tx) => Promise<T>): Promise<T>;
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/application/unit-of-work.d.ts
|
|
104
|
+
/**
|
|
105
|
+
* Commits the processed-message record, repository writes, and emitted events together before resolving.
|
|
106
|
+
* An existing record rejects with `MessageAlreadyProcessedError`; external effects must run through the outbox after commit.
|
|
107
|
+
* Nested calls reject with `UnitOfWorkAlreadyActiveError`; independent concurrent calls are allowed.
|
|
108
|
+
*/
|
|
109
|
+
interface IUnitOfWork<Repos> {
|
|
110
|
+
run<T>(messageId: MessageId, work: (repos: Repos) => Promise<T>): Promise<T>;
|
|
111
|
+
}
|
|
112
|
+
type UnitOfWorkDeps<Tx, Repos> = {
|
|
113
|
+
readonly transaction: ITransaction<Tx>;
|
|
114
|
+
/** The processed-messages and outbox repository for this transaction. */
|
|
115
|
+
readonly messageStore: (tx: Tx) => IMessageStore;
|
|
116
|
+
/** Repositories participate in the current transaction. */
|
|
117
|
+
readonly createRepositories: (tx: Tx) => Repos;
|
|
118
|
+
readonly eventCollector: IEventCollector;
|
|
119
|
+
readonly relay: IOutboxRelay;
|
|
120
|
+
};
|
|
121
|
+
/** The unit of work: the boundary, the repositories, the events. Every database call is a port. */
|
|
122
|
+
declare class UnitOfWork<Tx, Repos> implements IUnitOfWork<Repos> {
|
|
123
|
+
private readonly deps;
|
|
124
|
+
constructor(deps: UnitOfWorkDeps<Tx, Repos>);
|
|
125
|
+
run<T>(messageId: MessageId, work: (repos: Repos) => Promise<T>): Promise<T>;
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/application/record-email-event.d.ts
|
|
129
|
+
/** What a bounce records for one address. */
|
|
130
|
+
type EmailBounceRecord = {
|
|
131
|
+
readonly type: BounceType;
|
|
132
|
+
readonly subType: string | null;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* The application's deliverability state per address. An implementation keeps the higher bounce
|
|
136
|
+
* severity with `shouldUpdateBounce`, and treats an unknown address as nothing to record.
|
|
137
|
+
*/
|
|
138
|
+
interface IEmailDeliverabilityStore {
|
|
139
|
+
/** Keep the higher severity atomically. Equal severity permits replacement; the store owns timestamp ordering. */
|
|
140
|
+
recordBounce(address: EmailAddress, bounce: EmailBounceRecord): Promise<void>;
|
|
141
|
+
/** Record a complaint without clearing existing suppression state. */
|
|
142
|
+
recordComplaint(address: EmailAddress): Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
/** The repositories the handler needs from the unit of work. */
|
|
145
|
+
type RecordEmailEventRepos = {
|
|
146
|
+
readonly emailDeliverability: IEmailDeliverabilityStore;
|
|
147
|
+
};
|
|
148
|
+
/** The container slice the handler reads. */
|
|
149
|
+
type RecordEmailEventDeps = {
|
|
150
|
+
readonly uow: IUnitOfWork<RecordEmailEventRepos>;
|
|
151
|
+
};
|
|
152
|
+
/** The command, under whatever name the application registered the payload. */
|
|
153
|
+
type RecordEmailEventCommand = DomainCommand & RecordEmailEventPayload;
|
|
154
|
+
/**
|
|
155
|
+
* Record a bounce or a complaint for every recipient inside the command's unit of work.
|
|
156
|
+
* The command id is the provider's event id, so a redelivered webhook is `MessageAlreadyProcessedError`.
|
|
157
|
+
*/
|
|
158
|
+
declare function recordEmailEvent(command: RecordEmailEventCommand, deps: RecordEmailEventDeps): Promise<void>;
|
|
159
|
+
//#endregion
|
|
28
160
|
//#region src/application/registry.d.ts
|
|
29
161
|
/** One slot per command. `unknown` keeps the slot covariant; `MessageResult` recovers the value. */
|
|
30
162
|
type CommandRegistry<TCommand extends DomainCommand, Deps> = { readonly [M in TCommand as M['name']]: CommandHandler<M, Deps, unknown>; };
|
|
@@ -94,58 +226,6 @@ declare class MessageBus<Deps, TRegistry extends Handlers<Deps>> implements IMes
|
|
|
94
226
|
private handleEvent;
|
|
95
227
|
}
|
|
96
228
|
//#endregion
|
|
97
|
-
//#region src/application/outbox-relay.d.ts
|
|
98
|
-
/**
|
|
99
|
-
* Delivers committed outbox rows. The unit of work only wakes it after a commit that wrote
|
|
100
|
-
* events; the app decides what a wake is: `waitUntil`, a Durable Object alarm, nothing.
|
|
101
|
-
* The sweep is the source of truth, so a lost wake loses no events.
|
|
102
|
-
*/
|
|
103
|
-
interface IOutboxRelay {
|
|
104
|
-
wake(): void;
|
|
105
|
-
}
|
|
106
|
-
//#endregion
|
|
107
|
-
//#region src/application/transaction.d.ts
|
|
108
|
-
/**
|
|
109
|
-
* Supplies `Tx` to participating repositories and resolves after their writes commit. Failure rolls back or discards writes.
|
|
110
|
-
* Nested calls reject with `UnitOfWorkAlreadyActiveError` before opening another boundary.
|
|
111
|
-
* Independent concurrent calls are allowed.
|
|
112
|
-
*/
|
|
113
|
-
interface ITransaction<Tx> {
|
|
114
|
-
transaction<T>(work: (tx: Tx) => Promise<T>): Promise<T>;
|
|
115
|
-
}
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region src/application/event-collector.d.ts
|
|
118
|
-
/** Records events in the current unit of work; the unit of work collects a snapshot for outbox persistence. */
|
|
119
|
-
interface IEventCollector {
|
|
120
|
-
emit(event: DomainEvent): void;
|
|
121
|
-
collect(): ReadonlyArray<DomainEvent>;
|
|
122
|
-
}
|
|
123
|
-
//#endregion
|
|
124
|
-
//#region src/application/unit-of-work.d.ts
|
|
125
|
-
/**
|
|
126
|
-
* Commits the processed-message record, repository writes, and emitted events together before resolving.
|
|
127
|
-
* An existing record rejects with `MessageAlreadyProcessedError`; external effects must run through the outbox after commit.
|
|
128
|
-
* Nested calls reject with `UnitOfWorkAlreadyActiveError`; independent concurrent calls are allowed.
|
|
129
|
-
*/
|
|
130
|
-
interface IUnitOfWork<Repos> {
|
|
131
|
-
run<T>(messageId: MessageId, work: (repos: Repos) => Promise<T>): Promise<T>;
|
|
132
|
-
}
|
|
133
|
-
type UnitOfWorkDeps<Tx, Repos> = {
|
|
134
|
-
readonly transaction: ITransaction<Tx>;
|
|
135
|
-
/** The processed-messages and outbox repository for this transaction. */
|
|
136
|
-
readonly messageStore: (tx: Tx) => IMessageStore;
|
|
137
|
-
/** Repositories participate in the current transaction. */
|
|
138
|
-
readonly createRepositories: (tx: Tx) => Repos;
|
|
139
|
-
readonly eventCollector: IEventCollector;
|
|
140
|
-
readonly relay: IOutboxRelay;
|
|
141
|
-
};
|
|
142
|
-
/** The unit of work: the boundary, the repositories, the events. Every database call is a port. */
|
|
143
|
-
declare class UnitOfWork<Tx, Repos> implements IUnitOfWork<Repos> {
|
|
144
|
-
private readonly deps;
|
|
145
|
-
constructor(deps: UnitOfWorkDeps<Tx, Repos>);
|
|
146
|
-
run<T>(messageId: MessageId, work: (repos: Repos) => Promise<T>): Promise<T>;
|
|
147
|
-
}
|
|
148
|
-
//#endregion
|
|
149
229
|
//#region src/application/message-already-processed.error.d.ts
|
|
150
230
|
/** The message's effects already committed. A caller can skip duplicate delivery without repeating those effects. */
|
|
151
231
|
declare class MessageAlreadyProcessedError extends AppError {
|
|
@@ -167,5 +247,5 @@ declare class UnitOfWorkAlreadyActiveError extends AppError {
|
|
|
167
247
|
constructor();
|
|
168
248
|
}
|
|
169
249
|
//#endregion
|
|
170
|
-
export {
|
|
171
|
-
//# sourceMappingURL=index-
|
|
250
|
+
export { RecordingEmailService as A, IMessageStore as C, IEmailService as D, EmailAttachment as E, EventHandler as M, QueryHandler as N, MimeType as O, IOutboxRelay as S, EmailAccepted as T, recordEmailEvent as _, CommandRegistry as a, UnitOfWorkDeps as b, MessageRegistry as c, RegistryMessage as d, EmailBounceRecord as f, RecordEmailEventRepos as g, RecordEmailEventDeps as h, MessageBus as i, CommandHandler as j, OutboundEmail as k, MessageResult as l, RecordEmailEventCommand as m, MessageAlreadyProcessedError as n, EventRegistry as o, IEmailDeliverabilityStore as p, IMessageBus as r, Handlers as s, UnitOfWorkAlreadyActiveError as t, QueryRegistry as u, IUnitOfWork as v, IEventCollector as w, ITransaction as x, UnitOfWork as y };
|
|
251
|
+
//# sourceMappingURL=index-DgDyeR5s.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-DgDyeR5s.d.ts","names":[],"sources":["../src/application/handlers.ts","../src/application/email-service.ts","../src/application/event-collector.ts","../src/application/message-store.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/message-already-processed.error.ts","../src/application/unit-of-work.errors.ts"],"mappings":"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"}
|
package/dist/postgres.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { W as DomainEvent, nt as DatabaseFailure, q as MessageId, tt as DatabaseError } from "./index-
|
|
2
|
-
import {
|
|
3
|
-
import { n as DrizzleSchema, t as eventCollector } from "./unit-of-work-context-
|
|
1
|
+
import { W as DomainEvent, nt as DatabaseFailure, q as MessageId, tt as DatabaseError } from "./index-Bl0K1RQW.js";
|
|
2
|
+
import { C as IMessageStore, x as ITransaction } from "./index-DgDyeR5s.js";
|
|
3
|
+
import { n as DrizzleSchema, t as eventCollector } from "./unit-of-work-context-BzmnjlDa.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 { E as DatabaseError,
|
|
2
|
-
import { i as MessageAlreadyProcessedError } from "./application-
|
|
3
|
-
import { n as eventCollector, r as runWithUnitOfWorkContext } from "./unit-of-work-context-
|
|
1
|
+
import { E as DatabaseError, Q as AppError } from "./core-DG_cC8YT.js";
|
|
2
|
+
import { i as MessageAlreadyProcessedError } from "./application-CIxo_BpK.js";
|
|
3
|
+
import { n as eventCollector, r as runWithUnitOfWorkContext } from "./unit-of-work-context-BPE1In2f.js";
|
|
4
4
|
import { DrizzleQueryError } from "drizzle-orm/errors";
|
|
5
5
|
import { isNull } from "drizzle-orm";
|
|
6
6
|
import { index, integer, jsonb, pgTable, text, timestamp } from "drizzle-orm/pg-core";
|
package/dist/resend.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jt as BounceType } from "./index-Bl0K1RQW.js";
|
|
2
|
+
import { D as IEmailService, T as EmailAccepted, k as OutboundEmail } from "./index-DgDyeR5s.js";
|
|
3
|
+
import { r as WebhookVerifier, t as WebhookVerification } from "./webhook-verification-sZtwTI5n.js";
|
|
4
|
+
import { Resend } from "resend";
|
|
5
|
+
//#region src/infrastructure/resend/resend-email-service.d.ts
|
|
6
|
+
/** The SDK operations required by the adapter; a test factory can return a plain object. */
|
|
7
|
+
type ResendEmailClient = {
|
|
8
|
+
readonly emails: Pick<Resend['emails'], 'send'>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Send without package retries or logs. Ported from Suparelay's resend-email-service.ts.
|
|
12
|
+
* The Resend SDK itself logs API errors outside production.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ResendEmailService implements IEmailService {
|
|
15
|
+
private readonly createClient;
|
|
16
|
+
private readonly fromAddress;
|
|
17
|
+
/** Load the SDK on the first send. Constructing the service does not load it. */
|
|
18
|
+
static create(apiKey: string, fromAddress: string): ResendEmailService;
|
|
19
|
+
private client;
|
|
20
|
+
/** Supply an async factory. The service calls it once, on the first send, and keeps its promise. */
|
|
21
|
+
constructor(createClient: () => Promise<ResendEmailClient>, fromAddress: string);
|
|
22
|
+
/** Resolve after acceptance. Provider failures throw EmailServiceError; SDK defects retain their identity. */
|
|
23
|
+
sendEmail(email: OutboundEmail): Promise<EmailAccepted>;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/infrastructure/resend/email-event.d.ts
|
|
27
|
+
declare const SIMPLE_EMAIL_TYPES: readonly ['email.sent', 'email.scheduled', 'email.delivered', 'email.delivery_delayed', 'email.complained', 'email.opened', 'email.received', 'email.suppressed'];
|
|
28
|
+
/** Resend email event names supported by this module. */
|
|
29
|
+
type EmailEventType = (typeof SIMPLE_EMAIL_TYPES)[number] | 'email.bounced' | 'email.failed' | 'email.clicked';
|
|
30
|
+
type EmailEventBase = {
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly emailId: string;
|
|
33
|
+
readonly recipients: readonly string[];
|
|
34
|
+
readonly subject: string;
|
|
35
|
+
readonly tags: Readonly<Record<string, string>>;
|
|
36
|
+
readonly occurredAt: string;
|
|
37
|
+
};
|
|
38
|
+
/** A verified event. `id` is the Svix identity; use `resend:event:${id}` as the command id. */
|
|
39
|
+
type EmailEvent = (EmailEventBase & {
|
|
40
|
+
readonly type: 'email.bounced';
|
|
41
|
+
readonly bounce: {
|
|
42
|
+
readonly type: BounceType;
|
|
43
|
+
readonly subType: string | null;
|
|
44
|
+
readonly message: string;
|
|
45
|
+
};
|
|
46
|
+
}) | (EmailEventBase & {
|
|
47
|
+
readonly type: 'email.failed';
|
|
48
|
+
readonly reason: string;
|
|
49
|
+
}) | (EmailEventBase & {
|
|
50
|
+
readonly type: 'email.clicked';
|
|
51
|
+
readonly link: string;
|
|
52
|
+
}) | (EmailEventBase & {
|
|
53
|
+
readonly type: (typeof SIMPLE_EMAIL_TYPES)[number];
|
|
54
|
+
});
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/infrastructure/resend/resend-webhook.d.ts
|
|
57
|
+
/** The SDK's local signature verifier. It makes no API request. */
|
|
58
|
+
type ResendWebhookClient = Pick<Resend['webhooks'], 'verify'>;
|
|
59
|
+
/** Verify Svix signatures and map Resend email events. Ported from Typist's Resend route. */
|
|
60
|
+
export declare class ResendWebhook implements WebhookVerifier<EmailEvent> {
|
|
61
|
+
private readonly webhookSecret;
|
|
62
|
+
private readonly verifier;
|
|
63
|
+
/** Load the SDK on the first verification. Only the webhook secret is required. */
|
|
64
|
+
static create(webhookSecret: string): ResendWebhook;
|
|
65
|
+
private client;
|
|
66
|
+
/** Inject the local SDK verifier when testing. */
|
|
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>>;
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export type { EmailEvent, EmailEventType, ResendEmailClient, ResendWebhookClient };
|
|
73
|
+
//# sourceMappingURL=resend.d.ts.map
|
|
@@ -0,0 +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"}
|