chore: upgrade deps & drop node 10 support

This commit is contained in:
Zack Schuster 2022-04-14 10:13:58 -07:00
parent b91cf6c97f
commit f0cd1ce544
10 changed files with 524 additions and 1370 deletions

View File

@ -9,12 +9,6 @@
"plugin:@typescript-eslint/recommended" "plugin:@typescript-eslint/recommended"
], ],
"rules": { "rules": {
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description"
}
],
"@typescript-eslint/no-explicit-any": [ "@typescript-eslint/no-explicit-any": [
"error", "error",
{ {

View File

@ -7,7 +7,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
node: [^10, ^12, ^14, ^16, ^17] node: [^12, ^14, ^16, ^17]
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
steps: steps:
@ -19,12 +19,7 @@ jobs:
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
- name: install (node 10)
if: matrix.node == '^10'
run: yarn install --ignore-engines
- name: install - name: install
if: matrix.node != '^10'
run: yarn install run: yarn install
- name: lint - name: lint

View File

@ -7,7 +7,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
node: [^10, ^12, ^14, ^16, ^17] node: [^12, ^14, ^16, ^17]
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
steps: steps:
@ -19,16 +19,8 @@ jobs:
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
- name: install (node 10)
if: matrix.node == '^10'
run: yarn install --ignore-engines
- name: install - name: install
if: matrix.node != '^10'
run: yarn install run: yarn install
- name: test - name: test
run: yarn test run: yarn test
- name: test-cjs
run: yarn test-cjs

View File

@ -70,6 +70,7 @@ scripts
spec spec
test test
test-* test-*
!test-*.d.ts
tests tests
tsserverlibrary.* tsserverlibrary.*
typescriptservices.* typescriptservices.*

View File

@ -1,17 +1,14 @@
/* global process */
const useCjsConfig =
process.version.startsWith('v10') ||
process.argv.includes('--node-arguments=--title=cjs');
export default { export default {
files: ['test/*.ts'], extensions: {
extensions: useCjsConfig ? ['ts'] : { ts: 'module' }, ts: 'module',
require: useCjsConfig ? ['./email.test.ts'] : undefined, },
environmentVariables: { environmentVariables: {
NODE_TLS_REJECT_UNAUTHORIZED: '0', NODE_TLS_REJECT_UNAUTHORIZED: '0',
}, },
nonSemVerExperiments: useCjsConfig ? {} : { configurableModuleFormat: true }, files: ['test/*.ts'],
nodeArguments: useCjsConfig nodeArguments: [
? undefined '--loader=ts-node/esm',
: ['--loader=ts-node/esm', '--experimental-specifier-resolution=node'], '--experimental-specifier-resolution=node',
],
workerThreads: false, // makes tests far slower
}; };

View File

@ -1,15 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('ts-node').register({
moduleTypes: {
'test/*.ts': 'cjs',
},
compilerOptions: {
module: 'commonjs',
},
});
if (process.title === 'cjs') {
require('./rollup/email.cjs');
require.cache[require.resolve('./email.ts')] =
require.cache[require.resolve('./rollup/email.cjs')];
console.log('Testing email.cjs...\n');
}

View File

@ -17,26 +17,26 @@
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {
"@ledge/configs": "23.3.23322", "@ledge/configs": "23.3.23322",
"@rollup/plugin-typescript": "8.3.1", "@rollup/plugin-typescript": "8.3.2",
"@types/mailparser": "3.4.0", "@types/mailparser": "3.4.0",
"@types/node": "17.0.21", "@types/node": "17.0.23",
"@types/smtp-server": "3.5.7", "@types/smtp-server": "3.5.7",
"@typescript-eslint/eslint-plugin": "5.15.0", "@typescript-eslint/eslint-plugin": "5.19.0",
"@typescript-eslint/parser": "5.15.0", "@typescript-eslint/parser": "5.19.0",
"ava": "3.15.0", "ava": "4.2.0",
"eslint": "7.32.0", "eslint": "8.13.0",
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "4.0.0", "eslint-plugin-prettier": "4.0.0",
"mailparser": "3.4.0", "mailparser": "3.4.0",
"prettier": "2.6.0", "prettier": "2.6.2",
"rollup": "2.70.1", "rollup": "2.70.1",
"smtp-server": "3.10.0", "smtp-server": "3.10.0",
"ts-node": "10.7.0", "ts-node": "10.7.0",
"tslib": "2.3.1", "tslib": "2.3.1",
"typescript": "3.8.3" "typescript": "4.3.5"
}, },
"peerDependencies": { "peerDependencies": {
"typescript": ">=3.8.3" "typescript": ">=4.3.5"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"typescript": { "typescript": {
@ -44,10 +44,10 @@
} }
}, },
"resolutions": { "resolutions": {
"nodemailer": "6.7.2" "nodemailer": "6.7.3"
}, },
"engines": { "engines": {
"node": ">=10" "node": ">=12"
}, },
"files": [ "files": [
"email.ts", "email.ts",
@ -63,9 +63,7 @@
"scripts": { "scripts": {
"build": "rollup -c rollup.config.ts", "build": "rollup -c rollup.config.ts",
"lint": "eslint *.ts \"+(smtp|test)/*.ts\"", "lint": "eslint *.ts \"+(smtp|test)/*.ts\"",
"test": "ava", "test": "ava"
"pretest-cjs": "npm run build",
"test-cjs": "npm run test -- --node-arguments='--title=cjs'"
}, },
"license": "MIT" "license": "MIT"
} }

View File

@ -83,7 +83,7 @@ test('client invokes callback exactly once for invalid connection', async (t) =>
incrementCounter(); incrementCounter();
} }
}); });
// @ts-ignore the error event is only accessible from the protected socket property // @ts-expect-error the error event is only accessible from the protected socket property
invalidClient.smtp.sock.once('error', () => { invalidClient.smtp.sock.once('error', () => {
if (counter === 1) { if (counter === 1) {
resolve(); resolve();
@ -159,24 +159,27 @@ test('client accepts array sender', async (t) => {
}); });
test('client rejects message without `from` header', async (t) => { test('client rejects message without `from` header', async (t) => {
const { message: error } = await t.throwsAsync( const error = await t.throwsAsync(
send({ send({
subject: 'this is a test TEXT message from emailjs', subject: 'this is a test TEXT message from emailjs',
text: "It is hard to be brave when you're only a Very Small Animal.", text: "It is hard to be brave when you're only a Very Small Animal.",
}) })
); );
t.is(error, 'Message must have a `from` header'); t.is(error?.message, 'Message must have a `from` header');
}); });
test('client rejects message without `to`, `cc`, or `bcc` header', async (t) => { test('client rejects message without `to`, `cc`, or `bcc` header', async (t) => {
const { message: error } = await t.throwsAsync( const error = await t.throwsAsync(
send({ send({
subject: 'this is a test TEXT message from emailjs', subject: 'this is a test TEXT message from emailjs',
from: 'piglet@gmail.com', from: 'piglet@gmail.com',
text: "It is hard to be brave when you're only a Very Small Animal.", text: "It is hard to be brave when you're only a Very Small Animal.",
}) })
); );
t.is(error, 'Message must have at least one `to`, `cc`, or `bcc` header'); t.is(
error?.message,
'Message must have at least one `to`, `cc`, or `bcc` header'
);
}); });
test('client allows message with only `cc` recipient header', async (t) => { test('client allows message with only `cc` recipient header', async (t) => {
@ -311,7 +314,7 @@ test('client only responds once to greylisting', async (t) => {
}); });
const p = greylistPort++; const p = greylistPort++;
const { message: error } = await t.throwsAsync( const error = await t.throwsAsync(
new Promise<void>((resolve, reject) => { new Promise<void>((resolve, reject) => {
greylistServer.listen(p, () => { greylistServer.listen(p, () => {
new SMTPClient({ new SMTPClient({
@ -330,7 +333,7 @@ test('client only responds once to greylisting', async (t) => {
}); });
}) })
); );
t.is(error, "bad response on command 'RCPT': greylist"); t.is(error?.message, "bad response on command 'RCPT': greylist");
}); });
test('client send can have result awaited when promisified', async (t) => { test('client send can have result awaited when promisified', async (t) => {

View File

@ -1,5 +1,4 @@
import { readFileSync, createReadStream } from 'fs'; import { readFileSync, createReadStream } from 'fs';
import { join } from 'path';
import test from 'ava'; import test from 'ava';
import { simpleParser } from 'mailparser'; import { simpleParser } from 'mailparser';
@ -7,16 +6,7 @@ import type { AddressObject, ParsedMail } from 'mailparser';
import { SMTPServer } from 'smtp-server'; import { SMTPServer } from 'smtp-server';
import { SMTPClient, Message } from '../email'; import { SMTPClient, Message } from '../email';
import type { MessageAttachment } from '../email'; import type { MessageAttachment, MessageHeaders } from '../email';
import type { MessageHeaders } from '../smtp/message';
// eslint-disable-next-line no-var
var __dirname: string;
// @ts-ignore compat hack for node 10
if (__dirname == null) {
__dirname = join(process.cwd(), 'test');
}
/** /**
* \@types/mailparser@3.0.2 breaks our code * \@types/mailparser@3.0.2 breaks our code
@ -139,7 +129,10 @@ test('very large text message', async (t) => {
subject: 'this is a test TEXT message from emailjs', subject: 'this is a test TEXT message from emailjs',
from: 'ninjas@gmail.com', from: 'ninjas@gmail.com',
to: 'pirates@gmail.com', to: 'pirates@gmail.com',
text: readFileSync(join(__dirname, 'attachments/smtp.txt'), 'utf-8'), text: readFileSync(
new URL('attachments/smtp.txt', import.meta.url),
'utf-8'
),
}; };
const mail = await send(msg); const mail = await send(msg);
@ -152,7 +145,7 @@ test('very large text message', async (t) => {
test('very large text data message', async (t) => { test('very large text data message', async (t) => {
const text = const text =
'<html><body><pre>' + '<html><body><pre>' +
readFileSync(join(__dirname, 'attachments/smtp.txt'), 'utf-8') + readFileSync(new URL('attachments/smtp.txt', import.meta.url), 'utf-8') +
'</pre></body></html>'; '</pre></body></html>';
const msg = { const msg = {
@ -175,7 +168,10 @@ test('very large text data message', async (t) => {
}); });
test('html data message', async (t) => { test('html data message', async (t) => {
const html = readFileSync(join(__dirname, 'attachments/smtp.html'), 'utf-8'); const html = readFileSync(
new URL('attachments/smtp.html', import.meta.url),
'utf-8'
);
const msg = { const msg = {
subject: 'this is a test TEXT+HTML+DATA message from emailjs', subject: 'this is a test TEXT+HTML+DATA message from emailjs',
from: 'obama@gmail.com', from: 'obama@gmail.com',
@ -195,13 +191,16 @@ test('html data message', async (t) => {
}); });
test('html file message', async (t) => { test('html file message', async (t) => {
const html = readFileSync(join(__dirname, 'attachments/smtp.html'), 'utf-8'); const html = readFileSync(
new URL('attachments/smtp.html', import.meta.url),
'utf-8'
);
const msg = { const msg = {
subject: 'this is a test TEXT+HTML+FILE message from emailjs', subject: 'this is a test TEXT+HTML+FILE message from emailjs',
from: 'thomas@gmail.com', from: 'thomas@gmail.com',
to: 'nikolas@gmail.com', to: 'nikolas@gmail.com',
attachment: { attachment: {
path: join(__dirname, 'attachments/smtp.html'), path: new URL('attachments/smtp.html', import.meta.url),
alternative: true, alternative: true,
}, },
}; };
@ -215,18 +214,21 @@ test('html file message', async (t) => {
}); });
test('html with image embed message', async (t) => { test('html with image embed message', async (t) => {
const html = readFileSync(join(__dirname, 'attachments/smtp2.html'), 'utf-8'); const html = readFileSync(
const image = readFileSync(join(__dirname, 'attachments/smtp.gif')); new URL('attachments/smtp2.html', import.meta.url),
'utf-8'
);
const image = readFileSync(new URL('attachments/smtp.gif', import.meta.url));
const msg = { const msg = {
subject: 'this is a test TEXT+HTML+IMAGE message from emailjs', subject: 'this is a test TEXT+HTML+IMAGE message from emailjs',
from: 'ninja@gmail.com', from: 'ninja@gmail.com',
to: 'pirate@gmail.com', to: 'pirate@gmail.com',
attachment: { attachment: {
path: join(__dirname, 'attachments/smtp2.html'), path: new URL('attachments/smtp2.html', import.meta.url),
alternative: true, alternative: true,
related: [ related: [
{ {
path: join(__dirname, 'attachments/smtp.gif'), path: new URL('attachments/smtp.gif', import.meta.url),
type: 'image/gif', type: 'image/gif',
name: 'smtp-diagram.gif', name: 'smtp-diagram.gif',
headers: { 'Content-ID': '<smtp-diagram@local>' }, headers: { 'Content-ID': '<smtp-diagram@local>' },
@ -248,14 +250,20 @@ test('html with image embed message', async (t) => {
}); });
test('html data and attachment message', async (t) => { test('html data and attachment message', async (t) => {
const html = readFileSync(join(__dirname, 'attachments/smtp.html'), 'utf-8'); const html = readFileSync(
new URL('attachments/smtp.html', import.meta.url),
'utf-8'
);
const msg = { const msg = {
subject: 'this is a test TEXT+HTML+FILE message from emailjs', subject: 'this is a test TEXT+HTML+FILE message from emailjs',
from: 'thomas@gmail.com', from: 'thomas@gmail.com',
to: 'nikolas@gmail.com', to: 'nikolas@gmail.com',
attachment: [ attachment: [
{ path: join(__dirname, 'attachments/smtp.html'), alternative: true }, {
{ path: join(__dirname, 'attachments/smtp.gif') }, path: new URL('attachments/smtp.html', import.meta.url),
alternative: true,
},
{ path: new URL('attachments/smtp.gif', import.meta.url) },
] as MessageAttachment[], ] as MessageAttachment[],
}; };
@ -268,14 +276,14 @@ test('html data and attachment message', async (t) => {
}); });
test('attachment message', async (t) => { test('attachment message', async (t) => {
const pdf = readFileSync(join(__dirname, 'attachments/smtp.pdf')); const pdf = readFileSync(new URL('attachments/smtp.pdf', import.meta.url));
const msg = { const msg = {
subject: 'this is a test TEXT+ATTACHMENT message from emailjs', subject: 'this is a test TEXT+ATTACHMENT message from emailjs',
from: 'washing@gmail.com', from: 'washing@gmail.com',
to: 'lincoln@gmail.com', to: 'lincoln@gmail.com',
text: 'hello friend, i hope this message and pdf finds you well.', text: 'hello friend, i hope this message and pdf finds you well.',
attachment: { attachment: {
path: join(__dirname, 'attachments/smtp.pdf'), path: new URL('attachments/smtp.pdf', import.meta.url),
type: 'application/pdf', type: 'application/pdf',
name: 'smtp-info.pdf', name: 'smtp-info.pdf',
} as MessageAttachment, } as MessageAttachment,
@ -290,14 +298,14 @@ test('attachment message', async (t) => {
}); });
test('attachment sent with unicode filename message', async (t) => { test('attachment sent with unicode filename message', async (t) => {
const pdf = readFileSync(join(__dirname, 'attachments/smtp.pdf')); const pdf = readFileSync(new URL('attachments/smtp.pdf', import.meta.url));
const msg = { const msg = {
subject: 'this is a test TEXT+ATTACHMENT message from emailjs', subject: 'this is a test TEXT+ATTACHMENT message from emailjs',
from: 'washing@gmail.com', from: 'washing@gmail.com',
to: 'lincoln@gmail.com', to: 'lincoln@gmail.com',
text: 'hello friend, i hope this message and pdf finds you well.', text: 'hello friend, i hope this message and pdf finds you well.',
attachment: { attachment: {
path: join(__dirname, 'attachments/smtp.pdf'), path: new URL('attachments/smtp.pdf', import.meta.url),
type: 'application/pdf', type: 'application/pdf',
name: 'smtp-✓-info.pdf', name: 'smtp-✓-info.pdf',
} as MessageAttachment, } as MessageAttachment,
@ -313,8 +321,10 @@ test('attachment sent with unicode filename message', async (t) => {
}); });
test('attachments message', async (t) => { test('attachments message', async (t) => {
const pdf = readFileSync(join(__dirname, 'attachments/smtp.pdf')); const pdf = readFileSync(new URL('attachments/smtp.pdf', import.meta.url));
const tar = readFileSync(join(__dirname, 'attachments/postfix-2.8.7.tar.gz')); const tar = readFileSync(
new URL('attachments/postfix-2.8.7.tar.gz', import.meta.url)
);
const msg = { const msg = {
subject: 'this is a test TEXT+2+ATTACHMENTS message from emailjs', subject: 'this is a test TEXT+2+ATTACHMENTS message from emailjs',
from: 'sergey@gmail.com', from: 'sergey@gmail.com',
@ -322,12 +332,12 @@ test('attachments message', async (t) => {
text: 'hello friend, i hope this message and attachments finds you well.', text: 'hello friend, i hope this message and attachments finds you well.',
attachment: [ attachment: [
{ {
path: join(__dirname, 'attachments/smtp.pdf'), path: new URL('attachments/smtp.pdf', import.meta.url),
type: 'application/pdf', type: 'application/pdf',
name: 'smtp-info.pdf', name: 'smtp-info.pdf',
}, },
{ {
path: join(__dirname, 'attachments/postfix-2.8.7.tar.gz'), path: new URL('attachments/postfix-2.8.7.tar.gz', import.meta.url),
type: 'application/tar-gz', type: 'application/tar-gz',
name: 'postfix.source.2.8.7.tar.gz', name: 'postfix.source.2.8.7.tar.gz',
}, },
@ -344,11 +354,15 @@ test('attachments message', async (t) => {
}); });
test('streams message', async (t) => { test('streams message', async (t) => {
const pdf = readFileSync(join(__dirname, 'attachments/smtp.pdf')); const pdf = readFileSync(new URL('attachments/smtp.pdf', import.meta.url));
const tar = readFileSync(join(__dirname, 'attachments/postfix-2.8.7.tar.gz')); const tar = readFileSync(
const stream = createReadStream(join(__dirname, 'attachments/smtp.pdf')); new URL('attachments/postfix-2.8.7.tar.gz', import.meta.url)
);
const stream = createReadStream(
new URL('attachments/smtp.pdf', import.meta.url)
);
const stream2 = createReadStream( const stream2 = createReadStream(
join(__dirname, 'attachments/postfix-2.8.7.tar.gz') new URL('attachments/postfix-2.8.7.tar.gz', import.meta.url)
); );
const msg = { const msg = {

1707
yarn.lock

File diff suppressed because it is too large Load Diff