wildduck/imap-core/lib/handler/imap-compiler.js
2017-06-03 09:51:58 +03:00

120 lines
3.4 KiB
JavaScript

/* eslint no-console: 0, new-cap: 0 */
'use strict';
const imapFormalSyntax = require('./imap-formal-syntax');
/**
* Compiles an input object into
*/
module.exports = function(response, asArray, isLogging) {
let respParts = [];
let resp = (response.tag || '') + (response.command ? ' ' + response.command : '');
let val;
let lastType;
let walk = function(node) {
if (lastType === 'LITERAL' || (['(', '<', '['].indexOf(resp.substr(-1)) < 0 && resp.length)) {
resp += ' ';
}
if (node && node.buffer && !Buffer.isBuffer(node)) {
// mongodb binary
node = node.buffer;
}
if (Array.isArray(node)) {
lastType = 'LIST';
resp += '(';
node.forEach(walk);
resp += ')';
return;
}
if (!node && typeof node !== 'string' && typeof node !== 'number' && !Buffer.isBuffer(node)) {
resp += 'NIL';
return;
}
if (typeof node === 'string' || Buffer.isBuffer(node)) {
if (isLogging && node.length > 20) {
resp += '"(* ' + node.length + 'B string *)"';
} else {
resp += JSON.stringify(node.toString('binary'));
}
return;
}
if (typeof node === 'number') {
resp += Math.round(node) || 0; // Only integers allowed
return;
}
lastType = node.type;
if (isLogging && node.sensitive) {
resp += '"(* value hidden *)"';
return;
}
switch (node.type.toUpperCase()) {
case 'LITERAL':
if (isLogging) {
resp += '"(* ' + node.value.length + 'B literal *)"';
} else {
if (!node.value) {
resp += '{0}\r\n';
} else {
resp += '{' + node.value.length + '}\r\n';
}
respParts.push(resp);
resp = (node.value || '').toString('binary');
}
break;
case 'STRING':
if (isLogging && node.value.length > 20) {
resp += '"(* ' + node.value.length + 'B string *)"';
} else {
resp += JSON.stringify(node.value || '');
}
break;
case 'TEXT':
case 'SEQUENCE':
resp += (node.value || '').toString('binary');
break;
case 'NUMBER':
resp += node.value || 0;
break;
case 'ATOM':
case 'SECTION':
val = (node.value || '').toString('binary');
if (imapFormalSyntax.verify(val.charAt(0) === '\\' ? val.substr(1) : val, imapFormalSyntax['ATOM-CHAR']()) >= 0) {
val = JSON.stringify(val);
}
resp += val;
if (node.section) {
resp += '[';
node.section.forEach(walk);
resp += ']';
}
if (node.partial) {
resp += '<' + node.partial.join('.') + '>';
}
break;
}
};
[].concat(response.attributes || []).forEach(walk);
if (resp.length) {
respParts.push(resp);
}
return asArray ? respParts : respParts.join('');
};