Browse Source

feat(email-plugin): EmailSender now implements InjectableStrategy

Relates to #1767
Michael Bromley 3 years ago
parent
commit
0c30be226c

+ 1 - 0
packages/email-plugin/index.ts

@@ -8,3 +8,4 @@ export * from './src/plugin';
 export * from './src/template-loader';
 export * from './src/types';
 export * from './src/email-generator';
+export * from './src/email-sender';

+ 2 - 7
packages/email-plugin/src/email-processor.ts

@@ -6,16 +6,11 @@ import { deserializeAttachments } from './attachment-utils';
 import { isDevModeOptions } from './common';
 import { EMAIL_PLUGIN_OPTIONS, loggerCtx } from './constants';
 import { EmailGenerator } from './email-generator';
+import { EmailSender } from './email-sender';
 import { HandlebarsMjmlGenerator } from './handlebars-mjml-generator';
 import { NodemailerEmailSender } from './nodemailer-email-sender';
 import { TemplateLoader } from './template-loader';
-import {
-    EmailDetails,
-    EmailPluginOptions,
-    EmailSender,
-    EmailTransportOptions,
-    IntermediateEmailDetails,
-} from './types';
+import { EmailDetails, EmailPluginOptions, EmailTransportOptions, IntermediateEmailDetails } from './types';
 
 /**
  * This class combines the template loading, generation, and email sending - the actual "work" of

+ 47 - 0
packages/email-plugin/src/email-sender.ts

@@ -0,0 +1,47 @@
+import { InjectableStrategy } from '@vendure/core';
+
+import { EmailDetails, EmailTransportOptions } from './types';
+
+/**
+ * @description
+ * An EmailSender is responsible for sending the email, e.g. via an SMTP connection
+ * or using some other mail-sending API. By default, the EmailPlugin uses the
+ * {@link NodemailerEmailSender}, but it is also possible to supply a custom implementation:
+ *
+ * @example
+ * ```TypeScript
+ * const sgMail = require('\@sendgrid/mail');
+ *
+ * sgMail.setApiKey(process.env.SENDGRID_API_KEY);
+ *
+ * class SendgridEmailSender implements EmailSender {
+ *   async send(email: EmailDetails) {
+ *     await sgMail.send({
+ *       to: email.recipient,
+ *       from: email.from,
+ *       subject: email.subject,
+ *       html: email.body,
+ *     });
+ *   }
+ * }
+ *
+ * const config: VendureConfig = {
+ *   logger: new DefaultLogger({ level: LogLevel.Debug })
+ *   // ...
+ *   plugins: [
+ *     EmailPlugin.init({
+ *        // ... template, handlers config omitted
+ *       transport: { type: 'none' },
+ *        emailSender: new SendgridEmailSender(),
+ *     }),
+ *   ],
+ * };
+ * ```
+ *
+ * @docsCategory EmailPlugin
+ * @docsPage EmailSender
+ * @docsWeight 0
+ */
+export interface EmailSender extends InjectableStrategy {
+    send: (email: EmailDetails, options: EmailTransportOptions) => void | Promise<void>;
+}

+ 2 - 7
packages/email-plugin/src/nodemailer-email-sender.ts

@@ -10,13 +10,8 @@ import { Stream } from 'stream';
 import { format } from 'util';
 
 import { loggerCtx } from './constants';
-import {
-    EmailDetails,
-    EmailSender,
-    EmailTransportOptions,
-    SendmailTransportOptions,
-    SMTPTransportOptions,
-} from './types';
+import { EmailSender } from './email-sender';
+import { EmailDetails, EmailTransportOptions, SendmailTransportOptions, SMTPTransportOptions } from './types';
 
 export type StreamTransportInfo = {
     envelope: {

+ 2 - 1
packages/email-plugin/src/plugin.spec.ts

@@ -19,10 +19,11 @@ import path from 'path';
 import { Readable } from 'stream';
 
 import { orderConfirmationHandler } from './default-email-handlers';
+import { EmailSender } from './email-sender';
 import { EmailEventHandler } from './event-handler';
 import { EmailEventListener } from './event-listener';
 import { EmailPlugin } from './plugin';
-import { EmailDetails, EmailPluginOptions, EmailSender, EmailTransportOptions } from './types';
+import { EmailDetails, EmailPluginOptions, EmailTransportOptions } from './types';
 
 describe('EmailPlugin', () => {
     let eventBus: EventBus;

+ 6 - 0
packages/email-plugin/src/plugin.ts

@@ -297,12 +297,18 @@ export class EmailPlugin implements OnApplicationBootstrap, OnApplicationShutdow
         if (typeof this.options.emailGenerator?.init === 'function') {
             await this.options.emailGenerator.init(injector);
         }
+        if (typeof this.options.emailSender?.init === 'function') {
+            await this.options.emailSender.init(injector);
+        }
     }
 
     private async destroyInjectableStrategies() {
         if (typeof this.options.emailGenerator?.destroy === 'function') {
             await this.options.emailGenerator.destroy();
         }
+        if (typeof this.options.emailSender?.destroy === 'function') {
+            await this.options.emailSender.destroy();
+        }
     }
 
     private async setupEventSubscribers() {

+ 1 - 44
packages/email-plugin/src/types.ts

@@ -5,6 +5,7 @@ import { Attachment } from 'nodemailer/lib/mailer';
 import SMTPTransport from 'nodemailer/lib/smtp-transport';
 
 import { EmailGenerator } from './email-generator';
+import { EmailSender } from './email-sender';
 import { EmailEventHandler } from './event-handler';
 
 /**
@@ -208,50 +209,6 @@ export interface TestingTransportOptions {
     onSend: (details: EmailDetails) => void;
 }
 
-/**
- * @description
- * An EmailSender is responsible for sending the email, e.g. via an SMTP connection
- * or using some other mail-sending API. By default, the EmailPlugin uses the
- * {@link NodemailerEmailSender}, but it is also possible to supply a custom implementation:
- *
- * @example
- * ```TypeScript
- * const sgMail = require('\@sendgrid/mail');
- *
- * sgMail.setApiKey(process.env.SENDGRID_API_KEY);
- *
- * class SendgridEmailSender implements EmailSender {
- *   async send(email: EmailDetails) {
- *     await sgMail.send({
- *       to: email.recipient,
- *       from: email.from,
- *       subject: email.subject,
- *       html: email.body,
- *     });
- *   }
- * }
- *
- * const config: VendureConfig = {
- *   logger: new DefaultLogger({ level: LogLevel.Debug })
- *   // ...
- *   plugins: [
- *     EmailPlugin.init({
- *        // ... template, handlers config omitted
- *       transport: { type: 'none' },
- *        emailSender: new SendgridEmailSender(),
- *     }),
- *   ],
- * };
- * ```
- *
- * @docsCategory EmailPlugin
- * @docsPage EmailSender
- * @docsWeight 0
- */
-export interface EmailSender {
-    send: (email: EmailDetails, options: EmailTransportOptions) => void | Promise<void>;
-}
-
 /**
  * @description
  * A function used to load async data for use by an {@link EmailEventHandler}.