node-red-node-email
Advanced tools
Comparing version
# Changelog | ||
## Version 0.11.0 | ||
* (`selderee`) Escape sequences in selectors. | ||
## Version 0.10.0 | ||
@@ -4,0 +8,0 @@ |
{ | ||
"name": "@selderee/plugin-htmlparser2", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "selderee plugin - selectors decision tree builder for htmlparser2 DOM.", | ||
@@ -42,3 +42,3 @@ "keywords": [ | ||
"domhandler": "^5.0.3", | ||
"selderee": "^0.10.0" | ||
"selderee": "^0.11.0" | ||
}, | ||
@@ -45,0 +45,0 @@ "devDependencies": { |
# Changelog | ||
## Version 9.0.5 | ||
* `htmlparser2` updated from 8.0.1 to 8.0.2 ([release notes](https://github.com/fb55/htmlparser2/releases)) - this fixes broken parsing in certain situations: [#285](https://github.com/html-to-text/node-html-to-text/issues/285); | ||
* `deepmerge` updated from 4.3.0 to 4.3.1 - no functional changes; | ||
* added a link to attribute selectors syntax to Readme. | ||
All commits: [9.0.4...9.0.5](https://github.com/html-to-text/node-html-to-text/compare/9.0.4...9.0.5) | ||
## Version 9.0.4 | ||
@@ -4,0 +12,0 @@ |
{ | ||
"name": "html-to-text", | ||
"version": "9.0.4", | ||
"version": "9.0.5", | ||
"description": "Advanced html to plain text converter", | ||
@@ -51,7 +51,7 @@ "keywords": [ | ||
"dependencies": { | ||
"@selderee/plugin-htmlparser2": "^0.10.0", | ||
"deepmerge": "^4.3.0", | ||
"@selderee/plugin-htmlparser2": "^0.11.0", | ||
"deepmerge": "^4.3.1", | ||
"dom-serializer": "^2.0.0", | ||
"htmlparser2": "^8.0.1", | ||
"selderee": "^0.10.0" | ||
"htmlparser2": "^8.0.2", | ||
"selderee": "^0.11.0" | ||
}, | ||
@@ -58,0 +58,0 @@ "mocha": { |
@@ -171,3 +171,3 @@ # html-to-text | ||
* `[baz]` - attribute presence; | ||
* `[baz=buzz]` - attribute value (with any operators and also quotes and case sensitivity modifiers); | ||
* `[baz=buzz]` - attribute value (with any operators and also quotes and case sensitivity modifiers - [syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#syntax)); | ||
* `+` and `>` combinators (other combinators are not supported). | ||
@@ -174,0 +174,0 @@ |
@@ -90,3 +90,3 @@ 'use strict'; | ||
['subject', 'references', 'date', 'to', 'from', 'to', 'cc', 'bcc', 'message-id', 'in-reply-to', 'reply-to'].forEach(key => { | ||
if (mail.headers.has(key)) { | ||
if (mail.headers && mail.headers.has(key)) { | ||
mail[key.replace(/-([a-z])/g, (m, c) => c.toUpperCase())] = mail.headers.get(key); | ||
@@ -93,0 +93,0 @@ } |
# CHANGELOG | ||
## 6.9.3 2023-05-29 | ||
- Specified license identifier (was defined as MIT, actual value MIT-0) | ||
- If SMTP server disconnects with a message, process it and include as part of the response error | ||
## 6.9.2 2023-05-11 | ||
- Fix uncaught exception on invalid attachment content payload | ||
## 6.9.1 2023-01-27 | ||
@@ -4,0 +13,0 @@ |
@@ -953,3 +953,11 @@ /* eslint no-undefined: 0, prefer-spread: 0, no-control-regex: 0 */ | ||
contentStream = new PassThrough(); | ||
setImmediate(() => contentStream.end(content._resolvedValue)); | ||
setImmediate(() => { | ||
try { | ||
contentStream.end(content._resolvedValue); | ||
} catch (err) { | ||
contentStream.emit('error', err); | ||
} | ||
}); | ||
return contentStream; | ||
@@ -978,3 +986,10 @@ } else if (typeof content.pipe === 'function') { | ||
contentStream = new PassThrough(); | ||
setImmediate(() => contentStream.end(content || '')); | ||
setImmediate(() => { | ||
try { | ||
contentStream.end(content || ''); | ||
} catch (err) { | ||
contentStream.emit('error', err); | ||
} | ||
}); | ||
return contentStream; | ||
@@ -981,0 +996,0 @@ } |
@@ -820,2 +820,16 @@ 'use strict'; | ||
_onClose() { | ||
let serverResponse = false; | ||
if (this._remainder && this._remainder.trim()) { | ||
if (this.options.debug || this.options.transactionLog) { | ||
this.logger.debug( | ||
{ | ||
tnx: 'server' | ||
}, | ||
this._remainder.replace(/\r?\n$/, '') | ||
); | ||
} | ||
this.lastServerResponse = serverResponse = this._remainder.trim(); | ||
} | ||
this.logger.info( | ||
@@ -829,5 +843,7 @@ { | ||
if (this.upgrading && !this._destroyed) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ETLS', false, 'CONN'); | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ETLS', serverResponse, 'CONN'); | ||
} else if (![this._actionGreeting, this.close].includes(this._responseActions[0]) && !this._destroyed) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', false, 'CONN'); | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', serverResponse, 'CONN'); | ||
} else if (/^[45]\d{2}\b/.test(serverResponse)) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', serverResponse, 'CONN'); | ||
} | ||
@@ -949,3 +965,3 @@ | ||
// skip unexpected empty lines | ||
setImmediate(() => this._processResponse(true)); | ||
setImmediate(() => this._processResponse()); | ||
} | ||
@@ -957,3 +973,3 @@ | ||
action.call(this, str); | ||
setImmediate(() => this._processResponse(true)); | ||
setImmediate(() => this._processResponse()); | ||
} else { | ||
@@ -960,0 +976,0 @@ return this._onError(new Error('Unexpected Response'), 'EPROTOCOL', str, 'CONN'); |
@@ -45,2 +45,10 @@ { | ||
"Forward Email": { | ||
"aliases": ["FE", "ForwardEmail"], | ||
"domains": ["forwardemail.net"], | ||
"host": "smtp.forwardemail.net", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"GandiMail": { | ||
@@ -47,0 +55,0 @@ "aliases": ["Gandi", "Gandi Mail"], |
{ | ||
"name": "nodemailer", | ||
"version": "6.9.1", | ||
"version": "6.9.3", | ||
"description": "Easy as cake e-mail sending from your Node.js applications", | ||
@@ -17,3 +17,3 @@ "main": "lib/nodemailer.js", | ||
"author": "Andris Reinman", | ||
"license": "MIT", | ||
"license": "MIT-0", | ||
"bugs": { | ||
@@ -24,14 +24,14 @@ "url": "https://github.com/nodemailer/nodemailer/issues" | ||
"devDependencies": { | ||
"@aws-sdk/client-ses": "3.259.0", | ||
"aws-sdk": "2.1303.0", | ||
"@aws-sdk/client-ses": "3.341.0", | ||
"aws-sdk": "2.1386.0", | ||
"bunyan": "1.8.15", | ||
"chai": "4.3.7", | ||
"eslint-config-nodemailer": "1.2.0", | ||
"eslint-config-prettier": "8.6.0", | ||
"grunt": "1.5.3", | ||
"eslint-config-prettier": "8.8.0", | ||
"grunt": "1.6.1", | ||
"grunt-cli": "1.4.3", | ||
"grunt-eslint": "24.0.1", | ||
"grunt-eslint": "24.1.0", | ||
"grunt-mocha-test": "0.13.3", | ||
"libbase64": "1.2.1", | ||
"libmime": "5.2.0", | ||
"libmime": "5.2.1", | ||
"libqp": "2.0.1", | ||
@@ -42,4 +42,4 @@ "mocha": "10.2.0", | ||
"proxy-test-server": "1.0.0", | ||
"sinon": "15.0.1", | ||
"smtp-server": "3.11.0" | ||
"sinon": "15.1.0", | ||
"smtp-server": "3.12.0" | ||
}, | ||
@@ -46,0 +46,0 @@ "engines": { |
@@ -93,3 +93,3 @@ # Nodemailer | ||
Nodemailer is licensed under the **MIT license** | ||
Nodemailer is licensed under the **MIT No Attribution license** | ||
@@ -96,0 +96,0 @@ --- |
{ | ||
"name": "mailparser", | ||
"version": "3.6.4", | ||
"version": "3.6.5", | ||
"description": "Parse e-mails", | ||
@@ -21,3 +21,3 @@ "main": "index.js", | ||
"he": "1.2.0", | ||
"html-to-text": "9.0.4", | ||
"html-to-text": "9.0.5", | ||
"iconv-lite": "0.6.3", | ||
@@ -27,14 +27,14 @@ "libmime": "5.2.1", | ||
"mailsplit": "5.4.0", | ||
"nodemailer": "6.9.1", | ||
"tlds": "1.236.0" | ||
"nodemailer": "6.9.3", | ||
"tlds": "1.240.0" | ||
}, | ||
"devDependencies": { | ||
"ajv": "8.12.0", | ||
"eslint": "8.35.0", | ||
"eslint": "8.44.0", | ||
"eslint-config-nodemailer": "1.2.0", | ||
"eslint-config-prettier": "8.6.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"grunt": "1.6.1", | ||
"grunt-cli": "1.4.3", | ||
"grunt-contrib-nodeunit": "4.0.0", | ||
"grunt-eslint": "24.0.1", | ||
"grunt-contrib-nodeunit": "5.0.0", | ||
"grunt-eslint": "24.2.0", | ||
"iconv": "3.0.1", | ||
@@ -41,0 +41,0 @@ "random-message": "1.1.0" |
{ | ||
"presets": [ | ||
["@babel/preset-env"] | ||
["@babel/preset-env", { | ||
"targets": { | ||
"node": "14" | ||
} | ||
}] | ||
], | ||
"plugins": [ | ||
["add-module-exports"], | ||
["transform-async-to-promises"], | ||
["module-extension", { | ||
"mjs": "js" | ||
"js": "cjs" | ||
}] | ||
] | ||
} |
{ | ||
"extends": "eslint:recommended", | ||
"extends": "ash-nazg/sauron-overrides", | ||
"parserOptions": { | ||
"sourceType": "module", | ||
"ecmaVersion": 2020 | ||
"ecmaVersion": 2022 | ||
}, | ||
"settings": { | ||
"polyfills": [ | ||
"Promise", | ||
"URL" | ||
] | ||
}, | ||
"env": { | ||
@@ -13,2 +19,20 @@ "es6": true, | ||
{ | ||
"files": "*.md/*.js", | ||
"globals": { | ||
"require": true, | ||
"pop3": true, | ||
"Pop3Command": true | ||
}, | ||
"rules": { | ||
"import/unambiguous": "off", | ||
"import/no-unresolved": "off", | ||
"import/no-commonjs": "off", | ||
"no-console": "off", | ||
"no-shadow": ["error", { | ||
"allow": ["Pop3Command"] | ||
}], | ||
"no-unused-vars": ["error", {"varsIgnorePattern": "Pop3Command|str"}] | ||
} | ||
}, | ||
{ | ||
"files": ["test/**"], | ||
@@ -24,11 +48,3 @@ "env": { | ||
"rules": { | ||
"strict": ["error"], | ||
"indent": ["error", 2, {"outerIIFEBody": 0}], | ||
"semi": ["error"], | ||
"prefer-const": ["error"], | ||
"no-var": ["error"], | ||
"prefer-destructuring": ["error"], | ||
"object-shorthand": ["error"], | ||
"quotes": ["error", "single", {"avoidEscape": true}] | ||
} | ||
} |
#!/usr/bin/env node | ||
import {readFile} from 'fs/promises'; | ||
import {join} from 'path'; | ||
/*! Auto-generated file; please modify /bin/index.js instead */ | ||
"use strict"; | ||
import Pop3Command from '../src/Command.js'; | ||
import {stream2String} from '../src/helper.js'; | ||
var _path = require("path"); | ||
const {argv} = process, | ||
/** | ||
* @type {{ | ||
* help: [boolean], | ||
* [key: string]: any[] | ||
* }} | ||
*/ | ||
options = {}, | ||
alias = { | ||
c: 'config', | ||
u: 'user', | ||
p: 'password', | ||
h: 'host', | ||
m: 'method', | ||
}, | ||
requiredOptionNames = ['user', 'password', 'host', 'method'], | ||
/** | ||
* @typedef {number} Integer | ||
*/ | ||
var _Command = _interopRequireDefault(require("../lib/Command")); | ||
/** | ||
* @type {{ | ||
* user: string, | ||
* password: string, | ||
* host: string, | ||
* port?: Integer, | ||
* tls?: boolean, | ||
* timeout?: Integer, | ||
* tlsOptions?: import('tls').TlsOptions, | ||
* servername?: string | ||
* }} | ||
*/ | ||
mailStructure = {}, | ||
mailStructureOptionNames = ['user', 'password', 'host', 'port', 'tls', 'timeout']; | ||
var _helper = require("../lib/helper"); | ||
mailStructure.port = 110; | ||
mailStructure.tls = false; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _await(value, then, direct) { | ||
if (direct) { | ||
return then ? then(value) : value; | ||
} | ||
if (!value || !value.then) { | ||
value = Promise.resolve(value); | ||
} | ||
return then ? value.then(then) : value; | ||
} | ||
function _empty() {} | ||
function _invokeIgnored(body) { | ||
var result = body(); | ||
if (result && result.then) { | ||
return result.then(_empty); | ||
} | ||
} | ||
function _awaitIgnored(value, direct) { | ||
if (!direct) { | ||
return value && value.then ? value.then(_empty) : Promise.resolve(); | ||
} | ||
} | ||
function _invoke(body, then) { | ||
var result = body(); | ||
if (result && result.then) { | ||
return result.then(then); | ||
} | ||
return then(result); | ||
} | ||
function _catch(body, recover) { | ||
try { | ||
var result = body(); | ||
} catch (e) { | ||
return recover(e); | ||
} | ||
if (result && result.then) { | ||
return result.then(void 0, recover); | ||
} | ||
return result; | ||
} | ||
function _continue(value, then) { | ||
return value && value.then ? value.then(then) : then(value); | ||
} | ||
function _async(f) { | ||
return function () { | ||
for (var args = [], i = 0; i < arguments.length; i++) { | ||
args[i] = arguments[i]; | ||
} | ||
try { | ||
return Promise.resolve(f.apply(this, args)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
}; | ||
} | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } | ||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } | ||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } | ||
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } | ||
var _process = process, | ||
argv = _process.argv, | ||
options = {}, | ||
alias = { | ||
c: 'config', | ||
u: 'user', | ||
p: 'password', | ||
h: 'host', | ||
m: 'method' | ||
}, | ||
requiredOptionNames = ['user', 'password', 'host', 'method'], | ||
mailStructure = { | ||
port: 110, | ||
tls: false | ||
}, | ||
mailStructureOptionNames = ['user', 'password', 'host', 'port', 'tls', 'timeout']; | ||
function printHelpAndExit() { | ||
var text = 'Usage: pop [options]\r\n' + '\r\n' + 'Example: pop -u example@gmail.com -p pwd -h example.pop3.com -m UIDL\r\n' + '\r\n' + 'Options:\r\n' + ' -c, --config config file (in place of options below)\r\n' + ' -u, --user username\r\n' + ' -p, --password password\r\n' + ' -h, --host host of server\r\n' + ' --port port of server. Defaults to 110 or 995 if tls is used.\r\n' + ' --tls whether to use TLS(SSL). Defaults to false.\r\n' + ' --no-tls disables previously set TLS(SSL).\r\n' + ' -m, --method method and arguments of API in node-pop3. e.g. \'UIDL\', \'RETR 100\' or \'command USER example@gmail.com\'\r\n' + ' --help print help'; | ||
const text = 'Usage: pop [options]\r\n' | ||
+ '\r\n' | ||
+ 'Example: pop -u example@gmail.com -p pwd -h example.pop3.com -m UIDL\r\n' | ||
+ '\r\n' | ||
+ 'Options:\r\n' | ||
+ ' -c, --config config file (in place of options below)\r\n' | ||
+ ' -u, --user username\r\n' | ||
+ ' -p, --password password\r\n' | ||
+ ' -h, --host host of server\r\n' | ||
+ ' --port port of server. Defaults to 110 or 995 if tls is used.\r\n' | ||
+ ' --tls whether to use TLS(SSL). Defaults to false.\r\n' | ||
+ ' --no-tls disables previously set TLS(SSL).\r\n' | ||
+ ' -m, --method method and arguments of API in node-pop3. e.g. \'UIDL\', \'RETR 100\' or \'command USER example@gmail.com\'\r\n' | ||
+ ' --help print help'; | ||
console.log(text); | ||
@@ -127,18 +65,18 @@ process.exit(0); | ||
var optionName; | ||
if (argv.slice(2).some(function (arg, i, args) { | ||
/** @type {string} */ | ||
let optionName; | ||
if (argv.slice(2).some(function(arg, i, args) { | ||
if (arg.charAt(0) === '-') { | ||
optionName = arg.replace(/^-+/g, ''); | ||
if ((optionName || '').length === 1) { | ||
if (!{}.hasOwnProperty.call(alias, optionName)) { | ||
if (!Object.hasOwn(alias, optionName)) { | ||
console.error('Invalid alias', optionName); | ||
return true; | ||
} | ||
optionName = alias[optionName]; | ||
optionName = alias[/** @type {"c"|"u"|"p"|"h"|"m"} */ (optionName)]; | ||
} | ||
if (optionName && (i === args.length - 1 || args[i + 1].charAt(0) === '-')) { | ||
if ( | ||
optionName && | ||
(i === args.length - 1 || args[i + 1].charAt(0) === '-') | ||
) { | ||
options[optionName] = [true]; | ||
@@ -163,5 +101,10 @@ } | ||
if (options.config) { | ||
var configOptions = require((0, _path.resolve)(process.cwd(), options.config[0])); | ||
const configOptions = JSON.parse( | ||
// @ts-expect-error It's ok | ||
await readFile( | ||
new URL(join('../', options.config[0]), import.meta.url) | ||
) | ||
); | ||
['method'].concat(mailStructureOptionNames).forEach(function (optionName) { | ||
['method', ...mailStructureOptionNames].forEach((optionName) => { | ||
if (!(optionName in options) && optionName in configOptions) { | ||
@@ -173,5 +116,3 @@ options[optionName] = [configOptions[optionName]]; | ||
for (var _i = 0, _requiredOptionNames = requiredOptionNames; _i < _requiredOptionNames.length; _i++) { | ||
var requiredOptionName = _requiredOptionNames[_i]; | ||
for (const requiredOptionName of requiredOptionNames) { | ||
if (!options[requiredOptionName]) { | ||
@@ -191,61 +132,63 @@ console.error(requiredOptionName + ' is required!'); | ||
// By using `mailStructure`, can still be overridden below | ||
mailStructure.port = '995'; | ||
mailStructure.port = 995; | ||
} | ||
for (var _i2 = 0, _mailStructureOptionN = mailStructureOptionNames; _i2 < _mailStructureOptionN.length; _i2++) { | ||
var _optionName = _mailStructureOptionN[_i2]; | ||
mailStructure[_optionName] = (options[_optionName] || [])[0] || mailStructure[_optionName]; | ||
for (const _optionName of mailStructureOptionNames) { | ||
// @ts-expect-error Unclear what is wrong here? | ||
mailStructure[ | ||
/** @type {"user"|"password"|"host"|"port"|"tls"|"timeout"} */ ( | ||
_optionName | ||
) | ||
] = ( | ||
options[_optionName] || [] | ||
)[0] || mailStructure[ | ||
/** @type {"user"|"password"|"host"|"port"|"tls"|"timeout"} */ | ||
(_optionName) | ||
]; | ||
} | ||
var pop3Command = new _Command["default"](mailStructure); | ||
const pop3Command = new Pop3Command( | ||
/** | ||
* @type {{ | ||
* user: string, | ||
* password: string, | ||
* host: string, | ||
* port?: Integer, | ||
* tls?: boolean, | ||
* timeout?: Integer, | ||
* tlsOptions?: import('tls').TlsOptions, | ||
* servername?: string | ||
* }} | ||
*/ | ||
(mailStructure) | ||
); | ||
const [methodName] = options.method; | ||
var _options$method = _slicedToArray(options.method, 1), | ||
methodName = _options$method[0]; // Todo: Might want to report this to Istnabul as nyc doesn't seem to pick | ||
// this up, despite it running | ||
// istanbul ignore next | ||
let result; | ||
try { | ||
if (['UIDL', 'TOP', 'QUIT', 'RETR'].includes(methodName)) { | ||
result = await pop3Command[ | ||
/** @type {"UIDL"|"TOP"|"QUIT"|"RETR"} */ | ||
(methodName) | ||
]( | ||
// @ts-expect-error It's ok | ||
...options.method.slice(1) | ||
); | ||
} else { | ||
await pop3Command._connect(); | ||
result = await pop3Command.command(...options.method); | ||
if (result[1]) { | ||
const [info, stream] = result; | ||
const str = await stream2String(stream); | ||
result = [info, str]; | ||
} | ||
} | ||
if (methodName !== 'QUIT') { | ||
await pop3Command.QUIT(); | ||
} | ||
} catch (err) { | ||
console.error(err); | ||
process.exit(); | ||
} | ||
_async(function () { | ||
var result; | ||
return _continue(_catch(function () { | ||
return _invoke(function () { | ||
if (['UIDL', 'TOP', 'QUIT', 'RETR'].includes(methodName)) { | ||
return _await(pop3Command[methodName].apply(pop3Command, _toConsumableArray(options.method.slice(1))), function (_pop3Command$methodNa) { | ||
result = _pop3Command$methodNa; | ||
}); | ||
} else { | ||
return _await(pop3Command._connect(), function () { | ||
return _await(pop3Command.command.apply(pop3Command, _toConsumableArray(options.method)), function (_pop3Command$command) { | ||
result = _pop3Command$command; | ||
return _invokeIgnored(function () { | ||
if (result[1]) { | ||
var _result = result, | ||
_result2 = _slicedToArray(_result, 2), | ||
info = _result2[0], | ||
stream = _result2[1]; | ||
return _await((0, _helper.stream2String)(stream), function (str) { | ||
result = [info, str]; | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
}, function () { | ||
return _invokeIgnored(function () { | ||
if (methodName !== 'QUIT') { | ||
return _awaitIgnored(pop3Command.QUIT()); | ||
} | ||
}); | ||
}); | ||
}, function (err) { | ||
console.error(err); | ||
process.exit(); | ||
}), function () { | ||
console.dir(result); | ||
process.exit(0); | ||
}); | ||
})(); | ||
//# sourceMappingURL=pop.js.map | ||
console.dir(result); | ||
process.exit(0); |
# CHANGES to node-pop3 | ||
## 0.9.0 (2023-05-24) | ||
- feat: TypeScript types | ||
- feat: added LAST command (@metafloor) | ||
- fix: LIST and UIDL with msg-nbr (@metafloor) | ||
## 0.8.0 (2022-01-16) | ||
@@ -4,0 +10,0 @@ |
{ | ||
"name": "node-pop3", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "POP3 client for node", | ||
"main": "./lib/Command.js", | ||
"type": "commonjs", | ||
"main": "./lib/Command.cjs", | ||
"type": "module", | ||
"types": "./dist/src/Command.d.ts", | ||
"exports": { | ||
"import": "./src/Command.mjs", | ||
"require": "./lib/Command.js" | ||
"types": "./dist/src/Command.d.ts", | ||
"import": "./src/Command.js", | ||
"require": "./lib/Command.cjs" | ||
}, | ||
@@ -14,3 +16,3 @@ "bin": { | ||
}, | ||
"nyc": { | ||
"c8": { | ||
"reporter": [ | ||
@@ -41,30 +43,31 @@ "text", | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": ">=14.13.0" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.16.8", | ||
"@babel/core": "^7.16.7", | ||
"@babel/preset-env": "^7.16.8", | ||
"@comandeer/babel-plugin-banner": "^5.0.0", | ||
"@expo/spawn-async": "^1.5.0", | ||
"@babel/cli": "^7.21.5", | ||
"@babel/core": "^7.21.8", | ||
"@babel/preset-env": "^7.21.5", | ||
"@expo/spawn-async": "^1.7.2", | ||
"@types/chai": "^4.3.5", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "^20.2.3", | ||
"babel-plugin-add-module-exports": "^1.0.4", | ||
"babel-plugin-module-extension": "^0.1.3", | ||
"babel-plugin-transform-async-to-promises": "^0.8.18", | ||
"chai": "^4.3.4", | ||
"eslint": "^8.6.0", | ||
"mocha": "^9.1.4", | ||
"nyc": "^15.1.0" | ||
"c8": "^7.13.0", | ||
"chai": "^4.3.7", | ||
"emailjs": "^4.0.2", | ||
"eslint": "^8.41.0", | ||
"eslint-config-ash-nazg": "^34.13.0", | ||
"mocha": "^10.2.0" | ||
}, | ||
"scripts": { | ||
"tsc": "tsc", | ||
"build": "tsc -p tsconfig-prod.json", | ||
"cli": "node ./bin/pop.js", | ||
"lint": "npm run eslint", | ||
"eslint": "eslint --ext=mjs,js .", | ||
"babel-src": "babel src -d lib --source-maps --out-file-extension .js", | ||
"babel-bin": "rm bin/pop.js && babel bin/index.mjs -o bin/pop.js --source-maps --out-file-extension .js && chmod 0755 bin/pop.js", | ||
"babel": "npm run babel-src && npm run babel-bin", | ||
"mocha": "mocha --require chai/register-expect --exit", | ||
"test": "rm -Rf .nyc_output && rm -Rf ./node_modules/.cache && npm run babel && nyc npm run mocha" | ||
}, | ||
"readme": "# node-pop3\n\npop3 command for node. Supports **Promise** and **stream**.\n\n## CLI\n\ne.g. Test the API about `TOP`\n\n`pop -u example@gmail.com -p pwd -h example.pop.com -m TOP 100 10`\n\nor pass in some or all of the config in a designated config file (JSON or JS):\n\n`pop -c pop.config.js -m TOP 100 10`\n\nFor more detail, please input\n\n`pop --help`\n\n## Usage\n\nIn CommonJS, you can get the `Pop3Command` as follows:\n\n```js\nconst Pop3Command = require('node-pop3');\n```\n\nThe examples below, however, use the [ESM Modules](https://nodejs.org/api/esm.html)\nformat instead (i.e., `import`).\n\n## Example\n\n- Fetch mail by msgNum:\n\n```js\nimport Pop3Command from 'node-pop3';\n\nconst pop3 = new Pop3Command({\n user: 'example@example.com',\n password: 'example',\n host: 'pop3.example.com',\n});\n\nconst msgNum = 1;\n\n(async () => {\n\n await string = pop3.RETR(msgNum);\n // deal with mail string\n await pop3.QUIT();\n\n})();\n```\n\n- List msgNum to uid in Server\n\n```js\nconst list = await pop3.UIDL();\nconsole.dir(list);\n/**\n * [\n * ['1', 'ZC0113-H8wi_YChVab4F0QTbwP4B6i'],\n * ['2', 'ZC0114-3A9gAn8M2Sp1RhVCGTIII6i'],\n * ...\n * ]\n*/\n```\n\n## API\n\n* constructor(options)\n\nparams|optional|comment\n---|---|---\noptions.user|no|String\noptions.password|no|String\noptions.host|no|String\noptions.port|yes|Number. Defaults to `110`\noptions.servername|yes|String. Defaults to `host` value. Same as `servername` for Node TLS option.\noptions.tls|yes|Boolean. Defaults to `false`\noptions.timeout|yes|Number. Defaults to `undefined`\noptions.tlsOptions|yes|Defaults to `{}`\n\n`tlsOptions` takes the options documented for your Node version and\n`tls.connect` function.\n\n* basic\n\nmethod|params|return\n---|---|---\nconnect||`{Promise}` resolve to `undefined`\ncommand|`{String*}` command messages to Server|`{Promise}` resolve to `{Array[String, Stream]}`, which are messages of response and stream of response (if the response has multiple lines) from Server\n\n```js\nconst pop3 = new Pop3Command({ host: 'pop3.example.com' });\n\n(async () => {\n\n await pop3.connect();\n await pop3.command('USER', 'example@example.com');\n await pop3.command('PASS', 'example');\n\n const [info] = await pop3.command('STAT');\n console.log(info); // 100 102400\n\n const [info, stream] = await pop3.command('RETR', 1);\n console.log(info); // 1024 octets\n\n const [info] = await pop3.command('QUIT');\n console.log(info); // Bye\n\n})();\n\n```\n\n* common\n\nmethod|params|return|comment\n---|---|---|---\nUIDL|`{String\\|Number}` msgNum|`{Promise}` resolve to `{Array}` list of responsed|msgNum is optional\nRETR|`{String\\|Number}` msgNum|`{Promise}` resolve to `{String}` of mail stream|\nTOP|`{String\\|Number}` msgNum, `{Number}` n|`{Promise}` resolve to `{String}` message of responsed|n is default to 0\nQUIT||`{Promise}` resolve to `{String}` message of response message|\n\n## ERROR\n\npop3 will throw new Error's with an error message from Server.\nBeyond that, Error may have two properties attached by pop3.\n\nproperty|comment\n---|---\n`err.eventName`|event name comes from `socket.on`. Includes `error`, `close`, `timeout`, `end`, and `bad-server-response`. `command` may also throw `no-socket`.\n`err.command`|which command causes the error. For example, `PASS example`\n\n## To-dos\n\n1. Testing:\n 1. Ensure tests seed (and then delete) messages (e.g., using `emailjs`)\n 1. Set up CI with hidden `pop.config.json` credentials\n 1. Avoid skipping some tests\n1. Edge cases\n 1. After timeout, ensure any stream is ended (so other commands can\n continue)\n 1. Ensure `command` will reject if socket is ended.\n 1. Ensure in fixing the above that can QUIT and reuse same instance\n" | ||
"eslint": "eslint .", | ||
"babel": "babel src -d lib --source-maps --out-file-extension .cjs", | ||
"mocha": "mocha --require chai/register-expect.js --exit test/*.js", | ||
"test": "rm -Rf .nyc_output && rm -Rf ./node_modules/.cache && npm run babel && c8 npm run mocha" | ||
} | ||
} |
# node-pop3 | ||
pop3 command for node. Supports **Promise** and **stream**. | ||
[pop3](https://tools.ietf.org/html/rfc1939) command support for node. | ||
Supports **Promise** and **stream**. | ||
@@ -40,3 +41,3 @@ ## CLI | ||
password: 'example', | ||
host: 'pop3.example.com', | ||
host: 'pop3.example.com' | ||
}); | ||
@@ -46,9 +47,5 @@ | ||
(async () => { | ||
await string = pop3.RETR(msgNum); | ||
// deal with mail string | ||
await pop3.QUIT(); | ||
})(); | ||
const str = await pop3.RETR(msgNum); | ||
// deal with mail string | ||
await pop3.QUIT(); | ||
``` | ||
@@ -61,3 +58,3 @@ | ||
console.dir(list); | ||
/** | ||
/* | ||
* [ | ||
@@ -95,23 +92,27 @@ * ['1', 'ZC0113-H8wi_YChVab4F0QTbwP4B6i'], | ||
command|`{String*}` command messages to Server|`{Promise}` resolve to `{Array[String, Stream]}`, which are messages of response and stream of response (if the response has multiple lines) from Server | ||
listify|Splits lines by CRLF, filters out empty lines, and converts each line to a an array based on splitting by spaces | ||
```js | ||
const pop3 = new Pop3Command({ host: 'pop3.example.com' }); | ||
const pop3 = new Pop3Command({host: 'pop3.example.com'}); | ||
(async () => { | ||
// These must be in order | ||
await pop3.connect(); | ||
await pop3.command('USER', 'example@example.com'); | ||
await pop3.command('PASS', 'example'); | ||
await pop3.connect(); | ||
await pop3.command('USER', 'example@example.com'); | ||
await pop3.command('PASS', 'example'); | ||
const [statInfo] = await pop3.command('STAT'); | ||
const [retrInfo, retrStream] = await pop3.command('RETR', 1); | ||
const [info] = await pop3.command('STAT'); | ||
console.log(info); // 100 102400 | ||
console.log(statInfo); // 100 102400 | ||
console.log(retrInfo); // 1024 octets | ||
const [info, stream] = await pop3.command('RETR', 1); | ||
console.log(info); // 1024 octets | ||
const [quitInfo] = await pop3.command('QUIT'); | ||
console.log(quitInfo); // Logging out. | ||
const [info] = await pop3.command('QUIT'); | ||
console.log(info); // Bye | ||
const streamString = await Pop3Command.stream2String(retrStream); | ||
console.log(streamString); // <message details...> | ||
})(); | ||
console.log( | ||
await Pop3Command.listify(streamString) | ||
); // [ ['Return-Path:', 'brett@...'], ...] | ||
``` | ||
@@ -141,3 +142,2 @@ | ||
1. Testing: | ||
1. Ensure tests seed (and then delete) messages (e.g., using `emailjs`) | ||
1. Set up CI with hidden `pop.config.json` credentials | ||
@@ -144,0 +144,0 @@ 1. Avoid skipping some tests |
# CHANGELOG | ||
## [6.9.7](https://github.com/nodemailer/nodemailer/compare/v6.9.6...v6.9.7) (2023-10-22) | ||
### Bug Fixes | ||
* **customAuth:** Do not require user and pass to be set for custom authentication schemes (fixes [#1584](https://github.com/nodemailer/nodemailer/issues/1584)) ([41d482c](https://github.com/nodemailer/nodemailer/commit/41d482c3f01e26111b06f3e46351b193db3fb5cb)) | ||
## [6.9.6](https://github.com/nodemailer/nodemailer/compare/v6.9.5...v6.9.6) (2023-10-09) | ||
### Bug Fixes | ||
* **inline:** Use 'inline' as the default Content Dispostion value for embedded images ([db32c93](https://github.com/nodemailer/nodemailer/commit/db32c93fefee527bcc239f13056e5d9181a4d8af)) | ||
* **tests:** Removed Node v12 from test matrix as it is not compatible with the test framework anymore ([7fe0a60](https://github.com/nodemailer/nodemailer/commit/7fe0a608ed6bcb70dc6b2de543ebfc3a30abf984)) | ||
## [6.9.5](https://github.com/nodemailer/nodemailer/compare/v6.9.4...v6.9.5) (2023-09-06) | ||
### Bug Fixes | ||
* **license:** Updated license year ([da4744e](https://github.com/nodemailer/nodemailer/commit/da4744e491f3a68f4f68e4073684370592630e01)) | ||
## 6.9.4 2023-07-19 | ||
- Renamed SendinBlue to Brevo | ||
## 6.9.3 2023-05-29 | ||
@@ -4,0 +30,0 @@ |
@@ -94,5 +94,9 @@ /* eslint no-undefined: 0 */ | ||
let contentType = attachment.contentType || mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || 'bin'); | ||
let isImage = /^image\//i.test(contentType); | ||
let contentDisposition = attachment.contentDisposition || (isMessageNode || (isImage && attachment.cid) ? 'inline' : 'attachment'); | ||
data = { | ||
contentType: attachment.contentType || mimeFuncs.detectMimeType(attachment.filename || attachment.path || attachment.href || 'bin'), | ||
contentDisposition: attachment.contentDisposition || (isMessageNode ? 'inline' : 'attachment'), | ||
contentType, | ||
contentDisposition, | ||
contentTransferEncoding: 'contentTransferEncoding' in attachment ? attachment.contentTransferEncoding : 'base64' | ||
@@ -510,3 +514,6 @@ }; | ||
if (!/^text\//i.test(element.contentType) || element.contentDisposition) { | ||
node.setHeader('Content-Disposition', element.contentDisposition || (element.cid ? 'inline' : 'attachment')); | ||
node.setHeader( | ||
'Content-Disposition', | ||
element.contentDisposition || (element.cid && /^image\//i.test(element.contentType) ? 'inline' : 'attachment') | ||
); | ||
} | ||
@@ -513,0 +520,0 @@ |
@@ -437,3 +437,3 @@ 'use strict'; | ||
if (this._authMethod !== 'XOAUTH2' && (!this._auth.credentials || !this._auth.credentials.user || !this._auth.credentials.pass)) { | ||
if (this._auth.user && this._auth.pass) { | ||
if ((this._auth.user && this._auth.pass) || this.customAuth.has(this._authMethod)) { | ||
this._auth.credentials = { | ||
@@ -440,0 +440,0 @@ user: this._auth.user, |
@@ -8,3 +8,10 @@ { | ||
}, | ||
"Aliyun": { | ||
"domains": ["aliyun.com"], | ||
"host": "smtp.aliyun.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"AOL": { | ||
@@ -15,3 +22,3 @@ "domains": ["aol.com"], | ||
}, | ||
"Bluewin": { | ||
@@ -217,3 +224,4 @@ "host": "smtpauths.bluewin.ch", | ||
"SendinBlue": { | ||
"host": "smtp-relay.sendinblue.com", | ||
"aliases": ["Brevo"], | ||
"host": "smtp-relay.brevo.com", | ||
"port": 587 | ||
@@ -252,2 +260,38 @@ }, | ||
"SES-AP-SOUTH-1": { | ||
"host": "email-smtp.ap-south-1.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"SES-AP-NORTHEAST-1": { | ||
"host": "email-smtp.ap-northeast-1.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"SES-AP-NORTHEAST-2": { | ||
"host": "email-smtp.ap-northeast-2.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"SES-AP-NORTHEAST-3": { | ||
"host": "email-smtp.ap-northeast-3.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"SES-AP-SOUTHEAST-1": { | ||
"host": "email-smtp.ap-southeast-1.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"SES-AP-SOUTHEAST-2": { | ||
"host": "email-smtp.ap-southeast-2.amazonaws.com", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"Sparkpost": { | ||
@@ -254,0 +298,0 @@ "aliases": ["SparkPost", "SparkPost Mail"], |
{ | ||
"name": "nodemailer", | ||
"version": "6.9.3", | ||
"version": "6.9.7", | ||
"description": "Easy as cake e-mail sending from your Node.js applications", | ||
"main": "lib/nodemailer.js", | ||
"scripts": { | ||
"test": "grunt --trace-warnings" | ||
"test": "grunt --trace-warnings", | ||
"update": "rm -rf node_modules/ package-lock.json && ncu -u && npm install" | ||
}, | ||
@@ -23,11 +24,11 @@ "repository": { | ||
"devDependencies": { | ||
"@aws-sdk/client-ses": "3.341.0", | ||
"aws-sdk": "2.1386.0", | ||
"@aws-sdk/client-ses": "3.433.0", | ||
"aws-sdk": "2.1478.0", | ||
"bunyan": "1.8.15", | ||
"chai": "4.3.7", | ||
"chai": "4.3.10", | ||
"eslint-config-nodemailer": "1.2.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-config-prettier": "9.0.0", | ||
"grunt": "1.6.1", | ||
"grunt-cli": "1.4.3", | ||
"grunt-eslint": "24.1.0", | ||
"grunt-eslint": "24.3.0", | ||
"grunt-mocha-test": "0.13.3", | ||
@@ -38,7 +39,7 @@ "libbase64": "1.2.1", | ||
"mocha": "10.2.0", | ||
"nodemailer-ntlm-auth": "1.0.3", | ||
"nodemailer-ntlm-auth": "1.0.4", | ||
"proxy": "1.0.2", | ||
"proxy-test-server": "1.0.0", | ||
"sinon": "15.1.0", | ||
"smtp-server": "3.12.0" | ||
"sinon": "17.0.0", | ||
"smtp-server": "3.13.0" | ||
}, | ||
@@ -45,0 +46,0 @@ "engines": { |
# Changelog | ||
## Version 0.12.1 | ||
* Runtime check for input of `parse` and `parse1` to be a string. | ||
## Version 0.12.0 | ||
* Support for escape sequences according to specifications ([#97](https://github.com/mxxii/parseley/issues/97)). | ||
Now follows <https://www.w3.org/TR/selectors-3/#lex> for parsing and <https://w3c.github.io/csswg-drafts/cssom/#common-serializing-idioms> for serializing. | ||
Possibly breaking changes: | ||
* parsed strings (attribute values) retained escape sequences previously, now they are unescaped; | ||
* strings with `"` character were serialized as single-quoted previously, now all strings serialized as double-quoted, per spec suggestion. | ||
## Version 0.11.0 | ||
@@ -4,0 +19,0 @@ |
@@ -11,3 +11,3 @@ /** | ||
*/ | ||
export declare type Specificity = [number, number, number]; | ||
export type Specificity = [number, number, number]; | ||
/** | ||
@@ -21,3 +21,3 @@ * The `*` selector. | ||
*/ | ||
export declare type UniversalSelector = { | ||
export type UniversalSelector = { | ||
type: 'universal'; | ||
@@ -35,3 +35,3 @@ namespace: string | null; | ||
*/ | ||
export declare type TagSelector = { | ||
export type TagSelector = { | ||
type: 'tag'; | ||
@@ -47,3 +47,3 @@ name: string; | ||
*/ | ||
export declare type ClassSelector = { | ||
export type ClassSelector = { | ||
type: 'class'; | ||
@@ -58,3 +58,3 @@ name: string; | ||
*/ | ||
export declare type IdSelector = { | ||
export type IdSelector = { | ||
type: 'id'; | ||
@@ -72,3 +72,3 @@ name: string; | ||
*/ | ||
export declare type AttributePresenceSelector = { | ||
export type AttributePresenceSelector = { | ||
type: 'attrPresence'; | ||
@@ -87,3 +87,3 @@ name: string; | ||
*/ | ||
export declare type AttributeValueSelector = { | ||
export type AttributeValueSelector = { | ||
type: 'attrValue'; | ||
@@ -102,3 +102,3 @@ name: string; | ||
*/ | ||
export declare type Combinator = { | ||
export type Combinator = { | ||
type: 'combinator'; | ||
@@ -120,3 +120,3 @@ combinator: ' ' | '+' | '>' | '~' | '||'; | ||
*/ | ||
export declare type SimpleSelector = UniversalSelector | TagSelector | ClassSelector | IdSelector | AttributePresenceSelector | AttributeValueSelector | Combinator; | ||
export type SimpleSelector = UniversalSelector | TagSelector | ClassSelector | IdSelector | AttributePresenceSelector | AttributeValueSelector | Combinator; | ||
/** | ||
@@ -137,3 +137,3 @@ * Compound selector - a set of conditions describing a single element. | ||
*/ | ||
export declare type CompoundSelector = { | ||
export type CompoundSelector = { | ||
type: 'compound'; | ||
@@ -151,3 +151,3 @@ list: SimpleSelector[]; | ||
*/ | ||
export declare type ListSelector = { | ||
export type ListSelector = { | ||
type: 'list'; | ||
@@ -159,2 +159,2 @@ list: CompoundSelector[]; | ||
*/ | ||
export declare type Selector = ListSelector | CompoundSelector | SimpleSelector; | ||
export type Selector = ListSelector | CompoundSelector | SimpleSelector; |
{ | ||
"name": "parseley", | ||
"version": "0.11.0", | ||
"version": "0.12.1", | ||
"description": "CSS selectors parser", | ||
@@ -38,3 +38,3 @@ "keywords": [ | ||
"build:deno": "denoify", | ||
"build:docs": "typedoc", | ||
"build:docs": "typedoc --plugin typedoc-plugin-markdown", | ||
"build:rollup": "rollup -c", | ||
@@ -45,3 +45,3 @@ "build:types": "tsc --declaration --emitDeclarationOnly", | ||
"clean": "rimraf lib", | ||
"example": "node ./example/example.cjs", | ||
"example": "node ./example/example.mjs", | ||
"lint:eslint": "eslint .", | ||
@@ -55,24 +55,24 @@ "lint:md": "markdownlint-cli2", | ||
"leac": "^0.6.0", | ||
"peberminta": "^0.8.0" | ||
"peberminta": "^0.9.0" | ||
}, | ||
"devDependencies": { | ||
"@rollup/plugin-typescript": "^8.3.4", | ||
"@rollup/plugin-typescript": "^11.1.0", | ||
"@tsconfig/node14": "^1.0.3", | ||
"@types/node": "^14.18.23", | ||
"@typescript-eslint/eslint-plugin": "^5.33.1", | ||
"@typescript-eslint/parser": "^5.33.1", | ||
"ava": "^4.3.1", | ||
"denoify": "^1.0.1", | ||
"eslint": "^8.22.0", | ||
"eslint-plugin-jsonc": "^2.4.0", | ||
"eslint-plugin-tsdoc": "^0.2.16", | ||
"markdownlint-cli2": "^0.5.1", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.78.0", | ||
"@types/node": "^14.18.42", | ||
"@typescript-eslint/eslint-plugin": "^5.59.0", | ||
"@typescript-eslint/parser": "^5.59.0", | ||
"ava": "^5.2.0", | ||
"denoify": "^1.5.3", | ||
"eslint": "^8.39.0", | ||
"eslint-plugin-jsonc": "^2.7.0", | ||
"eslint-plugin-tsdoc": "^0.2.17", | ||
"markdownlint-cli2": "^0.7.0", | ||
"rimraf": "^5.0.0", | ||
"rollup": "^2.79.1", | ||
"rollup-plugin-cleanup": "^3.2.1", | ||
"ts-node": "^10.9.1", | ||
"tslib": "^2.4.0", | ||
"typedoc": "~0.23.10", | ||
"typedoc-plugin-markdown": "~3.13.4", | ||
"typescript": "~4.7.4" | ||
"tslib": "^2.5.0", | ||
"typedoc": "~0.23.28", | ||
"typedoc-plugin-markdown": "~3.14.0", | ||
"typescript": "~4.9.5" | ||
}, | ||
@@ -93,8 +93,4 @@ "ava": { | ||
"denoify": { | ||
"out": "./deno", | ||
"ports": { | ||
"leac": "https://deno.land/x/leac/leac.ts", | ||
"peberminta": "https://deno.land/x/peberminta/core.ts" | ||
} | ||
"out": "./deno" | ||
} | ||
} |
@@ -51,15 +51,15 @@ # parseley | ||
```js | ||
const parseley = require('parseley'); | ||
const util = require('util'); | ||
import { parse1, serialize, normalize } from 'parseley'; | ||
import { inspect } from 'node:util'; | ||
const str = 'div#id1 > .class1[attr1]'; | ||
const str = 'div#id1 > .class2.class1[attr1]'; | ||
const ast = parseley.parse1(str); | ||
console.log(util.inspect(ast, { breakLength: 45, depth: null })); | ||
const ast = parse1(str); | ||
console.log(inspect(ast, { breakLength: 45, depth: null })); | ||
const serialized = parseley.serialize(ast); | ||
const serialized = serialize(ast); | ||
console.log(`Serialized: '${serialized}'`); | ||
parseley.normalize(ast); | ||
const normalized = parseley.serialize(ast); | ||
normalize(ast); | ||
const normalized = serialize(ast); | ||
console.log(`Normalized: '${normalized}'`); | ||
@@ -71,25 +71,46 @@ ``` | ||
```text | ||
{ type: 'compound', | ||
list: | ||
[ { type: 'class', | ||
name: 'class1', | ||
specificity: [ 0, 1, 0 ] }, | ||
{ type: 'attrPresence', | ||
name: 'attr1', | ||
namespace: null, | ||
specificity: [ 0, 1, 0 ] }, | ||
{ type: 'combinator', | ||
combinator: '>', | ||
left: | ||
{ type: 'compound', | ||
list: | ||
[ { type: 'tag', | ||
name: 'div', | ||
namespace: null, | ||
specificity: [ 0, 0, 1 ] }, | ||
{ type: 'id', | ||
name: 'id1', | ||
specificity: [ 1, 0, 0 ] } ], | ||
specificity: [ 1, 0, 1 ] } } ], | ||
specificity: [ 1, 2, 1 ] } | ||
{ | ||
type: 'compound', | ||
list: [ | ||
{ | ||
type: 'class', | ||
name: 'class2', | ||
specificity: [ 0, 1, 0 ] | ||
}, | ||
{ | ||
type: 'class', | ||
name: 'class1', | ||
specificity: [ 0, 1, 0 ] | ||
}, | ||
{ | ||
type: 'attrPresence', | ||
name: 'attr1', | ||
namespace: null, | ||
specificity: [ 0, 1, 0 ] | ||
}, | ||
{ | ||
type: 'combinator', | ||
combinator: '>', | ||
left: { | ||
type: 'compound', | ||
list: [ | ||
{ | ||
type: 'tag', | ||
name: 'div', | ||
namespace: null, | ||
specificity: [ 0, 0, 1 ] | ||
}, | ||
{ | ||
type: 'id', | ||
name: 'id1', | ||
specificity: [ 1, 0, 0 ] | ||
} | ||
], | ||
specificity: [ 1, 0, 1 ] | ||
}, | ||
specificity: [ 1, 0, 1 ] | ||
} | ||
], | ||
specificity: [ 1, 3, 1 ] | ||
} | ||
Serialized: 'div#id1>.class2.class1[attr1]' | ||
@@ -96,0 +117,0 @@ Normalized: 'div#id1>.class1.class2[attr1]' |
# Changelog | ||
## Version 0.9.0 | ||
- many functions got overloads for `Matcher` type propagation in less common scenarios; | ||
- `condition` function now accepts Parsers/Matchers with different value types, result value type is the union of the two; | ||
- added type tests for overloads using [expect-type](https://github.com/mmkal/expect-type). | ||
## Version 0.8.0 | ||
@@ -4,0 +10,0 @@ |
@@ -27,3 +27,3 @@ /** | ||
*/ | ||
export declare type Data<TToken, TOptions> = { | ||
export type Data<TToken, TOptions> = { | ||
/** Tokens array - the subject of parsing. */ | ||
@@ -39,3 +39,3 @@ tokens: TToken[]; | ||
*/ | ||
export declare type Match<TValue> = { | ||
export type Match<TValue> = { | ||
matched: true; | ||
@@ -52,3 +52,3 @@ /** Parser position after this match. */ | ||
*/ | ||
export declare type NonMatch = { | ||
export type NonMatch = { | ||
matched: false; | ||
@@ -61,3 +61,3 @@ }; | ||
*/ | ||
export declare type Result<TValue> = Match<TValue> | NonMatch; | ||
export type Result<TValue> = Match<TValue> | NonMatch; | ||
/** | ||
@@ -72,3 +72,3 @@ * Parser function. | ||
*/ | ||
export declare type Parser<TToken, TOptions, TValue> = (data: Data<TToken, TOptions>, i: number) => Result<TValue>; | ||
export type Parser<TToken, TOptions, TValue> = (data: Data<TToken, TOptions>, i: number) => Result<TValue>; | ||
/** | ||
@@ -83,3 +83,3 @@ * Special case of {@link Parser} function. | ||
*/ | ||
export declare type Matcher<TToken, TOptions, TValue> = (data: Data<TToken, TOptions>, i: number) => Match<TValue>; | ||
export type Matcher<TToken, TOptions, TValue> = (data: Data<TToken, TOptions>, i: number) => Match<TValue>; | ||
/** | ||
@@ -307,2 +307,9 @@ * Make a {@link Matcher} that always succeeds with provided value and doesn't consume input. | ||
/** | ||
* This overload makes a {@link Matcher} that tries multiple parsers (last entry is a matcher) at the same position | ||
* and returns the first successful match. | ||
* | ||
* @param ps - Parsers to try. | ||
*/ | ||
export declare function choice<TToken, TOptions, TValue>(...ps: [...Parser<TToken, TOptions, TValue>[], Matcher<TToken, TOptions, TValue>]): Matcher<TToken, TOptions, TValue>; | ||
/** | ||
* Make a parser that tries multiple parsers at the same position | ||
@@ -312,5 +319,2 @@ * and returns the first successful match | ||
* | ||
* Combine with {@link otherwise} if you want to return a {@link Matcher} | ||
* or you have a limited number of parsers of different types. | ||
* | ||
* @param ps - Parsers to try. | ||
@@ -463,2 +467,24 @@ */ | ||
/** | ||
* This overload makes a {@link Matcher} that applies two matchers one after another and joins the results. | ||
* | ||
* Use {@link abc} if you want to join 3 different parsers/matchers. | ||
* | ||
* Use {@link left} or {@link right} if you want to keep one result and discard another. | ||
* | ||
* Use {@link all} if you want a sequence of parsers of arbitrary length (but they have to share a common value type). | ||
* | ||
* @param pa - First matcher. | ||
* @param pb - Second matcher. | ||
* @param join - A function to combine values from both matchers. | ||
*/ | ||
export declare function ab<TToken, TOptions, TValueA, TValueB, TValue>(pa: Matcher<TToken, TOptions, TValueA>, pb: Matcher<TToken, TOptions, TValueB>, | ||
/** | ||
* @param va - A value matched by the first matcher. | ||
* @param vb - A value matched by the second matcher. | ||
* @param data - Data object (tokens and options). | ||
* @param i - Parser position in the tokens array (before both matchers matched). | ||
* @param j - Parser position in the tokens array (after both matchers matched). | ||
*/ | ||
join: (va: TValueA, vb: TValueB, data: Data<TToken, TOptions>, i: number, j: number) => TValue): Matcher<TToken, TOptions, TValue>; | ||
/** | ||
* Make a parser that tries two parsers one after another and joins the results. | ||
@@ -476,3 +502,3 @@ * | ||
* @param pb - Second parser. | ||
* @param join - A function to combine matched results from both parsers. | ||
* @param join - A function to combine matched values from both parsers. | ||
*/ | ||
@@ -489,2 +515,12 @@ export declare function ab<TToken, TOptions, TValueA, TValueB, TValue>(pa: Parser<TToken, TOptions, TValueA>, pb: Parser<TToken, TOptions, TValueB>, | ||
/** | ||
* This overload makes a {@link Matcher} that applies two matchers one after another | ||
* and returns the result from the first one. | ||
* | ||
* Implementation is based on {@link ab}. | ||
* | ||
* @param pa - First matcher (result is returned). | ||
* @param pb - Second matcher (result is discarded). | ||
*/ | ||
export declare function left<TToken, TOptions, TValueA, TValueB>(pa: Matcher<TToken, TOptions, TValueA>, pb: Matcher<TToken, TOptions, TValueB>): Matcher<TToken, TOptions, TValueA>; | ||
/** | ||
* Make a parser that tries two parsers one after another | ||
@@ -502,2 +538,12 @@ * and returns the result from the first one if both matched. | ||
/** | ||
* This overload makes a {@link Matcher} that applies two matchers one after another | ||
* and returns the result from the second one. | ||
* | ||
* Implementation is based on {@link ab}. | ||
* | ||
* @param pa - First matcher (result is discarded). | ||
* @param pb - Second matcher (result is returned). | ||
*/ | ||
export declare function right<TToken, TOptions, TValueA, TValueB>(pa: Matcher<TToken, TOptions, TValueA>, pb: Matcher<TToken, TOptions, TValueB>): Matcher<TToken, TOptions, TValueB>; | ||
/** | ||
* Make a parser that tries two parsers one after another | ||
@@ -515,2 +561,26 @@ * and returns the result from the second one if both matched. | ||
/** | ||
* This overload makes a {@link Matcher} that applies three matchers one after another and joins the results. | ||
* | ||
* Use {@link ab} if you want to join just 2 different parsers/matchers. | ||
* | ||
* Use {@link middle} if you want to keep only the middle result and discard two others. | ||
* | ||
* Use {@link all} if you want a sequence of parsers of arbitrary length (but they have to share a common value type). | ||
* | ||
* @param pa - First matcher. | ||
* @param pb - Second matcher. | ||
* @param pc - Third matcher. | ||
* @param join - A function to combine matched values from all three matchers. | ||
*/ | ||
export declare function abc<TToken, TOptions, TValueA, TValueB, TValueC, TValue>(pa: Matcher<TToken, TOptions, TValueA>, pb: Matcher<TToken, TOptions, TValueB>, pc: Matcher<TToken, TOptions, TValueC>, | ||
/** | ||
* @param va - A value matched by the first matcher. | ||
* @param vb - A value matched by the second matcher. | ||
* @param vc - A value matched by the third matcher. | ||
* @param data - Data object (tokens and options). | ||
* @param i - Parser position in the tokens array (before all three matchers matched). | ||
* @param j - Parser position in the tokens array (after all three matchers matched). | ||
*/ | ||
join: (va: TValueA, vb: TValueB, vc: TValueC, data: Data<TToken, TOptions>, i: number, j: number) => TValue): Matcher<TToken, TOptions, TValue>; | ||
/** | ||
* Make a parser that tries three parsers one after another and joins the results. | ||
@@ -542,2 +612,13 @@ * | ||
/** | ||
* This overload makes a {@link Matcher} that applies three matchers one after another | ||
* and returns the middle result. | ||
* | ||
* Implementation is based on {@link abc}. | ||
* | ||
* @param pa - First matcher (result is discarded). | ||
* @param pb - Second matcher (result is returned). | ||
* @param pc - Third matcher (result is discarded). | ||
*/ | ||
export declare function middle<TToken, TOptions, TValueA, TValueB, TValueC>(pa: Matcher<TToken, TOptions, TValueA>, pb: Matcher<TToken, TOptions, TValueB>, pc: Matcher<TToken, TOptions, TValueC>): Matcher<TToken, TOptions, TValueB>; | ||
/** | ||
* Make a parser that tries three parsers one after another | ||
@@ -556,2 +637,9 @@ * and returns the middle result if all three matched. | ||
/** | ||
* This overload makes a {@link Matcher} that runs all given matchers one after another | ||
* and returns all results in an array. | ||
* | ||
* @param ps - Matchers to run sequentially. | ||
*/ | ||
export declare function all<TToken, TOptions, TValue>(...ps: Matcher<TToken, TOptions, TValue>[]): Matcher<TToken, TOptions, TValue[]>; | ||
/** | ||
* Make a parser that runs all given parsers one after another | ||
@@ -569,4 +657,17 @@ * and returns all results in an array. | ||
/** | ||
* This overload makes a {@link Matcher} that runs all given matchers in sequence | ||
* and discards (skips) all results (Returns a match with a dummy value). | ||
* | ||
* Implementation is based on {@link all} and {@link map}. | ||
* | ||
* This function only exists to make the intent clear. | ||
* Use in combination with {@link left}, {@link right} or other combinators | ||
* to make the `null` result disappear. | ||
* | ||
* @param ps - Parsers to run sequentially. | ||
*/ | ||
export declare function skip<TToken, TOptions>(...ps: Matcher<TToken, TOptions, unknown>[]): Matcher<TToken, TOptions, unknown>; | ||
/** | ||
* Make a parser that runs all given parsers in sequence | ||
* and discards (skips) all results (Returns a match with a single `null` value). | ||
* and discards (skips) all results (Returns a match with a dummy value). | ||
* | ||
@@ -777,2 +878,18 @@ * Nonmatch is returned if any of parsers didn't match. | ||
/** | ||
* This overload makes a {@link Matcher} that chooses between two given matchers based on a condition. | ||
* This makes possible to allow/disallow a grammar based on context/options. | ||
* | ||
* {@link decide} and {@link chain} allow for more complex dynamic rules. | ||
* | ||
* @param cond - Condition. | ||
* @param pTrue - Matcher to run when the condition is true. | ||
* @param pFalse - Matcher to run when the condition is false. | ||
*/ | ||
export declare function condition<TToken, TOptions, TValueA, TValueB>( | ||
/** | ||
* @param data - Data object (tokens and options). | ||
* @param i - Parser position in the tokens array (before parsing). | ||
*/ | ||
cond: (data: Data<TToken, TOptions>, i: number) => boolean, pTrue: Matcher<TToken, TOptions, TValueA>, pFalse: Matcher<TToken, TOptions, TValueB>): Matcher<TToken, TOptions, TValueA | TValueB>; | ||
/** | ||
* Make a parser that chooses between two given parsers based on a condition. | ||
@@ -787,3 +904,3 @@ * This makes possible to allow/disallow a grammar based on context/options. | ||
*/ | ||
export declare function condition<TToken, TOptions, TValue>( | ||
export declare function condition<TToken, TOptions, TValueA, TValueB>( | ||
/** | ||
@@ -793,3 +910,3 @@ * @param data - Data object (tokens and options). | ||
*/ | ||
cond: (data: Data<TToken, TOptions>, i: number) => boolean, pTrue: Parser<TToken, TOptions, TValue>, pFalse: Parser<TToken, TOptions, TValue>): Parser<TToken, TOptions, TValue>; | ||
cond: (data: Data<TToken, TOptions>, i: number) => boolean, pTrue: Parser<TToken, TOptions, TValueA>, pFalse: Parser<TToken, TOptions, TValueB>): Parser<TToken, TOptions, TValueA | TValueB>; | ||
/** | ||
@@ -796,0 +913,0 @@ * Make a parser that runs a given parser and then a dynamically returned parser. |
{ | ||
"name": "peberminta", | ||
"version": "0.8.0", | ||
"version": "0.9.0", | ||
"description": "Simple, transparent parser combinators toolkit that supports any tokens", | ||
@@ -69,3 +69,5 @@ "keywords": [ | ||
"prepublishOnly": "npm run build && npm run checkAll", | ||
"test": "ava --timeout=20s", | ||
"test:ava": "ava --timeout=20s", | ||
"test:tsc": "tsc --noEmit --project tsconfig.tsc.json", | ||
"test": "concurrently npm:test:*", | ||
"ts": "node --experimental-specifier-resolution=node --loader ts-node/esm" | ||
@@ -75,23 +77,24 @@ }, | ||
"devDependencies": { | ||
"@rollup/plugin-typescript": "^8.3.4", | ||
"@rollup/plugin-typescript": "^11.0.0", | ||
"@tsconfig/node14": "^1.0.3", | ||
"@types/node": "14.18.23", | ||
"@typescript-eslint/eslint-plugin": "^5.33.1", | ||
"@typescript-eslint/parser": "^5.33.1", | ||
"ava": "^4.3.1", | ||
"@types/node": "14.18.36", | ||
"@typescript-eslint/eslint-plugin": "^5.48.2", | ||
"@typescript-eslint/parser": "^5.48.2", | ||
"ava": "^5.1.1", | ||
"c8": "^7.12.0", | ||
"concurrently": "^7.3.0", | ||
"denoify": "^1.0.0", | ||
"eslint": "^8.22.0", | ||
"eslint-plugin-jsonc": "^2.4.0", | ||
"eslint-plugin-tsdoc": "^0.2.16", | ||
"concurrently": "^7.6.0", | ||
"denoify": "^1.4.5", | ||
"eslint": "^8.32.0", | ||
"eslint-plugin-jsonc": "^2.6.0", | ||
"eslint-plugin-tsdoc": "^0.2.17", | ||
"expect-type": "^0.15.0", | ||
"leac": "^0.6.0", | ||
"markdownlint-cli2": "^0.5.1", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.78.0", | ||
"markdownlint-cli2": "^0.6.0", | ||
"rimraf": "^4.1.1", | ||
"rollup": "^2.79.1", | ||
"rollup-plugin-cleanup": "^3.2.1", | ||
"ts-node": "^10.9.1", | ||
"tslib": "^2.4.0", | ||
"typedoc": "~0.23.10", | ||
"typescript": "~4.7.4" | ||
"tslib": "^2.4.1", | ||
"typedoc": "~0.23.24", | ||
"typescript": "~4.9.4" | ||
}, | ||
@@ -98,0 +101,0 @@ "ava": { |
@@ -8,2 +8,3 @@ # peberminta | ||
[](https://www.npmjs.com/package/peberminta) | ||
[](https://www.npmjs.com/package/peberminta) | ||
[](https://deno.land/x/peberminta) | ||
@@ -77,3 +78,8 @@ | ||
### Published packages using `peberminta` | ||
- [aspargvs](https://github.com/mxxii/aspargvs) - arg parser, CLI wrapper | ||
- [parseley](https://github.com/mxxii/parseley) - CSS selectors parser | ||
## API | ||
@@ -80,0 +86,0 @@ |
# Changelog | ||
## Version 0.11.0 | ||
* Bump `parseley` dependency to version 0.12.0 ([changelog](https://github.com/mxxii/parseley/blob/main/CHANGELOG.md)). Escape sequences in selectors. | ||
## Version 0.10.0 | ||
@@ -4,0 +8,0 @@ |
{ | ||
"name": "selderee", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "Selectors decision tree - choose matching selectors, fast", | ||
@@ -42,4 +42,4 @@ "keywords": [ | ||
"dependencies": { | ||
"parseley": "^0.11.0" | ||
"parseley": "^0.12.0" | ||
} | ||
} |
# Changelog | ||
## v3.13.0 2023-08-15 | ||
- new event handler `onSecure` | ||
- specified license identifier in package.json (from `MIT` to `MIT-0`) | ||
## v3.12.0 2023-05-24 | ||
@@ -4,0 +9,0 @@ |
@@ -163,2 +163,17 @@ 'use strict'; | ||
let onSecureIfNeeded = next => { | ||
if (!this.session.secure) { | ||
// no TLS | ||
return next(); | ||
} | ||
this.session.servername = this._socket.servername; | ||
this._server.onSecure(this._socket, this.session, err => { | ||
if (err) { | ||
return this._onError(err); | ||
} | ||
next(); | ||
}); | ||
}; | ||
this._server.onConnect(this.session, err => { | ||
@@ -181,16 +196,21 @@ this._server.logger.info( | ||
this._ready = true; // Start accepting data from input | ||
onSecureIfNeeded(() => { | ||
this._ready = true; // Start accepting data from input | ||
if (!this._server.options.useXClient && !this._server.options.useXForward) { | ||
this.emitConnection(); | ||
} | ||
if (!this._server.options.useXClient && !this._server.options.useXForward) { | ||
this.emitConnection(); | ||
} | ||
this.send( | ||
220, | ||
this.name + ' ' + (this._server.options.lmtp ? 'LMTP' : 'ESMTP') + (this._server.options.banner ? ' ' + this._server.options.banner : '') | ||
); | ||
this.send( | ||
220, | ||
this.name + | ||
' ' + | ||
(this._server.options.lmtp ? 'LMTP' : 'ESMTP') + | ||
(this._server.options.banner ? ' ' + this._server.options.banner : '') | ||
); | ||
if (typeof next === 'function') { | ||
next(); | ||
} | ||
if (typeof next === 'function') { | ||
next(); | ||
} | ||
}); | ||
}); | ||
@@ -495,3 +515,6 @@ }; | ||
if (!this.session.user && this._isSupported('AUTH') && ['MAIL', 'RCPT', 'DATA'].includes(commandName) && !this._server.options.authOptional) { | ||
this.send(530, typeof this._server.options.authRequiredMessage === 'string' ? this._server.options.authRequiredMessage : 'Error: authentication Required'); | ||
this.send( | ||
530, | ||
typeof this._server.options.authRequiredMessage === 'string' ? this._server.options.authRequiredMessage : 'Error: authentication Required' | ||
); | ||
return setImmediate(callback); | ||
@@ -1429,2 +1452,3 @@ } | ||
this.session.tlsOptions = this.tlsOptions = this._socket.getCipher(); | ||
this.session.servername = this._socket.servername; | ||
let cipher = this.session.tlsOptions && this.session.tlsOptions.name; | ||
@@ -1441,6 +1465,11 @@ this._server.logger.info( | ||
); | ||
this._socket.pipe(this._parser); | ||
if (typeof secureCallback === 'function') { | ||
secureCallback(); | ||
} | ||
this._server.onSecure(this._socket, this.session, err => { | ||
if (err) { | ||
return this._onError(err); | ||
} | ||
this._socket.pipe(this._parser); | ||
if (typeof secureCallback === 'function') { | ||
secureCallback(); | ||
} | ||
}); | ||
}); | ||
@@ -1447,0 +1476,0 @@ } |
@@ -44,3 +44,3 @@ 'use strict'; | ||
// apply shorthand handlers | ||
['onConnect', 'onAuth', 'onMailFrom', 'onRcptTo', 'onData', 'onClose'].forEach(handler => { | ||
['onConnect', 'onSecure', 'onAuth', 'onMailFrom', 'onRcptTo', 'onData', 'onClose'].forEach(handler => { | ||
if (typeof this.options[handler] === 'function') { | ||
@@ -200,3 +200,5 @@ this[handler] = this.options[handler]; | ||
} | ||
onSecure(socket, session, callback) { | ||
setImmediate(callback); | ||
} | ||
onData(stream, session, callback) { | ||
@@ -203,0 +205,0 @@ let chunklen = 0; |
# CHANGELOG | ||
## 6.9.4 2023-07-19 | ||
- Renamed SendinBlue to Brevo | ||
## 6.9.3 2023-05-29 | ||
- Specified license identifier (was defined as MIT, actual value MIT-0) | ||
- If SMTP server disconnects with a message, process it and include as part of the response error | ||
## 6.9.2 2023-05-11 | ||
@@ -4,0 +13,0 @@ |
@@ -820,2 +820,16 @@ 'use strict'; | ||
_onClose() { | ||
let serverResponse = false; | ||
if (this._remainder && this._remainder.trim()) { | ||
if (this.options.debug || this.options.transactionLog) { | ||
this.logger.debug( | ||
{ | ||
tnx: 'server' | ||
}, | ||
this._remainder.replace(/\r?\n$/, '') | ||
); | ||
} | ||
this.lastServerResponse = serverResponse = this._remainder.trim(); | ||
} | ||
this.logger.info( | ||
@@ -829,5 +843,7 @@ { | ||
if (this.upgrading && !this._destroyed) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ETLS', false, 'CONN'); | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ETLS', serverResponse, 'CONN'); | ||
} else if (![this._actionGreeting, this.close].includes(this._responseActions[0]) && !this._destroyed) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', false, 'CONN'); | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', serverResponse, 'CONN'); | ||
} else if (/^[45]\d{2}\b/.test(serverResponse)) { | ||
return this._onError(new Error('Connection closed unexpectedly'), 'ECONNECTION', serverResponse, 'CONN'); | ||
} | ||
@@ -949,3 +965,3 @@ | ||
// skip unexpected empty lines | ||
setImmediate(() => this._processResponse(true)); | ||
setImmediate(() => this._processResponse()); | ||
} | ||
@@ -957,3 +973,3 @@ | ||
action.call(this, str); | ||
setImmediate(() => this._processResponse(true)); | ||
setImmediate(() => this._processResponse()); | ||
} else { | ||
@@ -960,0 +976,0 @@ return this._onError(new Error('Unexpected Response'), 'EPROTOCOL', str, 'CONN'); |
@@ -14,3 +14,3 @@ { | ||
}, | ||
"Bluewin": { | ||
@@ -46,2 +46,10 @@ "host": "smtpauths.bluewin.ch", | ||
"Forward Email": { | ||
"aliases": ["FE", "ForwardEmail"], | ||
"domains": ["forwardemail.net"], | ||
"host": "smtp.forwardemail.net", | ||
"port": 465, | ||
"secure": true | ||
}, | ||
"GandiMail": { | ||
@@ -209,3 +217,4 @@ "aliases": ["Gandi", "Gandi Mail"], | ||
"SendinBlue": { | ||
"host": "smtp-relay.sendinblue.com", | ||
"aliases": ["Brevo"], | ||
"host": "smtp-relay.brevo.com", | ||
"port": 587 | ||
@@ -212,0 +221,0 @@ }, |
{ | ||
"name": "nodemailer", | ||
"version": "6.9.2", | ||
"version": "6.9.4", | ||
"description": "Easy as cake e-mail sending from your Node.js applications", | ||
@@ -17,3 +17,3 @@ "main": "lib/nodemailer.js", | ||
"author": "Andris Reinman", | ||
"license": "MIT", | ||
"license": "MIT-0", | ||
"bugs": { | ||
@@ -24,4 +24,4 @@ "url": "https://github.com/nodemailer/nodemailer/issues" | ||
"devDependencies": { | ||
"@aws-sdk/client-ses": "3.329.0", | ||
"aws-sdk": "2.1376.0", | ||
"@aws-sdk/client-ses": "3.370.0", | ||
"aws-sdk": "2.1417.0", | ||
"bunyan": "1.8.15", | ||
@@ -33,3 +33,3 @@ "chai": "4.3.7", | ||
"grunt-cli": "1.4.3", | ||
"grunt-eslint": "24.1.0", | ||
"grunt-eslint": "24.3.0", | ||
"grunt-mocha-test": "0.13.3", | ||
@@ -40,7 +40,7 @@ "libbase64": "1.2.1", | ||
"mocha": "10.2.0", | ||
"nodemailer-ntlm-auth": "1.0.3", | ||
"nodemailer-ntlm-auth": "1.0.4", | ||
"proxy": "1.0.2", | ||
"proxy-test-server": "1.0.0", | ||
"sinon": "15.0.4", | ||
"smtp-server": "3.11.0" | ||
"sinon": "15.2.0", | ||
"smtp-server": "3.12.0" | ||
}, | ||
@@ -47,0 +47,0 @@ "engines": { |
@@ -93,3 +93,3 @@ # Nodemailer | ||
Nodemailer is licensed under the **MIT license** | ||
Nodemailer is licensed under the **MIT No Attribution license** | ||
@@ -96,0 +96,0 @@ --- |
{ | ||
"name": "smtp-server", | ||
"version": "3.12.0", | ||
"version": "3.13.0", | ||
"description": "Create custom SMTP servers on the fly", | ||
@@ -10,7 +10,7 @@ "main": "lib/smtp-server.js", | ||
"author": "Andris Reinman", | ||
"license": "MIT", | ||
"license": "MIT-0", | ||
"dependencies": { | ||
"base32.js": "0.1.0", | ||
"ipv6-normalize": "1.0.1", | ||
"nodemailer": "6.9.2" | ||
"nodemailer": "6.9.4" | ||
}, | ||
@@ -20,9 +20,9 @@ "devDependencies": { | ||
"eslint-config-nodemailer": "1.2.0", | ||
"eslint-config-prettier": "8.8.0", | ||
"eslint-config-prettier": "9.0.0", | ||
"grunt": "1.6.1", | ||
"grunt-cli": "1.4.3", | ||
"grunt-eslint": "24.1.0", | ||
"grunt-eslint": "24.3.0", | ||
"grunt-mocha-test": "0.13.3", | ||
"mocha": "10.2.0", | ||
"pem": "1.14.7" | ||
"pem": "1.14.8" | ||
}, | ||
@@ -40,4 +40,4 @@ "repository": { | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": ">=12.0.0" | ||
} | ||
} |
@@ -626,4 +626,3 @@ /* eslint no-unused-expressions:0, prefer-arrow-callback: 0 */ | ||
key: keys.serviceKey, | ||
cert: keys.certificate, | ||
logInfo: true | ||
cert: keys.certificate | ||
}); | ||
@@ -1482,2 +1481,167 @@ | ||
}); | ||
describe('onSecure handler', function () { | ||
let PORT = 1336; | ||
it('should detect once a connection is established with TLS', function (done) { | ||
let server; | ||
pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
let secureCount = 0; | ||
server = new SMTPServer({ | ||
secure: true, | ||
logger: false, | ||
key: keys.serviceKey, | ||
cert: keys.certificate, | ||
onSecure(socket, session, done) { | ||
expect(session).to.exist; | ||
expect(session.servername).to.equal('teretere1'); | ||
secureCount++; | ||
done(); | ||
} | ||
}); | ||
server.listen(PORT, '127.0.0.1'); | ||
let connection = new Client({ | ||
port: PORT, | ||
host: '127.0.0.1', | ||
secure: true, | ||
tls: { | ||
rejectUnauthorized: false, | ||
servername: 'teretere1' | ||
} | ||
}); | ||
connection.connect(function () { | ||
setTimeout(() => { | ||
connection.quit(); | ||
server.close(() => { | ||
expect(secureCount).to.equal(1); | ||
done(); | ||
}); | ||
}, 100); | ||
}); | ||
connection.on('error', err => { | ||
server.close(() => done(err)); | ||
}); | ||
}); | ||
}); | ||
it('should detect once a connection is upgraded to TLS', function (done) { | ||
let server; | ||
pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
let secureCount = 0; | ||
server = new SMTPServer({ | ||
secure: false, | ||
logger: false, | ||
key: keys.serviceKey, | ||
cert: keys.certificate, | ||
onSecure(socket, session, done) { | ||
expect(session).to.exist; | ||
expect(session.servername).to.equal('teretere2'); | ||
secureCount++; | ||
done(); | ||
}, | ||
onConnect(session, done) { | ||
done(); | ||
} | ||
}); | ||
server.listen(PORT, '127.0.0.1'); | ||
let connection = new Client({ | ||
port: PORT, | ||
host: '127.0.0.1', | ||
secure: false, | ||
tls: { | ||
rejectUnauthorized: false, | ||
servername: 'teretere2' | ||
} | ||
}); | ||
connection.connect(function () { | ||
setTimeout(() => { | ||
connection.quit(); | ||
server.close(() => { | ||
expect(secureCount).to.equal(1); | ||
done(); | ||
}); | ||
}, 100); | ||
}); | ||
connection.on('error', err => { | ||
server.close(() => done(err)); | ||
}); | ||
}); | ||
}); | ||
it('onSecure is not triggered for cleartext connections', function (done) { | ||
let server; | ||
pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => { | ||
if (err) { | ||
return done(err); | ||
} | ||
let secureCount = 0; | ||
server = new SMTPServer({ | ||
secure: false, | ||
logger: false, | ||
key: keys.serviceKey, | ||
cert: keys.certificate, | ||
onSecure(socket, session, done) { | ||
expect(session).to.exist; | ||
expect(session.servername).to.equal('teretere2'); | ||
secureCount++; | ||
done(); | ||
}, | ||
onConnect(session, done) { | ||
done(); | ||
} | ||
}); | ||
server.listen(PORT, '127.0.0.1'); | ||
let connection = new Client({ | ||
port: PORT, | ||
host: '127.0.0.1', | ||
secure: false, | ||
ignoreTLS: true, | ||
tls: { | ||
rejectUnauthorized: false, | ||
servername: 'teretere2' | ||
} | ||
}); | ||
connection.connect(function () { | ||
setTimeout(() => { | ||
connection.quit(); | ||
server.close(() => { | ||
expect(secureCount).to.equal(0); | ||
done(); | ||
}); | ||
}, 100); | ||
}); | ||
connection.on('error', err => { | ||
server.close(() => done(err)); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
[ | ||
"aaa", | ||
"aarp", | ||
"abarth", | ||
"abb", | ||
@@ -39,3 +38,2 @@ "abbott", | ||
"al", | ||
"alfaromeo", | ||
"alibaba", | ||
@@ -282,3 +280,2 @@ "alipay", | ||
"cooking", | ||
"cookingchannel", | ||
"cool", | ||
@@ -415,3 +412,2 @@ "coop", | ||
"fi", | ||
"fiat", | ||
"fidelity", | ||
@@ -442,3 +438,2 @@ "fido", | ||
"food", | ||
"foodnetwork", | ||
"football", | ||
@@ -549,3 +544,2 @@ "ford", | ||
"hermes", | ||
"hgtv", | ||
"hiphop", | ||
@@ -685,3 +679,2 @@ "hisamitsu", | ||
"lancaster", | ||
"lancia", | ||
"land", | ||
@@ -717,3 +710,2 @@ "landrover", | ||
"lincoln", | ||
"linde", | ||
"link", | ||
@@ -749,3 +741,2 @@ "lipsy", | ||
"ma", | ||
"macys", | ||
"madrid", | ||
@@ -764,3 +755,2 @@ "maif", | ||
"marshalls", | ||
"maserati", | ||
"mattel", | ||
@@ -1214,3 +1204,2 @@ "mba", | ||
"travel", | ||
"travelchannel", | ||
"travelers", | ||
@@ -1217,0 +1206,0 @@ "travelersinsurance", |
{ | ||
"name": "tlds", | ||
"version": "1.236.0", | ||
"version": "1.240.0", | ||
"description": "A list of TLDs.", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/stephenmathieson/node-tlds.git", |
{ | ||
"name": "node-red-node-email", | ||
"version": "2.0.1", | ||
"version": "2.1.0", | ||
"description": "Node-RED nodes to send and receive simple emails.", | ||
"dependencies": { | ||
"imap": "^0.8.19", | ||
"node-pop3": "^0.8.0", | ||
"node-pop3": "^0.9.0", | ||
"mailparser": "^3.6.4", | ||
"nodemailer": "^6.9.3", | ||
"smtp-server": "^3.12.0" | ||
"nodemailer": "^6.9.7", | ||
"smtp-server": "^3.13.0" | ||
}, | ||
@@ -12,0 +12,0 @@ "bundledDependencies": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
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
7920611
22.86%710
1.43%104568
0.55%37
-2.63%Updated
Updated
Updated