mail esm 2/2
This commit is contained in:
parent
1f4df47e07
commit
b73843bdc5
3
packages/mail/dist-in/_cli.d.ts
vendored
Normal file
3
packages/mail/dist-in/_cli.d.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
import { IOptions } from './types.js';
|
||||
export declare const defaults: () => void;
|
||||
export declare const sanitize: (argv: any) => IOptions | boolean;
|
||||
67
packages/mail/dist-in/_cli.js
Normal file
67
packages/mail/dist-in/_cli.js
Normal file
@ -0,0 +1,67 @@
|
||||
import { forward_slash, pathInfo, substitute, globBase } from "@polymech/commons";
|
||||
import { isFile, resolve } from "@polymech/commons";
|
||||
import { sync as exists } from "@polymech/fs/exists";
|
||||
export const defaults = () => {
|
||||
const DefaultCommand = 'info';
|
||||
if (process.argv.length === 2) {
|
||||
process.argv.push(DefaultCommand);
|
||||
}
|
||||
process.on('unhandledRejection', (reason) => {
|
||||
console.error('Unhandled rejection, reason: ', reason);
|
||||
});
|
||||
};
|
||||
export const sanitize = (argv) => {
|
||||
const options = {
|
||||
src: argv.src,
|
||||
dry: argv.dry,
|
||||
alt: argv.alt,
|
||||
logLevel: argv.logLevel,
|
||||
transport: argv.transport,
|
||||
...argv
|
||||
};
|
||||
let srcInfo;
|
||||
let variables = {
|
||||
...options.variables
|
||||
};
|
||||
if (options.src) {
|
||||
const srcIn = resolve(options.src, options.alt, variables);
|
||||
options.src = forward_slash(substitute(options.alt, srcIn, variables));
|
||||
// in case a file with a glob pattern is provided, strip the glob
|
||||
// this is a special case, enabling shared scripts in Alt-Tap Salamand
|
||||
const glob_base = globBase(options.src);
|
||||
const file = options.src.replace(glob_base.glob, '').replace(/\/$/, '');
|
||||
if (exists(file) && isFile(file)) {
|
||||
options.src = file;
|
||||
}
|
||||
srcInfo = pathInfo(resolve(options.src, options.alt, variables));
|
||||
if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
|
||||
options.srcInfo = srcInfo;
|
||||
for (const key in srcInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
|
||||
variables['SRC_' + key] = srcInfo[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
options.src = resolve(options.src, options.alt, variables);
|
||||
}
|
||||
}
|
||||
const out = resolve(options.dst || "", options.alt, variables);
|
||||
options.dstInfo = pathInfo(out);
|
||||
if (options.dst) {
|
||||
if (options.srcInfo && options.dstInfo) {
|
||||
options.dstInfo.PATH = options.dst;
|
||||
for (const key in options.dstInfo) {
|
||||
if (Object.prototype.hasOwnProperty.call(options.dstInfo, key)) {
|
||||
variables['DST_' + key] = options.dstInfo[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
options.dst = resolve(options.dst || '', options.alt, variables);
|
||||
}
|
||||
}
|
||||
options.variables = variables;
|
||||
return options;
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NsaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9fY2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUNqRixPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ25ELE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFcEQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLEdBQUcsRUFBRTtJQUN6QixNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUM7SUFDOUIsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM1QixPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBQ0QsT0FBTyxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLE1BQWMsRUFBRSxFQUFFO1FBQ2hELE9BQU8sQ0FBQyxLQUFLLENBQUMsK0JBQStCLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDMUQsQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFTLEVBQXNCLEVBQUU7SUFFdEQsTUFBTSxPQUFPLEdBQWE7UUFDdEIsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2IsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2IsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO1FBQ2IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ3ZCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztRQUN6QixHQUFHLElBQUk7S0FDRSxDQUFBO0lBRWIsSUFBSSxPQUFPLENBQUE7SUFFWCxJQUFJLFNBQVMsR0FB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
|
||||
74
packages/mail/src/__tests__/mail.test.ts
Normal file
74
packages/mail/src/__tests__/mail.test.ts
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
import { describe, it, expect, beforeAll, vi } from 'vitest'
|
||||
import nodemailer from 'nodemailer'
|
||||
import { test as sendTestEmail } from '../lib/nodemailer/index.js'
|
||||
import { IOptions, ITransportOptions } from '../types.js'
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('@polymech/commons', async () => {
|
||||
return {
|
||||
CONFIG_DEFAULT: vi.fn(),
|
||||
forward_slash: (s: string) => s,
|
||||
pathInfo: () => ({}),
|
||||
substitute: (_: any, s: string) => s,
|
||||
resolve: (_: any, s: string) => s,
|
||||
globBase: () => ({ glob: '', base: '' }),
|
||||
isFile: () => true,
|
||||
exists: () => true
|
||||
}
|
||||
})
|
||||
|
||||
// We need to import the mocked module to control the mock
|
||||
import { CONFIG_DEFAULT } from '@polymech/commons'
|
||||
|
||||
describe('Mail E2E Tests', () => {
|
||||
let testAccount: nodemailer.TestAccount
|
||||
|
||||
beforeAll(async () => {
|
||||
// Create a real SMTP account on Ethereal for testing
|
||||
testAccount = await nodemailer.createTestAccount()
|
||||
})
|
||||
|
||||
it('should send a test email using ethereal account', async () => {
|
||||
const transportConfig: ITransportOptions = {
|
||||
host: testAccount.smtp.host,
|
||||
port: testAccount.smtp.port,
|
||||
secure: testAccount.smtp.secure,
|
||||
auth: {
|
||||
user: testAccount.user,
|
||||
pass: testAccount.pass
|
||||
}
|
||||
}
|
||||
|
||||
// Setup the mock to return our test transport configuration
|
||||
vi.mocked(CONFIG_DEFAULT).mockReturnValue({
|
||||
email: {
|
||||
'ethereal': transportConfig
|
||||
}
|
||||
})
|
||||
|
||||
const options: IOptions = {
|
||||
transport: 'ethereal',
|
||||
from: 'sender@example.com',
|
||||
to: 'recipient@example.com',
|
||||
subject: 'Vitest E2E Test',
|
||||
html: '<p>Hello from Vitest!</p>',
|
||||
logLevel: 'error' // suppress logs during test
|
||||
}
|
||||
|
||||
const info = await sendTestEmail(options)
|
||||
|
||||
if (!info) {
|
||||
throw new Error('Email sending failed, info is undefined')
|
||||
}
|
||||
|
||||
expect(info).toBeDefined()
|
||||
expect(info.messageId).toBeDefined()
|
||||
expect(info.accepted).toContain('recipient@example.com')
|
||||
|
||||
// Ethereal allows us to preview the email
|
||||
const previewUrl = nodemailer.getTestMessageUrl(info)
|
||||
console.log('Preview URL: %s', previewUrl)
|
||||
expect(previewUrl).toBeTruthy()
|
||||
})
|
||||
})
|
||||
8
packages/mail/vitest.config.ts
Normal file
8
packages/mail/vitest.config.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
environment: 'node',
|
||||
},
|
||||
})
|
||||
Loading…
Reference in New Issue
Block a user