@c9up/rover 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +1 -1
  2. package/dist/BaseMail.d.ts +41 -1
  3. package/dist/BaseMail.d.ts.map +1 -1
  4. package/dist/BaseMail.js +48 -1
  5. package/dist/BaseMail.js.map +1 -1
  6. package/dist/Mail.d.ts +90 -24
  7. package/dist/Mail.d.ts.map +1 -1
  8. package/dist/Mail.js +123 -40
  9. package/dist/Mail.js.map +1 -1
  10. package/dist/MessageBuilder.d.ts +296 -8
  11. package/dist/MessageBuilder.d.ts.map +1 -1
  12. package/dist/MessageBuilder.js +537 -8
  13. package/dist/MessageBuilder.js.map +1 -1
  14. package/dist/config.d.ts +38 -0
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js +34 -0
  17. package/dist/config.js.map +1 -1
  18. package/dist/format.d.ts +10 -0
  19. package/dist/format.d.ts.map +1 -1
  20. package/dist/format.js +28 -1
  21. package/dist/format.js.map +1 -1
  22. package/dist/index.d.ts +19 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +16 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/testing/FakeMail.d.ts +33 -0
  27. package/dist/testing/FakeMail.d.ts.map +1 -1
  28. package/dist/testing/FakeMail.js +28 -0
  29. package/dist/testing/FakeMail.js.map +1 -1
  30. package/dist/transports/BrevoTransport.d.ts.map +1 -1
  31. package/dist/transports/BrevoTransport.js +7 -5
  32. package/dist/transports/BrevoTransport.js.map +1 -1
  33. package/dist/transports/MailgunTransport.d.ts.map +1 -1
  34. package/dist/transports/MailgunTransport.js +5 -3
  35. package/dist/transports/MailgunTransport.js.map +1 -1
  36. package/dist/transports/ResendTransport.d.ts.map +1 -1
  37. package/dist/transports/ResendTransport.js +7 -5
  38. package/dist/transports/ResendTransport.js.map +1 -1
  39. package/dist/transports/SendGridTransport.d.ts.map +1 -1
  40. package/dist/transports/SendGridTransport.js +10 -6
  41. package/dist/transports/SendGridTransport.js.map +1 -1
  42. package/dist/transports/SesTransport.d.ts.map +1 -1
  43. package/dist/transports/SesTransport.js +16 -7
  44. package/dist/transports/SesTransport.js.map +1 -1
  45. package/dist/transports/SparkPostTransport.d.ts.map +1 -1
  46. package/dist/transports/SparkPostTransport.js +7 -5
  47. package/dist/transports/SparkPostTransport.js.map +1 -1
  48. package/dist/transports/fetchError.d.ts +10 -0
  49. package/dist/transports/fetchError.d.ts.map +1 -1
  50. package/dist/transports/fetchError.js +30 -0
  51. package/dist/transports/fetchError.js.map +1 -1
  52. package/index.darwin-arm64.node +0 -0
  53. package/index.darwin-x64.node +0 -0
  54. package/index.linux-arm64-gnu.node +0 -0
  55. package/index.linux-x64-gnu.node +0 -0
  56. package/index.win32-x64-msvc.node +0 -0
  57. package/package.json +6 -1
  58. package/src/BaseMail.ts +59 -2
  59. package/src/Mail.ts +194 -65
  60. package/src/MessageBuilder.ts +756 -12
  61. package/src/config.ts +46 -0
  62. package/src/format.ts +33 -1
  63. package/src/index.ts +31 -2
  64. package/src/testing/FakeMail.ts +46 -0
  65. package/src/transports/BrevoTransport.ts +7 -5
  66. package/src/transports/MailgunTransport.ts +5 -3
  67. package/src/transports/ResendTransport.ts +7 -5
  68. package/src/transports/SendGridTransport.ts +10 -6
  69. package/src/transports/SesTransport.ts +16 -7
  70. package/src/transports/SparkPostTransport.ts +17 -11
  71. package/src/transports/fetchError.ts +39 -0
@@ -1,5 +1,108 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { basename } from "node:path";
3
+ import { fileURLToPath } from "node:url";
1
4
  import { formatAddress } from "./format.js";
5
+ import { RoverError } from "./RoverError.js";
2
6
  import { renderFile as renderTemplateFile } from "./templating/SimpleTemplate.js";
