Transition to TypeScript

main
Gabe Farrell 2 years ago
parent c3788cc413
commit 92bf5eda58

1
.gitignore vendored

@ -1,3 +1,4 @@
.env
*.env
node_modules/*
yarn-error.log

@ -2,7 +2,7 @@
"name": "mailer",
"version": "1.0.0",
"description": "E-Mailer microservice for the Talgo Cloud infrastructure.",
"main": "./src/index.js",
"main": "./src/index.ts",
"repository": "github.com/talgo-cloud/Mailer",
"license": "MIT",
"private": true,
@ -11,13 +11,18 @@
"@aws-sdk/client-sesv2": "^3.465.0",
"aws-sdk": "^2.1507.0",
"express": "^4.18.2",
"fs": "^0.0.1-security",
"max-listeners-exceeded-warning": "^0.0.1",
"nodemon": "^3.0.1",
"pug": "^3.0.2",
"squirrelly": "^9.0.0"
},
"type": "module",
"scripts": {
"dev": ". ./.env && node ./src/index.js"
"dev": ". ./.env && nodemon --exec node --loader ts-node/esm ./src/index.ts"
},
"devDependencies": {
"@types/node": "^20.10.3",
"ts-node": "^10.9.1",
"typescript": "^5.3.2"
}
}

@ -1,6 +1,6 @@
import express from 'express'
import * as express from 'express'
const app = express()
import router from './routes.js'
import router from './routes'
import { EventEmitter } from 'events'
EventEmitter.defaultMaxListeners = 15;

@ -0,0 +1,84 @@
import { SendEmailCommandInput } from "@aws-sdk/client-sesv2"
import { EmailRequest } from './routes'
import * as Sqrl from 'squirrelly'
import { readFileSync } from 'fs'
// this file definies an interface for email objects
export default class Email {
to: string
from: string
subject: string
body: string
template: string
constructor(req: EmailRequest) {
if (req.to == undefined) {
throw new Error('to address must be provided')
}
this.to = req.to
switch(req.template_type) {
case 'verification_valid':
this.template = './templates/verification.html'
if (req.verification_code == undefined) {
throw new Error('verification_url must be provided')
}
this.from = '"Talgo Cloud" <accounts@talgo.cc>'
this.subject = 'Verify your email for Talgo Cloud'
break
case 'recovery_valid':
this.template = './templates/recovery.html'
if (req.recovery_url == undefined) {
throw new Error('recovery_url must be provided')
}
this.from = '"Talgo Cloud" <accounts@talgo.cc>'
this.subject = 'Recover your Talgo Cloud account'
break
default:
this.template = './templates/default.html'
if (req.title == undefined) {
throw new Error('title must be provided for non-templated emails')
}
if (req.from == undefined) {
throw new Error('from address must be provided for non-templated emails')
}
if (req.subject == undefined) {
throw new Error('subject must be provided for non-templated emails')
}
if (req.message == undefined) {
throw new Error('message must be provided for non-templated emails')
}
this.from = req.from
this.subject = req.subject
break
}
this.body = Sqrl.render(readFileSync(this.template).toString(), req)
}
build(): SendEmailCommandInput {
return { // SendEmailRequest
FromEmailAddress: this.from,
Destination: { // Destination
ToAddresses: [ // EmailAddressList
this.to,
],
},
Content: { // EmailContent
Simple: { // Message
Subject: { // Content
Data: this.subject, // required
Charset: 'utf-8',
},
Body: { // Body
Html: {
Data: this.body, // required
Charset: 'utf-8',
},
},
},
},
}
}
}

@ -1,31 +0,0 @@
// Load the AWS SDK for Node.js
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2"; // ES Modules import
const client = new SESv2Client();
export default function sendEmail(mailData) {
const input = { // SendEmailRequest
FromEmailAddress: mailData.from,
Destination: { // Destination
ToAddresses: [ // EmailAddressList
mailData.to,
],
},
Content: { // EmailContent
Simple: { // Message
Subject: { // Content
Data: mailData.subject, // required
Charset: 'utf-8',
},
Body: { // Body
Html: {
Data: mailData.body, // required
Charset: 'utf-8',
},
},
},
},
};
const command = new SendEmailCommand(input);
return client.send(command);
}

@ -0,0 +1,8 @@
// Load the AWS SDK for Node.js
import { SESv2Client, SendEmailCommand, SendEmailCommandInput } from "@aws-sdk/client-sesv2"; // ES Modules import
const client = new SESv2Client();
export default function mailer(input: SendEmailCommandInput) {
const command = new SendEmailCommand(input);
return client.send(command);
}

@ -1,70 +0,0 @@
import express from 'express'
const router = new express.Router();
import mailer from './mailer.js'
import sqrl from 'squirrelly'
import fs from 'fs'
router.post('/email', (req, res) => {
console.log(req.body)
let emailTemplate = ''
let mailData = {
body: '',
to: req.body.to,
from: '',
subject: '',
}
console.log(req.Headers)
// property validation
let errList = []
if (!req.body.to) {
errList.push({"to": "valid email address is required"})
}
// if (!req.body.from) {
// errList.push({"from": "valid email address is required"})
// }
// if (!req.body.subject) {
// errList.push({"subject": "non-empty string expected"})
// }
if (!req.body.hasOwnProperty('template_type')) {
errList.push({"template_type": "a value must be provided, even an empty string"})
}
if (errList.length > 0) {
res.status(400).json({ errors: errList }).end()
return
}
switch(req.body.template_type) {
case 'verification_valid':
mailData.subject = 'Verify your Talgo Cloud email address'
emailTemplate = './templates/verification.html'
mailData.from = '"Talgo Cloud" <accounts@talgo.cc>'
break;
case 'recovery_valid':
mailData.subject = 'Recover your Talgo Cloud account'
emailTemplate = './templates/recovery.html'
mailData.from = '"Talgo Cloud" <accounts@talgo.cc>'
break;
default:
mailData.subject = req.body.subject
emailTemplate = './templates/default.html'
mailData.from = req.body.from
break;
}
mailData.body = sqrl.render(fs.readFileSync(emailTemplate).toString(), req.body)
mailer(mailData).then((data) => {
console.log(data)
res.status(200).end()
}).catch((err) => {
console.log(err)
res.status(500).end()
})
})
// {"template_type": "verification_valid", "to":"gabe@mnrva.dev", "verification_url":"https://google.com"}
export default router

@ -0,0 +1,41 @@
import * as express from 'express'
const router = new express.Router();
import mailer from './mailer'
import Email from './mail'
export type EmailRequest = {
to: string
from?: string
subject?: string
template_type?: string
verification_code?: string
recovery_url?: string
title?: string
message?: string
}
router.post('/email', (req, res) => {
console.log(req.body)
let email: Email
try {
email = new Email(req.body)
} catch(err) {
console.log(err)
res.status(400).send(err.toString())
return
}
mailer(email.build()).then((data) => {
console.log(data)
res.status(200).end()
}).catch((err) => {
console.log(err)
res.status(500).end()
})
})
// {"template_type": "verification_valid", "to":"gabe@mnrva.dev", "verification_url":"https://google.com"}
export default router

@ -1,8 +1,8 @@
{
"compilerOptions": {
"outDir": "./built",
"allowJs": true,
"target": "es5"
"allowJs": false,
"target": "es5",
},
"include": ["./src/**/*"]
}

