@techie04/xpresser-mailer
Advanced tools
Comparing version 0.1.1 to 0.1.2
@@ -1,5 +0,1 @@ | ||
/// <reference types="node" /> | ||
import { Address, AttachmentLike, Attachment } from "nodemailer/lib/mailer"; | ||
import { Readable } from "stream"; | ||
export declare const sendMail: ($to: string | Address | Array<string | Address>, $subject: string, $message: string | Buffer | Readable | AttachmentLike, $messageType?: string, $attachments?: Attachment[] | undefined) => Promise<void>; | ||
export declare type AttachmentType = Attachment; | ||
export declare function sendMail<Mail = any, MailResponse = any>(mail: Mail, provider?: string): Promise<MailResponse>; |
68
index.js
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.sendMail = void 0; | ||
const nodemailer_1 = __importDefault(require("nodemailer")); | ||
const xpresser_1 = require("xpresser"); | ||
@@ -12,47 +8,23 @@ const $ = (0, xpresser_1.getInstance)(); | ||
const config = $.config.path("mailer"); | ||
const provider = config.get("provider"); | ||
let transporter; | ||
if (provider === "AWS") { | ||
// Only require of provider is AWS | ||
const aws = require("@aws-sdk/client-ses"); | ||
process.env.AWS_ACCESS_KEY_ID = config.get("AWS_ACCESS_KEY_ID"); | ||
process.env.AWS_SECRET_ACCESS_KEY = config.get("AWS_SECRET_ACCESS_KEY"); | ||
// Set the AWS Region. | ||
const REGION = config.get("region"); //e.g. "us-east-1" | ||
// const sesClient = new SESClient({ region: REGION }); | ||
const ses = new aws.SES({ | ||
apiVersion: "2010-12-01", | ||
region: REGION | ||
}); | ||
transporter = nodemailer_1.default.createTransport({ | ||
SES: { ses, aws }, | ||
sendingRate: config.get("sendingRate") || 1 | ||
}); | ||
// Default Provider | ||
const defaultProvider = config.get("provider"); | ||
// Get Resolved Providers | ||
const resolvedProviders = $.engineData.sync("mailer.resolvedProviders"); | ||
async function sendMail(mail, provider) { | ||
if (!provider) | ||
provider = defaultProvider; | ||
/** | ||
* Validate default provider config | ||
*/ | ||
const Provider = resolvedProviders.sync[provider]; | ||
// throw Error if provider does not exists. | ||
if (!Provider) | ||
throw new Error(`Provider: {${provider}} used in (sendMail) does not exists.`); | ||
// Initialize if not initialized | ||
if (!Provider.initialized) { | ||
await Provider.initialize(); | ||
} | ||
// Return mailer | ||
return Provider.sendMail(mail); | ||
} | ||
else if (provider === "Postmark") { | ||
const postmark = require("postmark"); | ||
transporter = new postmark.Client(config.get("apiToken")); | ||
} | ||
else { | ||
transporter = nodemailer_1.default.createTransport({ | ||
host: config.get("host"), | ||
port: config.get("port"), | ||
...(config.get("port") === 465 ? { secure: true } : { secure: false }), | ||
auth: { | ||
user: config.get("username"), | ||
pass: config.get("password") | ||
} | ||
}); | ||
} | ||
const sendMail = async ($to, $subject, $message, $messageType = "html", $attachments) => { | ||
const from = config.get("from") || $.config.get("name"); | ||
const mail = { | ||
from: `${from} <${config.get("fromEmail")}>`, | ||
to: $to, | ||
subject: $subject, | ||
...($messageType === "html" ? { html: $message } : { text: $message }), | ||
...($attachments && { attachments: $attachments }) | ||
}; | ||
await transporter.sendMail(mail); | ||
}; | ||
exports.sendMail = sendMail; |
{ | ||
"name": "@techie04/xpresser-mailer", | ||
"version": "0.1.1", | ||
"description": "mailer helper for xpresser", | ||
"version": "0.1.2", | ||
"description": "Mailer Plugin for xpresser", | ||
"main": "index.js", | ||
@@ -23,6 +23,16 @@ "types": "index.d.ts", | ||
"@types/nodemailer": "^6.4.4", | ||
"@xpresser/env": "^1.1.0", | ||
"postmark": "^2.7.8", | ||
"prettier": "^2.4.1", | ||
"typescript": "^4.4.4", | ||
"xpresser": "^0.23.2" | ||
} | ||
"xpresser": "^0.24.0" | ||
}, | ||
"keywords": [ | ||
"xpresser", | ||
"techie", | ||
"mailer", | ||
"nodemailer", | ||
"postmark", | ||
"client-ses" | ||
] | ||
} |
@@ -1,2 +0,13 @@ | ||
import { DollarSign } from "xpresser/types"; | ||
export declare function run(plugin: any, $: DollarSign): void; | ||
import type { DollarSign, PluginData } from "xpresser/types"; | ||
/** | ||
* Define Plugin Dependencies. | ||
* @param plugin | ||
* @param $ | ||
*/ | ||
export declare function dependsOn(plugin: PluginData, $: DollarSign): string[]; | ||
/** | ||
* Plugin run function. | ||
* @param plugin | ||
* @param $ | ||
*/ | ||
export declare function run(plugin: PluginData, $: DollarSign): Promise<void>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.run = void 0; | ||
const local_pkg_1 = require("local-pkg"); | ||
function run(plugin, $) { | ||
exports.run = exports.dependsOn = void 0; | ||
/** | ||
* Define Plugin Dependencies. | ||
* @param plugin | ||
* @param $ | ||
*/ | ||
function dependsOn(plugin, $) { | ||
const provider = $.config.get(`${plugin.namespace}.provider`); | ||
switch (provider) { | ||
case "aws": | ||
return ["@aws-sdk/client-ses"]; | ||
case "postmark": | ||
return ["postmark"]; | ||
default: | ||
return []; | ||
} | ||
} | ||
exports.dependsOn = dependsOn; | ||
/** | ||
* Plugin run function. | ||
* @param plugin | ||
* @param $ | ||
*/ | ||
async function run(plugin, $) { | ||
// Do nothing if native command e.g 'make:controller' | ||
if ($.isNativeCliCommand()) | ||
return; | ||
// Get package name. | ||
const packageName = plugin.namespace; | ||
$.ifNotConsole(() => { | ||
// Check package config | ||
if (!$.config.has(packageName)) { | ||
return $.logErrorAndExit(`Config ${packageName}" is required!`); | ||
/** | ||
* Create a memory space in xpresser's EngineData. | ||
* For storing plugin's re-usable related data | ||
*/ | ||
const pluginMemory = $.engineData.path(packageName).defaults({ | ||
// Holds resolved provider class instances. | ||
resolvedProviders: {}, | ||
// Holds initialized providers data. | ||
initializedProviders: {} | ||
}); | ||
// Get resolvedProviders as a Collection | ||
const resolvedProviders = pluginMemory.path("resolvedProviders"); | ||
// Check plugin config exists | ||
if (!$.config.has(packageName)) { | ||
return $.logErrorAndExit(`Config ${packageName}" is required!`); | ||
} | ||
// Get plugin config | ||
const config = $.config.path(packageName); | ||
/** | ||
* Out of the box providers. | ||
*/ | ||
const Providers = { | ||
smtp: plugin.path + "/providers/SmtpProvider", | ||
aws: plugin.path + "/providers/AwsSesProvider", | ||
postmark: plugin.path + "/providers/PostmarkProvider" | ||
}; | ||
/** | ||
* if config has customProviders object with values. | ||
* merge them to the list of providers above. | ||
*/ | ||
const CustomProviders = config.path("customProviders").removeNullOrUndefined(); | ||
if (CustomProviders.length()) { | ||
Object.assign(Providers, CustomProviders.data); | ||
} | ||
/** | ||
* Load Provider files | ||
*/ | ||
for (const [provider, providerPath] of Object.entries(Providers)) { | ||
try { | ||
let p = require($.path.resolve(providerPath)); | ||
// for esm export default support. | ||
if (p.default) | ||
p = p.default; | ||
// Store resolved provider. | ||
resolvedProviders.set(provider, p); | ||
} | ||
// Validate package config. | ||
const config = $.config.path(packageName); | ||
// Get provider | ||
const provider = config.get("provider"); | ||
if (!provider) { | ||
return $.logErrorAndExit(`"provider" is required in config: "${packageName}"`); | ||
catch (e) { | ||
$.logError(`Error loading ${packageName} Provider: ${providerPath}`); | ||
$.logErrorAndExit(e); | ||
} | ||
// validate provider. | ||
if (!provider.match(/^(AWS|SMTP)$/)) { | ||
return $.logErrorAndExit(`"${config.get("provider")}" is not a valid provider {SMTP | AWS}`); | ||
} | ||
if (provider === "AWS") { | ||
if (!(0, local_pkg_1.isPackageExists)("@aws-sdk/client-ses")) { | ||
$.logWarning(`Package {@aws-sdk/client-ses} is required for AWS`); | ||
return $.logErrorAndExit("Install missing package and restart server!"); | ||
} | ||
let requiredFields = [ | ||
"region", | ||
"fromEmail", | ||
"AWS_SECRET_ACCESS_KEY", | ||
"AWS_ACCESS_KEY_ID" | ||
]; | ||
requiredFields.forEach((value) => { | ||
if (!config.get(value)) { | ||
return $.logErrorAndExit(`mailer {${value}} is missing!`); | ||
} | ||
}); | ||
} | ||
else { | ||
let requiredFields = ["host", "port", "username", "password", "fromEmail"]; | ||
requiredFields.forEach((value) => { | ||
if (!config.get(value)) { | ||
return $.logErrorAndExit(`mailer {${value}} is missing!`); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
// Get provider | ||
const provider = config.get("provider"); | ||
if (!provider) { | ||
return $.logErrorAndExit(`"provider" is required in config: "${packageName}"`); | ||
} | ||
// Check if provider exists in resolved providers | ||
if (!resolvedProviders.has(provider)) { | ||
return $.logErrorAndExit([ | ||
`"${provider}" is not a registered provider.`, | ||
`Registered Providers: [${resolvedProviders.keys().join(", ")}]` | ||
].join("\n")); | ||
} | ||
/** | ||
* Validate default provider config | ||
*/ | ||
const defProvider = resolvedProviders.get(provider); | ||
try { | ||
await defProvider.initialize(); | ||
} | ||
catch (e) { | ||
return $.logErrorAndExit(e.message); | ||
} | ||
} | ||
exports.run = run; |
137
readme.md
# XpresserJs Mailer Plugin | ||
[![Build Status](https://circleci.com/gh/wildbit/postmark.js.svg?style=shield)](https://circleci.com/gh/wildbit/postmark.js) | ||
@@ -8,5 +9,7 @@ [![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://www.opensource.org/licenses/MIT) | ||
This plugin makes use of [nodemailer](https://www.npmjs.com/package/nodemailer) and [aws-sdk ses](https://www.npmjs.com/package/@aws-sdk/client-ses). | ||
This plugin makes use of [nodemailer](https://www.npmjs.com/package/nodemailer) | ||
and [aws-sdk ses](https://www.npmjs.com/package/@aws-sdk/client-ses). | ||
**MENU** | ||
- [Installation](#installation) | ||
@@ -27,3 +30,2 @@ - [Add to plugins.json](#add-to-pluginsjson) | ||
### Add to plugins.json | ||
@@ -41,26 +43,31 @@ | ||
({ | ||
// SMTP CONFIG | ||
// SMTP CONFIG | ||
"mailer": { | ||
provider: "SMTP", // SMTP | ||
host: "", // SMTP Server Host | ||
port: "", // SMTP Server Port | ||
username: "", // SMTP Server Username | ||
password: "", // SMTP Server Password | ||
fromEmail: "no-reply@example.com" // From email | ||
configs: { | ||
smtp: { | ||
host: "", // SMTP Server Host | ||
port: "", // SMTP Server Port | ||
username: "", // SMTP Server Username | ||
password: "", // SMTP Server Password | ||
fromEmail: "no-reply@example.com" // From email | ||
}, | ||
aws: { | ||
region: "", // AWS Server Region | ||
fromEmail: "no-reply@example.com", // From email | ||
// AWS credentials | ||
AWS_ACCESS_KEY_ID: "", | ||
AWS_SECRET_ACCESS_KEY: "" | ||
}, | ||
postmark: { | ||
apiToken: "" | ||
} | ||
} | ||
}, | ||
// AWS CONFIG | ||
"mailer": { | ||
provider: "AWS", // AWS | ||
region: "", // AWS Server Region | ||
fromEmail: "no-reply@example.com", // From email | ||
// AWS credentials | ||
AWS_ACCESS_KEY_ID: "", | ||
AWS_SECRET_ACCESS_KEY: "" | ||
}, | ||
}) | ||
``` | ||
### Usage | ||
@@ -70,49 +77,67 @@ | ||
###### Javascript | ||
```javascript | ||
const { sendMail } = require("@techie04/xpresser-mailer"); | ||
(async () => { | ||
// array of attachments | ||
const attachments = [ | ||
{ | ||
// filename (optional) | ||
filename: "techieoriname.png", | ||
// file path or url | ||
path: path.join(__dirname, "..", "TechieOriname.png") | ||
} | ||
] | ||
await sendMail( | ||
"example@example.com", // to email | ||
"testing subject", // message subject | ||
"my message here", // message body | ||
"text", // message format ("html" or "text") | ||
attachments // optional field | ||
); | ||
}); | ||
await sendMail(message); | ||
``` | ||
###### Typescript | ||
```typescript | ||
import { sendMail } from "@techie04/xpresser-mailer"; | ||
await sendMail<Message, MessageResponse>(message); | ||
``` | ||
### Typescript support | ||
- **Message:** Type of message content (depending on provider) | ||
- **MessageResponse:** Type of response returned to the `sendMail` function (depending on provider) | ||
### Creating a custom provider | ||
Create a file, maybe `providers/CustomProvider.ts` | ||
```typescript | ||
import { AttachmentType, sendMail } from "@techie04/xpresser-mailer"; | ||
import { MailProvider } from "@techie04/xpresser-mailer/MailProvider"; | ||
// array of attachments | ||
const attachments: AttachmentType[] = [ | ||
{ | ||
// filename (optional) | ||
filename: "techieoriname.png", | ||
// file path or url | ||
path: path.join(__dirname, "..", "TechieOriname.png") | ||
// The name should be the same with the config key. | ||
const CustomProvider = new MailProvider("customProvider", { | ||
/** | ||
* Initialize your provider. | ||
* @param config - The config for your provider. i.e mailer.configs.customProvider | ||
* @param $ - xpresser instance | ||
*/ | ||
initialize(config, $) { | ||
// Validate config here | ||
// return client. | ||
}, | ||
/** | ||
* Send mail function. | ||
* @param mail - the mail object or data | ||
* @param config - The config for your provider. i.e mailer.configs.customProvider | ||
* @param client - The client returned from the initialize function above. | ||
* @param $ | ||
*/ | ||
sendMail({ mail, config, client }, $) { | ||
// Send mail here. | ||
} | ||
]; | ||
}); | ||
await sendMail( | ||
"example@example.com", | ||
"testing subject", | ||
"my message here", | ||
"text", | ||
attachments // optional field | ||
); | ||
export default PostmarkProvider; | ||
``` | ||
###### Add to config | ||
```javascript | ||
const config = { | ||
"mailer": { | ||
// ... other configs | ||
customProviders: { | ||
// key is providers name | ||
// value is path to provider file without .js or .ts | ||
customProvider: "providers/CustomProvider" | ||
} | ||
} | ||
} | ||
``` |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
27606
17
442
139
7
4
2