From f0198b62f39a6ce74fc8c8f57236d2b8e8416278 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Thu, 18 Apr 2024 11:59:03 -0400 Subject: [PATCH] feat: implement stdout email adapter, use if no adapter configured --- .../src/email/getStringifiedToAddress.ts | 23 +++++++++++++++++++ packages/payload/src/email/sendEmail.ts | 21 +++-------------- packages/payload/src/email/stdoutAdapter.ts | 23 +++++++++++++++++++ packages/payload/src/index.ts | 9 +++++++- 4 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 packages/payload/src/email/getStringifiedToAddress.ts create mode 100644 packages/payload/src/email/stdoutAdapter.ts diff --git a/packages/payload/src/email/getStringifiedToAddress.ts b/packages/payload/src/email/getStringifiedToAddress.ts new file mode 100644 index 000000000..878c5267d --- /dev/null +++ b/packages/payload/src/email/getStringifiedToAddress.ts @@ -0,0 +1,23 @@ +import type { SendMailOptions } from 'nodemailer' + +export const getStringifiedToAddress = (message: SendMailOptions): string | undefined => { + let stringifiedTo: string | undefined + + if (typeof message.to === 'string') { + stringifiedTo = message.to + } else if (Array.isArray(message.to)) { + stringifiedTo = message.to + .map((to) => { + if (typeof to === 'string') { + return to + } else if (to.address) { + return to.address + } + return '' + }) + .join(', ') + } else if (message.to.address) { + stringifiedTo = message.to.address + } + return stringifiedTo +} diff --git a/packages/payload/src/email/sendEmail.ts b/packages/payload/src/email/sendEmail.ts index a5022ea6e..15a48b7f1 100644 --- a/packages/payload/src/email/sendEmail.ts +++ b/packages/payload/src/email/sendEmail.ts @@ -2,30 +2,15 @@ import type { SendMailOptions } from 'nodemailer' import type { Payload } from '../types/index.js' +import { getStringifiedToAddress } from './getStringifiedToAddress.js' + export async function sendEmail(this: Payload, message: SendMailOptions): Promise { let result try { result = await this.email.sendEmail(message) } catch (err: unknown) { - let stringifiedTo: string | undefined - - if (typeof message.to === 'string') { - stringifiedTo = message.to - } else if (Array.isArray(message.to)) { - stringifiedTo = message.to - .map((to) => { - if (typeof to === 'string') { - return to - } else if (to.address) { - return to.address - } - return '' - }) - .join(', ') - } else if (message.to.address) { - stringifiedTo = message.to.address - } + const stringifiedTo = getStringifiedToAddress(message) this.logger.error({ err, diff --git a/packages/payload/src/email/stdoutAdapter.ts b/packages/payload/src/email/stdoutAdapter.ts new file mode 100644 index 000000000..4e218bf25 --- /dev/null +++ b/packages/payload/src/email/stdoutAdapter.ts @@ -0,0 +1,23 @@ +import type { SendMailOptions } from 'nodemailer' + +import type { Payload } from '../index.js' +import type { EmailAdapter } from './types.js' + +import { emailDefaults } from './defaults.js' +import { getStringifiedToAddress } from './getStringifiedToAddress.js' + +export type StdoutAdapter = EmailAdapter + +export const createStdoutAdapter = (payload: Payload) => { + const stdoutAdapter: StdoutAdapter = { + defaultFromAddress: emailDefaults.defaultFromAddress, + defaultFromName: emailDefaults.defaultFromName, + sendEmail: async (message) => { + const stringifiedTo = getStringifiedToAddress(message) + const res = `EMAIL NON-DELIVERY. To: '${stringifiedTo}', Subject: '${message.subject}'` + payload.logger.info({ msg: res }) + return Promise.resolve() + }, + } + return stdoutAdapter +} diff --git a/packages/payload/src/index.ts b/packages/payload/src/index.ts index e77dc65cb..f9720edab 100644 --- a/packages/payload/src/index.ts +++ b/packages/payload/src/index.ts @@ -49,6 +49,7 @@ import { APIKeyAuthentication } from './auth/strategies/apiKey.js' import { JWTAuthentication } from './auth/strategies/jwt.js' import localOperations from './collections/operations/local/index.js' import { validateSchema } from './config/validate.js' +import { createStdoutAdapter } from './email/stdoutAdapter.js' import { fieldAffectsData } from './exports/types.js' import localGlobalOperations from './globals/operations/local/index.js' import flattenFields from './utilities/flattenTopLevelFields.js' @@ -366,8 +367,14 @@ export class BasePayload { // Load email adapter if (this.config.email instanceof Promise) { this.email = await this.config.email - } else { + } else if (this.config.email) { this.email = this.config.email + } else { + this.logger.warn( + `No email adapter provided. Email will be written to stdout. More info at https://payloadcms.com/docs/email/overview.`, + ) + + this.email = createStdoutAdapter(this) } this.sendEmail = this.email.sendEmail