File diff suppressed because it is too large Load Diff

@ -514,6 +514,31 @@
"@babel/helper-validator-identifier" "^7.22.20"
to-fast-properties "^2.0.0"
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@jridgewell/resolve-uri@^3.0.3":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721"
integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
"@jridgewell/sourcemap-codec@^1.4.10":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@smithy/abort-controller@^2.0.14":
version "2.0.14"
resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-2.0.14.tgz#0608c34e35289e66ba839bbdda0c2ccd971e8d26"
@ -883,6 +908,33 @@
"@smithy/types" "^2.6.0"
tslib "^2.5.0"
"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
"@tsconfig/node12@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
"@tsconfig/node14@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
"@tsconfig/node16@^1.0.2":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@types/node@^20.10.3":
version "20.10.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.3.tgz#4900adcc7fc189d5af5bb41da8f543cea6962030"
integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg==
dependencies:
undici-types "~5.26.4"
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
@ -896,11 +948,21 @@ accepts@~1.3.8:
mime-types "~2.1.34"
negotiator "0.6.3"
acorn-walk@^8.1.1:
version "8.3.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f"
integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==
acorn@^7.1.1:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.4.1:
version "8.11.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b"
integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@ -909,6 +971,11 @@ anymatch@~3.1.2:
normalize-path "^3.0.0"
picomatch "^2.0.4"
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@ -1085,6 +1152,11 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
debug@2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -1118,6 +1190,11 @@ destroy@1.2.0:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
doctypes@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9"
@ -1229,6 +1306,11 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
fs@^0.0.1-security:
version "0.0.1-security"
resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4"
integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==
fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
@ -1451,6 +1533,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
max-listeners-exceeded-warning@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/max-listeners-exceeded-warning/-/max-listeners-exceeded-warning-0.0.1.tgz#3115afeb2204f0843f612dccd64834428561efbd"
@ -1889,6 +1976,25 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
ts-node@^10.9.1:
version "10.9.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
dependencies:
"@cspotcode/source-map-support" "^0.8.0"
"@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0"
"@tsconfig/node16" "^1.0.2"
acorn "^8.4.1"
acorn-walk "^8.1.1"
arg "^4.1.0"
create-require "^1.1.0"
diff "^4.0.1"
make-error "^1.1.1"
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
tslib@^1.11.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@ -1907,11 +2013,21 @@ type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
typescript@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43"
integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==
undefsafe@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
undici-types@~5.26.4:
version "5.26.5"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@ -1951,6 +2067,11 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@ -1999,3 +2120,8 @@ yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==

Loading…
Cancel
Save