@travetto/email 3.1.8 → 3.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/service.ts +36 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/email",
3
- "version": "3.1.8",
3
+ "version": "3.1.10",
4
4
  "description": "Email transmission module.",
5
5
  "keywords": [
6
6
  "email",
package/src/service.ts CHANGED
@@ -7,7 +7,8 @@ import { MailTemplateEngine } from './template';
7
7
  import { MailUtil } from './util';
8
8
  import { EmailResource } from './resource';
9
9
 
10
- type MessageWithoutBody = Omit<MessageOptions, 'html' | 'text' | 'subject'>;
10
+ type Compiled = { html: string, text?: string, subject: string };
11
+ type MessageWithoutBody = Omit<MessageOptions, keyof Compiled>;
11
12
 
12
13
  /**
13
14
  * Email service for sending and templating emails
@@ -15,7 +16,7 @@ type MessageWithoutBody = Omit<MessageOptions, 'html' | 'text' | 'subject'>;
15
16
  @Injectable()
16
17
  export class MailService {
17
18
 
18
- #compiled = new Map<string, { html: string, subject: string, text?: string }>();
19
+ #compiled = new Map<string, Compiled>();
19
20
  #transport: MailTransport;
20
21
  #tplEngine: MailTemplateEngine;
21
22
  #resources: EmailResource;
@@ -33,7 +34,7 @@ export class MailService {
33
34
  /**
34
35
  * Get compiled content by key
35
36
  */
36
- async getCompiled(key: string): Promise<{ html: string, text?: string, subject: string }> {
37
+ async getCompiled(key: string): Promise<Compiled> {
37
38
  if (GlobalEnv.dynamic || !this.#compiled.has(key)) {
38
39
  const [html, text, subject] = await Promise.all([
39
40
  this.#resources.read(`${key}.compiled.html`),
@@ -48,43 +49,53 @@ export class MailService {
48
49
 
49
50
  /**
50
51
  * Build message from key/context
51
- * @param key
52
+ * @param keyOrMessage
52
53
  * @param ctx
53
54
  * @returns
54
55
  */
55
- async buildMessage(key: string | MessageOptions, ctx: Record<string, unknown>): Promise<MessageOptions> {
56
- const tpl = (typeof key === 'string' ? await this.getCompiled(key) : key);
56
+ async templateMessage(keyOrMessage: string | Compiled, ctx: Record<string, unknown>): Promise<Compiled> {
57
+ const tpl = (typeof keyOrMessage === 'string' ? await this.getCompiled(keyOrMessage) : keyOrMessage);
57
58
 
58
- const [rawHtml, text, subject] = await Promise.all([
59
+ const [html, text, subject] = await Promise.all([
59
60
  tpl.html ? this.#tplEngine!.template(tpl.html, ctx) : undefined,
60
61
  tpl.text ? this.#tplEngine!.template(tpl.text, ctx) : undefined,
61
62
  tpl.subject ? this.#tplEngine!.template(tpl.subject, ctx) : undefined
62
63
  ]);
63
64
 
64
- const msg: MessageOptions = {
65
- html: rawHtml ?? '',
66
- text,
67
- subject
68
- };
69
-
70
- if (msg.html) {
71
- const { html, attachments } = await MailUtil.extractImageAttachments(msg.html);
72
- msg.html = html;
73
- msg.attachments = attachments;
74
- }
75
-
76
- return msg;
65
+ return { html: html!, text, subject: subject! };
77
66
  }
78
67
 
79
68
  /**
80
69
  * Send a single message
81
70
  */
82
- async send<S extends SentMessage = SentMessage>(key: string, ctx?: Record<string, unknown>, base?: MessageWithoutBody): Promise<S>;
71
+ async send<S extends SentMessage = SentMessage>(
72
+ message: Pick<MessageOptions, 'to' | 'from' | 'replyTo'>,
73
+ key: string,
74
+ ctx?: Record<string, unknown>,
75
+ base?: MessageWithoutBody
76
+ ): Promise<S>;
83
77
  async send<S extends SentMessage = SentMessage>(message: MessageOptions): Promise<S>;
84
- async send<S extends SentMessage = SentMessage>(keyOrMessage: MessageOptions | string, ctx?: Record<string, unknown>, base?: MessageWithoutBody): Promise<S> {
85
- ctx ??= (typeof keyOrMessage === 'string' ? {} : keyOrMessage.context) ?? {};
86
- const msg = await this.buildMessage(keyOrMessage, ctx);
87
- return this.#transport.send<S>({ ...base, ...msg });
78
+ async send<S extends SentMessage = SentMessage>(
79
+ message: MessageOptions | Pick<MessageOptions, 'to' | 'from' | 'replyTo'>,
80
+ key?: string,
81
+ ctx?: Record<string, unknown>,
82
+ base?: MessageWithoutBody
83
+ ): Promise<S> {
84
+ const keyOrMessage = key ?? ('html' in message ? message : '') ?? '';
85
+ const context = ctx ?? (('context' in message) ? message.context : {}) ?? {};
86
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
87
+ const compiled = await this.templateMessage(keyOrMessage as Compiled, context);
88
+
89
+ const final = { ...base, ...message, ...compiled, context };
90
+
91
+ // Extract images
92
+ if (compiled.html) {
93
+ const { html, attachments } = await MailUtil.extractImageAttachments(compiled.html);
94
+ final.html = html;
95
+ final.attachments = [...attachments, ...(final.attachments ?? [])];
96
+ }
97
+
98
+ return this.#transport.send<S>(final);
88
99
  }
89
100
 
90
101
  /**