@voltro/plugin-mail 0.83.1 → 0.85.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/index.js CHANGED
@@ -1,134 +1,134 @@
1
- import { Context as e, Duration as t, Effect as n, Fiber as r, Layer as i, ParseResult as a, Schedule as o, Schema as s } from "effect";
2
- import { definePlugin as c, pluginInstanceName as l } from "@voltro/protocol";
3
- import { pluginEnv as u } from "@voltro/env";
4
- import { createLogger as d } from "@voltro/logger";
5
- import { and as f, dropped as p, eq as m, id as h, inSet as g, queryFor as _, registerRetention as ee, retentionTtlMsFromEnv as v, table as y, text as b, timestamp as x } from "@voltro/database";
6
- import { FetchHttpClient as te, HttpClient as S, HttpClientRequest as C } from "@effect/platform";
1
+ import { Context as e, Duration as t, Effect as n, Fiber as r, Layer as i, Result as a, Schedule as o, Schema as s, SchemaIssue as c } from "effect";
2
+ import { definePlugin as l, pluginInstanceName as u } from "@voltro/protocol";
3
+ import { pluginEnv as d } from "@voltro/env";
4
+ import { createLogger as f } from "@voltro/logger";
5
+ import { and as p, dropped as m, eq as h, id as g, inSet as _, queryFor as v, registerRetention as y, retentionTtlMsFromEnv as b, table as x, text as S, timestamp as C } from "@voltro/database";
6
+ import { FetchHttpClient as w, HttpClient as T, HttpClientRequest as E } from "effect/http";
7
7
  //#region src/types.ts