7
+ /**
8
+ * A header value as a plain string, for the HTTP-API transports.
9
+ *
10
+ * "Prepared" is a nodemailer notion — it tells its MIME encoder to leave the
11
+ * value alone. A provider REST API takes a JSON string and does no MIME
12
+ * encoding, so the flag has nothing to say there; sending the wrapper object
13
+ * would put `[object Object]` on the wire.
14
+ */
15
+ export function headerValue(value) {
16
+ if (Array.isArray(value) || typeof value === "string")
17
+ return value;
18
+ return value.value;
19
+ }
20
+ /** Whether `list` holds `address`, or anything at all when it is omitted. */
21
+ function contains(list, address, name) {
22
+ if (address === undefined)
23
+ return list.length > 0;
24
+ // With a name, both halves must match — the entry was stored through
25
+ // `formatAddress`, so rebuilding it is the exact comparison (AdonisJS
26
+ // checks address AND name the same way).
27
+ if (name !== undefined) {
28
+ const formatted = formatAddress(address, name);
29
+ return list.some((entry) => entry === formatted);
30
+ }
31
+ // Addresses are stored formatted (`"Name" <a@b.c>`), so an assertion on the
32
+ // bare address has to match inside the display form too.
33
+ return list.some((entry) => entry === address || entry.includes(`<${address}>`));
34
+ }
35
+ /**
36
+ * The parts a transport with no calendar field must send: the declared
37
+ * attachments, plus the invitation rendered as a `text/calendar` part.
38
+ *
39
+ * Only nodemailer has a native `icalEvent`; the provider HTTP APIs carry an
40
+ * invitation the way every mail client reads it anyway — as an attachment with
41
+ * the right media type and `method` parameter.
42
+ */
43
+ export function attachmentsFor(message) {
44
+ const ical = message.icalEvent;
45
+ if (ical === undefined)
46
+ return message.attachments;
47
+ if (ical.content === undefined) {
48
+ // `icalEventFromUrl` leaves only an href, which nodemailer fetches for
49
+ // SMTP. An HTTP provider takes the bytes, and silently dropping the
50
+ // invitation would be worse than saying so.
51
+ throw new RoverError("ICAL_HREF_UNSUPPORTED", "icalEventFromUrl() is only supported by the SMTP transport, which fetches the URL itself.", {
52
+ hint: "Fetch the ICS yourself and pass it to icalEvent(contents), or use icalEventFromFile().",
53
+ });
54
+ }
55
+ const method = ical.method ?? "PUBLISH";
56
+ return [
57
+ ...message.attachments,
58
+ {
59
+ filename: ical.filename ?? "invite.ics",
60
+ content: ical.content,
61
+ contentType: `text/calendar; charset=utf-8; method=${method}`,
62
+ encoding: ical.encoding,
63
+ },
64
+ ];
65
+ }
66
+ /** Read a file declared by `attach()` / `embed()` / `icalEventFromFile()`. */
67
+ async function readAttachment(path, label) {
68
+ try {
69
+ return await readFile(path);
70
+ }
71
+ catch (err) {
72
+ throw new RoverError("ATTACHMENT_UNREADABLE", `Could not read ${label} from "${path}": ${err instanceof Error ? err.message : String(err)}`, {
73
+ hint: "Give an absolute path, or attach the bytes with attachData() / embedData().",
74
+ });
75
+ }
76
+ }
77
+ /** Every URL inside a `List-*` value, whatever nesting form it was written in. */
78
+ function listUrls(value) {
79
+ if (typeof value === "string")
80
+ return [value];
81
+ if (Array.isArray(value))
82
+ return value.flatMap((entry) => listUrls(entry));
83
+ return [value.url];
84
+ }
85
+ /** `unsubscribe` → `Unsubscribe`, `unsubscribe-post` → `Unsubscribe-Post`. */
86
+ function titleCaseKey(key) {
87
+ return key
88
+ .split("-")
89
+ .map((part) => (part ? part[0].toUpperCase() + part.slice(1) : part))
90
+ .join("-");
91
+ }
92
+ /** Render one `List-*` value the way RFC 2369 writes it: `<url> (comment)`. */
93
+ function renderListHeader(value) {
94
+ if (typeof value === "string")
95
+ return `<${value}>`;
96
+ if (Array.isArray(value)) {
97
+ return value.map((entry) => renderListHeader(entry)).join(", ");
98
+ }
99
+ return value.comment ? `<${value.url}> (${value.comment})` : `<${value.url}>`;
100
+ }
101
+ function expect(passed, expectation, actual) {
102
+ if (passed)
103
+ return;
104
+ throw new RoverError("ASSERTION_FAILED", `Expected the message ${expectation}, got ${JSON.stringify(actual)}`);
105
+ }
3
106
  export class MessageBuilder {
4
107
  #msg = {
5
108
  from: "",
@@ -11,6 +114,204 @@ export class MessageBuilder {
11
114
  headers: {},
12
115
  };
13
116
  #pendingView = null;
117
+ /**
118
+ * The templates {@link build} actually rendered. Recorded because `build()`
119
+ * clears the pending views once they are rendered, and the lifecycle events
120
+ * carry them (AdonisJS `views`, the third field of every mail event) — an
121
+ * app logging a send wants to know which template produced it.
122
+ */
123
+ #renderedViews = {};
124
+ #pendingWatchView = null;
125
+ #pendingTextView = null;
126
+ /**
127
+ * Render a template as the PLAIN-TEXT body (AdonisJS `textView`).
128
+ *
129
+ * The counterpart of `htmlView`. A message with only an HTML part scores
130
+ * worse with spam filters and is unreadable in a text-only client, which is
131
+ * why upstream offers both.
132
+ */
133
+ textView(path, data = {}) {
134
+ this.#pendingTextView = { path, data };
135
+ return this;
136
+ }
137
+ /**
138
+ * Override the SMTP envelope — who the message is really from and to, as
139
+ * far as the mail servers are concerned (AdonisJS `envelope`).
140
+ *
141
+ * Distinct from the `From`/`To` HEADERS: a bounce goes to the envelope
142
+ * sender, which is how VERP and mailing lists route failures away from the
143
+ * visible author.
144
+ */
145
+ envelope(envelope) {
146
+ this.#msg.envelope = envelope;
147
+ return this;
148
+ }
149
+ /**
150
+ * The message as built so far — what the `has*` / `assert*` helpers read.
151
+ *
152
+ * Exposed because a test asserts against a mail it never sent, and the
153
+ * alternative is rebuilding the message just to look at it.
154
+ */
155
+ toObject() {
156
+ return this.#msg;
157
+ }
158
+ toJSON() {
159
+ return this.toObject();
160
+ }
161
+ // ── Inspection ────────────────────────────────────────────────────────
162
+ // `has*` answers, `assert*` throws. Both exist because a test reads better
163
+ // as an assertion and a conditional reads better as a question.
164
+ hasTo(address, name) {
165
+ return contains(this.#msg.to, address, name);
166
+ }
167
+ hasCc(address, name) {
168
+ return contains(this.#msg.cc, address, name);
169
+ }
170
+ hasBcc(address, name) {
171
+ return contains(this.#msg.bcc, address, name);
172
+ }
173
+ hasFrom(address, name) {
174
+ return contains(this.#msg.from ? [this.#msg.from] : [], address, name);
175
+ }
176
+ hasReplyTo(address, name) {
177
+ return contains(this.#msg.replyTo ? [this.#msg.replyTo] : [], address, name);
178
+ }
179
+ hasSubject(subject) {
180
+ if (subject === undefined)
181
+ return this.#msg.subject !== "";
182
+ return this.#msg.subject === subject;
183
+ }
184
+ /**
185
+ * Whether the message carries an attachment — any at all, one with this
186
+ * filename or source path, or one a predicate accepts (AdonisJS
187
+ * `hasAttachment`, whose overloads are the same three).
188
+ */
189
+ hasAttachment(match) {
190
+ if (match === undefined)
191
+ return this.#msg.attachments.length > 0;
192
+ if (typeof match === "function")
193
+ return this.#msg.attachments.some(match);
194
+ const needle = match instanceof URL ? fileURLToPath(match) : match;
195
+ return this.#msg.attachments.some((a) => a.filename === needle || a.path === needle);
196
+ }
197
+ /**
198
+ * Whether `address` appears in ONE named field (AdonisJS `hasRecipient`).
199
+ *
200
+ * The field comes first, as upstream: `hasRecipient('to', 'a@b.c')`. It used
201
+ * to take the address alone and search every field, so a migrated
202
+ * `hasRecipient('to', addr)` asked whether `'to'` was a recipient and quietly
203
+ * answered false — the worst possible outcome inside a test assertion.
204
+ * {@link hasAnyRecipient} is the any-field question under a name that says so.
205
+ */
206
+ hasRecipient(property, address, name) {
207
+ switch (property) {
208
+ case "to":
209
+ return this.hasTo(address, name);
210
+ case "cc":
211
+ return this.hasCc(address, name);
212
+ case "bcc":
213
+ return this.hasBcc(address, name);
214
+ case "replyTo":
215
+ return this.hasReplyTo(address, name);
216
+ }
217
+ }
218
+ /**
219
+ * Whether `address` is a recipient in any of `to` / `cc` / `bcc`. Without
220
+ * one, whether the message has a recipient at all. Ream's own, since
221
+ * "does this reach them" is the question an assertion usually asks.
222
+ */
223
+ hasAnyRecipient(address, name) {
224
+ return (this.hasTo(address, name) ||
225
+ this.hasCc(address, name) ||
226
+ this.hasBcc(address, name));
227
+ }
228
+ /**
229
+ * Whether the given text appears in the HTML body or the plain-text one
230
+ * (AdonisJS `hasContent`). The field-specific assertions are
231
+ * {@link assertHtmlIncludes} and {@link assertTextIncludes}.
232
+ */
233
+ hasContent(needle) {
234
+ return ((this.#msg.html?.includes(needle) ?? false) ||
235
+ (this.#msg.text?.includes(needle) ?? false));
236
+ }
237
+ /** Whether a `List-<key>` header was defined. */
238
+ hasListHeader(key, url) {
239
+ const value = this.#msg.list?.[key];
240
+ if (value === undefined)
241
+ return false;
242
+ if (url === undefined)
243
+ return true;
244
+ return listUrls(value).includes(url);
245
+ }
246
+ hasHeader(name, value) {
247
+ const found = this.#msg.headers[name];
248
+ if (found === undefined)
249
+ return false;
250
+ if (value === undefined)
251
+ return true;
252
+ return Array.isArray(found) ? found.includes(value) : found === value;
253
+ }
254
+ assertTo(address) {
255
+ expect(this.hasTo(address), `to include "${address}"`, this.#msg.to);
256
+ }
257
+ assertFrom(address) {
258
+ expect(this.hasFrom(address), `from to be "${address}"`, this.#msg.from);
259
+ }
260
+ assertCc(address) {
261
+ expect(this.hasCc(address), `cc to include "${address}"`, this.#msg.cc);
262
+ }
263
+ assertBcc(address) {
264
+ expect(this.hasBcc(address), `bcc to include "${address}"`, this.#msg.bcc);
265
+ }
266
+ assertReplyTo(address) {
267
+ expect(this.hasReplyTo(address), `replyTo to be "${address}"`, this.#msg.replyTo);
268
+ }
269
+ assertSubject(subject) {
270
+ expect(this.hasSubject(subject), `subject to be "${subject}"`, this.#msg.subject);
271
+ }
272
+ assertAttachment(match) {
273
+ expect(this.hasAttachment(match), typeof match === "function"
274
+ ? "an attachment matching the predicate"
275
+ : `an attachment named "${String(match)}"`, this.#msg.attachments.map((a) => a.path ?? a.filename));
276
+ }
277
+ /** `address` is a recipient in some field (AdonisJS `assertRecipient`). */
278
+ assertRecipient(address) {
279
+ expect(this.hasAnyRecipient(address), `to reach "${address}"`, {
280
+ to: this.#msg.to,
281
+ cc: this.#msg.cc,
282
+ bcc: this.#msg.bcc,
283
+ });
284
+ }
285
+ /** The text appears in the HTML or the plain-text body (AdonisJS `assertContent`). */
286
+ assertContent(needle) {
287
+ expect(this.hasContent(needle), `to contain "${needle}"`, {
288
+ html: this.#msg.html,
289
+ text: this.#msg.text,
290
+ });
291
+ }
292
+ assertHeader(name, value) {
293
+ expect(this.hasHeader(name, value), value === undefined ? `a "${name}" header` : `${name}: ${value}`, this.#msg.headers[name]);
294
+ }
295
+ assertHtmlIncludes(substring) {
296
+ expect((this.#msg.html ?? "").includes(substring), `html to include "${substring}"`, this.#msg.html);
297
+ }
298
+ assertTextIncludes(substring) {
299
+ expect((this.#msg.text ?? "").includes(substring), `text to include "${substring}"`, this.#msg.text);
300
+ }
301
+ /**
302
+ * The Apple Watch body contains `substring` (AdonisJS
303
+ * `assertWatchIncludes`).
304
+ *
305
+ * Takes a RegExp as well as a string, as upstream does — a rendered body
306
+ * rarely matches a fixed substring exactly.
307
+ */
308
+ assertWatchIncludes(substring) {
309
+ const body = this.#msg.watchHtml ?? "";
310
+ const hit = typeof substring === "string"
311
+ ? body.includes(substring)
312
+ : substring.test(body);
313
+ expect(hit, `watch body to include "${String(substring)}"`, body);
314
+ }
14
315
  from(address, name) {
15
316
  this.#msg.from = formatAddress(address, name);
16
317
  return this;
@@ -39,6 +340,32 @@ export class MessageBuilder {
39
340
  this.#msg.html = content;
40
341
  return this;
41
342
  }
343
+ /**
344
+ * The Apple Watch body (AdonisJS `watch`).
345
+ *
346
+ * NAMED DEVIATION — this writes nodemailer's `watchHtml`. AdonisJS writes a
347
+ * bare `watch` field, which nodemailer's mail composer never reads
348
+ * (lib/mail-composer/index.js only looks at `watchHtml`), so upstream's
349
+ * watch body never reaches the wire. {@link watchHtml} is the same method
350
+ * under the field's own name.
351
+ */
352
+ watch(content) {
353
+ return this.watchHtml(content);
354
+ }
355
+ watchHtml(content) {
356
+ this.#msg.watchHtml = content;
357
+ return this;
358
+ }
359
+ /**
360
+ * Render a template as the Apple Watch body (AdonisJS `watchView`).
361
+ *
362
+ * The counterpart of {@link htmlView} and {@link textView}: the render
363
+ * happens lazily at `build()` time so the fluent chain stays synchronous.
364
+ */
365
+ watchView(viewPath, data) {
366
+ this.#pendingWatchView = { path: viewPath, data: data ?? {} };
367
+ return this;
368
+ }
42
369
  text(content) {
43
370
  this.#msg.text = content;
44
371
  return this;
@@ -63,24 +390,170 @@ export class MessageBuilder {
63
390
  this.#msg.references = messageIds.slice();
64
391
  return this;
65
392
  }
66
- attach(filename, content, contentType) {
67
- this.#msg.attachments.push({ filename, content, contentType });
393
+ /**
394
+ * Attach a FILE by path or `file://` URL (AdonisJS `attach`). The bytes are
395
+ * read at {@link build} time, so the fluent chain stays synchronous.
396
+ *
397
+ * The filename defaults to the file's own basename. For bytes you already
398
+ * hold, use {@link attachData}.
399
+ */
400
+ attach(file, options) {
401
+ const path = file instanceof URL ? fileURLToPath(file) : file;
402
+ this.#msg.attachments.push({
403
+ filename: options?.filename ?? basename(path),
404
+ // Filled in by `build()`; an unread attachment must never ship as an
405
+ // empty part, so `build()` failing to read is an error, not a warning.
406
+ content: "",
407
+ path,
408
+ contentType: options?.contentType,
409
+ contentDisposition: options?.contentDisposition,
410
+ encoding: options?.encoding,
411
+ headers: options?.headers,
412
+ });
413
+ return this;
414
+ }
415
+ /**
416
+ * Attach bytes you already hold (AdonisJS `attachData`). `filename` is
417
+ * required — there is no path to take it from.
418
+ */
419
+ attachData(content, options) {
420
+ this.#msg.attachments.push({
421
+ filename: options.filename,
422
+ content,
423
+ contentType: options.contentType,
424
+ contentDisposition: options.contentDisposition,
425
+ encoding: options.encoding,
426
+ headers: options.headers,
427
+ });
68
428
  return this;
69
429
  }
70
430
  /**
71
- * Embed inline content referenced by a Content-ID. Use `cid:<cid>` inside the
72
- * HTML body to reference it. Content-based (rover is agnostic / no-fs): the
73
- * path-based `embed(file, cid)` form from `@adonisjs/mail` is a deliberate
74
- * divergence — pass the bytes directly instead.
431
+ * Embed a FILE inline, referenced by `cid:<cid>` in the HTML body (AdonisJS
432
+ * `embed`). Read at {@link build} time, like {@link attach}.
75
433
  */
76
- embedData(content, cid, contentType) {
77
- this.#msg.attachments.push({ filename: cid, content, contentType, cid });
434
+ embed(file, cid, options) {
435
+ const path = file instanceof URL ? fileURLToPath(file) : file;
436
+ this.#msg.attachments.push({
437
+ filename: options?.filename ?? basename(path),
438
+ content: "",
439
+ path,
440
+ cid,
441
+ contentType: options?.contentType,
442
+ contentDisposition: options?.contentDisposition ?? "inline",
443
+ encoding: options?.encoding,
444
+ headers: options?.headers,
445
+ });
446
+ return this;
447
+ }
448
+ /**
449
+ * Embed bytes you already hold, referenced by `cid:<cid>` in the HTML body
450
+ * (AdonisJS `embedData`).
451
+ */
452
+ embedData(content, cid, options) {
453
+ this.#msg.attachments.push({
454
+ filename: options?.filename ?? cid,
455
+ content,
456
+ cid,
457
+ contentType: options?.contentType,
458
+ contentDisposition: options?.contentDisposition ?? "inline",
459
+ encoding: options?.encoding,
460
+ headers: options?.headers,
461
+ });
78
462
  return this;
79
463
  }
80
464
  header(key, value) {
81
465
  this.#msg.headers[key] = value;
82
466
  return this;
83
467
  }
468
+ /**
469
+ * A header nodemailer passes through untouched (AdonisJS `preparedHeader`).
470
+ *
471
+ * Use it when the value IS what must appear on the wire and re-encoding
472
+ * would corrupt it — a signature, an already-encoded message id.
473
+ */
474
+ preparedHeader(key, value) {
475
+ this.#msg.headers[key] = { prepared: true, value };
476
+ return this;
477
+ }
478
+ /**
479
+ * Body transfer encoding (AdonisJS `encoding`) — `7bit`, `base64`,
480
+ * `quoted-printable`… SMTP only: the provider HTTP APIs encode the payload
481
+ * themselves and expose no equivalent.
482
+ */
483
+ encoding(encoding) {
484
+ this.#msg.encoding = encoding;
485
+ return this;
486
+ }
487
+ // ── RFC 2369 List-* headers ───────────────────────────────────────────
488
+ /**
489
+ * Define a `List-<key>` header (AdonisJS `addListHeader`). `key` carries no
490
+ * `List-` prefix — `addListHeader('archive', url)` emits `List-Archive`.
491
+ * Calling it again for the same key replaces the value.
492
+ */
493
+ addListHeader(key, value) {
494
+ this.#msg.list ??= {};
495
+ this.#msg.list[key] = value;
496
+ return this;
497
+ }
498
+ /**
499
+ * `List-Unsubscribe` (AdonisJS `listUnsubscribe`).
500
+ *
501
+ * `{ oneClick: true }` also emits the RFC 8058 `List-Unsubscribe-Post`
502
+ * header. Gmail and Yahoo require BOTH for bulk senders, and only a `https:`
503
+ * URL is a valid one-click target — a `mailto:` cannot answer a POST, so
504
+ * pairing them is refused rather than silently shipped.
505
+ */
506
+ listUnsubscribe(value, options) {
507
+ if (options?.oneClick === true) {
508
+ for (const url of listUrls(value)) {
509
+ if (!url.toLowerCase().startsWith("http")) {
510
+ throw new RoverError("INVALID_LIST_HEADER", `listUnsubscribe({ oneClick: true }) needs an https URL that can answer a POST, got "${url}".`, {
511
+ hint: "Keep the mailto: form without oneClick, or add an https endpoint alongside it.",
512
+ });
513
+ }
514
+ }
515
+ // A RAW header, not a `List-*` entry: nodemailer wraps every list value
516
+ // in angle brackets, and `<List-Unsubscribe=One-Click>` is not what
517
+ // RFC 8058 specifies — receivers would ignore it.
518
+ this.#msg.headers["List-Unsubscribe-Post"] = "List-Unsubscribe=One-Click";
519
+ }
520
+ return this.addListHeader("unsubscribe", value);
521
+ }
522
+ /** `List-Subscribe` (AdonisJS `listSubscribe`). */
523
+ listSubscribe(value) {
524
+ return this.addListHeader("subscribe", value);
525
+ }
526
+ /** `List-Help` (AdonisJS `listHelp`). */
527
+ listHelp(value) {
528
+ return this.addListHeader("help", value);
529
+ }
530
+ // ── Calendar invitations ──────────────────────────────────────────────
531
+ /**
532
+ * Attach a calendar invitation from an ICS string (AdonisJS `icalEvent`).
533
+ *
534
+ * Named deviation: upstream also accepts a `(calendar: ICalCalendar) => void`
535
+ * builder, which is `ical-generator`'s API. rover carries no such
536
+ * dependency, so it takes the ICS text — produced by whichever generator you
537
+ * prefer. {@link icalEventFromFile} and {@link icalEventFromUrl} are the
538
+ * other two upstream forms, unchanged.
539
+ */
540
+ icalEvent(contents, options) {
541
+ this.#msg.icalEvent = { ...options, content: contents };
542
+ return this;
543
+ }
544
+ /** Calendar invitation read from a file at {@link build} time (AdonisJS `icalEventFromFile`). */
545
+ icalEventFromFile(file, options) {
546
+ this.#msg.icalEvent = {
547
+ ...options,
548
+ path: file instanceof URL ? fileURLToPath(file) : file,
549
+ };
550
+ return this;
551
+ }
552
+ /** Calendar invitation the transport fetches from a URL (AdonisJS `icalEventFromUrl`). */
553
+ icalEventFromUrl(url, options) {
554
+ this.#msg.icalEvent = { ...options, href: url };
555
+ return this;
556
+ }
84
557
  /**
85
558
  * Queue an HTML template render. The render happens lazily at `build()` time
86
559
  * so the fluent chain stays synchronous; `build()` is async and awaits the
@@ -90,6 +563,23 @@ export class MessageBuilder {
90
563
  this.#pendingView = { path: viewPath, data: data ?? {} };
91
564
  return this;
92
565
  }
566
+ /** The templates {@link build} rendered, for the lifecycle events. */
567
+ get views() {
568
+ return { ...this.#renderedViews };
569
+ }
570
+ /** AdonisJS' name for {@link views}. */
571
+ get contentViews() {
572
+ return this.views;
573
+ }
574
+ /**
575
+ * The message as a plain object (AdonisJS `nodeMailerMessage`).
576
+ *
577
+ * A live reference, as upstream's is — this is the object the transports
578
+ * read, not a snapshot. {@link build} is what finalises it.
579
+ */
580
+ get nodeMailerMessage() {
581
+ return this.#msg;
582
+ }
93
583
  /**
94
584
  * Finalise the message. `viewsRoot`, when provided by the owning `Mail`,
95
585
  * scopes template resolution to that instance's configured root instead of
@@ -98,9 +588,48 @@ export class MessageBuilder {
98
588
  */
99
589
  async build(viewsRoot) {
100
590
  if (this.#pendingView !== null) {
591
+ this.#renderedViews.html = {
592
+ template: this.#pendingView.path,
593
+ data: this.#pendingView.data,
594
+ };
101
595
  this.#msg.html = await renderTemplateFile(this.#pendingView.path, this.#pendingView.data, undefined, viewsRoot);
102
596
  this.#pendingView = null;
103
597
  }
598
+ if (this.#pendingWatchView !== null) {
599
+ this.#renderedViews.watch = {
600
+ template: this.#pendingWatchView.path,
601
+ data: this.#pendingWatchView.data,
602
+ };
603
+ this.#msg.watchHtml = await renderTemplateFile(this.#pendingWatchView.path, this.#pendingWatchView.data, undefined, viewsRoot);
604
+ this.#pendingWatchView = null;
605
+ }
606
+ if (this.#pendingTextView !== null) {
607
+ this.#renderedViews.text = {
608
+ template: this.#pendingTextView.path,
609
+ data: this.#pendingTextView.data,
610
+ };
611
+ this.#msg.text = await renderTemplateFile(this.#pendingTextView.path, this.#pendingTextView.data, undefined, viewsRoot);
612
+ this.#pendingTextView = null;
613
+ }
614
+ // Path-based attachments and invitations are read here, not when they were
615
+ // declared, so the fluent chain stays synchronous. A read failure raises:
616
+ // an attachment the recipient expects must never ship as an empty part.
617
+ for (const attachment of this.#msg.attachments) {
618
+ if (attachment.path === undefined)
619
+ continue;
620
+ attachment.content = await readAttachment(attachment.path, attachment.filename);
621
+ }
622
+ const ical = this.#msg.icalEvent;
623
+ if (ical?.path !== undefined && ical.content === undefined) {
624
+ ical.content = (await readAttachment(ical.path, "the calendar event")).toString("utf8");
625
+ }
626
+ // `List-*` headers are rendered here, once, rather than in each transport:
627
+ // every transport already forwards `headers`, and only nodemailer has a
628
+ // structured `list` field. `#msg.list` stays as the structured record the
629
+ // `hasListHeader` inspection reads.
630
+ for (const [key, value] of Object.entries(this.#msg.list ?? {})) {
631
+ this.#msg.headers[`List-${titleCaseKey(key)}`] = renderListHeader(value);
632
+ }
104
633
  return this.#msg;
105
634
  }
106
635
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessageBuilder.js","sourceRoot":"","sources":["../src/MessageBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MessageBuilder.js","sourceRoot":"","sources":["../src/MessageBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAclF;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAC1B,KAAyC;IAEzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACpE,OAAO,KAAK,CAAC,KAAK,CAAC;AACpB,CAAC;AAoHD,6EAA6E;AAC7E,SAAS,QAAQ,CAChB,IAAuB,EACvB,OAAgB,EAChB,IAAa;IAEb,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAClD,qEAAqE;IACrE,sEAAsE;IACtE,yCAAyC;IACzC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAClD,CAAC;IACD,4EAA4E;IAC5E,yDAAyD;IACzD,OAAO,IAAI,CAAC,IAAI,CACf,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,OAAO,GAAG,CAAC,CAC9D,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAoB;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC;IAC/B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC;IACnD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,uEAAuE;QACvE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,IAAI,UAAU,CACnB,uBAAuB,EACvB,2FAA2F,EAC3F;YACC,IAAI,EAAE,wFAAwF;SAC9F,CACD,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;IACxC,OAAO;QACN,GAAG,OAAO,CAAC,WAAW;QACtB;YACC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,YAAY;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,wCAAwC,MAAM,EAAE;YAC7D,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACvB;KACD,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,KAAa;IACxD,IAAI,CAAC;QACJ,OAAO,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,MAAM,IAAI,UAAU,CACnB,uBAAuB,EACvB,kBAAkB,KAAK,UAAU,IAAI,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC7F;YACC,IAAI,EAAE,6EAA6E;SACnF,CACD,CAAC;IACH,CAAC;AACF,CAAC;AAED,kFAAkF;AAClF,SAAS,QAAQ,CAAC,KAAiD;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC;AAED,8EAA8E;AAC9E,SAAS,YAAY,CAAC,GAAW;IAChC,OAAO,GAAG;SACR,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACpE,IAAI,CAAC,GAAG,CAAC,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,SAAS,gBAAgB,CACxB,KAAiD;IAEjD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,KAAK,GAAG,CAAC;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC;AAC/E,CAAC;AAED,SAAS,MAAM,CAAC,MAAe,EAAE,WAAmB,EAAE,MAAe;IACpE,IAAI,MAAM;QAAE,OAAO;IACnB,MAAM,IAAI,UAAU,CACnB,kBAAkB,EAClB,wBAAwB,WAAW,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CACpE,CAAC;AACH,CAAC;AAYD,MAAM,OAAO,cAAc;IAC1B,IAAI,GAAgB;QACnB,IAAI,EAAE,EAAE;QACR,EAAE,EAAE,EAAE;QACN,EAAE,EAAE,EAAE;QACN,GAAG,EAAE,EAAE;QACP,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,EAAE;QACf,OAAO,EAAE,EAAE;KACX,CAAC;IACF,YAAY,GAA2D,IAAI,CAAC;IAC5E;;;;;OAKG;IACH,cAAc,GAAyB,EAAE,CAAC;IAC1C,iBAAiB,GAChB,IAAI,CAAC;IACN,gBAAgB,GACf,IAAI,CAAC;IAEN;;;;;;OAMG;IACH,QAAQ,CAAC,IAAY,EAAE,OAAgC,EAAE;QACxD,IAAI,CAAC,gBAAgB,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACvC,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAsB;QAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACP,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED,MAAM;QACL,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED,yEAAyE;IACzE,2EAA2E;IAC3E,gEAAgE;IAEhE,KAAK,CAAC,OAAgB,EAAE,IAAa;QACpC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,KAAK,CAAC,OAAgB,EAAE,IAAa;QACpC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,MAAM,CAAC,OAAgB,EAAE,IAAa;QACrC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,CAAC,OAAgB,EAAE,IAAa;QACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACxE,CAAC;IACD,UAAU,CAAC,OAAgB,EAAE,IAAa;QACzC,OAAO,QAAQ,CACd,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAC5C,OAAO,EACP,IAAI,CACJ,CAAC;IACH,CAAC;IACD,UAAU,CAAC,OAAgB;QAC1B,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC;IACtC,CAAC;IACD;;;;OAIG;IACH,aAAa,CACZ,KAAgE;QAEhE,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACjE,IAAI,OAAO,KAAK,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,KAAK,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACnE,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CACjD,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACH,YAAY,CACX,QAAyC,EACzC,OAAe,EACf,IAAa;QAEb,QAAQ,QAAQ,EAAE,CAAC;YAClB,KAAK,IAAI;gBACR,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAClC,KAAK,IAAI;gBACR,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAClC,KAAK,KAAK;gBACT,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACnC,KAAK,SAAS;gBACb,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;IACF,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,OAAgB,EAAE,IAAa;QAC9C,OAAO,CACN,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAC1B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,MAAc;QACxB,OAAO,CACN,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC;YAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAC3C,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,aAAa,CAAC,GAAW,EAAE,GAAY;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,SAAS,CAAC,IAAY,EAAE,KAAc;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC;IACvE,CAAC;IAED,QAAQ,CAAC,OAAe;QACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,eAAe,OAAO,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,UAAU,CAAC,OAAe;QACzB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,eAAe,OAAO,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC;IACD,QAAQ,CAAC,OAAe;QACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,kBAAkB,OAAO,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,SAAS,CAAC,OAAe;QACxB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,OAAO,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,aAAa,CAAC,OAAe;QAC5B,MAAM,CACL,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EACxB,kBAAkB,OAAO,GAAG,EAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,CACjB,CAAC;IACH,CAAC;IACD,aAAa,CAAC,OAAe;QAC5B,MAAM,CACL,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EACxB,kBAAkB,OAAO,GAAG,EAC5B,IAAI,CAAC,IAAI,CAAC,OAAO,CACjB,CAAC;IACH,CAAC;IACD,gBAAgB,CACf,KAA+D;QAE/D,MAAM,CACL,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EACzB,OAAO,KAAK,KAAK,UAAU;YAC1B,CAAC,CAAC,sCAAsC;YACxC,CAAC,CAAC,wBAAwB,MAAM,CAAC,KAAK,CAAC,GAAG,EAC3C,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CACtD,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,eAAe,CAAC,OAAe;QAC9B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,aAAa,OAAO,GAAG,EAAE;YAC9D,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;YAChB,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE;YAChB,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG;SAClB,CAAC,CAAC;IACJ,CAAC;IAED,sFAAsF;IACtF,aAAa,CAAC,MAAc;QAC3B,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,eAAe,MAAM,GAAG,EAAE;YACzD,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;YACpB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI;SACpB,CAAC,CAAC;IACJ,CAAC;IACD,YAAY,CAAC,IAAY,EAAE,KAAc;QACxC,MAAM,CACL,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,EAC3B,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,EAAE,EAChE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CACvB,CAAC;IACH,CAAC;IACD,kBAAkB,CAAC,SAAiB;QACnC,MAAM,CACL,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAC1C,oBAAoB,SAAS,GAAG,EAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CACd,CAAC;IACH,CAAC;IACD,kBAAkB,CAAC,SAAiB;QACnC,MAAM,CACL,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAC1C,oBAAoB,SAAS,GAAG,EAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CACd,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,SAA0B;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC;QACvC,MAAM,GAAG,GACR,OAAO,SAAS,KAAK,QAAQ;YAC5B,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC1B,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,EAAE,0BAA0B,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAAa;QAClC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACb,CAAC;IAID,EAAE,CAAC,OAA6B,EAAE,IAAa;QAC9C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACb,CAAC;IAID,EAAE,CAAC,OAA6B,EAAE,IAAa;QAC9C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACb,CAAC;IAID,GAAG,CAAC,OAA6B,EAAE,IAAa;QAC/C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CAAC,OAAe,EAAE,IAAa;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CAAC,IAAY;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,CAAC,OAAe;QACnB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,OAAe;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,OAAe;QACxB,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAgB,EAAE,IAA8B;QACzD,IAAI,CAAC,iBAAiB,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;QAC9D,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IAAI,CAAC,OAAe;QACnB,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,kDAAkD;IAClD,QAAQ,CAAC,QAAmC;QAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,wCAAwC;IACxC,SAAS,CAAC,SAAiB;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAChC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,0DAA0D;IAC1D,SAAS,CAAC,SAAiB;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAChC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,wDAAwD;IACxD,UAAU,CAAC,UAAoB;QAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,IAAkB,EAAE,OAA2B;QACrD,MAAM,IAAI,GAAG,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC;YAC7C,qEAAqE;YACrE,uEAAuE;YACvE,OAAO,EAAE,EAAE;YACX,IAAI;YACJ,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB;YAC/C,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,OAAO,EAAE,OAAO,EAAE,OAAO;SACzB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,UAAU,CACT,OAAwB,EACxB,OAAiD;QAEjD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;YAC9C,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;SACxB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAkB,EAAE,GAAW,EAAE,OAA2B;QACjE,MAAM,IAAI,GAAG,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC;YAC7C,OAAO,EAAE,EAAE;YACX,IAAI;YACJ,GAAG;YACH,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB,IAAI,QAAQ;YAC3D,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,OAAO,EAAE,OAAO,EAAE,OAAO;SACzB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;OAGG;IACH,SAAS,CACR,OAAwB,EACxB,GAAW,EACX,OAA2B;QAE3B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YAC1B,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,GAAG;YAClC,OAAO;YACP,GAAG;YACH,WAAW,EAAE,OAAO,EAAE,WAAW;YACjC,kBAAkB,EAAE,OAAO,EAAE,kBAAkB,IAAI,QAAQ;YAC3D,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,OAAO,EAAE,OAAO,EAAE,OAAO;SACzB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,KAAwB;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC/B,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACH,cAAc,CAAC,GAAW,EAAE,KAAa;QACxC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAgB;QACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC9B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,yEAAyE;IAEzE;;;;OAIG;IACH,aAAa,CACZ,GAAW,EACX,KAAiD;QAEjD,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC5B,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CACd,KAAiD,EACjD,OAAgC;QAEhC,IAAI,OAAO,EAAE,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChC,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3C,MAAM,IAAI,UAAU,CACnB,qBAAqB,EACrB,uFAAuF,GAAG,IAAI,EAC9F;wBACC,IAAI,EAAE,gFAAgF;qBACtF,CACD,CAAC;gBACH,CAAC;YACF,CAAC;YACD,wEAAwE;YACxE,oEAAoE;YACpE,kDAAkD;YAClD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,uBAAuB,CAAC,GAAG,4BAA4B,CAAC;QAC3E,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,mDAAmD;IACnD,aAAa,CAAC,KAAiD;QAC9D,OAAO,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,yCAAyC;IACzC,QAAQ,CAAC,KAAiD;QACzD,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,yEAAyE;IAEzE;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAgB,EAAE,OAA8B;QACzD,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;QACxD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,iGAAiG;IACjG,iBAAiB,CAAC,IAAkB,EAAE,OAA8B;QACnE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG;YACrB,GAAG,OAAO;YACV,IAAI,EAAE,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI;SACtD,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,0FAA0F;IAC1F,gBAAgB,CAAC,GAAW,EAAE,OAA8B;QAC3D,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,QAAgB,EAAE,IAA8B;QACxD,IAAI,CAAC,YAAY,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACb,CAAC;IAED,sEAAsE;IACtE,IAAI,KAAK;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,CAAC;IAED,wCAAwC;IACxC,IAAI,YAAY;QACf,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;;;OAKG;IACH,IAAI,iBAAiB;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,SAAkB;QAC7B,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;YAChC,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG;gBAC1B,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI;gBAChC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI;aAC5B,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,kBAAkB,CACxC,IAAI,CAAC,YAAY,CAAC,IAAI,EACtB,IAAI,CAAC,YAAY,CAAC,IAAI,EACtB,SAAS,EACT,SAAS,CACT,CAAC;YACF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG;gBAC3B,QAAQ,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI;gBACrC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI;aACjC,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,MAAM,kBAAkB,CAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAC3B,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAC3B,SAAS,EACT,SAAS,CACT,CAAC;YACF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG;gBAC1B,QAAQ,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI;gBACpC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI;aAChC,CAAC;YACF,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,kBAAkB,CACxC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAC1B,SAAS,EACT,SAAS,CACT,CAAC;YACF,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,2EAA2E;QAC3E,0EAA0E;QAC1E,wEAAwE;QACxE,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAChD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS;YAC5C,UAAU,CAAC,OAAO,GAAG,MAAM,cAAc,CACxC,UAAU,CAAC,IAAI,EACf,UAAU,CAAC,QAAQ,CACnB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,IAAI,EAAE,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC5D,IAAI,CAAC,OAAO,GAAG,CACd,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,CACrD,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC;QACD,2EAA2E;QAC3E,wEAAwE;QACxE,0EAA0E;QAC1E,oCAAoC;QACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;CACD;AAED;;;;GAIG;AACH,SAAS,aAAa,CACrB,IAAc,EACd,OAA6B,EAC7B,IAAa;IAEb,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CACR,OAAO,KAAK,KAAK,QAAQ;gBACxB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAC3C,CAAC;QACH,CAAC;QACD,OAAO;IACR,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC"}