@johnmmackey/ms-utils 3.3.2 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## Version 4.0.0
2
+ BREAKING CHANGES
3
+ * @johnmmackey/amqp-utils removed as a dependency
4
+ * sendmail is removed, and replaced with the Mailer Class
5
+ ```js
6
+ let m = new Mailer(connectionManager);
7
+ await m.send(recipients, options);
8
+ ```
9
+ * winstonMSLoggerFactory now requires the third parameter of connectionManager
10
+ * mail attachements now placed in REDIS with base64 encoding
11
+ * new REDIS client and other dependency upgrades
12
+
1
13
  ## Version 3.3.1
2
14
 
3
15
  * updated etcd3 package to v1.1.0 (major rev upgrade)
package/index.js CHANGED
@@ -3,6 +3,6 @@
3
3
  const Config = require('./lib/config');
4
4
  const winstonMSLoggerFactory = require('./lib/winston-mslogger');
5
5
  const Utils = require('./lib/utils');
6
- const sendmail = require('./lib/mail');
6
+ const Mailer = require('./lib/mail');
7
7
 
8
- module.exports = { Utils, Config, winstonMSLoggerFactory, sendmail };
8
+ module.exports = { Utils, Config, winstonMSLoggerFactory, Mailer };
package/lib/mail.js CHANGED
@@ -3,79 +3,84 @@
3
3
  const fs = require('fs');
4
4
  const redis = require("redis");
5
5
  const { v4: uuid } = require('uuid');
6
-
7
- const { ConnectionManager: aC } = require('@johnmmackey/amqp-utils');
8
-
9
- const rClient = redis.createClient({ url: process.env.REDIS_URI || 'redis://localhost' });
10
-
11
6
  const { promisify } = require('util');
12
- const setAsync = promisify(rClient.set).bind(rClient);
13
- const expireAsync = promisify(rClient.expire).bind(rClient);
14
7
  const readFileAsync = promisify(fs.readFile);
15
8
 