8
- var w = class extends s.TaggedError()("MailError", {
8
+ var D = class extends s.TaggedError()("MailError", {
9
9
  provider: s.String,
10
10
  message: s.String,
11
11
  transient: s.Boolean,
12
12
  status: s.optional(s.Number)
13
- }) {}, T = class extends s.TaggedError()("MailWebhookError", {
13
+ }) {}, O = class extends s.TaggedError()("MailWebhookError", {
14
14
  provider: s.String,
15
15
  message: s.String
16
- }) {}, ne = (e) => ({
16
+ }) {}, k = (e) => ({
17
17
  name: e.name,
18
18
  props: e.props,
19
19
  subject: e.subject,
20
20
  render: e.render,
21
21
  ...e.locale === void 0 ? {} : { locale: e.locale },
22
22
  ...e.preview === void 0 ? {} : { preview: e.preview }
23
- }), E = class extends e.Tag("@voltro/plugin-mail/MailService")() {}, D = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, re = (e) => {
23
+ }), A = class extends e.Service()("@voltro/plugin-mail/MailService") {}, j = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, ee = (e) => {
24
24
  try {
25
- let t = a.ArrayFormatter.formatErrorSync(e);
26
- return t.length === 0 ? String(e) : t.map((e) => `${e.path.length > 0 ? e.path.join(".") : "(root)"}: ${e.message}`).join("; ");
25
+ let t = c.makeFormatterStandardSchemaV1()(e.issue).issues;
26
+ return t.length === 0 ? String(e) : t.map((e) => `${e.path !== void 0 && e.path.length > 0 ? e.path.map(String).join(".") : "(root)"}: ${e.message}`).join("; ");
27
27
  } catch {
28
28
  return String(e);
29
29
  }
30
- }, O = null, ie = async () => {
31
- if (!O) {
30
+ }, M = null, te = async () => {
31
+ if (!M) {
32
32
  let e = await import("@react-email/render");
33
- if (O = e.render ?? e.default?.render ?? null, !O) throw Error("@react-email/render: `render` export not found (install @react-email/render + react + react-dom)");
33
+ if (M = e.render ?? e.default?.render ?? null, !M) throw Error("@react-email/render: `render` export not found (install @react-email/render + react + react-dom)");
34
34
  }
35
- return O;
36
- }, k = (e, t) => n.gen(function* () {
37
- let r = e, i = yield* s.decodeUnknown(r.props)(t).pipe(n.mapError((t) => new w({
35
+ return M;
36
+ }, ne = (e, t) => n.gen(function* () {
37
+ let r = e, i = yield* s.decodeUnknownEffect(r.props)(t).pipe(n.mapError((t) => new D({
38
38
  provider: "template",
39
- message: `invalid props for '${e.name}': ${re(t)}`.slice(0, 500),
39
+ message: `invalid props for '${e.name}': ${ee(t)}`.slice(0, 500),
40
40
  transient: !1
41
41
  }))), a = r.subject(i), o = r.render(i);
42
42
  return {
43
43
  subject: a,
44
44
  html: yield* n.tryPromise({
45
- try: async () => (await ie())(o, { plainText: !1 }),
46
- catch: (t) => new w({
45
+ try: async () => (await te())(o, { plainText: !1 }),
46
+ catch: (t) => new D({
47
47
  provider: "template",
48
48
  message: `render failed for '${e.name}': ${String(t)}`.slice(0, 500),
49
49
  transient: !1
50
50
  })
51
51
  }),
52
52
  text: yield* n.tryPromise({
53
- try: async () => (await ie())(o, { plainText: !0 }),
54
- catch: (t) => new w({
53
+ try: async () => (await te())(o, { plainText: !0 }),
54
+ catch: (t) => new D({
55
55
  provider: "template",
56
56
  message: `render(text) failed for '${e.name}': ${String(t)}`.slice(0, 500),
57
57
  transient: !1
58
58
  })
59
59
  })
60
60
  };
61
- }), A = /* @__PURE__ */ new Map(), ae = (e) => e.locale ? `${e.name}:${e.locale}` : e.name, oe = (e) => {
62
- for (let t of e) A.set(ae(t), t);
63
- }, j = (e, t) => (t ? A.get(`${e}:${t}`) : void 0) ?? A.get(e), se = () => A.size, ce = () => [...A.values()].map((e) => e.locale ? {
61
+ }), N = /* @__PURE__ */ new Map(), re = (e) => e.locale ? `${e.name}:${e.locale}` : e.name, ie = (e) => {
62
+ for (let t of e) N.set(re(t), t);
63
+ }, P = (e, t) => (t ? N.get(`${e}:${t}`) : void 0) ?? N.get(e), ae = () => N.size, oe = () => [...N.values()].map((e) => e.locale ? {
64
64
  name: e.name,
65
65
  locale: e.locale
66
- } : { name: e.name }), le = () => A.clear(), ue = (e) => {
66
+ } : { name: e.name }), se = () => N.clear(), ce = (e) => {
67
67
  if (typeof e != "object" || !e) return !1;
68
68
  let t = e;
69
69
  return typeof t.name == "string" && typeof t.subject == "function" && typeof t.render == "function" && t.props !== void 0;
70
- }, M = "_voltro_mail_suppression", N = "_voltro_mail_idempotency", de = y(M, {
71
- id: h({ scheme: "numeric" }),
72
- tenant: b().maxLength(191),
73
- email: b().maxLength(320),
74
- reason: b().nullable(),
75
- createdAt: x().default("now"),
76
- created_at: p()
77
- }).unique("mailSuppressionAddress", ["tenant", "email"]).nonReactive(), fe = y(N, {
78
- id: h({ scheme: "numeric" }),
79
- tenant: b().maxLength(191),
80
- key: b().maxLength(255),
81
- resultId: b().nullable().renamedFrom("result_id"),
82
- resultProvider: b().nullable().renamedFrom("result_provider"),
83
- createdAt: x().default("now"),
84
- created_at: p()
85
- }).unique("mailIdempotencyKey", ["tenant", "key"]).nonReactive(), P = (e) => n.tryPromise({
70
+ }, F = "_voltro_mail_suppression", I = "_voltro_mail_idempotency", le = x(F, {
71
+ id: g({ scheme: "numeric" }),
72
+ tenant: S().maxLength(191),
73
+ email: S().maxLength(320),
74
+ reason: S().nullable(),
75
+ createdAt: C().default("now"),
76
+ created_at: m()
77
+ }).unique("mailSuppressionAddress", ["tenant", "email"]).nonReactive(), ue = x(I, {
78
+ id: g({ scheme: "numeric" }),
79
+ tenant: S().maxLength(191),
80
+ key: S().maxLength(255),
81
+ resultId: S().nullable().renamedFrom("result_id"),
82
+ resultProvider: S().nullable().renamedFrom("result_provider"),
83
+ createdAt: C().default("now"),
84
+ created_at: m()
85
+ }).unique("mailIdempotencyKey", ["tenant", "key"]).nonReactive(), L = (e) => n.tryPromise({
86
86
  try: e,
87
87
  catch: (e) => e
88
- }), F = (e) => {
88
+ }), R = (e) => {
89
89
  let t = [];
90
90
  for (let n = e, r = 0; n != null && r < 4; n = n.cause, r++) t.push(n instanceof Error ? n.message : String(n));
91
91
  return t.join(" ← ");
92
- }, pe = d({ scope: "@voltro/plugin-mail" }), I = (e) => e.trim().toLowerCase(), me = "*", L = (e) => e ?? me, R = () => {
93
- let e = /* @__PURE__ */ new Set(), t = (e, t) => `${L(e)}\u0000${I(t)}`;
92
+ }, de = f({ scope: "@voltro/plugin-mail" }), z = (e) => e.trim().toLowerCase(), fe = "*", pe = (e) => e ?? fe, B = () => {
93
+ let e = /* @__PURE__ */ new Set(), t = (e, t) => `${pe(e)}\u0000${z(t)}`;
94
94
  return {
95
95
  isSuppressed: (r, i) => n.sync(() => e.has(t(r, i)) || e.has(t(null, i))),
96
96
  suppress: (r, i) => n.sync(() => void e.add(t(r, i))),
97
97
  unsuppress: (r, i) => n.sync(() => void e.delete(t(r, i)))
98
98
  };
99
- }, he = () => {
99
+ }, me = () => {
100
100
  let e = null, t = (e, t) => ({
101
- tenant: L(e),
102
- email: I(t)
101
+ tenant: pe(e),
102
+ email: z(t)
103
103
  });
104
104
  return {
105
105
  isSuppressed: (t, r) => {
106
106
  let i = e;
107
- return i ? P(() => i.query(_(de).where(f(m("email", I(r)), g("tenant", [L(t), me]))).limit(1).descriptor)).pipe(n.map((e) => e.length > 0), n.catchAll(() => n.succeed(!1))) : n.succeed(!1);
107
+ return i ? L(() => i.query(v(le).where(p(h("email", z(r)), _("tenant", [pe(t), fe]))).limit(1).descriptor)).pipe(n.map((e) => e.length > 0), n.catch(() => n.succeed(!1))) : n.succeed(!1);
108
108
  },
109
109
  suppress: (r, i, a) => {
110
110
  let o = e;
111
- return o ? P(() => o.upsert(M, {
111
+ return o ? L(() => o.upsert(F, {
112
112
  ...t(r, i),
113
113
  reason: a,
114
114
  createdAt: /* @__PURE__ */ new Date()
115
- }, { conflictColumns: ["tenant", "email"] })).pipe(n.asVoid, n.catchAll((e) => n.sync(() => pe.warn("suppress write failed", {
116
- email: I(i),
117
- message: F(e)
115
+ }, { conflictColumns: ["tenant", "email"] })).pipe(n.asVoid, n.catch((e) => n.sync(() => de.warn("suppress write failed", {
116
+ email: z(i),
117
+ message: R(e)
118
118
  })))) : n.void;
119
119
  },
120
120
  unsuppress: (r, i) => {
121
121
  let a = e;
122
122
  if (!a) return n.void;
123
123
  let { tenant: o, email: s } = t(r, i);
124
- return P(() => a.deleteMany(M, { where: f(m("tenant", o), m("email", s)) })).pipe(n.asVoid, n.catchAll(() => n.void));
124
+ return L(() => a.deleteMany(F, { where: p(h("tenant", o), h("email", s)) })).pipe(n.asVoid, n.catch(() => n.void));
125
125
  },
126
126
  bind: async (t) => {
127
127
  e = t;
128
128
  }
129
129
  };
130
- }, ge = d({ scope: "@voltro/plugin-mail" }), z = (e) => e ?? "*", B = () => {
131
- let e = /* @__PURE__ */ new Map(), t = (e, t) => `${z(e)} ${t}`;
130
+ }, he = f({ scope: "@voltro/plugin-mail" }), V = (e) => e ?? "*", H = () => {
131
+ let e = /* @__PURE__ */ new Map(), t = (e, t) => `${V(e)} ${t}`;
132
132
  return {
133
133
  reserve: (r, i) => n.sync(() => {
134
134
  let n = t(r, i);
@@ -143,13 +143,13 @@ var w = class extends s.TaggedError()("MailError", {
143
143
  }),
144
144
  record: (r, i, a) => n.sync(() => void e.set(t(r, i), a))
145
145
  };
146
- }, _e = () => {
146
+ }, ge = () => {
147
147
  let e = null;
148
148
  return {
149
149
  reserve: (t, r) => {
150
150
  let i = e;
151
- return i ? P(() => i.insertIgnoreWithOutcome(N, {
152
- tenant: z(t),
151
+ return i ? L(() => i.insertIgnoreWithOutcome(I, {
152
+ tenant: V(t),
153
153
  key: r,
154
154
  createdAt: /* @__PURE__ */ new Date()
155
155
  }, { conflictColumns: ["tenant", "key"] })).pipe(n.map(({ row: e, outcome: t }) => {
@@ -162,26 +162,26 @@ var w = class extends s.TaggedError()("MailError", {
162
162
  provider: r
163
163
  }
164
164
  } : { won: !1 };
165
- }), n.catchAll((e) => n.sync(() => (ge.warn("idempotency reserve failed — skipping send to avoid a double", {
165
+ }), n.catch((e) => n.sync(() => (he.warn("idempotency reserve failed — skipping send to avoid a double", {
166
166
  key: r,
167
- message: F(e)
167
+ message: R(e)
168
168
  }), { won: !1 })))) : n.succeed({ won: !0 });
169
169
  },
170
170
  record: (t, r, i) => {
171
171
  let a = e;
172
- return a ? P(() => a.updateMany(N, {
172
+ return a ? L(() => a.updateMany(I, {
173
173
  resultId: i.id,
174
174
  resultProvider: i.provider
175
- }, { where: f(m("tenant", z(t)), m("key", r)) })).pipe(n.asVoid, n.catchAll((e) => n.sync(() => ge.warn("idempotency record failed", {
175
+ }, { where: p(h("tenant", V(t)), h("key", r)) })).pipe(n.asVoid, n.catch((e) => n.sync(() => he.warn("idempotency record failed", {
176
176
  key: r,
177
- message: F(e)
177
+ message: R(e)
178
178
  })))) : n.void;
179
179
  },
180
180
  bind: async (t) => {
181
181
  e = t;
182
182
  }
183
183
  };
184
- }, ve = d({ scope: "@voltro/plugin-mail" }), V = () => {
184
+ }, _e = f({ scope: "@voltro/plugin-mail" }), U = () => {
185
185
  let e = /* @__PURE__ */ new Map();
186
186
  return {
187
187
  hold: (t) => n.sync(() => void e.set(t.id, t)),
@@ -192,34 +192,34 @@ var w = class extends s.TaggedError()("MailError", {
192
192
  }),
193
193
  size: () => n.sync(() => e.size)
194
194
  };
195
- }, ye = 0, be = (e) => e.idempotencyKey ?? `held-${ye += 1}`, xe = (e) => ({
195
+ }, ve = 0, ye = (e) => e.idempotencyKey ?? `held-${ve += 1}`, be = (e) => ({
196
196
  shouldHold: (t) => !e.providerSchedules && t !== void 0 && t.getTime() > Date.now(),
197
197
  hold: (t) => {
198
198
  let { scheduledAt: n, ...r } = t;
199
199
  return e.store.hold({
200
- id: be(t),
200
+ id: ye(t),
201
201
  dueAt: t.scheduledAt?.getTime() ?? Date.now(),
202
202
  message: r
203
203
  });
204
204
  },
205
205
  tick: (t = Date.now()) => n.gen(function* () {
206
206
  let r = yield* e.store.claimDue(t);
207
- for (let t of r) yield* e.flush(t.message).pipe(n.catchAll((e) => n.sync(() => ve.warn("scheduled flush failed", {
207
+ for (let t of r) yield* e.flush(t.message).pipe(n.catch((e) => n.sync(() => _e.warn("scheduled flush failed", {
208
208
  id: t.id,
209
209
  message: String(e)
210
210
  }))));
211
211
  return r.length;
212
212
  }),
213
213
  pending: () => e.store.size()
214
- }), Se = 0, Ce = (e) => `${e}-${Se += 1}`, we = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, H = (e, t) => {
214
+ }), xe = 0, Se = (e) => `${e}-${xe += 1}`, Ce = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, W = (e, t) => {
215
215
  let n = t.status;
216
- return new w({
216
+ return new D({
217
217
  provider: e,
218
218
  message: (t.message ?? "send failed").slice(0, 500),
219
- transient: e === "smtp" ? n === void 0 || n >= 400 && n < 500 : we(n),
219
+ transient: e === "smtp" ? n === void 0 || n >= 400 && n < 500 : Ce(n),
220
220
  ...n === void 0 ? {} : { status: n }
221
221
  });
222
- }, U = (e, t, r, i, a) => n.tryPromise({
222
+ }, G = (e, t, r, i, a) => n.tryPromise({
223
223
  try: async () => {
224
224
  let e = await fetch(t, {
225
225
  method: "POST",
@@ -240,19 +240,19 @@ var w = class extends s.TaggedError()("MailError", {
240
240
  },
241
241
  catch: (t) => {
242
242
  let n = t;
243
- return H(e, {
243
+ return W(e, {
244
244
  ...typeof n.status == "number" ? { status: n.status } : {},
245
245
  message: n.message ?? t?.message ?? String(t)
246
246
  });
247
247
  }
248
- }), W = 500, Te = (e, t) => {
248
+ }), K = 500, we = (e, t) => {
249
249
  let n = e.stream === "broadcast" ? t?.broadcast ?? "broadcast" : t?.transactional;
250
250
  return {
251
251
  ...n === void 0 ? {} : { route: n },
252
252
  from: e.from,
253
- to: D(e.to),
254
- ...e.cc ? { cc: D(e.cc) } : {},
255
- ...e.bcc ? { bcc: D(e.bcc) } : {},
253
+ to: j(e.to),
254
+ ...e.cc ? { cc: j(e.cc) } : {},
255
+ ...e.bcc ? { bcc: j(e.bcc) } : {},
256
256
  ...e.replyTo ? { reply_to: [e.replyTo] } : {},
257
257
  subject: e.subject,
258
258
  ...e.html === void 0 ? {} : { html: e.html },
@@ -270,10 +270,10 @@ var w = class extends s.TaggedError()("MailError", {
270
270
  ...e.contentType ? { content_type: e.contentType } : {}
271
271
  })) } : {}
272
272
  };
273
- }, Ee = (e, t, r, i = Math.floor(Date.now() / 1e3), a = 300) => n.tryPromise({
273
+ }, Te = (e, t, r, i = Math.floor(Date.now() / 1e3), a = 300) => n.tryPromise({
274
274
  try: async () => {
275
275
  let n = (e) => {
276
- throw new T({
276
+ throw new O({
277
277
  provider: "lettermint",
278
278
  message: e
279
279
  });
@@ -293,11 +293,11 @@ var w = class extends s.TaggedError()("MailError", {
293
293
  return n("body is not JSON");
294
294
  }
295
295
  },
296
- catch: (e) => e instanceof T ? e : new T({
296
+ catch: (e) => e instanceof O ? e : new O({
297
297
  provider: "lettermint",
298
298
  message: e?.message ?? String(e)
299
299
  })
300
- }), De = (e) => {
300
+ }), Ee = (e) => {
301
301
  let t = (e.baseUrl ?? "https://api.lettermint.co/v1").replace(/\/+$/, ""), r = {
302
302
  "x-lettermint-token": e.projectToken,
303
303
  accept: "application/json"
@@ -306,31 +306,31 @@ var w = class extends s.TaggedError()("MailError", {
306
306
  name: "lettermint",
307
307
  supportsScheduling: !0,
308
308
  managesUnsubscribe: !0,
309
- send: (n) => U("lettermint", `${t}/send`, {
309
+ send: (n) => G("lettermint", `${t}/send`, {
310
310
  ...r,
311
311
  ...n.idempotencyKey === void 0 ? {} : { "idempotency-key": n.idempotencyKey }
312
- }, Te(n, e.routes), async (e) => ({
312
+ }, we(n, e.routes), async (e) => ({
313
313
  id: (await e.json()).message_id ?? "lettermint",
314
314
  provider: "lettermint"
315
315
  })),
316
- sendBatch: (i) => n.forEach(Array.from({ length: Math.ceil(i.length / W) }, (e, t) => i.slice(t * W, (t + 1) * W)), (n) => U("lettermint", `${t}/send/batch`, r, n.map((t) => Te(t, e.routes)), async (e) => {
316
+ sendBatch: (i) => n.forEach(Array.from({ length: Math.ceil(i.length / K) }, (e, t) => i.slice(t * K, (t + 1) * K)), (n) => G("lettermint", `${t}/send/batch`, r, n.map((t) => we(t, e.routes)), async (e) => {
317
317
  let t = await e.json();
318
318
  return n.map((e, n) => ({
319
319
  id: t[n]?.message_id ?? "lettermint",
320
320
  provider: "lettermint"
321
321
  }));
322
322
  })).pipe(n.map((e) => e.flat())),
323
- webhook: { verify: Ee }
323
+ webhook: { verify: Te }
324
324
  };
325
- }, Oe = (e) => ({
325
+ }, De = (e) => ({
326
326
  from: e.from,
327
- to: D(e.to),
327
+ to: j(e.to),
328
328
  subject: e.subject,
329
329
  html: e.html,
330
330
  text: e.text,
331
331
  reply_to: e.replyTo,
332
- cc: e.cc ? D(e.cc) : void 0,
333
- bcc: e.bcc ? D(e.bcc) : void 0,
332
+ cc: e.cc ? j(e.cc) : void 0,
333
+ bcc: e.bcc ? j(e.bcc) : void 0,
334
334
  headers: e.headers,
335
335
  tags: e.tags?.map((e) => ({
336
336
  name: e,
@@ -342,34 +342,34 @@ var w = class extends s.TaggedError()("MailError", {
342
342
  content: e.content,
343
343
  ...e.contentType ? { content_type: e.contentType } : {}
344
344
  }))
345
- }), ke = (e) => ({
345
+ }), Oe = (e) => ({
346
346
  name: "resend",
347
347
  supportsScheduling: !0,
348
- send: (t) => U("resend", "https://api.resend.com/emails", { authorization: `Bearer ${e.apiKey}` }, Oe(t), async (e) => ({
348
+ send: (t) => G("resend", "https://api.resend.com/emails", { authorization: `Bearer ${e.apiKey}` }, De(t), async (e) => ({
349
349
  id: (await e.json()).id ?? "resend",
350
350
  provider: "resend"
351
351
  })),
352
- sendBatch: (t) => U("resend", "https://api.resend.com/emails/batch", { authorization: `Bearer ${e.apiKey}` }, t.map(Oe), async (e) => {
352
+ sendBatch: (t) => G("resend", "https://api.resend.com/emails/batch", { authorization: `Bearer ${e.apiKey}` }, t.map(De), async (e) => {
353
353
  let n = (await e.json()).data ?? [];
354
354
  return t.map((e, t) => ({
355
355
  id: n[t]?.id ?? "resend",
356
356
  provider: "resend"
357
357
  }));
358
358
  })
359
- }), Ae = (e) => ({
359
+ }), ke = (e) => ({
360
360
  name: "postmark",
361
- send: (t) => U("postmark", "https://api.postmarkapp.com/email", {
361
+ send: (t) => G("postmark", "https://api.postmarkapp.com/email", {
362
362
  "x-postmark-server-token": e.serverToken,
363
363
  accept: "application/json"
364
364
  }, {
365
365
  From: t.from,
366
- To: D(t.to).join(","),
366
+ To: j(t.to).join(","),
367
367
  Subject: t.subject,
368
368
  HtmlBody: t.html,
369
369
  TextBody: t.text,
370
370
  ReplyTo: t.replyTo,
371
- Cc: t.cc ? D(t.cc).join(",") : void 0,
372
- Bcc: t.bcc ? D(t.bcc).join(",") : void 0,
371
+ Cc: t.cc ? j(t.cc).join(",") : void 0,
372
+ Bcc: t.bcc ? j(t.bcc).join(",") : void 0,
373
373
  MessageStream: t.stream === "broadcast" ? e.streams?.broadcast ?? "broadcast" : e.streams?.transactional ?? "outbound",
374
374
  Headers: t.headers ? Object.entries(t.headers).map(([e, t]) => ({
375
375
  Name: e,
@@ -385,44 +385,44 @@ var w = class extends s.TaggedError()("MailError", {
385
385
  id: (await e.json()).MessageID ?? "postmark",
386
386
  provider: "postmark"
387
387
  }))
388
- }), je = (e) => [...e.text ? [{
388
+ }), Ae = (e) => [...e.text ? [{
389
389
  type: "text/plain",
390
390
  value: e.text
391
391
  }] : [], ...e.html ? [{
392
392
  type: "text/html",
393
393
  value: e.html
394
- }] : []], Me = (e) => ({
395
- to: D(e.to).map((e) => ({ email: e })),
396
- cc: e.cc ? D(e.cc).map((e) => ({ email: e })) : void 0,
397
- bcc: e.bcc ? D(e.bcc).map((e) => ({ email: e })) : void 0,
394
+ }] : []], je = (e) => ({
395
+ to: j(e.to).map((e) => ({ email: e })),
396
+ cc: e.cc ? j(e.cc).map((e) => ({ email: e })) : void 0,
397
+ bcc: e.bcc ? j(e.bcc).map((e) => ({ email: e })) : void 0,
398
398
  subject: e.subject,
399
399
  ...e.scheduledAt ? { send_at: Math.floor(e.scheduledAt.getTime() / 1e3) } : {}
400
- }), Ne = (e) => e.attachments?.map((e) => ({
400
+ }), Me = (e) => e.attachments?.map((e) => ({
401
401
  filename: e.filename,
402
402
  content: e.content,
403
403
  type: e.contentType ?? "application/octet-stream",
404
404
  disposition: "attachment"
405
- })), Pe = (e) => {
405
+ })), Ne = (e) => {
406
406
  let t = (e) => ({
407
- personalizations: [Me(e)],
407
+ personalizations: [je(e)],
408
408
  from: { email: e.from },
409
409
  reply_to: e.replyTo ? { email: e.replyTo } : void 0,
410
410
  subject: e.subject,
411
- content: je(e),
412
- attachments: Ne(e)
411
+ content: Ae(e),
412
+ attachments: Me(e)
413
413
  });
414
414
  return {
415
415
  name: "sendgrid",
416
416
  supportsScheduling: !0,
417
- send: (n) => U("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, t(n), async (e) => ({
417
+ send: (n) => G("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, t(n), async (e) => ({
418
418
  id: e.headers.get("x-message-id") ?? "sendgrid",
419
419
  provider: "sendgrid"
420
420
  })),
421
- sendBatch: (t) => U("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, {
422
- personalizations: t.map(Me),
421
+ sendBatch: (t) => G("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, {
422
+ personalizations: t.map(je),
423
423
  from: { email: t[0]?.from },
424
424
  subject: t[0]?.subject,
425
- content: je(t[0] ?? {})
425
+ content: Ae(t[0] ?? {})
426
426
  }, async (e) => {
427
427
  let n = e.headers.get("x-message-id") ?? "sendgrid";
428
428
  return t.map((e, t) => ({
@@ -431,35 +431,35 @@ var w = class extends s.TaggedError()("MailError", {
431
431
  }));
432
432
  })
433
433
  };
434
- }, Fe = (e, t) => {
434
+ }, Pe = (e, t) => {
435
435
  let n = t, r = n.response?.status;
436
- return H(e, {
436
+ return W(e, {
437
437
  ...typeof r == "number" ? { status: r } : {},
438
438
  message: n.message ?? String(t)
439
439
  });
440
- }, Ie = (e, t, r) => n.gen(function* () {
441
- let i = yield* (yield* S.HttpClient).execute(t);
440
+ }, Fe = (e, t, r) => n.gen(function* () {
441
+ let i = yield* (yield* T.HttpClient).execute(t);
442
442
  if (i.status < 200 || i.status >= 300) {
443
- let t = yield* i.text.pipe(n.catchAll(() => n.succeed("")));
444
- return yield* n.fail(H(e, {
443
+ let t = yield* i.text.pipe(n.catch(() => n.succeed("")));
444
+ return yield* n.fail(W(e, {
445
445
  status: i.status,
446
446
  message: t || `HTTP ${i.status}`
447
447
  }));
448
448
  }
449
449
  return yield* r(i);
450
- }).pipe(n.catchAll((t) => t instanceof w ? n.fail(t) : n.fail(Fe(e, t))), n.provide(te.layer)), Le = (e) => ({ sign: async (t, n, r) => {
450
+ }).pipe(n.catch((t) => t instanceof D ? n.fail(t) : n.fail(Pe(e, t))), n.provide(w.layer), n.provideService(w.Fetch, (e, t) => globalThis.fetch(e, t))), Ie = (e) => ({ sign: async (t, n, r) => {
451
451
  let { createHash: i, createHmac: a } = await import("node:crypto"), o = (e) => i("sha256").update(e).digest("hex"), s = (e, t) => a("sha256", e).update(t).digest(), c = (/* @__PURE__ */ new Date()).toISOString().replace(/[:-]|\.\d{3}/g, ""), l = c.slice(0, 8), u = `host:${new URL(t).host}\nx-amz-date:${c}\n` + (e.sessionToken ? `x-amz-security-token:${e.sessionToken}\n` : ""), d = e.sessionToken ? "host;x-amz-date;x-amz-security-token" : "host;x-amz-date", f = `POST\n${n}\n\n${u}\n${d}\n${o(r)}`, p = `${l}/${e.region}/ses/aws4_request`, m = `AWS4-HMAC-SHA256\n${c}\n${p}\n${o(f)}`, h = a("sha256", s(s(s(s(`AWS4${e.secretAccessKey}`, l), e.region), "ses"), "aws4_request")).update(m).digest("hex");
452
452
  return {
453
453
  authorization: `AWS4-HMAC-SHA256 Credential=${e.accessKeyId}/${p}, SignedHeaders=${d}, Signature=${h}`,
454
454
  "x-amz-date": c,
455
455
  ...e.sessionToken ? { "x-amz-security-token": e.sessionToken } : {}
456
456
  };
457
- } }), Re = (e) => JSON.stringify({
457
+ } }), Le = (e) => JSON.stringify({
458
458
  FromEmailAddress: e.from,
459
459
  Destination: {
460
- ToAddresses: D(e.to),
461
- ...e.cc ? { CcAddresses: D(e.cc) } : {},
462
- ...e.bcc ? { BccAddresses: D(e.bcc) } : {}
460
+ ToAddresses: j(e.to),
461
+ ...e.cc ? { CcAddresses: j(e.cc) } : {},
462
+ ...e.bcc ? { BccAddresses: j(e.bcc) } : {}
463
463
  },
464
464
  ...e.replyTo ? { ReplyToAddresses: [e.replyTo] } : {},
465
465
  Content: { Simple: {
@@ -478,47 +478,47 @@ var w = class extends s.TaggedError()("MailError", {
478
478
  } } : {}
479
479
  }
480
480
  } }
481
- }), ze = (e) => {
482
- let t = Le(e), r = `https://email.${e.region}.amazonaws.com`, i = "/v2/email/outbound-emails";
481
+ }), Re = (e) => {
482
+ let t = Ie(e), r = `https://email.${e.region}.amazonaws.com`, i = "/v2/email/outbound-emails";
483
483
  return {
484
484
  name: "ses",
485
485
  send: (e) => n.gen(function* () {
486
- let a = Re(e), o = yield* n.tryPromise({
486
+ let a = Le(e), o = yield* n.tryPromise({
487
487
  try: () => t.sign(r, i, a),
488
- catch: (e) => H("ses", { message: e?.message ?? String(e) })
488
+ catch: (e) => W("ses", { message: e?.message ?? String(e) })
489
489
  });
490
- return yield* Ie("ses", C.post(`${r}${i}`).pipe(C.setHeaders({
490
+ return yield* Fe("ses", E.post(`${r}${i}`).pipe(E.setHeaders({
491
491
  "content-type": "application/json",
492
492
  ...o
493
- }), C.bodyUnsafeJson(JSON.parse(a))), (e) => e.json.pipe(n.map((e) => ({
493
+ }), E.bodyJsonUnsafe(JSON.parse(a))), (e) => e.json.pipe(n.map((e) => ({
494
494
  id: e.MessageId ?? "ses",
495
495
  provider: "ses"
496
496
  }))));
497
497
  })
498
498
  };
499
- }, Be = (e) => {
499
+ }, ze = (e) => {
500
500
  let t = [["from", e.from], ["subject", e.subject]];
501
- for (let n of D(e.to)) t.push(["to", n]);
502
- if (e.cc) for (let n of D(e.cc)) t.push(["cc", n]);
503
- if (e.bcc) for (let n of D(e.bcc)) t.push(["bcc", n]);
501
+ for (let n of j(e.to)) t.push(["to", n]);
502
+ if (e.cc) for (let n of j(e.cc)) t.push(["cc", n]);
503
+ if (e.bcc) for (let n of j(e.bcc)) t.push(["bcc", n]);
504
504
  if (e.replyTo && t.push(["h:Reply-To", e.replyTo]), e.html && t.push(["html", e.html]), e.text && t.push(["text", e.text]), e.headers) for (let [n, r] of Object.entries(e.headers)) t.push([`h:${n}`, r]);
505
505
  if (e.tags) for (let n of e.tags) t.push(["o:tag", n]);
506
506
  return e.scheduledAt && t.push(["o:deliverytime", e.scheduledAt.toUTCString()]), t;
507
- }, Ve = (e) => {
507
+ }, Be = (e) => {
508
508
  let t = `${e.baseUrl ?? "https://api.mailgun.net"}/v3/${e.domain}/messages`;
509
509
  return {
510
510
  name: "mailgun",
511
511
  supportsScheduling: !0,
512
512
  send: (r) => {
513
513
  let i = new URLSearchParams();
514
- for (let [e, t] of Be(r)) i.append(e, t);
515
- return Ie("mailgun", C.post(t).pipe(C.setHeader("authorization", `Basic ${Buffer.from(`api:${e.apiKey}`).toString("base64")}`), C.bodyText(i.toString(), "application/x-www-form-urlencoded")), (e) => e.json.pipe(n.map((e) => ({
514
+ for (let [e, t] of ze(r)) i.append(e, t);
515
+ return Fe("mailgun", E.post(t).pipe(E.setHeader("authorization", `Basic ${Buffer.from(`api:${e.apiKey}`).toString("base64")}`), E.bodyText(i.toString(), "application/x-www-form-urlencoded")), (e) => e.json.pipe(n.map((e) => ({
516
516
  id: e.id ?? "mailgun",
517
517
  provider: "mailgun"
518
518
  }))));
519
519
  }
520
520
  };
521
- }, G = (e) => {
521
+ }, q = (e) => {
522
522
  let t = null;
523
523
  return {
524
524
  name: "smtp",
@@ -537,9 +537,9 @@ var w = class extends s.TaggedError()("MailError", {
537
537
  return {
538
538
  id: (await t.sendMail({
539
539
  from: r.from,
540
- to: D(r.to),
541
- cc: r.cc ? D(r.cc) : void 0,
542
- bcc: r.bcc ? D(r.bcc) : void 0,
540
+ to: j(r.to),
541
+ cc: r.cc ? j(r.cc) : void 0,
542
+ bcc: r.bcc ? j(r.bcc) : void 0,
543
543
  replyTo: r.replyTo,
544
544
  subject: r.subject,
545
545
  html: r.html,
@@ -557,53 +557,53 @@ var w = class extends s.TaggedError()("MailError", {
557
557
  },
558
558
  catch: (e) => {
559
559
  let t = e;
560
- return H("smtp", {
560
+ return W("smtp", {
561
561
  ...typeof t.responseCode == "number" ? { status: t.responseCode } : {},
562
562
  message: t.message ?? String(e)
563
563
  });
564
564
  }
565
565
  })
566
566
  };
567
- }, He = (e) => ({
567
+ }, Ve = (e) => ({
568
568
  name: "console",
569
569
  send: (t) => n.sync(() => {
570
- let n = `✉ to=${D(t.to).join(",")} subject=${JSON.stringify(t.subject)}`;
570
+ let n = `✉ to=${j(t.to).join(",")} subject=${JSON.stringify(t.subject)}`;
571
571
  return e ? e(n, { from: t.from }) : process.stdout.write(`[mail:console] ${n}\n`), {
572
- id: Ce("console"),
572
+ id: Se("console"),
573
573
  provider: "console"
574
574
  };
575
575
  })
576
- }), K = [], Ue = () => [...K], We = () => {
577
- K.length = 0;
578
- }, Ge = () => ({
576
+ }), J = [], He = () => [...J], Ue = () => {
577
+ J.length = 0;
578
+ }, We = () => ({
579
579
  name: "memory",
580
- send: (e) => n.sync(() => (K.push(e), {
581
- id: Ce("mem"),
580
+ send: (e) => n.sync(() => (J.push(e), {
581
+ id: Se("mem"),
582
582
  provider: "memory"
583
583
  }))
584
- }), q = d({ scope: "@voltro/plugin-mail" }), Ke = (e) => {
584
+ }), Y = f({ scope: "@voltro/plugin-mail" }), Ge = (e) => {
585
585
  if (e.provider !== void 0 && typeof e.provider != "string") return e.provider;
586
586
  let t = e.env ?? {}, n = e.provider ?? t.MAIL_PROVIDER ?? "console", r = (e, t) => {
587
587
  if (!t) throw Error(`@voltro/plugin-mail: provider '${n}' needs apiKey or ${e}`);
588
588
  return t;
589
589
  };
590
590
  switch (n) {
591
- case "lettermint": return De({ projectToken: r("LETTERMINT_PROJECT_TOKEN", e.apiKey ?? t.LETTERMINT_PROJECT_TOKEN) });
592
- case "resend": return ke({ apiKey: r("RESEND_API_KEY", e.apiKey ?? t.RESEND_API_KEY) });
593
- case "postmark": return Ae({ serverToken: r("POSTMARK_SERVER_TOKEN", e.apiKey ?? t.POSTMARK_SERVER_TOKEN) });
594
- case "sendgrid": return Pe({ apiKey: r("SENDGRID_API_KEY", e.apiKey ?? t.SENDGRID_API_KEY) });
595
- case "ses": return ze({
591
+ case "lettermint": return Ee({ projectToken: r("LETTERMINT_PROJECT_TOKEN", e.apiKey ?? t.LETTERMINT_PROJECT_TOKEN) });
592
+ case "resend": return Oe({ apiKey: r("RESEND_API_KEY", e.apiKey ?? t.RESEND_API_KEY) });
593
+ case "postmark": return ke({ serverToken: r("POSTMARK_SERVER_TOKEN", e.apiKey ?? t.POSTMARK_SERVER_TOKEN) });
594
+ case "sendgrid": return Ne({ apiKey: r("SENDGRID_API_KEY", e.apiKey ?? t.SENDGRID_API_KEY) });
595
+ case "ses": return Re({
596
596
  region: r("AWS_REGION", t.AWS_REGION),
597
597
  accessKeyId: r("AWS_ACCESS_KEY_ID", t.AWS_ACCESS_KEY_ID),
598
598
  secretAccessKey: r("AWS_SECRET_ACCESS_KEY", t.AWS_SECRET_ACCESS_KEY),
599
599
  ...t.AWS_SESSION_TOKEN ? { sessionToken: t.AWS_SESSION_TOKEN } : {}
600
600
  });
601
- case "mailgun": return Ve({
601
+ case "mailgun": return Be({
602
602
  apiKey: r("MAILGUN_API_KEY", e.apiKey ?? t.MAILGUN_API_KEY),
603
603
  domain: r("MAILGUN_DOMAIN", t.MAILGUN_DOMAIN),
604
604
  ...t.MAILGUN_BASE_URL ? { baseUrl: t.MAILGUN_BASE_URL } : {}
605
605
  });
606
- case "smtp": return t.SMTP_URL ? G({ url: t.SMTP_URL }) : G({
606
+ case "smtp": return t.SMTP_URL ? q({ url: t.SMTP_URL }) : q({
607
607
  host: r("SMTP_URL/SMTP_HOST", t.SMTP_HOST),
608
608
  ...t.SMTP_PORT ? { port: Number(t.SMTP_PORT) } : {},
609
609
  secure: t.SMTP_SECURE === "true",
@@ -612,25 +612,25 @@ var w = class extends s.TaggedError()("MailError", {
612
612
  pass: t.SMTP_PASS
613
613
  } } : {}
614
614
  });
615
- case "memory": return Ge();
616
- default: return He((e, t) => q.info(e, t));
615
+ case "memory": return We();
616
+ default: return Ve((e, t) => Y.info(e, t));
617
617
  }
618
- }, J = (e) => {
619
- let t = e.attempts ?? 3, r = e.suppression ?? R(), i = e.allowlist, a = e.production !== !0 && i !== void 0 && i.length > 0, s = (e) => i.some((t) => t.toLowerCase() === e.toLowerCase()), c = o.recurs(t).pipe(o.whileInput((e) => e.transient)), l = /* @__PURE__ */ new Map();
618
+ }, X = (e) => {
619
+ let t = e.attempts ?? 3, r = e.suppression ?? B(), i = e.allowlist, a = e.production !== !0 && i !== void 0 && i.length > 0, s = (e) => i.some((t) => t.toLowerCase() === e.toLowerCase()), c = o.recurs(t).pipe(o.while(({ input: e }) => e.transient)), l = /* @__PURE__ */ new Map();
620
620
  for (let t of e.templates ?? []) l.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
621
- let u = (e, t) => (t ? l.get(`${e}:${t}`) : void 0) ?? l.get(e) ?? j(e, t), d = /* @__PURE__ */ new Map(), f = (e, t) => `${e.name}|${e.locale ?? ""}|${JSON.stringify(t ?? null)}`, p = (e, t) => {
621
+ let u = (e, t) => (t ? l.get(`${e}:${t}`) : void 0) ?? l.get(e) ?? P(e, t), d = /* @__PURE__ */ new Map(), f = (e, t) => `${e.name}|${e.locale ?? ""}|${JSON.stringify(t ?? null)}`, p = (e, t) => {
622
622
  if (d.set(e, t), d.size > 500) {
623
623
  let e = d.keys().next().value;
624
624
  e !== void 0 && d.delete(e);
625
625
  }
626
- }, m = e.idempotency ?? B(), h = xe({
627
- store: e.schedule ?? V(),
626
+ }, m = e.idempotency ?? H(), h = be({
627
+ store: e.schedule ?? U(),
628
628
  providerSchedules: e.provider.supportsScheduling === !0,
629
- flush: (e) => v(e)
629
+ flush: (e) => y(e)
630
630
  }), g = (t) => {
631
631
  if (t.stream !== "broadcast" || e.provider.managesUnsubscribe === !0) return n.succeed(void 0);
632
632
  let r = t.unsubscribe;
633
- if (r === void 0 || !r.oneClickUrl.startsWith("https://")) return n.fail(new w({
633
+ if (r === void 0 || !r.oneClickUrl.startsWith("https://")) return n.fail(new D({
634
634
  provider: e.provider.name,
635
635
  message: `a broadcast needs \`unsubscribe: { oneClickUrl }\` (an https URL) — '${e.provider.name}' does not unsubscribe recipients itself`,
636
636
  transient: !1
@@ -642,15 +642,15 @@ var w = class extends s.TaggedError()("MailError", {
642
642
  });
643
643
  }, _ = (t) => n.gen(function* () {
644
644
  let i = t.from ?? e.from;
645
- if (!i) return yield* n.fail(new w({
645
+ if (!i) return yield* n.fail(new D({
646
646
  provider: e.provider.name,
647
647
  message: "no `from` — set mailPlugin({ from }) or pass message.from",
648
648
  transient: !1
649
649
  }));
650
- let o = D(t.to);
650
+ let o = j(t.to);
651
651
  if (a) {
652
652
  let n = o.filter(s);
653
- if (n.length === 0) return q.warn("mail skipped — no recipient in allowlist (non-production)", {
653
+ if (n.length === 0) return Y.warn("mail skipped — no recipient in allowlist (non-production)", {
654
654
  to: o.join(","),
655
655
  subject: t.subject
656
656
  }), e.onSent?.({
@@ -672,7 +672,7 @@ var w = class extends s.TaggedError()("MailError", {
672
672
  }
673
673
  let c = t.tenantId ?? null, l = [];
674
674
  for (let e of o) (yield* r.isSuppressed(c, e)) || l.push(e);
675
- if (l.length === 0) return q.warn("mail skipped — all recipients suppressed", {
675
+ if (l.length === 0) return Y.warn("mail skipped — all recipients suppressed", {
676
676
  to: o.join(","),
677
677
  subject: t.subject
678
678
  }), e.onSent?.({
@@ -705,10 +705,10 @@ var w = class extends s.TaggedError()("MailError", {
705
705
  ...f === void 0 ? {} : { headers: f }
706
706
  }
707
707
  };
708
- }), ee = (t) => {
709
- let r = D(t.to);
708
+ }), v = (t) => {
709
+ let r = j(t.to);
710
710
  return e.provider.send(t).pipe(n.retry(c), n.tap((i) => n.sync(() => {
711
- q.info("mail sent", {
711
+ Y.info("mail sent", {
712
712
  provider: i.provider,
713
713
  id: i.id,
714
714
  to: r.join(",")
@@ -722,7 +722,7 @@ var w = class extends s.TaggedError()("MailError", {
722
722
  ts: Date.now()
723
723
  });
724
724
  })), n.tapError((i) => n.sync(() => {
725
- q.warn("mail failed", {
725
+ Y.warn("mail failed", {
726
726
  provider: i.provider,
727
727
  status: i.status,
728
728
  message: i.message
@@ -737,14 +737,14 @@ var w = class extends s.TaggedError()("MailError", {
737
737
  ts: Date.now()
738
738
  });
739
739
  })));
740
- }, v = (t) => n.gen(function* () {
740
+ }, y = (t) => n.gen(function* () {
741
741
  let n = yield* _(t);
742
- return n.kind === "skip" ? n.result : h.shouldHold(t.scheduledAt) ? (yield* h.hold(n.message), q.info("mail scheduled (held for later flush)", {
742
+ return n.kind === "skip" ? n.result : h.shouldHold(t.scheduledAt) ? (yield* h.hold(n.message), Y.info("mail scheduled (held for later flush)", {
743
743
  subject: n.message.subject,
744
744
  dueAt: t.scheduledAt?.toISOString()
745
745
  }), e.onSent?.({
746
746
  id: "scheduled",
747
- to: D(n.message.to),
747
+ to: j(n.message.to),
748
748
  from: n.message.from,
749
749
  subject: n.message.subject,
750
750
  provider: "scheduled",
@@ -753,24 +753,24 @@ var w = class extends s.TaggedError()("MailError", {
753
753
  }), {
754
754
  id: "scheduled",
755
755
  provider: "scheduled"
756
- }) : yield* ee(n.message);
757
- }), y = (e, t, r) => t === void 0 ? r : n.gen(function* () {
756
+ }) : yield* v(n.message);
757
+ }), b = (e, t, r) => t === void 0 ? r : n.gen(function* () {
758
758
  let n = yield* m.reserve(e, t);
759
- if (!n.won) return q.info("mail idempotent replay — skipped", { key: t }), n.prior ?? {
759
+ if (!n.won) return Y.info("mail idempotent replay — skipped", { key: t }), n.prior ?? {
760
760
  id: "idempotent-replay",
761
761
  provider: "idempotent"
762
762
  };
763
763
  let i = yield* r;
764
764
  return yield* m.record(e, t, i), i;
765
- }), b = (e) => n.suspend(() => {
765
+ }), x = (e) => n.suspend(() => {
766
766
  let t = u(e.template, e.locale);
767
- if (!t) return n.fail(new w({
767
+ if (!t) return n.fail(new D({
768
768
  provider: "template",
769
769
  message: `unknown template '${e.template}'${e.locale ? ` (locale '${e.locale}')` : ""}`,
770
770
  transient: !1
771
771
  }));
772
772
  let r = f(t, e.props), i = d.get(r);
773
- return (i ? n.succeed(i) : k(t, e.props).pipe(n.tap((e) => n.sync(() => p(r, e))))).pipe(n.map((t) => ({
773
+ return (i ? n.succeed(i) : ne(t, e.props).pipe(n.tap((e) => n.sync(() => p(r, e))))).pipe(n.map((t) => ({
774
774
  to: e.to,
775
775
  subject: t.subject,
776
776
  html: t.html,
@@ -789,15 +789,15 @@ var w = class extends s.TaggedError()("MailError", {
789
789
  ...e.unsubscribe === void 0 ? {} : { unsubscribe: e.unsubscribe },
790
790
  ...e.metadata === void 0 ? {} : { metadata: e.metadata }
791
791
  })));
792
- }), x = (e) => "template" in e ? b(e) : n.succeed(e);
792
+ }), S = (e) => "template" in e ? x(e) : n.succeed(e);
793
793
  return {
794
794
  service: {
795
795
  send: (e) => n.gen(function* () {
796
- let t = yield* x(e);
797
- return yield* y(t.tenantId ?? null, t.idempotencyKey, v(t));
796
+ let t = yield* S(e);
797
+ return yield* b(t.tenantId ?? null, t.idempotencyKey, y(t));
798
798
  }),
799
799
  sendBatch: (t) => n.gen(function* () {
800
- let r = yield* n.forEach(t, x), i = r.some((e) => e.idempotencyKey !== void 0 || h.shouldHold(e.scheduledAt));
800
+ let r = yield* n.forEach(t, S), i = r.some((e) => e.idempotencyKey !== void 0 || h.shouldHold(e.scheduledAt));
801
801
  if (e.provider.sendBatch && !i) {
802
802
  let t = [], i = [];
803
803
  for (let e of r) {
@@ -807,13 +807,13 @@ var w = class extends s.TaggedError()("MailError", {
807
807
  let a = t.length > 0 ? yield* e.provider.sendBatch(t).pipe(n.retry(c), n.tap((r) => n.sync(() => {
808
808
  t.forEach((t, n) => {
809
809
  let i = r[n];
810
- i && (q.info("mail sent (batch)", {
810
+ i && (Y.info("mail sent (batch)", {
811
811
  provider: i.provider,
812
812
  id: i.id,
813
- to: D(t.to).join(",")
813
+ to: j(t.to).join(",")
814
814
  }), e.onSent?.({
815
815
  id: i.id,
816
- to: D(t.to),
816
+ to: j(t.to),
817
817
  from: t.from,
818
818
  subject: t.subject,
819
819
  provider: i.provider,
@@ -821,7 +821,7 @@ var w = class extends s.TaggedError()("MailError", {
821
821
  ts: Date.now()
822
822
  }));
823
823
  });
824
- })), n.tapError((e) => n.sync(() => q.warn("mail batch failed", {
824
+ })), n.tapError((e) => n.sync(() => Y.warn("mail batch failed", {
825
825
  provider: e.provider,
826
826
  status: e.status,
827
827
  message: e.message
@@ -831,7 +831,7 @@ var w = class extends s.TaggedError()("MailError", {
831
831
  provider: e.provider.name
832
832
  } : t);
833
833
  }
834
- return yield* n.forEach(r, (e) => y(e.tenantId ?? null, e.idempotencyKey, v(e)));
834
+ return yield* n.forEach(r, (e) => b(e.tenantId ?? null, e.idempotencyKey, y(e)));
835
835
  }),
836
836
  suppress: r.suppress,
837
837
  unsuppress: r.unsuppress,
@@ -843,7 +843,7 @@ var w = class extends s.TaggedError()("MailError", {
843
843
  },
844
844
  scheduler: h
845
845
  };
846
- }, qe = (e) => J(e).service, Je = (e) => i.succeed(E, qe(e)), Y = (e, t, n, r, i, a = {}) => {
846
+ }, Ke = (e) => X(e).service, qe = (e) => i.succeed(A, Ke(e)), Z = (e, t, n, r, i, a = {}) => {
847
847
  if (!t) return null;
848
848
  let o = a.metadata !== null && typeof a.metadata == "object" ? Object.fromEntries(Object.entries(a.metadata).filter(([, e]) => typeof e == "string")) : void 0;
849
849
  return {
@@ -855,33 +855,33 @@ var w = class extends s.TaggedError()("MailError", {
855
855
  ...a.eventId === void 0 ? {} : { eventId: a.eventId },
856
856
  ...o === void 0 ? {} : { metadata: o }
857
857
  };
858
- }, Ye = (e) => e === "message.hard_bounced" ? "bounced" : e === "message.spam_complaint" ? "complained" : e === "message.unsubscribed" ? "unsubscribed" : e === "message.delivered" ? "delivered" : e === "message.opened" ? "opened" : e === "message.clicked" ? "clicked" : "unknown", Xe = (e) => e === "hard_bounce" ? "bounced" : e === "spam_complaint" ? "complained" : e === "unsubscribe" ? "unsubscribed" : "unknown", Ze = (e) => e === "email.bounced" ? "bounced" : e === "email.complained" ? "complained" : e === "email.delivered" ? "delivered" : e === "email.opened" ? "opened" : e === "email.clicked" ? "clicked" : "unknown", Qe = (e) => e === "Bounce" ? "bounced" : e === "SpamComplaint" ? "complained" : e === "Delivery" ? "delivered" : e === "Open" ? "opened" : e === "Click" ? "clicked" : "unknown", $e = (e) => e === "bounce" || e === "dropped" ? "bounced" : e === "spamreport" ? "complained" : e === "delivered" ? "delivered" : e === "open" ? "opened" : e === "click" ? "clicked" : "unknown", X = (e, t) => {
858
+ }, Je = (e) => e === "message.hard_bounced" ? "bounced" : e === "message.spam_complaint" ? "complained" : e === "message.unsubscribed" ? "unsubscribed" : e === "message.delivered" ? "delivered" : e === "message.opened" ? "opened" : e === "message.clicked" ? "clicked" : "unknown", Ye = (e) => e === "hard_bounce" ? "bounced" : e === "spam_complaint" ? "complained" : e === "unsubscribe" ? "unsubscribed" : "unknown", Xe = (e) => e === "email.bounced" ? "bounced" : e === "email.complained" ? "complained" : e === "email.delivered" ? "delivered" : e === "email.opened" ? "opened" : e === "email.clicked" ? "clicked" : "unknown", Ze = (e) => e === "Bounce" ? "bounced" : e === "SpamComplaint" ? "complained" : e === "Delivery" ? "delivered" : e === "Open" ? "opened" : e === "Click" ? "clicked" : "unknown", Qe = (e) => e === "bounce" || e === "dropped" ? "bounced" : e === "spamreport" ? "complained" : e === "delivered" ? "delivered" : e === "open" ? "opened" : e === "click" ? "clicked" : "unknown", $e = (e, t) => {
859
859
  let n = [], r = (e) => {
860
860
  e && n.push(e);
861
861
  };
862
862
  if (e === "sendgrid" && Array.isArray(t)) {
863
- for (let e of t) r(Y($e(String(e.event)), e.email, "sendgrid", e.sg_message_id, e));
863
+ for (let e of t) r(Z(Qe(String(e.event)), e.email, "sendgrid", e.sg_message_id, e));
864
864
  return n;
865
865
  }
866
866
  let i = t ?? {};
867
867
  if (e === "lettermint") {
868
868
  let e = String(i.event), a = i.data ?? {}, o = typeof i.id == "string" ? i.id : void 0;
869
- return e === "suppression.added" ? (a.type === "email" && r(Y(Xe(String(a.reason)), a.value, "lettermint", void 0, t, { eventId: o })), n) : e === "suppression.removed" ? (a.type === "email" && r(Y("unsuppressed", a.value, "lettermint", void 0, t, { eventId: o })), n) : (e.startsWith("message.") && r(Y(Ye(e), a.recipient, "lettermint", a.message_id, t, {
869
+ return e === "suppression.added" ? (a.type === "email" && r(Z(Ye(String(a.reason)), a.value, "lettermint", void 0, t, { eventId: o })), n) : e === "suppression.removed" ? (a.type === "email" && r(Z("unsuppressed", a.value, "lettermint", void 0, t, { eventId: o })), n) : (e.startsWith("message.") && r(Z(Je(e), a.recipient, "lettermint", a.message_id, t, {
870
870
  eventId: o,
871
871
  metadata: a.metadata
872
872
  })), n);
873
873
  }
874
874
  if (e === "resend") {
875
875
  let e = i.data ?? {}, a = Array.isArray(e.to) ? e.to[0] : e.to ?? e.email;
876
- return r(Y(Ze(String(i.type)), a, "resend", e.email_id, t)), n;
876
+ return r(Z(Xe(String(i.type)), a, "resend", e.email_id, t)), n;
877
877
  }
878
878
  if (e === "postmark") {
879
879
  let e = i.Email ?? i.Recipient;
880
- return r(Y(Qe(String(i.RecordType)), e, "postmark", i.MessageID, t, { metadata: i.Metadata })), n;
880
+ return r(Z(Ze(String(i.RecordType)), e, "postmark", i.MessageID, t, { metadata: i.Metadata })), n;
881
881
  }
882
882
  return n;
883
883
  }, et = (e, t, r, i = null) => n.gen(function* () {
884
- let n = X(e, t);
884
+ let n = $e(e, t);
885
885
  for (let e of n) e.type === "bounced" || e.type === "complained" ? yield* r.suppress(i, e.email, e.type) : e.type === "unsuppressed" && (yield* r.unsuppress(i, e.email));
886
886
  return n;
887
887
  }), tt = (e = 200) => {
@@ -925,27 +925,27 @@ var w = class extends s.TaggedError()("MailError", {
925
925
  case "smtp": return n((t.SMTP_URL ? rt(t.SMTP_URL) : void 0) ?? (t.SMTP_HOST ? `${t.SMTP_HOST}${t.SMTP_PORT ? `:${t.SMTP_PORT}` : ""}` : void 0) ?? "runtime:SMTP_URL or SMTP_HOST");
926
926
  default: return [];
927
927
  }
928
- }, Z = (e, t) => {
928
+ }, Q = (e, t) => {
929
929
  if (t > 6) return null;
930
+ let n = e.encoding === void 0 ? e : e.encoding[e.encoding.length - 1].to;
931
+ if (n !== e) return Q(n, t + 1);
930
932
  switch (e._tag) {
931
- case "StringKeyword": return "";
932
- case "NumberKeyword": return 0;
933
- case "BooleanKeyword": return !1;
933
+ case "String": return "";
934
+ case "Number": return 0;
935
+ case "Boolean": return !1;
934
936
  case "Literal": return e.literal;
935
- case "Enums": return e.enums.length > 0 ? e.enums[0][1] : null;
936
- case "TypeLiteral": {
937
+ case "Enum": return e.enums.length > 0 ? e.enums[0][1] : null;
938
+ case "Objects": {
937
939
  let n = {};
938
- for (let r of e.propertySignatures) typeof r.name == "string" && (n[r.name] = Z(r.type, t + 1));
940
+ for (let r of e.propertySignatures) typeof r.name == "string" && (n[r.name] = Q(r.type, t + 1));
939
941
  return n;
940
942
  }
941
- case "TupleType": return [];
942
- case "Union": return e.types.length > 0 ? Z(e.types[0], t + 1) : null;
943
- case "Refinement": return Z(e.from, t + 1);
944
- case "Transformation": return Z(e.from, t + 1);
945
- case "Suspend": return Z(e.f(), t + 1);
943
+ case "Arrays": return [];
944
+ case "Union": return e.types.length > 0 ? Q(e.types[0], t + 1) : null;
945
+ case "Suspend": return Q(e.thunk(), t + 1);
946
946
  default: return null;
947
947
  }
948
- }, at = (e) => Z(e.ast, 0), Q = u([
948
+ }, at = (e) => Q(e.ast, 0), ot = d([
949
949
  {
950
950
  name: "MAIL_PROVIDER",
951
951
  required: !1,
@@ -1066,25 +1066,25 @@ var w = class extends s.TaggedError()("MailError", {
1066
1066
  secret: !1,
1067
1067
  description: "Comma-separated recipient allowlist; in dev, mail to addresses outside it is skipped."
1068
1068
  }
1069
- ]), ot = "@voltro/plugin-mail", $ = (e, t) => ({
1069
+ ]), st = "@voltro/plugin-mail", $ = (e, t) => ({
1070
1070
  status: e,
1071
1071
  contentType: "application/json",
1072
1072
  body: JSON.stringify(t)
1073
- }), st = (e, t, r, i) => {
1074
- let a = e.webhook;
1075
- if (a === void 0) throw Error(`@voltro/plugin-mail: provider '${e.name}' has no webhook verifier — mailPlugin({ webhook }) needs one (lettermint)`);
1076
- let o = r.secret ?? Q.read("MAIL_WEBHOOK_SECRET");
1077
- if (!o && i) throw Error("@voltro/plugin-mail: mailPlugin({ webhook }) needs a signing secret in production — set MAIL_WEBHOOK_SECRET");
1073
+ }), ct = (e, t, r, i) => {
1074
+ let o = e.webhook;
1075
+ if (o === void 0) throw Error(`@voltro/plugin-mail: provider '${e.name}' has no webhook verifier — mailPlugin({ webhook }) needs one (lettermint)`);
1076
+ let s = r.secret ?? ot.read("MAIL_WEBHOOK_SECRET");
1077
+ if (!s && i) throw Error("@voltro/plugin-mail: mailPlugin({ webhook }) needs a signing secret in production — set MAIL_WEBHOOK_SECRET");
1078
1078
  return {
1079
1079
  method: "POST",
1080
1080
  path: r.path ?? "/webhooks/mail",
1081
1081
  handle: async (i) => {
1082
- if (!o) return $(503, { error: "mail webhook secret not configured" });
1083
- let s = await n.runPromise(n.either(a.verify(i.headers, new TextDecoder().decode(i.rawBody), o)));
1084
- if (s._tag === "Left") return $(401, { error: s.left.message });
1085
- let c = X(e.name, s.right);
1082
+ if (!s) return $(503, { error: "mail webhook secret not configured" });
1083
+ let c = await n.runPromise(n.result(o.verify(i.headers, new TextDecoder().decode(i.rawBody), s)));
1084
+ if (a.isFailure(c)) return $(401, { error: c.failure.message });
1085
+ let l = $e(e.name, c.success);
1086
1086
  try {
1087
- for (let e of c) {
1087
+ for (let e of l) {
1088
1088
  e.type === "bounced" || e.type === "complained" ? await n.runPromise(t.suppress(null, e.email, e.type)) : e.type === "unsuppressed" && await n.runPromise(t.unsuppress(null, e.email));
1089
1089
  let a = r.onEvent?.(e, { store: i.store });
1090
1090
  n.isEffect(a) ? await n.runPromise(a) : await a;
@@ -1095,23 +1095,23 @@ var w = class extends s.TaggedError()("MailError", {
1095
1095
  cause: e
1096
1096
  };
1097
1097
  }
1098
- return $(200, { received: c.length });
1098
+ return $(200, { received: l.length });
1099
1099
  }
1100
1100
  };
1101
- }, ct = (e = {}) => {
1102
- let a = process.env, s = Ke({
1101
+ }, lt = (e = {}) => {
1102
+ let a = process.env, s = Ge({
1103
1103
  ...e.provider === void 0 ? {} : { provider: e.provider },
1104
1104
  ...e.apiKey === void 0 ? {} : { apiKey: e.apiKey },
1105
1105
  env: a
1106
- }), u = Q.read("MAIL_ALLOWLIST"), d = e.allowlist ?? (u ? u.split(",").map((e) => e.trim()).filter(Boolean) : void 0), f = a.NODE_ENV === "production", p = e.suppression === void 0 || e.suppression === "memory" ? R() : e.suppression === "postgres" ? he() : e.suppression, m = e.idempotency === void 0 || e.idempotency === "memory" ? B() : e.idempotency === "postgres" ? _e() : e.idempotency, h = e.schedule ?? V(), g = [...e.suppression === "postgres" ? [de] : [], ...e.idempotency === "postgres" ? [fe] : []];
1107
- e.idempotency === "postgres" && ee({
1106
+ }), c = ot.read("MAIL_ALLOWLIST"), d = e.allowlist ?? (c ? c.split(",").map((e) => e.trim()).filter(Boolean) : void 0), f = a.NODE_ENV === "production", p = e.suppression === void 0 || e.suppression === "memory" ? B() : e.suppression === "postgres" ? me() : e.suppression, m = e.idempotency === void 0 || e.idempotency === "memory" ? H() : e.idempotency === "postgres" ? ge() : e.idempotency, h = e.schedule ?? U(), g = [...e.suppression === "postgres" ? [le] : [], ...e.idempotency === "postgres" ? [ue] : []];
1107
+ e.idempotency === "postgres" && y({
1108
1108
  source: "plugin",
1109
- table: N,
1109
+ table: I,
1110
1110
  timeColumn: "createdAt",
1111
- ttlMs: v(process.env.VOLTRO_MAIL_IDEMPOTENCY_TTL_HOURS, 720),
1111
+ ttlMs: b(process.env.VOLTRO_MAIL_IDEMPOTENCY_TTL_HOURS, 720),
1112
1112
  label: "mail idempotency keys"
1113
1113
  });
1114
- let _ = tt(), y = J({
1114
+ let _ = tt(), v = X({
1115
1115
  provider: s,
1116
1116
  suppression: p,
1117
1117
  idempotency: m,
@@ -1123,21 +1123,21 @@ var w = class extends s.TaggedError()("MailError", {
1123
1123
  ...e.attempts === void 0 ? {} : { attempts: e.attempts },
1124
1124
  ...e.templates === void 0 ? {} : { templates: e.templates },
1125
1125
  production: f
1126
- }), b = i.succeed(E, y.service), x = s.supportsScheduling !== !0, te = e.scheduleTickMs ?? 1e3, S, C = /* @__PURE__ */ new Map();
1127
- for (let t of e.templates ?? []) C.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
1128
- let w = (e, t) => (t ? C.get(`${e}:${t}`) : void 0) ?? C.get(e) ?? j(e, t), T = (e) => ({
1126
+ }), x = i.succeed(A, v.service), S = s.supportsScheduling !== !0, C = e.scheduleTickMs ?? 1e3, w, T = /* @__PURE__ */ new Map();
1127
+ for (let t of e.templates ?? []) T.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
1128
+ let E = (e, t) => (t ? T.get(`${e}:${t}`) : void 0) ?? T.get(e) ?? P(e, t), D = (e) => ({
1129
1129
  name: e.name,
1130
1130
  ...e.locale ? { locale: e.locale } : {},
1131
1131
  props: e.preview ?? at(e.props)
1132
- }), ne = () => {
1132
+ }), O = () => {
1133
1133
  let t = /* @__PURE__ */ new Map();
1134
- for (let n of e.templates ?? []) t.set(n.locale ? `${n.name}:${n.locale}` : n.name, T(n));
1135
- for (let e of ce()) {
1136
- let n = j(e.name, e.locale);
1137
- n && t.set(e.locale ? `${e.name}:${e.locale}` : e.name, T(n));
1134
+ for (let n of e.templates ?? []) t.set(n.locale ? `${n.name}:${n.locale}` : n.name, D(n));
1135
+ for (let e of oe()) {
1136
+ let n = P(e.name, e.locale);
1137
+ n && t.set(e.locale ? `${e.name}:${e.locale}` : e.name, D(n));
1138
1138
  }
1139
1139
  return [...t.values()];
1140
- }, D = e.webhook === void 0 ? [] : [st(s, p, e.webhook, f)], re = [
1140
+ }, k = e.webhook === void 0 ? [] : [ct(s, p, e.webhook, f)], j = [
1141
1141
  {
1142
1142
  method: "GET",
1143
1143
  path: "/outbox",
@@ -1155,7 +1155,7 @@ var w = class extends s.TaggedError()("MailError", {
1155
1155
  description: "Discovered + registered email templates",
1156
1156
  handler: () => n.succeed({
1157
1157
  kind: "json",
1158
- data: { templates: ne() }
1158
+ data: { templates: O() }
1159
1159
  })
1160
1160
  },
1161
1161
  {
@@ -1178,11 +1178,11 @@ var w = class extends s.TaggedError()("MailError", {
1178
1178
  status: 400,
1179
1179
  data: { error: "missing \"template\"" }
1180
1180
  };
1181
- let r = w(t.template, t.locale);
1182
- return r ? yield* k(r, t.props).pipe(n.map((e) => ({
1181
+ let r = E(t.template, t.locale);
1182
+ return r ? yield* ne(r, t.props).pipe(n.map((e) => ({
1183
1183
  kind: "json",
1184
1184
  data: e
1185
- })), n.catchAll((e) => n.succeed({
1185
+ })), n.catch((e) => n.succeed({
1186
1186
  kind: "json",
1187
1187
  status: 400,
1188
1188
  data: { error: e.message }
@@ -1193,38 +1193,38 @@ var w = class extends s.TaggedError()("MailError", {
1193
1193
  };
1194
1194
  })
1195
1195
  }
1196
- ], O = [
1196
+ ], ee = [
1197
1197
  "network:outbound:*",
1198
1198
  "inspect:read",
1199
1199
  "inspect:write",
1200
1200
  ...g.length > 0 ? ["store:write"] : []
1201
1201
  ];
1202
1202
  return {
1203
- ...c({
1204
- name: l({
1205
- base: ot,
1203
+ ...l({
1204
+ name: u({
1205
+ base: st,
1206
1206
  alias: e.alias,
1207
1207
  instance: e.name
1208
1208
  }),
1209
- baseName: ot,
1209
+ baseName: st,
1210
1210
  description: "Transactional and broadcast email — MailService over Lettermint / Resend / Postmark / SendGrid / SES / Mailgun / SMTP (+ console/memory), with default-from, transient retry, suppression and a dev allowlist.",
1211
- permissions: O,
1212
- declaredEnv: Q.declared,
1211
+ permissions: ee,
1212
+ declaredEnv: ot.declared,
1213
1213
  egress: it({
1214
1214
  ...e.provider === void 0 ? {} : { provider: e.provider },
1215
1215
  env: a
1216
1216
  }),
1217
- services: b,
1218
- inspectEndpoints: re,
1219
- ...D.length > 0 ? { httpRoutes: D } : {},
1217
+ services: x,
1218
+ inspectEndpoints: j,
1219
+ ...k.length > 0 ? { httpRoutes: k } : {},
1220
1220
  ...g.length > 0 ? { extendSchema: { tables: g } } : {},
1221
1221
  bindDataStore: async (e) => {
1222
1222
  await p.bind?.(e), await m.bind?.(e);
1223
1223
  },
1224
1224
  onActivate: (r) => n.gen(function* () {
1225
- if (p.activate && (yield* n.promise(() => p.activate(r.env))), m.activate && (yield* n.promise(() => m.activate(r.env))), x) {
1226
- let e = y.scheduler.tick().pipe(n.repeat(o.spaced(t.millis(Math.max(50, te)))));
1227
- S = n.runFork(e);
1225
+ if (p.activate && (yield* n.promise(() => p.activate(r.env))), m.activate && (yield* n.promise(() => m.activate(r.env))), S) {
1226
+ let e = v.scheduler.tick().pipe(n.repeat(o.spaced(t.millis(Math.max(50, C)))));
1227
+ w = n.runFork(e);
1228
1228
  }
1229
1229
  r.logger.info("mail active", {
1230
1230
  provider: s.name,
@@ -1237,11 +1237,11 @@ var w = class extends s.TaggedError()("MailError", {
1237
1237
  });
1238
1238
  }),
1239
1239
  onDeactivate: () => n.gen(function* () {
1240
- S !== void 0 && (yield* r.interrupt(S), S = void 0), p.deactivate && (yield* n.promise(() => p.deactivate())), m.deactivate && (yield* n.promise(() => m.deactivate()));
1240
+ w !== void 0 && (yield* r.interrupt(w), w = void 0), p.deactivate && (yield* n.promise(() => p.deactivate())), m.deactivate && (yield* n.promise(() => m.deactivate()));
1241
1241
  })
1242
1242
  }),
1243
- service: y.service
1243
+ service: v.service
1244
1244
  };
1245
1245
  };
1246
1246
  //#endregion
1247
- export { w as MailError, E as MailService, T as MailWebhookError, qe as buildMailService, J as buildMailServiceWithScheduler, le as clearGlobalTemplates, We as clearMailBuffer, He as consoleProvider, tt as createOutbox, ne as defineEmail, se as globalTemplateCount, et as handleMailEvents, be as heldId, ue as isEmailTemplate, De as lettermintProvider, ce as listGlobalTemplates, j as lookupGlobalTemplate, it as mailEgressOf, ct as mailPlugin, Je as mailServiceLayer, Ve as mailgunProvider, xe as makeScheduler, B as memoryIdempotencyStore, Ge as memoryProvider, V as memoryScheduleStore, R as memorySuppressionStore, X as parseMailEvent, _e as postgresIdempotencyStore, he as postgresSuppressionStore, Ae as postmarkProvider, Ue as readMailBuffer, oe as registerEmailTemplates, k as renderTemplate, ke as resendProvider, Ke as resolveProvider, Pe as sendgridProvider, ze as sesProvider, G as smtpProvider, Ee as verifyLettermintSignature };
1247
+ export { D as MailError, A as MailService, O as MailWebhookError, Ke as buildMailService, X as buildMailServiceWithScheduler, se as clearGlobalTemplates, Ue as clearMailBuffer, Ve as consoleProvider, tt as createOutbox, k as defineEmail, ae as globalTemplateCount, et as handleMailEvents, ye as heldId, ce as isEmailTemplate, Ee as lettermintProvider, oe as listGlobalTemplates, P as lookupGlobalTemplate, it as mailEgressOf, lt as mailPlugin, qe as mailServiceLayer, Be as mailgunProvider, be as makeScheduler, H as memoryIdempotencyStore, We as memoryProvider, U as memoryScheduleStore, B as memorySuppressionStore, $e as parseMailEvent, ge as postgresIdempotencyStore, me as postgresSuppressionStore, ke as postmarkProvider, He as readMailBuffer, ie as registerEmailTemplates, ne as renderTemplate, Oe as resendProvider, Ge as resolveProvider, Ne as sendgridProvider, Re as sesProvider, q as smtpProvider, Te as verifyLettermintSignature };