@voltro/plugin-mail 0.33.0 → 0.34.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,24 +1,24 @@
1
1
  import { Config as e, Context as t, Duration as n, Effect as r, Fiber as i, Layer as a, ManagedRuntime as o, ParseResult as s, Redacted as c, Schedule as l, Schema as u } from "effect";
2
- import { definePlugin as d } from "@voltro/protocol";
3
- import { pluginEnv as f } from "@voltro/env";
4
- import { createLogger as p } from "@voltro/logger";
5
- import { SqlClient as m } from "@effect/sql";
6
- import { PgClient as h } from "@effect/sql-pg";
7
- import { FetchHttpClient as g, HttpClient as _, HttpClientRequest as v } from "@effect/platform";
2
+ import { definePlugin as d, pluginInstanceName as f } from "@voltro/protocol";
3
+ import { pluginEnv as p } from "@voltro/env";
4
+ import { createLogger as m } from "@voltro/logger";
5
+ import { SqlClient as h } from "@effect/sql";
6
+ import { PgClient as g } from "@effect/sql-pg";
7
+ import { FetchHttpClient as _, HttpClient as v, HttpClientRequest as y } from "@effect/platform";
8
8
  //#region src/types.ts
9
- var y = class extends u.TaggedError()("MailError", {
9
+ var b = class extends u.TaggedError()("MailError", {
10
10
  provider: u.String,
11
11
  message: u.String,
12
12
  transient: u.Boolean,
13
13
  status: u.optional(u.Number)
14
- }) {}, b = (e) => ({
14
+ }) {}, x = (e) => ({
15
15
  name: e.name,
16
16
  props: e.props,
17
17
  subject: e.subject,
18
18
  render: e.render,
19
19
  ...e.locale === void 0 ? {} : { locale: e.locale },
20
20
  ...e.preview === void 0 ? {} : { preview: e.preview }
21
- }), x = class extends t.Tag("@voltro/plugin-mail/MailService")() {}, S = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, C = (e) => {
21
+ }), S = class extends t.Tag("@voltro/plugin-mail/MailService")() {}, C = (e) => e === void 0 ? [] : typeof e == "string" ? [e] : e, ee = (e) => {
22
22
  try {
23
23
  let t = s.ArrayFormatter.formatErrorSync(e);
24
24
  return t.length === 0 ? String(e) : t.map((e) => `${e.path.length > 0 ? e.path.join(".") : "(root)"}: ${e.message}`).join("; ");
@@ -32,16 +32,16 @@ var y = class extends u.TaggedError()("MailError", {
32
32
  }
33
33
  return w;
34
34
  }, E = (e, t) => r.gen(function* () {
35
- let n = e, i = yield* u.decodeUnknown(n.props)(t).pipe(r.mapError((t) => new y({
35
+ let n = e, i = yield* u.decodeUnknown(n.props)(t).pipe(r.mapError((t) => new b({
36
36
  provider: "template",
37
- message: `invalid props for '${e.name}': ${C(t)}`.slice(0, 500),
37
+ message: `invalid props for '${e.name}': ${ee(t)}`.slice(0, 500),
38
38
  transient: !1
39
39
  }))), a = n.subject(i), o = n.render(i);
40
40
  return {
41
41
  subject: a,
42
42
  html: yield* r.tryPromise({
43
43
  try: async () => (await T())(o, { plainText: !1 }),
44
- catch: (t) => new y({
44
+ catch: (t) => new b({
45
45
  provider: "template",
46
46
  message: `render failed for '${e.name}': ${String(t)}`.slice(0, 500),
47
47
  transient: !1
@@ -49,30 +49,30 @@ var y = class extends u.TaggedError()("MailError", {
49
49
  }),
50
50
  text: yield* r.tryPromise({
51
51
  try: async () => (await T())(o, { plainText: !0 }),
52
- catch: (t) => new y({
52
+ catch: (t) => new b({
53
53
  provider: "template",
54
54
  message: `render(text) failed for '${e.name}': ${String(t)}`.slice(0, 500),
55
55
  transient: !1
56
56
  })
57
57
  })
58
58
  };
59
- }), D = /* @__PURE__ */ new Map(), ee = (e) => e.locale ? `${e.name}:${e.locale}` : e.name, te = (e) => {
60
- for (let t of e) D.set(ee(t), t);
61
- }, O = (e, t) => (t ? D.get(`${e}:${t}`) : void 0) ?? D.get(e), ne = () => D.size, re = () => [...D.values()].map((e) => e.locale ? {
59
+ }), D = /* @__PURE__ */ new Map(), te = (e) => e.locale ? `${e.name}:${e.locale}` : e.name, ne = (e) => {
60
+ for (let t of e) D.set(te(t), t);
61
+ }, O = (e, t) => (t ? D.get(`${e}:${t}`) : void 0) ?? D.get(e), re = () => D.size, k = () => [...D.values()].map((e) => e.locale ? {
62
62
  name: e.name,
63
63
  locale: e.locale
64
64
  } : { name: e.name }), ie = () => D.clear(), ae = (e) => {
65
65
  if (typeof e != "object" || !e) return !1;
66
66
  let t = e;
67
67
  return typeof t.name == "string" && typeof t.subject == "function" && typeof t.render == "function" && t.props !== void 0;
68
- }, oe = p({ scope: "@voltro/plugin-mail" }), k = (e) => e.trim().toLowerCase(), A = (e) => e ?? "*", j = () => {
69
- let e = /* @__PURE__ */ new Set(), t = (e, t) => `${A(e)}\u0000${k(t)}`;
68
+ }, oe = m({ scope: "@voltro/plugin-mail" }), A = (e) => e.trim().toLowerCase(), se = "*", j = (e) => e ?? se, M = () => {
69
+ let e = /* @__PURE__ */ new Set(), t = (e, t) => `${j(e)}\u0000${A(t)}`;
70
70
  return {
71
- isSuppressed: (n, i) => r.sync(() => e.has(t(n, i))),
71
+ isSuppressed: (n, i) => r.sync(() => e.has(t(n, i)) || e.has(t(null, i))),
72
72
  suppress: (n, i) => r.sync(() => void e.add(t(n, i))),
73
73
  unsuppress: (n, i) => r.sync(() => void e.delete(t(n, i)))
74
74
  };
75
- }, se = (e) => {
75
+ }, ce = (e) => {
76
76
  let t = e.DB_URL ?? e.DB_PRIMARY_URL;
77
77
  if (t) {
78
78
  let e = new URL(t);
@@ -91,8 +91,8 @@ var y = class extends u.TaggedError()("MailError", {
91
91
  password: e.DB_PASSWORD ?? e.PG_PASSWORD ?? "app",
92
92
  database: e.DB_DATABASE ?? e.PG_DATABASE ?? "app"
93
93
  };
94
- }, ce = (t = {}) => {
95
- let n = t.table ?? "_voltro_mail_suppression", i = null, a = (n) => h.layerConfig({
94
+ }, le = (t = {}) => {
95
+ let n = t.table ?? "_voltro_mail_suppression", i = null, a = (n) => g.layerConfig({
96
96
  host: e.succeed(n.host),
97
97
  port: e.succeed(n.port),
98
98
  username: e.succeed(n.username),
@@ -105,9 +105,10 @@ var y = class extends u.TaggedError()("MailError", {
105
105
  let a = i;
106
106
  if (!a) return r.succeed(!1);
107
107
  let o = r.gen(function* () {
108
- let r = yield* m.SqlClient;
108
+ let r = yield* h.SqlClient;
109
109
  return (yield* r`
110
- SELECT 1 AS one FROM ${r(n)} WHERE tenant = ${A(e)} AND email = ${k(t)} LIMIT 1`).length > 0;
110
+ SELECT 1 AS one FROM ${r(n)}
111
+ WHERE email = ${A(t)} AND tenant IN (${j(e)}, ${se}) LIMIT 1`).length > 0;
111
112
  });
112
113
  return r.tryPromise(() => a.runPromise(o)).pipe(r.catchAll(() => r.succeed(!1)));
113
114
  },
@@ -115,14 +116,14 @@ var y = class extends u.TaggedError()("MailError", {
115
116
  let o = i;
116
117
  if (!o) return r.void;
117
118
  let s = r.gen(function* () {
118
- let r = yield* m.SqlClient;
119
+ let r = yield* h.SqlClient;
119
120
  yield* r`
120
121
  INSERT INTO ${r(n)} (tenant, email, reason, created_at)
121
- VALUES (${A(e)}, ${k(t)}, ${a}, ${Date.now()})
122
+ VALUES (${j(e)}, ${A(t)}, ${a}, ${Date.now()})
122
123
  ON CONFLICT (tenant, email) DO UPDATE SET reason = ${a}, created_at = ${Date.now()}`;
123
124
  });
124
125
  return r.tryPromise(() => o.runPromise(s)).pipe(r.catchAll((e) => r.sync(() => oe.warn("suppress write failed", {
125
- email: k(t),
126
+ email: A(t),
126
127
  message: String(e)
127
128
  }))));
128
129
  },
@@ -130,15 +131,15 @@ var y = class extends u.TaggedError()("MailError", {
130
131
  let a = i;
131
132
  if (!a) return r.void;
132
133
  let o = r.gen(function* () {
133
- let r = yield* m.SqlClient;
134
- yield* r`DELETE FROM ${r(n)} WHERE tenant = ${A(e)} AND email = ${k(t)}`;
134
+ let r = yield* h.SqlClient;
135
+ yield* r`DELETE FROM ${r(n)} WHERE tenant = ${j(e)} AND email = ${A(t)}`;
135
136
  });
136
137
  return r.tryPromise(() => a.runPromise(o)).pipe(r.catchAll(() => r.void));
137
138
  },
138
139
  activate: async (e) => {
139
- let t = o.make(a(se(e)));
140
+ let t = o.make(a(ce(e)));
140
141
  await t.runPromise(r.gen(function* () {
141
- let e = yield* m.SqlClient;
142
+ let e = yield* h.SqlClient;
142
143
  yield* e`
143
144
  CREATE TABLE IF NOT EXISTS ${e(n)} (
144
145
  tenant TEXT NOT NULL,
@@ -154,8 +155,8 @@ var y = class extends u.TaggedError()("MailError", {
154
155
  i = null, e && await e.dispose();
155
156
  }
156
157
  };
157
- }, le = p({ scope: "@voltro/plugin-mail" }), M = (e) => e ?? "*", N = () => {
158
- let e = /* @__PURE__ */ new Map(), t = (e, t) => `${M(e)} ${t}`;
158
+ }, ue = m({ scope: "@voltro/plugin-mail" }), N = (e) => e ?? "*", P = () => {
159
+ let e = /* @__PURE__ */ new Map(), t = (e, t) => `${N(e)} ${t}`;
159
160
  return {
160
161
  reserve: (n, i) => r.sync(() => {
161
162
  let r = t(n, i);
@@ -170,7 +171,7 @@ var y = class extends u.TaggedError()("MailError", {
170
171
  }),
171
172
  record: (n, i, a) => r.sync(() => void e.set(t(n, i), a))
172
173
  };
173
- }, ue = (e) => {
174
+ }, de = (e) => {
174
175
  let t = e.DB_URL ?? e.DB_PRIMARY_URL;
175
176
  if (t) {
176
177
  let e = new URL(t);
@@ -189,8 +190,8 @@ var y = class extends u.TaggedError()("MailError", {
189
190
  password: e.DB_PASSWORD ?? e.PG_PASSWORD ?? "app",
190
191
  database: e.DB_DATABASE ?? e.PG_DATABASE ?? "app"
191
192
  };
192
- }, P = (t = {}) => {
193
- let n = t.table ?? "_voltro_mail_idempotency", i = null, a = (n) => h.layerConfig({
193
+ }, F = (t = {}) => {
194
+ let n = t.table ?? "_voltro_mail_idempotency", i = null, a = (n) => g.layerConfig({
194
195
  host: e.succeed(n.host),
195
196
  port: e.succeed(n.port),
196
197
  username: e.succeed(n.username),
@@ -203,15 +204,15 @@ var y = class extends u.TaggedError()("MailError", {
203
204
  let a = i;
204
205
  if (!a) return r.succeed({ won: !0 });
205
206
  let o = r.gen(function* () {
206
- let r = yield* m.SqlClient;
207
+ let r = yield* h.SqlClient;
207
208
  if ((yield* r`
208
209
  INSERT INTO ${r(n)} (tenant, key, created_at)
209
- VALUES (${M(e)}, ${t}, ${Date.now()})
210
+ VALUES (${N(e)}, ${t}, ${Date.now()})
210
211
  ON CONFLICT (tenant, key) DO NOTHING
211
212
  RETURNING key`).length > 0) return { won: !0 };
212
213
  let i = (yield* r`
213
214
  SELECT result_id, result_provider FROM ${r(n)}
214
- WHERE tenant = ${M(e)} AND key = ${t} LIMIT 1`)[0];
215
+ WHERE tenant = ${N(e)} AND key = ${t} LIMIT 1`)[0];
215
216
  return i && i.result_id && i.result_provider ? {
216
217
  won: !1,
217
218
  prior: {
@@ -220,7 +221,7 @@ var y = class extends u.TaggedError()("MailError", {
220
221
  }
221
222
  } : { won: !1 };
222
223
  });
223
- return r.tryPromise(() => a.runPromise(o)).pipe(r.catchAll((e) => r.sync(() => (le.warn("idempotency reserve failed — skipping send to avoid a double", {
224
+ return r.tryPromise(() => a.runPromise(o)).pipe(r.catchAll((e) => r.sync(() => (ue.warn("idempotency reserve failed — skipping send to avoid a double", {
224
225
  key: t,
225
226
  message: String(e)
226
227
  }), { won: !1 }))));
@@ -229,20 +230,20 @@ var y = class extends u.TaggedError()("MailError", {
229
230
  let o = i;
230
231
  if (!o) return r.void;
231
232
  let s = r.gen(function* () {
232
- let r = yield* m.SqlClient;
233
+ let r = yield* h.SqlClient;
233
234
  yield* r`
234
235
  UPDATE ${r(n)} SET result_id = ${a.id}, result_provider = ${a.provider}
235
- WHERE tenant = ${M(e)} AND key = ${t}`;
236
+ WHERE tenant = ${N(e)} AND key = ${t}`;
236
237
  });
237
- return r.tryPromise(() => o.runPromise(s)).pipe(r.catchAll((e) => r.sync(() => le.warn("idempotency record failed", {
238
+ return r.tryPromise(() => o.runPromise(s)).pipe(r.catchAll((e) => r.sync(() => ue.warn("idempotency record failed", {
238
239
  key: t,
239
240
  message: String(e)
240
241
  }))));
241
242
  },
242
243
  activate: async (e) => {
243
- let t = o.make(a(ue(e)));
244
+ let t = o.make(a(de(e)));
244
245
  await t.runPromise(r.gen(function* () {
245
- let e = yield* m.SqlClient;
246
+ let e = yield* h.SqlClient;
246
247
  yield* e`
247
248
  CREATE TABLE IF NOT EXISTS ${e(n)} (
248
249
  tenant TEXT NOT NULL,
@@ -259,7 +260,7 @@ var y = class extends u.TaggedError()("MailError", {
259
260
  i = null, e && await e.dispose();
260
261
  }
261
262
  };
262
- }, de = p({ scope: "@voltro/plugin-mail" }), F = () => {
263
+ }, fe = m({ scope: "@voltro/plugin-mail" }), I = () => {
263
264
  let e = /* @__PURE__ */ new Map();
264
265
  return {
265
266
  hold: (t) => r.sync(() => void e.set(t.id, t)),
@@ -270,34 +271,34 @@ var y = class extends u.TaggedError()("MailError", {
270
271
  }),
271
272
  size: () => r.sync(() => e.size)
272
273
  };
273
- }, fe = 0, I = (e) => e.idempotencyKey ?? `held-${fe += 1}`, L = (e) => ({
274
+ }, pe = 0, L = (e) => e.idempotencyKey ?? `held-${pe += 1}`, R = (e) => ({
274
275
  shouldHold: (t) => !e.providerSchedules && t !== void 0 && t.getTime() > Date.now(),
275
276
  hold: (t) => {
276
277
  let { scheduledAt: n, ...r } = t;
277
278
  return e.store.hold({
278
- id: I(t),
279
+ id: L(t),
279
280
  dueAt: t.scheduledAt?.getTime() ?? Date.now(),
280
281
  message: r
281
282
  });
282
283
  },
283
284
  tick: (t = Date.now()) => r.gen(function* () {
284
285
  let n = yield* e.store.claimDue(t);
285
- for (let t of n) yield* e.flush(t.message).pipe(r.catchAll((e) => r.sync(() => de.warn("scheduled flush failed", {
286
+ for (let t of n) yield* e.flush(t.message).pipe(r.catchAll((e) => r.sync(() => fe.warn("scheduled flush failed", {
286
287
  id: t.id,
287
288
  message: String(e)
288
289
  }))));
289
290
  return n.length;
290
291
  }),
291
292
  pending: () => e.store.size()
292
- }), pe = 0, R = (e) => `${e}-${pe += 1}`, me = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, z = (e, t) => {
293
+ }), me = 0, z = (e) => `${e}-${me += 1}`, he = (e) => e === void 0 || e === 408 || e === 429 || e >= 500, B = (e, t) => {
293
294
  let n = t.status;
294
- return new y({
295
+ return new b({
295
296
  provider: e,
296
297
  message: (t.message ?? "send failed").slice(0, 500),
297
- transient: me(n),
298
+ transient: he(n),
298
299
  ...n === void 0 ? {} : { status: n }
299
300
  });
300
- }, B = (e, t, n, i, a) => r.tryPromise({
301
+ }, V = (e, t, n, i, a) => r.tryPromise({
301
302
  try: async () => {
302
303
  let e = await fetch(t, {
303
304
  method: "POST",
@@ -318,20 +319,20 @@ var y = class extends u.TaggedError()("MailError", {
318
319
  },
319
320
  catch: (t) => {
320
321
  let n = t;
321
- return z(e, {
322
+ return B(e, {
322
323
  ...typeof n.status == "number" ? { status: n.status } : {},
323
324
  message: n.message ?? t?.message ?? String(t)
324
325
  });
325
326
  }
326
- }), V = (e) => ({
327
+ }), H = (e) => ({
327
328
  from: e.from,
328
- to: S(e.to),
329
+ to: C(e.to),
329
330
  subject: e.subject,
330
331
  html: e.html,
331
332
  text: e.text,
332
333
  reply_to: e.replyTo,
333
- cc: e.cc ? S(e.cc) : void 0,
334
- bcc: e.bcc ? S(e.bcc) : void 0,
334
+ cc: e.cc ? C(e.cc) : void 0,
335
+ bcc: e.bcc ? C(e.bcc) : void 0,
335
336
  headers: e.headers,
336
337
  tags: e.tags?.map((e) => ({
337
338
  name: e,
@@ -343,34 +344,34 @@ var y = class extends u.TaggedError()("MailError", {
343
344
  content: e.content,
344
345
  ...e.contentType ? { content_type: e.contentType } : {}
345
346
  }))
346
- }), H = (e) => ({
347
+ }), U = (e) => ({
347
348
  name: "resend",
348
349
  supportsScheduling: !0,
349
- send: (t) => B("resend", "https://api.resend.com/emails", { authorization: `Bearer ${e.apiKey}` }, V(t), async (e) => ({
350
+ send: (t) => V("resend", "https://api.resend.com/emails", { authorization: `Bearer ${e.apiKey}` }, H(t), async (e) => ({
350
351
  id: (await e.json()).id ?? "resend",
351
352
  provider: "resend"
352
353
  })),
353
- sendBatch: (t) => B("resend", "https://api.resend.com/emails/batch", { authorization: `Bearer ${e.apiKey}` }, t.map(V), async (e) => {
354
+ sendBatch: (t) => V("resend", "https://api.resend.com/emails/batch", { authorization: `Bearer ${e.apiKey}` }, t.map(H), async (e) => {
354
355
  let n = (await e.json()).data ?? [];
355
356
  return t.map((e, t) => ({
356
357
  id: n[t]?.id ?? "resend",
357
358
  provider: "resend"
358
359
  }));
359
360
  })
360
- }), U = (e) => ({
361
+ }), W = (e) => ({
361
362
  name: "postmark",
362
- send: (t) => B("postmark", "https://api.postmarkapp.com/email", {
363
+ send: (t) => V("postmark", "https://api.postmarkapp.com/email", {
363
364
  "x-postmark-server-token": e.serverToken,
364
365
  accept: "application/json"
365
366
  }, {
366
367
  From: t.from,
367
- To: S(t.to).join(","),
368
+ To: C(t.to).join(","),
368
369
  Subject: t.subject,
369
370
  HtmlBody: t.html,
370
371
  TextBody: t.text,
371
372
  ReplyTo: t.replyTo,
372
- Cc: t.cc ? S(t.cc).join(",") : void 0,
373
- Bcc: t.bcc ? S(t.bcc).join(",") : void 0,
373
+ Cc: t.cc ? C(t.cc).join(",") : void 0,
374
+ Bcc: t.bcc ? C(t.bcc).join(",") : void 0,
374
375
  Attachments: t.attachments?.map((e) => ({
375
376
  Name: e.filename,
376
377
  Content: e.content,
@@ -380,44 +381,44 @@ var y = class extends u.TaggedError()("MailError", {
380
381
  id: (await e.json()).MessageID ?? "postmark",
381
382
  provider: "postmark"
382
383
  }))
383
- }), W = (e) => [...e.text ? [{
384
+ }), G = (e) => [...e.text ? [{
384
385
  type: "text/plain",
385
386
  value: e.text
386
387
  }] : [], ...e.html ? [{
387
388
  type: "text/html",
388
389
  value: e.html
389
- }] : []], G = (e) => ({
390
- to: S(e.to).map((e) => ({ email: e })),
391
- cc: e.cc ? S(e.cc).map((e) => ({ email: e })) : void 0,
392
- bcc: e.bcc ? S(e.bcc).map((e) => ({ email: e })) : void 0,
390
+ }] : []], K = (e) => ({
391
+ to: C(e.to).map((e) => ({ email: e })),
392
+ cc: e.cc ? C(e.cc).map((e) => ({ email: e })) : void 0,
393
+ bcc: e.bcc ? C(e.bcc).map((e) => ({ email: e })) : void 0,
393
394
  subject: e.subject,
394
395
  ...e.scheduledAt ? { send_at: Math.floor(e.scheduledAt.getTime() / 1e3) } : {}
395
- }), he = (e) => e.attachments?.map((e) => ({
396
+ }), ge = (e) => e.attachments?.map((e) => ({
396
397
  filename: e.filename,
397
398
  content: e.content,
398
399
  type: e.contentType ?? "application/octet-stream",
399
400
  disposition: "attachment"
400
- })), K = (e) => {
401
+ })), _e = (e) => {
401
402
  let t = (e) => ({
402
- personalizations: [G(e)],
403
+ personalizations: [K(e)],
403
404
  from: { email: e.from },
404
405
  reply_to: e.replyTo ? { email: e.replyTo } : void 0,
405
406
  subject: e.subject,
406
- content: W(e),
407
- attachments: he(e)
407
+ content: G(e),
408
+ attachments: ge(e)
408
409
  });
409
410
  return {
410
411
  name: "sendgrid",
411
412
  supportsScheduling: !0,
412
- send: (n) => B("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, t(n), async (e) => ({
413
+ send: (n) => V("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, t(n), async (e) => ({
413
414
  id: e.headers.get("x-message-id") ?? "sendgrid",
414
415
  provider: "sendgrid"
415
416
  })),
416
- sendBatch: (t) => B("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, {
417
- personalizations: t.map(G),
417
+ sendBatch: (t) => V("sendgrid", "https://api.sendgrid.com/v3/mail/send", { authorization: `Bearer ${e.apiKey}` }, {
418
+ personalizations: t.map(K),
418
419
  from: { email: t[0]?.from },
419
420
  subject: t[0]?.subject,
420
- content: W(t[0] ?? {})
421
+ content: G(t[0] ?? {})
421
422
  }, async (e) => {
422
423
  let n = e.headers.get("x-message-id") ?? "sendgrid";
423
424
  return t.map((e, t) => ({
@@ -426,35 +427,35 @@ var y = class extends u.TaggedError()("MailError", {
426
427
  }));
427
428
  })
428
429
  };
429
- }, ge = (e, t) => {
430
+ }, ve = (e, t) => {
430
431
  let n = t, r = n.response?.status;
431
- return z(e, {
432
+ return B(e, {
432
433
  ...typeof r == "number" ? { status: r } : {},
433
434
  message: n.message ?? String(t)
434
435
  });
435
- }, _e = (e, t, n) => r.gen(function* () {
436
- let i = yield* (yield* _.HttpClient).execute(t);
436
+ }, ye = (e, t, n) => r.gen(function* () {
437
+ let i = yield* (yield* v.HttpClient).execute(t);
437
438
  if (i.status < 200 || i.status >= 300) {
438
439
  let t = yield* i.text.pipe(r.catchAll(() => r.succeed("")));
439
- return yield* r.fail(z(e, {
440
+ return yield* r.fail(B(e, {
440
441
  status: i.status,
441
442
  message: t || `HTTP ${i.status}`
442
443
  }));
443
444
  }
444
445
  return yield* n(i);
445
- }).pipe(r.catchAll((t) => t instanceof y ? r.fail(t) : r.fail(ge(e, t))), r.provide(g.layer)), ve = (e) => ({ sign: async (t, n, r) => {
446
+ }).pipe(r.catchAll((t) => t instanceof b ? r.fail(t) : r.fail(ve(e, t))), r.provide(_.layer)), be = (e) => ({ sign: async (t, n, r) => {
446
447
  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");
447
448
  return {
448
449
  authorization: `AWS4-HMAC-SHA256 Credential=${e.accessKeyId}/${p}, SignedHeaders=${d}, Signature=${h}`,
449
450
  "x-amz-date": c,
450
451
  ...e.sessionToken ? { "x-amz-security-token": e.sessionToken } : {}
451
452
  };
452
- } }), ye = (e) => JSON.stringify({
453
+ } }), xe = (e) => JSON.stringify({
453
454
  FromEmailAddress: e.from,
454
455
  Destination: {
455
- ToAddresses: S(e.to),
456
- ...e.cc ? { CcAddresses: S(e.cc) } : {},
457
- ...e.bcc ? { BccAddresses: S(e.bcc) } : {}
456
+ ToAddresses: C(e.to),
457
+ ...e.cc ? { CcAddresses: C(e.cc) } : {},
458
+ ...e.bcc ? { BccAddresses: C(e.bcc) } : {}
458
459
  },
459
460
  ...e.replyTo ? { ReplyToAddresses: [e.replyTo] } : {},
460
461
  Content: { Simple: {
@@ -473,41 +474,41 @@ var y = class extends u.TaggedError()("MailError", {
473
474
  } } : {}
474
475
  }
475
476
  } }
476
- }), be = (e) => {
477
- let t = ve(e), n = `https://email.${e.region}.amazonaws.com`, i = "/v2/email/outbound-emails";
477
+ }), Se = (e) => {
478
+ let t = be(e), n = `https://email.${e.region}.amazonaws.com`, i = "/v2/email/outbound-emails";
478
479
  return {
479
480
  name: "ses",
480
481
  send: (e) => r.gen(function* () {
481
- let a = ye(e), o = yield* r.tryPromise({
482
+ let a = xe(e), o = yield* r.tryPromise({
482
483
  try: () => t.sign(n, i, a),
483
- catch: (e) => z("ses", { message: e?.message ?? String(e) })
484
+ catch: (e) => B("ses", { message: e?.message ?? String(e) })
484
485
  });
485
- return yield* _e("ses", v.post(`${n}${i}`).pipe(v.setHeaders({
486
+ return yield* ye("ses", y.post(`${n}${i}`).pipe(y.setHeaders({
486
487
  "content-type": "application/json",
487
488
  ...o
488
- }), v.bodyUnsafeJson(JSON.parse(a))), (e) => e.json.pipe(r.map((e) => ({
489
+ }), y.bodyUnsafeJson(JSON.parse(a))), (e) => e.json.pipe(r.map((e) => ({
489
490
  id: e.MessageId ?? "ses",
490
491
  provider: "ses"
491
492
  }))));
492
493
  })
493
494
  };
494
- }, xe = (e) => {
495
+ }, Ce = (e) => {
495
496
  let t = [["from", e.from], ["subject", e.subject]];
496
- for (let n of S(e.to)) t.push(["to", n]);
497
- if (e.cc) for (let n of S(e.cc)) t.push(["cc", n]);
498
- if (e.bcc) for (let n of S(e.bcc)) t.push(["bcc", n]);
497
+ for (let n of C(e.to)) t.push(["to", n]);
498
+ if (e.cc) for (let n of C(e.cc)) t.push(["cc", n]);
499
+ if (e.bcc) for (let n of C(e.bcc)) t.push(["bcc", n]);
499
500
  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]);
500
501
  if (e.tags) for (let n of e.tags) t.push(["o:tag", n]);
501
502
  return e.scheduledAt && t.push(["o:deliverytime", e.scheduledAt.toUTCString()]), t;
502
- }, Se = (e) => {
503
+ }, we = (e) => {
503
504
  let t = `${e.baseUrl ?? "https://api.mailgun.net"}/v3/${e.domain}/messages`;
504
505
  return {
505
506
  name: "mailgun",
506
507
  supportsScheduling: !0,
507
508
  send: (n) => {
508
509
  let i = new URLSearchParams();
509
- for (let [e, t] of xe(n)) i.append(e, t);
510
- return _e("mailgun", v.post(t).pipe(v.setHeader("authorization", `Basic ${Buffer.from(`api:${e.apiKey}`).toString("base64")}`), v.bodyText(i.toString(), "application/x-www-form-urlencoded")), (e) => e.json.pipe(r.map((e) => ({
510
+ for (let [e, t] of Ce(n)) i.append(e, t);
511
+ return ye("mailgun", y.post(t).pipe(y.setHeader("authorization", `Basic ${Buffer.from(`api:${e.apiKey}`).toString("base64")}`), y.bodyText(i.toString(), "application/x-www-form-urlencoded")), (e) => e.json.pipe(r.map((e) => ({
511
512
  id: e.id ?? "mailgun",
512
513
  provider: "mailgun"
513
514
  }))));
@@ -532,9 +533,9 @@ var y = class extends u.TaggedError()("MailError", {
532
533
  return {
533
534
  id: (await t.sendMail({
534
535
  from: n.from,
535
- to: S(n.to),
536
- cc: n.cc ? S(n.cc) : void 0,
537
- bcc: n.bcc ? S(n.bcc) : void 0,
536
+ to: C(n.to),
537
+ cc: n.cc ? C(n.cc) : void 0,
538
+ bcc: n.bcc ? C(n.bcc) : void 0,
538
539
  replyTo: n.replyTo,
539
540
  subject: n.subject,
540
541
  html: n.html,
@@ -552,47 +553,47 @@ var y = class extends u.TaggedError()("MailError", {
552
553
  },
553
554
  catch: (e) => {
554
555
  let t = e;
555
- return z("smtp", {
556
+ return B("smtp", {
556
557
  ...typeof t.responseCode == "number" ? { status: t.responseCode } : {},
557
558
  message: t.message ?? String(e)
558
559
  });
559
560
  }
560
561
  })
561
562
  };
562
- }, Ce = (e) => ({
563
+ }, Te = (e) => ({
563
564
  name: "console",
564
565
  send: (t) => r.sync(() => {
565
- let n = `✉ to=${S(t.to).join(",")} subject=${JSON.stringify(t.subject)}`;
566
+ let n = `✉ to=${C(t.to).join(",")} subject=${JSON.stringify(t.subject)}`;
566
567
  return e ? e(n, { from: t.from }) : process.stdout.write(`[mail:console] ${n}\n`), {
567
- id: R("console"),
568
+ id: z("console"),
568
569
  provider: "console"
569
570
  };
570
571
  })
571
- }), J = [], we = () => [...J], Te = () => {
572
+ }), J = [], Ee = () => [...J], De = () => {
572
573
  J.length = 0;
573
- }, Ee = () => ({
574
+ }, Oe = () => ({
574
575
  name: "memory",
575
576
  send: (e) => r.sync(() => (J.push(e), {
576
- id: R("mem"),
577
+ id: z("mem"),
577
578
  provider: "memory"
578
579
  }))
579
- }), Y = p({ scope: "@voltro/plugin-mail" }), De = (e) => {
580
+ }), Y = m({ scope: "@voltro/plugin-mail" }), ke = (e) => {
580
581
  if (e.provider !== void 0 && typeof e.provider != "string") return e.provider;
581
582
  let t = e.env ?? {}, n = e.provider ?? t.MAIL_PROVIDER ?? "console", r = (e, t) => {
582
583
  if (!t) throw Error(`@voltro/plugin-mail: provider '${n}' needs apiKey or ${e}`);
583
584
  return t;
584
585
  };
585
586
  switch (n) {
586
- case "resend": return H({ apiKey: r("RESEND_API_KEY", e.apiKey ?? t.RESEND_API_KEY) });
587
- case "postmark": return U({ serverToken: r("POSTMARK_SERVER_TOKEN", e.apiKey ?? t.POSTMARK_SERVER_TOKEN) });
588
- case "sendgrid": return K({ apiKey: r("SENDGRID_API_KEY", e.apiKey ?? t.SENDGRID_API_KEY) });
589
- case "ses": return be({
587
+ case "resend": return U({ apiKey: r("RESEND_API_KEY", e.apiKey ?? t.RESEND_API_KEY) });
588
+ case "postmark": return W({ serverToken: r("POSTMARK_SERVER_TOKEN", e.apiKey ?? t.POSTMARK_SERVER_TOKEN) });
589
+ case "sendgrid": return _e({ apiKey: r("SENDGRID_API_KEY", e.apiKey ?? t.SENDGRID_API_KEY) });
590
+ case "ses": return Se({
590
591
  region: r("AWS_REGION", t.AWS_REGION),
591
592
  accessKeyId: r("AWS_ACCESS_KEY_ID", t.AWS_ACCESS_KEY_ID),
592
593
  secretAccessKey: r("AWS_SECRET_ACCESS_KEY", t.AWS_SECRET_ACCESS_KEY),
593
594
  ...t.AWS_SESSION_TOKEN ? { sessionToken: t.AWS_SESSION_TOKEN } : {}
594
595
  });
595
- case "mailgun": return Se({
596
+ case "mailgun": return we({
596
597
  apiKey: r("MAILGUN_API_KEY", e.apiKey ?? t.MAILGUN_API_KEY),
597
598
  domain: r("MAILGUN_DOMAIN", t.MAILGUN_DOMAIN),
598
599
  ...t.MAILGUN_BASE_URL ? { baseUrl: t.MAILGUN_BASE_URL } : {}
@@ -606,29 +607,29 @@ var y = class extends u.TaggedError()("MailError", {
606
607
  pass: t.SMTP_PASS
607
608
  } } : {}
608
609
  });
609
- case "memory": return Ee();
610
- default: return Ce((e, t) => Y.info(e, t));
610
+ case "memory": return Oe();
611
+ default: return Te((e, t) => Y.info(e, t));
611
612
  }
612
613
  }, X = (e) => {
613
- let t = e.attempts ?? 3, n = e.suppression ?? j(), i = e.allowlist, a = e.production !== !0 && i !== void 0 && i.length > 0, o = (e) => i.some((t) => t.toLowerCase() === e.toLowerCase()), s = l.recurs(t).pipe(l.whileInput((e) => e.transient)), c = /* @__PURE__ */ new Map();
614
+ let t = e.attempts ?? 3, n = e.suppression ?? M(), i = e.allowlist, a = e.production !== !0 && i !== void 0 && i.length > 0, o = (e) => i.some((t) => t.toLowerCase() === e.toLowerCase()), s = l.recurs(t).pipe(l.whileInput((e) => e.transient)), c = /* @__PURE__ */ new Map();
614
615
  for (let t of e.templates ?? []) c.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
615
616
  let u = (e, t) => (t ? c.get(`${e}:${t}`) : void 0) ?? c.get(e) ?? O(e, t), d = /* @__PURE__ */ new Map(), f = (e, t) => `${e.name}|${e.locale ?? ""}|${JSON.stringify(t ?? null)}`, p = (e, t) => {
616
617
  if (d.set(e, t), d.size > 500) {
617
618
  let e = d.keys().next().value;
618
619
  e !== void 0 && d.delete(e);
619
620
  }
620
- }, m = e.idempotency ?? N(), h = L({
621
- store: e.schedule ?? F(),
621
+ }, m = e.idempotency ?? P(), h = R({
622
+ store: e.schedule ?? I(),
622
623
  providerSchedules: e.provider.supportsScheduling === !0,
623
624
  flush: (e) => v(e)
624
625
  }), g = (t) => r.gen(function* () {
625
626
  let i = t.from ?? e.from;
626
- if (!i) return yield* r.fail(new y({
627
+ if (!i) return yield* r.fail(new b({
627
628
  provider: e.provider.name,
628
629
  message: "no `from` — set mailPlugin({ from }) or pass message.from",
629
630
  transient: !1
630
631
  }));
631
- let s = S(t.to);
632
+ let s = C(t.to);
632
633
  if (a) {
633
634
  let n = s.filter(o);
634
635
  if (n.length === 0) return Y.warn("mail skipped — no recipient in allowlist (non-production)", {
@@ -683,7 +684,7 @@ var y = class extends u.TaggedError()("MailError", {
683
684
  }
684
685
  };
685
686
  }), _ = (t) => {
686
- let n = S(t.to);
687
+ let n = C(t.to);
687
688
  return e.provider.send(t).pipe(r.retry(s), r.tap((i) => r.sync(() => {
688
689
  Y.info("mail sent", {
689
690
  provider: i.provider,
@@ -721,7 +722,7 @@ var y = class extends u.TaggedError()("MailError", {
721
722
  dueAt: t.scheduledAt?.toISOString()
722
723
  }), e.onSent?.({
723
724
  id: "scheduled",
724
- to: S(n.message.to),
725
+ to: C(n.message.to),
725
726
  from: n.message.from,
726
727
  subject: n.message.subject,
727
728
  provider: "scheduled",
@@ -731,7 +732,7 @@ var y = class extends u.TaggedError()("MailError", {
731
732
  id: "scheduled",
732
733
  provider: "scheduled"
733
734
  }) : yield* _(n.message);
734
- }), b = (e, t, n) => t === void 0 ? n : r.gen(function* () {
735
+ }), y = (e, t, n) => t === void 0 ? n : r.gen(function* () {
735
736
  let r = yield* m.reserve(e, t);
736
737
  if (!r.won) return Y.info("mail idempotent replay — skipped", { key: t }), r.prior ?? {
737
738
  id: "idempotent-replay",
@@ -741,7 +742,7 @@ var y = class extends u.TaggedError()("MailError", {
741
742
  return yield* m.record(e, t, i), i;
742
743
  }), x = (e) => r.suspend(() => {
743
744
  let t = u(e.template, e.locale);
744
- if (!t) return r.fail(new y({
745
+ if (!t) return r.fail(new b({
745
746
  provider: "template",
746
747
  message: `unknown template '${e.template}'${e.locale ? ` (locale '${e.locale}')` : ""}`,
747
748
  transient: !1
@@ -763,15 +764,15 @@ var y = class extends u.TaggedError()("MailError", {
763
764
  ...e.scheduledAt === void 0 ? {} : { scheduledAt: e.scheduledAt },
764
765
  ...e.idempotencyKey === void 0 ? {} : { idempotencyKey: e.idempotencyKey }
765
766
  })));
766
- }), C = (e) => "template" in e ? x(e) : r.succeed(e);
767
+ }), S = (e) => "template" in e ? x(e) : r.succeed(e);
767
768
  return {
768
769
  service: {
769
770
  send: (e) => r.gen(function* () {
770
- let t = yield* C(e);
771
- return yield* b(t.tenantId ?? null, t.idempotencyKey, v(t));
771
+ let t = yield* S(e);
772
+ return yield* y(t.tenantId ?? null, t.idempotencyKey, v(t));
772
773
  }),
773
774
  sendBatch: (t) => r.gen(function* () {
774
- let n = yield* r.forEach(t, C), i = n.some((e) => e.idempotencyKey !== void 0 || h.shouldHold(e.scheduledAt));
775
+ let n = yield* r.forEach(t, S), i = n.some((e) => e.idempotencyKey !== void 0 || h.shouldHold(e.scheduledAt));
775
776
  if (e.provider.sendBatch && !i) {
776
777
  let t = [], i = [];
777
778
  for (let e of n) {
@@ -784,10 +785,10 @@ var y = class extends u.TaggedError()("MailError", {
784
785
  i && (Y.info("mail sent (batch)", {
785
786
  provider: i.provider,
786
787
  id: i.id,
787
- to: S(t.to).join(",")
788
+ to: C(t.to).join(",")
788
789
  }), e.onSent?.({
789
790
  id: i.id,
790
- to: S(t.to),
791
+ to: C(t.to),
791
792
  from: t.from,
792
793
  subject: t.subject,
793
794
  provider: i.provider,
@@ -805,7 +806,7 @@ var y = class extends u.TaggedError()("MailError", {
805
806
  provider: e.provider.name
806
807
  } : t);
807
808
  }
808
- return yield* r.forEach(n, (e) => b(e.tenantId ?? null, e.idempotencyKey, v(e)));
809
+ return yield* r.forEach(n, (e) => y(e.tenantId ?? null, e.idempotencyKey, v(e)));
809
810
  }),
810
811
  suppress: n.suppress,
811
812
  unsuppress: n.unsuppress,
@@ -813,7 +814,7 @@ var y = class extends u.TaggedError()("MailError", {
813
814
  },
814
815
  scheduler: h
815
816
  };
816
- }, Oe = (e) => X(e).service, ke = (e) => a.succeed(x, Oe(e)), Z = (e = 200) => {
817
+ }, Z = (e) => X(e).service, Ae = (e) => a.succeed(S, Z(e)), je = (e = 200) => {
817
818
  let t = [];
818
819
  return {
819
820
  record: (n) => {
@@ -844,35 +845,35 @@ var y = class extends u.TaggedError()("MailError", {
844
845
  case "Suspend": return Q(e.f(), t + 1);
845
846
  default: return null;
846
847
  }
847
- }, Ae = (e) => Q(e.ast, 0), $ = (e, t, n, r, i) => t ? {
848
+ }, Me = (e) => Q(e.ast, 0), $ = (e, t, n, r, i) => t ? {
848
849
  type: e,
849
850
  email: t,
850
851
  provider: n,
851
852
  raw: i,
852
853
  ...r === void 0 ? {} : { messageId: r }
853
- } : null, je = (e) => e === "email.bounced" ? "bounced" : e === "email.complained" ? "complained" : e === "email.delivered" ? "delivered" : e === "email.opened" ? "opened" : e === "email.clicked" ? "clicked" : "unknown", Me = (e) => e === "Bounce" ? "bounced" : e === "SpamComplaint" ? "complained" : e === "Delivery" ? "delivered" : e === "Open" ? "opened" : e === "Click" ? "clicked" : "unknown", Ne = (e) => e === "bounce" || e === "dropped" ? "bounced" : e === "spamreport" ? "complained" : e === "delivered" ? "delivered" : e === "open" ? "opened" : e === "click" ? "clicked" : "unknown", Pe = (e, t) => {
854
+ } : null, Ne = (e) => e === "email.bounced" ? "bounced" : e === "email.complained" ? "complained" : e === "email.delivered" ? "delivered" : e === "email.opened" ? "opened" : e === "email.clicked" ? "clicked" : "unknown", Pe = (e) => e === "Bounce" ? "bounced" : e === "SpamComplaint" ? "complained" : e === "Delivery" ? "delivered" : e === "Open" ? "opened" : e === "Click" ? "clicked" : "unknown", Fe = (e) => e === "bounce" || e === "dropped" ? "bounced" : e === "spamreport" ? "complained" : e === "delivered" ? "delivered" : e === "open" ? "opened" : e === "click" ? "clicked" : "unknown", Ie = (e, t) => {
854
855
  let n = [], r = (e) => {
855
856
  e && n.push(e);
856
857
  };
857
858
  if (e === "sendgrid" && Array.isArray(t)) {
858
- for (let e of t) r($(Ne(String(e.event)), e.email, "sendgrid", e.sg_message_id, e));
859
+ for (let e of t) r($(Fe(String(e.event)), e.email, "sendgrid", e.sg_message_id, e));
859
860
  return n;
860
861
  }
861
862
  let i = t ?? {};
862
863
  if (e === "resend") {
863
864
  let e = i.data ?? {}, a = Array.isArray(e.to) ? e.to[0] : e.to ?? e.email;
864
- return r($(je(String(i.type)), a, "resend", e.email_id, t)), n;
865
+ return r($(Ne(String(i.type)), a, "resend", e.email_id, t)), n;
865
866
  }
866
867
  if (e === "postmark") {
867
868
  let e = i.Email ?? i.Recipient;
868
- return r($(Me(String(i.RecordType)), e, "postmark", i.MessageID, t)), n;
869
+ return r($(Pe(String(i.RecordType)), e, "postmark", i.MessageID, t)), n;
869
870
  }
870
871
  return n;
871
- }, Fe = (e, t, n, i = null) => r.gen(function* () {
872
- let r = Pe(e, t);
872
+ }, Le = (e, t, n, i = null) => r.gen(function* () {
873
+ let r = Ie(e, t);
873
874
  for (let e of r) (e.type === "bounced" || e.type === "complained") && (yield* n.suppress(i, e.email, e.type));
874
875
  return r;
875
- }), Ie = f([
876
+ }), Re = p([
876
877
  {
877
878
  name: "MAIL_PROVIDER",
878
879
  required: !1,
@@ -1053,48 +1054,53 @@ var y = class extends u.TaggedError()("MailError", {
1053
1054
  secret: !1,
1054
1055
  description: "Fallback Postgres database name for the postgres suppression store."
1055
1056
  }
1056
- ]), Le = (e = {}) => {
1057
- let t = process.env, o = De({
1057
+ ]), ze = "@voltro/plugin-mail", Be = (e = {}) => {
1058
+ let t = process.env, o = ke({
1058
1059
  ...e.provider === void 0 ? {} : { provider: e.provider },
1059
1060
  ...e.apiKey === void 0 ? {} : { apiKey: e.apiKey },
1060
1061
  env: t
1061
- }), s = Ie.read("MAIL_ALLOWLIST"), c = e.allowlist ?? (s ? s.split(",").map((e) => e.trim()).filter(Boolean) : void 0), u = t.NODE_ENV === "production", f = e.suppression === void 0 || e.suppression === "memory" ? j() : e.suppression === "postgres" ? ce() : e.suppression, p = e.idempotency === void 0 || e.idempotency === "memory" ? N() : e.idempotency === "postgres" ? P() : e.idempotency, m = e.schedule ?? F(), h = Z(), g = X({
1062
+ }), s = Re.read("MAIL_ALLOWLIST"), c = e.allowlist ?? (s ? s.split(",").map((e) => e.trim()).filter(Boolean) : void 0), u = t.NODE_ENV === "production", p = e.suppression === void 0 || e.suppression === "memory" ? M() : e.suppression === "postgres" ? le() : e.suppression, m = e.idempotency === void 0 || e.idempotency === "memory" ? P() : e.idempotency === "postgres" ? F() : e.idempotency, h = e.schedule ?? I(), g = je(), _ = X({
1062
1063
  provider: o,
1063
- suppression: f,
1064
- idempotency: p,
1065
- schedule: m,
1066
- onSent: h.record,
1064
+ suppression: p,
1065
+ idempotency: m,
1066
+ schedule: h,
1067
+ onSent: g.record,
1067
1068
  ...e.from === void 0 ? {} : { from: e.from },
1068
1069
  ...e.replyTo === void 0 ? {} : { replyTo: e.replyTo },
1069
1070
  ...c === void 0 ? {} : { allowlist: c },
1070
1071
  ...e.attempts === void 0 ? {} : { attempts: e.attempts },
1071
1072
  ...e.templates === void 0 ? {} : { templates: e.templates },
1072
1073
  production: u
1073
- }), _ = a.succeed(x, g.service), v = o.supportsScheduling !== !0, y = e.scheduleTickMs ?? 1e3, b, S = /* @__PURE__ */ new Map();
1074
- for (let t of e.templates ?? []) S.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
1075
- let C = (e, t) => (t ? S.get(`${e}:${t}`) : void 0) ?? S.get(e) ?? O(e, t), w = (e) => ({
1074
+ }), v = a.succeed(S, _.service), y = o.supportsScheduling !== !0, b = e.scheduleTickMs ?? 1e3, x, C = /* @__PURE__ */ new Map();
1075
+ for (let t of e.templates ?? []) C.set(t.locale ? `${t.name}:${t.locale}` : t.name, t);
1076
+ let ee = (e, t) => (t ? C.get(`${e}:${t}`) : void 0) ?? C.get(e) ?? O(e, t), w = (e) => ({
1076
1077
  name: e.name,
1077
1078
  ...e.locale ? { locale: e.locale } : {},
1078
- props: e.preview ?? Ae(e.props)
1079
+ props: e.preview ?? Me(e.props)
1079
1080
  }), T = () => {
1080
1081
  let t = /* @__PURE__ */ new Map();
1081
1082
  for (let n of e.templates ?? []) t.set(n.locale ? `${n.name}:${n.locale}` : n.name, w(n));
1082
- for (let e of re()) {
1083
+ for (let e of k()) {
1083
1084
  let n = O(e.name, e.locale);
1084
1085
  n && t.set(e.locale ? `${e.name}:${e.locale}` : e.name, w(n));
1085
1086
  }
1086
1087
  return [...t.values()];
1087
1088
  };
1088
1089
  return d({
1089
- name: e.name ? `@voltro/plugin-mail#${e.name}` : "@voltro/plugin-mail",
1090
+ name: f({
1091
+ base: ze,
1092
+ alias: e.alias,
1093
+ instance: e.name
1094
+ }),
1095
+ baseName: ze,
1090
1096
  description: "Transactional email — MailService over Resend / Postmark / SendGrid / SMTP (+ console/memory), with default-from, transient retry and a dev allowlist.",
1091
1097
  permissions: [
1092
1098
  "network:outbound:*",
1093
1099
  "inspect:read",
1094
1100
  "inspect:write"
1095
1101
  ],
1096
- declaredEnv: Ie.declared,
1097
- services: _,
1102
+ declaredEnv: Re.declared,
1103
+ services: v,
1098
1104
  inspectEndpoints: [
1099
1105
  {
1100
1106
  method: "GET",
@@ -1102,7 +1108,7 @@ var y = class extends u.TaggedError()("MailError", {
1102
1108
  description: "Recent sent mail (dev capture buffer), newest first",
1103
1109
  handler: () => r.succeed({
1104
1110
  kind: "json",
1105
- data: { sends: h.list() }
1111
+ data: { sends: g.list() }
1106
1112
  })
1107
1113
  },
1108
1114
  {
@@ -1134,7 +1140,7 @@ var y = class extends u.TaggedError()("MailError", {
1134
1140
  status: 400,
1135
1141
  data: { error: "missing \"template\"" }
1136
1142
  };
1137
- let n = C(t.template, t.locale);
1143
+ let n = ee(t.template, t.locale);
1138
1144
  return n ? yield* E(n, t.props).pipe(r.map((e) => ({
1139
1145
  kind: "json",
1140
1146
  data: e
@@ -1151,9 +1157,9 @@ var y = class extends u.TaggedError()("MailError", {
1151
1157
  }
1152
1158
  ],
1153
1159
  onActivate: (t) => r.gen(function* () {
1154
- if (f.activate && (yield* r.promise(() => f.activate(t.env))), p.activate && (yield* r.promise(() => p.activate(t.env))), v) {
1155
- let e = g.scheduler.tick().pipe(r.repeat(l.spaced(n.millis(Math.max(50, y)))));
1156
- b = r.runFork(e);
1160
+ if (p.activate && (yield* r.promise(() => p.activate(t.env))), m.activate && (yield* r.promise(() => m.activate(t.env))), y) {
1161
+ let e = _.scheduler.tick().pipe(r.repeat(l.spaced(n.millis(Math.max(50, b)))));
1162
+ x = r.runFork(e);
1157
1163
  }
1158
1164
  t.logger.info("mail active", {
1159
1165
  provider: o.name,
@@ -1166,9 +1172,9 @@ var y = class extends u.TaggedError()("MailError", {
1166
1172
  });
1167
1173
  }),
1168
1174
  onDeactivate: () => r.gen(function* () {
1169
- b !== void 0 && (yield* i.interrupt(b), b = void 0), f.deactivate && (yield* r.promise(() => f.deactivate())), p.deactivate && (yield* r.promise(() => p.deactivate()));
1175
+ x !== void 0 && (yield* i.interrupt(x), x = void 0), p.deactivate && (yield* r.promise(() => p.deactivate())), m.deactivate && (yield* r.promise(() => m.deactivate()));
1170
1176
  })
1171
1177
  });
1172
1178
  };
1173
1179
  //#endregion
1174
- export { y as MailError, x as MailService, Oe as buildMailService, X as buildMailServiceWithScheduler, ie as clearGlobalTemplates, Te as clearMailBuffer, Ce as consoleProvider, Z as createOutbox, b as defineEmail, ne as globalTemplateCount, Fe as handleMailEvents, I as heldId, ae as isEmailTemplate, re as listGlobalTemplates, O as lookupGlobalTemplate, Le as mailPlugin, ke as mailServiceLayer, Se as mailgunProvider, L as makeScheduler, N as memoryIdempotencyStore, Ee as memoryProvider, F as memoryScheduleStore, j as memorySuppressionStore, Pe as parseMailEvent, P as postgresIdempotencyStore, ce as postgresSuppressionStore, U as postmarkProvider, we as readMailBuffer, te as registerEmailTemplates, E as renderTemplate, H as resendProvider, De as resolveProvider, K as sendgridProvider, be as sesProvider, q as smtpProvider };
1180
+ export { b as MailError, S as MailService, Z as buildMailService, X as buildMailServiceWithScheduler, ie as clearGlobalTemplates, De as clearMailBuffer, Te as consoleProvider, je as createOutbox, x as defineEmail, re as globalTemplateCount, Le as handleMailEvents, L as heldId, ae as isEmailTemplate, k as listGlobalTemplates, O as lookupGlobalTemplate, Be as mailPlugin, Ae as mailServiceLayer, we as mailgunProvider, R as makeScheduler, P as memoryIdempotencyStore, Oe as memoryProvider, I as memoryScheduleStore, M as memorySuppressionStore, Ie as parseMailEvent, F as postgresIdempotencyStore, le as postgresSuppressionStore, W as postmarkProvider, Ee as readMailBuffer, ne as registerEmailTemplates, E as renderTemplate, U as resendProvider, ke as resolveProvider, _e as sendgridProvider, Se as sesProvider, q as smtpProvider };