16
- aC.addConfig(ch => {
17
- ch.assertQueue('email', { durable: true });
18
- })
19
-
20
- // recipients structure: [{"email": "johnmmackey@yahoo.ca","name": "John Mackey"}]
21
- // options:
22
- // from
23
- // subject
24
- // replyTo
25
- // textBody
26
- // htmlBody
27
- // attachments[]
28
- // includeUnsubscribeLink
29
-
30
- // returns a promise
31
-
32
- module.exports = async function (recipients, options) {
33
-
34
- if (!options.htmlBody) // Always want a html body
35
- options.htmlBody = (options.textBody || '').replace(/\r?\n/g, '<br>');
36
-
37
- var msg = {
38
- from: options.from || "",
39
- subject: options.subject || "",
40
- attachments: [],
41
- includeUnsubscribeLink: options.includeUnsubscribeLink
42
- }
43
-
44
- if (options.textBody) {
45
- msg.textBodyKey = await writeKey(options.textBody, 'txt');
9
+ module.exports = class Mailer {
10
+ constructor(connectionManager) {
11
+ // param is amqp connection manager - see @johnmmackey/amqp-utils
12
+ this.aC = connectionManager;
13
+ this.rClient = redis.createClient({ url: process.env.REDIS_URI || 'redis://localhost' });
14
+ // while this is async, it has a retry, so should be OK
15
+ this.rClient.connect();
16
+ this.aC.addConfig(ch => {
17
+ ch.assertQueue('email', { durable: true });
18
+ })
46
19
  }
47
20
 
48
- msg.htmlBodyKey = await writeKey(options.htmlBody, 'html');
49
-
50
- for (let a of (options.attachments || [])) {
51
- var da = {
52
- filename: a.originalname,
53
- contentType: a.mimetype
21
+ // recipients structure: [{"email": "johnmmackey@yahoo.ca","name": "John Mackey"}]
22
+ // options:
23
+ // from
24
+ // subject
25
+ // replyTo
26
+ // textBody
27
+ // htmlBody
28
+ // attachments[]
29
+ // includeUnsubscribeLink
30
+
31
+ // returns a promise
32
+
33
+ async send(recipients, options) {
34
+
35
+
36
+ if (!options.htmlBody) // Always want a html body
37
+ options.htmlBody = (options.textBody || '').replace(/\r?\n/g, '<br>');
38
+
39
+ var msg = {
40
+ from: options.from || "",
41
+ subject: options.subject || "",
42
+ attachments: [],
43
+ includeUnsubscribeLink: options.includeUnsubscribeLink,
44
+ ...(options.mailingLists ? {mailingLists: options.mailingLists} : {})
45
+ }
46
+
47
+ if (options.textBody) {
48
+ msg.textBodyKey = await this.writeKey(options.textBody, 'txt');
49
+ }
50
+
51
+ msg.htmlBodyKey = await this.writeKey(options.htmlBody, 'html');
52
+
53
+ for (let a of (options.attachments || [])) {
54
+ var da = {
55
+ filename: a.originalname,
56
+ contentType: a.mimetype
57
+ };
58
+ a.contentDisposition && (da.contentDisposition = a.contentDisposition);
59
+ a.cid && (da.cid = a.cid);
60
+
61
+ da.key = await this.writeKey(
62
+ Buffer.from(a.path ? await readFileAsync(a.path) : a.content).toString('base64'),
63
+ 'attachment'
64
+ );
65
+ msg.attachments.push(da);
54
66
  };
55
- a.contentDisposition && (da.contentDisposition = a.contentDisposition);
56
- a.cid && (da.cid = a.cid);
57
67
 
58
- da.key = await writeKey(
59
- a.path ? await readFileAsync(a.path) : a.content,
60
- 'attachment'
61
- );
62
- msg.attachments.push(da);
63
- };
68
+ if (options.replyTo)
69
+ msg.replyTo = options.replyTo;
64
70
 
65
- if (options.replyTo)
66
- msg.replyTo = options.replyTo;
71
+ msg.recipientsKey = await this.writeKey(JSON.stringify(recipients), 'recipients');
67
72
 
68
- msg.recipientsKey = await writeKey(JSON.stringify(recipients), 'recipients');
73
+ // Send it to queue here
74
+ if (!this.aC.ch)
75
+ throw new Error('No current AMQP channel available');
69
76
 
70
- // Send it to queue here
71
- if (!aC.ch)
72
- throw new Error('No current AMQP channel available');
73
- aC.ch.sendToQueue('email', new Buffer(JSON.stringify(msg)));
74
- }
77
+ this.aC.ch.sendToQueue('email', Buffer.from(JSON.stringify(msg)));
78
+ }
75
79
 
76
- function writeKey(v, type) {
77
- let k = 'mail:' + uuid() + ':' + type;
78
- return setAsync(k, v)
79
- .then(() => expireAsync(k, 60*60*24))
80
- .then(() => k); // resolve to key name
80
+ async writeKey(v, type) {
81
+ let k = 'mail:' + uuid() + ':' + type;
82
+ await this.rClient.set(k, v);
83
+ await this.rClient.expire(k, 60 * 60 * 24);
84
+ return k;
85
+ }
81
86
  }
@@ -1,18 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  const util = require('util');
4
- const {ConnectionManagerClass} = require('@johnmmackey/amqp-utils');
5
4
 
6
- module.exports = function(winston, serviceName, existingConnectionManager) {
5
+ module.exports = function(winston, serviceName, cm) {
7
6
 
8
- var cm;
9
-
10
- if(existingConnectionManager) {
11
- cm = existingConnectionManager;
12
- } else {
13
- cm = new ConnectionManagerClass();
14
- cm.connect();
15
- }
16
7
  cm.addConfig(ch => {
17
8
  ch.assertQueue('logger', { durable: true });
18
9
  });
@@ -41,7 +32,7 @@ module.exports = function(winston, serviceName, existingConnectionManager) {
41
32
 
42
33
  MSLogger.prototype.log = function (level, msg, meta, callback) {
43
34
  cm.sendToQueue( 'logger',
44
- new Buffer(msg + (isEmpty(meta) ? '' : ' ' + JSON.stringify(meta))),
35
+ new Buffer.from(msg + (isEmpty(meta) ? '' : ' ' + JSON.stringify(meta))),
45
36
  {headers: {level: level || 'debug', createdBy: serviceName || '', created: Date.now()}}
46
37
  )
47
38
  callback(null, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johnmmackey/ms-utils",
3
- "version": "3.3.2",
3
+ "version": "4.0.1",
4
4
  "description": "Utility functions for Microservice Architecture",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -14,9 +14,8 @@
14
14
  "license": "ISC",
15
15
  "homepage": "https://bitbucket.org/52westlabs/ms-utils#readme",
16
16
  "dependencies": {
17
- "@johnmmackey/amqp-utils": "^1.3.1",
18
- "etcd3": "^1.1.0",
19
- "redis": "^3.0.2",
20
- "uuid": "^8.3.2"
17
+ "etcd3": "^1.1.2",
18
+ "redis": "^4.6.12",
19
+ "uuid": "^9.0.1"
21
20
  }
22
21
  }