email-bounce-parser 1.0.19 → 1.0.20

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.
Files changed (2) hide show
  1. package/lib/parser.js +53 -70
  2. package/package.json +2 -2
package/lib/parser.js CHANGED
@@ -125,32 +125,34 @@ var REGEXES = {
125
125
  blocked : /((?:is listed)|blocked|banned|denied|dnsbl)/i,
126
126
  spam : /(spam)/i,
127
127
 
128
- enhanced_types_no_such_recipient : [
129
- /(recipient address rejected: access denied)/i, // Outlook DBEB for invalid addresses
130
- /(no such (?:account|user|mailbox|recipient))/i,
131
- /((?:terminated|disabled|inactive|not found|unavailable|invalid) (?:account|user|mailbox|recipient))/i,
132
- /(do(e)?sn\'t exist)/i, // Some Chinese SMTP return "dosn't" instead of "doesn't"
133
- /(user (?:.+?) does not exist)/i,
134
- /((?:account|user|mailbox|recipient) (?:.+@.+ )?(?:is )?(?:terminated|disabled|inactive|not found|unavailable|invalid))/i
135
- ],
136
-
137
- enhanced_types_server_unknown : [
138
- /(does not accept mail)/i,
139
- /(domain (?:name\s+)?(?:\S+\s)?(?:not found|does not exist))/i, // "domain does not exist" or "domain name does not exist" or "domain acme.com does not exist" or "domain name acme.com does not exist"
140
- /(no route to host)/i
141
- ],
142
-
143
- enhanced_types_server_timeout : [
144
- /(timeout|timed[\s\-]out)/i
145
- ],
146
-
147
- enhanced_types_mailbox_full : [
148
- /(out of storage|(?:mailbox (?:is )?full)|(?:user (?:is )?over quota))/i // "user is over quota" (iCloud)
149
- ],
150
-
151
- enhanced_types_reputation : [
152
- /(rate limited due to IP reputation)/i
153
- ],
128
+ enhanced_types : {
129
+ no_such_recipient : [
130
+ /(recipient address rejected: access denied)/i, // Outlook DBEB for invalid addresses
131
+ /(no such (?:account|user|mailbox|recipient))/i,
132
+ /((?:terminated|disabled|inactive|not found|unavailable|invalid) (?:account|user|mailbox|recipient))/i,
133
+ /(do(e)?sn\'t exist)/i, // Some Chinese SMTP return "dosn't" instead of "doesn't"
134
+ /(user (?:.+?) does not exist)/i,
135
+ /((?:account|user|mailbox|recipient) (?:.+@.+ )?(?:is )?(?:terminated|disabled|inactive|not found|unavailable|invalid|rejected))/i
136
+ ],
137
+
138
+ server_unknown : [
139
+ /(does not accept mail)/i,
140
+ /(domain (?:name\s+)?(?:\S+\s)?(?:not found|does not exist))/i, // "domain does not exist" or "domain name does not exist" or "domain acme.com does not exist" or "domain name acme.com does not exist"
141
+ /(no route to host)/i
142
+ ],
143
+
144
+ server_timeout : [
145
+ /(timeout|timed[\s\-]out)/i
146
+ ],
147
+
148
+ mailbox_full : [
149
+ /(out of storage|(?:mailbox (?:is )?full)|(?:user (?:is )?over quota))/i // "user is over quota" (iCloud)
150
+ ],
151
+
152
+ reputation : [
153
+ /(rate limited due to IP reputation)/i
154
+ ]
155
+ },
154
156
 
155
157
  error_code : [
156
158
  /(\d{3})[\s\-](\d\.\d\.\d{1,3})/, // "550 5.4.1" or "550-5.4.1" or "550-5.4.11" or "550-5.4.110"
@@ -169,9 +171,7 @@ class Parser {
169
171
  * Constructor
170
172
  */
171
173
  constructor() {
172
- this.__regexes = {};
173
-
174
- this.__initRegexes();
174
+ this.__regexes = this.__initRegexes(REGEXES);
175
175
  }
176
176
 
177
177
 
@@ -248,30 +248,31 @@ class Parser {
248
248
  /**
249
249
  * Initializes regexes
250
250
  * @private
251
- * @return {undefined}
251
+ * @param {object} obj
252
+ * @return {object} Regexes
252
253
  */
253
- __initRegexes() {
254
- for (var _key in REGEXES) {
255
- var _key_line = `${_key}_line`;
256
- var _entry = REGEXES[_key];
254
+ __initRegexes(obj) {
255
+ var _regexes = {};
256
+
257
+ for (var _key in obj) {
258
+ var _entry = obj[_key];
257
259
 
258
260
  if (Array.isArray(_entry)) {
259
- this.__regexes[_key] = [];
260
- this.__regexes[_key_line] = [];
261
+ _regexes[_key] = [];
261
262
 
262
263
  for (var _i = 0; _i < _entry.length; _i++) {
263
- var _regex = _entry[_i];
264
-
265
- this.__regexes[_key].push(
266
- new RE2(_regex)
264
+ _regexes[_key].push(
265
+ new RE2(_entry[_i])
267
266
  );
268
267
  }
268
+ } else if (typeof _entry === "object" && Object.keys(_entry).length > 0) {
269
+ _regexes[_key] = this.__initRegexes(_entry);
269
270
  } else {
270
- var _regex = _entry;
271
-
272
- this.__regexes[_key] = new RE2(_regex);
271
+ _regexes[_key] = new RE2(_entry);
273
272
  }
274
273
  }
274
+
275
+ return _regexes;
275
276
  }
276
277
 
277
278
 
@@ -391,40 +392,22 @@ class Parser {
391
392
  _spam = false;
392
393
 
393
394
  // Detect enhanced-type from bounce content
394
- var _match = loopRegexes(this.__regexes.enhanced_types_no_such_recipient, str);
395
+ for (var _key in this.__regexes.enhanced_types) {
396
+ var _match = loopRegexes(
397
+ this.__regexes.enhanced_types[_key],
395
398
 
396
- if (_match && _match.length > 1) {
397
- _type = "no_such_recipient";
398
- }
399
+ str
400
+ );
399
401
 
400
- _match = loopRegexes(this.__regexes.enhanced_types_server_unknown, str);
401
-
402
- if (!_type && _match && _match.length > 1) {
403
- _type = "server_unknown";
404
- }
405
-
406
- _match = loopRegexes(this.__regexes.enhanced_types_server_timeout, str);
407
-
408
- if (!_type && _match && _match.length > 1) {
409
- _type = "server_timeout";
410
- }
411
-
412
- _match = loopRegexes(this.__regexes.enhanced_types_mailbox_full, str);
413
-
414
- if (!_type && _match && _match.length > 1) {
415
- _type = "mailbox_full";
416
- }
417
-
418
- _match = loopRegexes(this.__regexes.enhanced_types_reputation, str);
419
-
420
- if (!_type && _match && _match.length > 1) {
421
- _type = "reputation";
402
+ if (!_type && _match && _match.length > 1) {
403
+ _type = _key;
404
+ }
422
405
  }
423
406
 
424
407
  // Detect enhanced-type from enhanced error code
425
408
  // Notice: this is done as a last resort, as sometimes enhanced code \
426
409
  // doesn't clearly convey the actual error
427
- if (!_type && _match && code.enhanced) {
410
+ if (!_type && code.enhanced) {
428
411
  _type = ERROR_CODES_TYPES[`${code.basic} ${code.enhanced}`] || null;
429
412
  }
430
413
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "email-bounce-parser",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "Parses bounce emails and extract errors",
5
5
  "author": "Eliott Vincent <eliott@crisp.chat>",
6
6
  "main": "lib/index.js",
@@ -23,7 +23,7 @@
23
23
  "nodeunit-x": "0.15.0"
24
24
  },
25
25
  "dependencies": {
26
- "re2": "1.20.1"
26
+ "re2": "1.20.7"
27
27
  },
28
28
  "keywords": [
29
29
  "parser",