| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import { Channel, RequestContext } from '@vendure/core';
- import express from 'express';
- import fs from 'fs-extra';
- import http from 'http';
- import path from 'path';
- import { LanguageCode } from '../../common/lib/generated-types';
- import { EmailEventHandler } from './event-listener';
- import { EmailPluginDevModeOptions, EventWithContext } from './types';
- /**
- * An email inbox application that serves the contents of the dev mode `outputPath` directory.
- */
- export class DevMailbox {
- server: http.Server;
- private handleMockEventFn: (handler: EmailEventHandler<string, any>, event: EventWithContext) => void | undefined;
- serve(options: EmailPluginDevModeOptions) {
- const { outputPath, handlers, mailboxPort } = options;
- const server = express();
- server.get('/', (req, res) => {
- res.sendFile(path.join(__dirname, '../../dev-mailbox.html'));
- });
- server.get('/list', async (req, res) => {
- const list = await fs.readdir(outputPath);
- const contents = await this.getEmailList(outputPath);
- res.send(contents);
- });
- server.get('/types', async (req, res) => {
- res.send(handlers.map(h => h.type));
- });
- server.get('/generate/:type/:languageCode', async (req, res) => {
- const { type, languageCode } = req.params;
- if (this.handleMockEventFn) {
- const handler = handlers.find(h => h.type === type);
- if (!handler || !handler.mockEvent) {
- res.statusCode = 404;
- res.send({ success: false, error: `No mock event registered for type "${type}"`});
- return;
- }
- try {
- await this.handleMockEventFn(handler, { ...handler.mockEvent, ctx: this.createRequestContext(languageCode) });
- res.send({ success: true });
- } catch (e) {
- res.statusCode = 500;
- res.send({success: false, error: e.message });
- }
- return;
- } else {
- res.send({success: false, error: `Mock email generation not set up.`});
- }
- });
- server.get('/item/:id', async (req, res) => {
- const fileName = req.params.id;
- const content = await this.getEmail(outputPath, fileName);
- res.send(content);
- });
- this.server = server.listen(mailboxPort);
- }
- handleMockEvent(handler: (handler: EmailEventHandler<string, any>, event: EventWithContext) => void) {
- this.handleMockEventFn = handler;
- }
- destroy() {
- this.server.close();
- }
- private async getEmailList(outputPath: string) {
- const list = await fs.readdir(outputPath);
- const contents: any[] = [];
- for (const fileName of list) {
- const json = await fs.readFile(path.join(outputPath, fileName), 'utf-8');
- const content = JSON.parse(json);
- contents.push({
- fileName,
- date: content.date,
- subject: content.subject,
- recipient: content.recipient,
- });
- }
- contents.sort((a, b) => {
- return +new Date(b.date) - +new Date(a.date);
- });
- return contents;
- }
- private async getEmail(outputPath: string, fileName: string) {
- const safeSuffix = path.normalize(fileName).replace(/^(\.\.(\/|\\|$))+/, '');
- const safeFilePath = path.join(outputPath, safeSuffix);
- const json = await fs.readFile(safeFilePath, 'utf-8');
- const content = JSON.parse(json);
- return content;
- }
- private createRequestContext(languageCode: LanguageCode): RequestContext {
- return new RequestContext({
- languageCode,
- apiType: 'admin',
- session: {} as any,
- isAuthorized: false,
- authorizedAsOwnerOnly: true,
- channel: new Channel(),
- });
- }
- }
|