Comparing version 0.8.3 to 0.8.4
@@ -23,2 +23,3 @@ var tls = require('tls'), | ||
'BODYSTRUCTURE': 'struct', | ||
'ENVELOPE': 'envelope', | ||
'INTERNALDATE': 'date' | ||
@@ -209,3 +210,4 @@ }, | ||
&& self._config.keepalive | ||
&& self.state === 'authenticated') { | ||
&& self.state === 'authenticated' | ||
&& !self._idle.enabled) { | ||
self._idle.enabled = true; | ||
@@ -264,4 +266,9 @@ self._doKeepaliveTimer(true); | ||
options.flags = [options.flags]; | ||
if (options.flags.length > 0) | ||
cmd += ' (\\' + options.flags.join(' \\') + ')'; | ||
if (options.flags.length > 0) { | ||
for (var i = 0, len = options.flags.length; i < len; ++i) { | ||
if (options.flags[i][0] !== '\\') | ||
options.flags[i] = '\\' + options.flags[i]; | ||
} | ||
cmd += ' (' + options.flags.join(' ') + ')'; | ||
} | ||
} | ||
@@ -307,2 +314,25 @@ if (options.date) { | ||
Connection.prototype.id = function(identification, cb) { | ||
if (!this.serverSupports('ID')) | ||
throw new Error('Server does not support ID'); | ||
var cmd = 'ID'; | ||
if ((identification === null) || (Object.keys(identification).length === 0)) | ||
cmd += ' NIL'; | ||
else { | ||
if (Object.keys(identification).length > 30) | ||
throw new Error('Max allowed number of keys is 30'); | ||
var kv = []; | ||
for (var k in identification) { | ||
if (Buffer.byteLength(k) > 30) | ||
throw new Error('Max allowed key length is 30'); | ||
if (Buffer.byteLength(identification[k]) > 1024) | ||
throw new Error('Max allowed value length is 1024'); | ||
kv.push('"' + escape(k) + '"'); | ||
kv.push('"' + escape(identification[k]) + '"'); | ||
} | ||
cmd += ' (' + kv.join(' ') + ')'; | ||
} | ||
this._enqueue(cmd, cb); | ||
}; | ||
Connection.prototype.openBox = function(name, readOnly, cb) { | ||
@@ -387,8 +417,2 @@ if (this.state !== 'authenticated') | ||
Connection.prototype.renameBox = function(oldname, newname, cb) { | ||
var destname = newname; | ||
if (this._box | ||
&& oldname === this._box.name | ||
&& oldname.toUpperCase() !== 'INBOX') | ||
destname = ''+oldname; | ||
var encoldname = escape(utf7.encode(''+oldname)), | ||
@@ -402,4 +426,10 @@ encnewname = escape(utf7.encode(''+newname)), | ||
return cb(err); | ||
self._box.name = destname; | ||
cb(err, self._box); | ||
if (self._box | ||
&& self._box.name === oldname | ||
&& oldname.toUpperCase() !== 'INBOX') { | ||
self._box.name = newname; | ||
cb(err, self._box); | ||
} else | ||
cb(); | ||
} | ||
@@ -441,4 +471,3 @@ ); | ||
this._enqueue('STATUS "' + boxName + '" (' + info + ')', | ||
cb); | ||
this._enqueue('STATUS "' + boxName + '" (' + info + ')', cb); | ||
}; | ||
@@ -459,2 +488,5 @@ | ||
if (!this.serverSupports('UIDPLUS')) | ||
throw new Error('Server does not support this feature (UIDPLUS)'); | ||
this._enqueue('UID EXPUNGE ' + uids, cb); | ||
@@ -575,4 +607,3 @@ } else | ||
this._enqueue(which + 'COPY ' + uids.join(',') + ' "' | ||
+ boxTo + '"', cb); | ||
this._enqueue(which + 'COPY ' + uids.join(',') + ' "' + boxTo + '"', cb); | ||
}; | ||
@@ -696,2 +727,4 @@ | ||
modifiers = options.modifiers; | ||
if (options.envelope) | ||
fetching.push('ENVELOPE'); | ||
if (options.struct) | ||
@@ -837,3 +870,3 @@ fetching.push('BODYSTRUCTURE'); | ||
Connection.prototype.esearch = function(criteria, options, cb) { | ||
this._search('UID ', criteria, options, cb); | ||
this._esearch('UID ', criteria, options, cb); | ||
}; | ||
@@ -852,3 +885,3 @@ | ||
if (info.hasUTF8) { | ||
charset = 'CHARSET UTF-8'; | ||
charset = ' CHARSET UTF-8'; | ||
lines = query.split(CRLF); | ||
@@ -867,3 +900,3 @@ query = lines.shift(); | ||
this._enqueue(which + 'SEARCH RETURN (' + options + ') ' + charset + query, cb); | ||
this._enqueue(which + 'SEARCH RETURN (' + options + ')' + charset + query, cb); | ||
if (info.hasUTF8) { | ||
@@ -1104,2 +1137,4 @@ var req = this._queue[this._queue.length - 1]; | ||
this.namespaces = info.text; | ||
else if (type === 'id') | ||
this._curReq.cbargs.push(info.text); | ||
else if (type === 'capability') | ||
@@ -1109,3 +1144,3 @@ this._caps = info.text.map(function(v) { return v.toUpperCase(); }); | ||
this.state = 'authenticated'; | ||
else if (type === 'sort' || type === 'thread') | ||
else if (type === 'sort' || type === 'thread' || type === 'esearch') | ||
this._curReq.cbargs.push(info.text); | ||
@@ -1167,3 +1202,3 @@ else if (type === 'search') { | ||
else if (this._curReq | ||
&& typeof info.textCode === 'object' | ||
&& info.textCode | ||
&& (RE_OPENBOX.test(this._curReq.type))) { | ||
@@ -1175,3 +1210,6 @@ // we're opening a mailbox | ||
key = info.textCode.key.toUpperCase(); | ||
if (info.textCode.key) | ||
key = info.textCode.key.toUpperCase(); | ||
else | ||
key = info.textCode; | ||
@@ -1196,3 +1234,4 @@ if (key === 'UIDVALIDITY') | ||
permFlags.splice(permFlags.indexOf(keywords[i]), 1); | ||
} | ||
} else if (key === 'UIDNOTSTICKY') | ||
this._box.persistentUIDs = false; | ||
} else if (typeof info.textCode === 'string' | ||
@@ -1350,3 +1389,3 @@ && info.textCode.toUpperCase() === 'UIDVALIDITY') | ||
if (info.text) | ||
errtext = info.text; | ||
errtext = info.text; | ||
else | ||
@@ -1380,2 +1419,9 @@ errtext = req.oauthError; | ||
req.cbargs.unshift(err); | ||
if (info.textCode && info.textCode.key) { | ||
var key = info.textCode.key.toUpperCase(); | ||
if (key === 'APPENDUID') // [uidvalidity, newUID] | ||
req.cbargs.push(info.textCode.val[1]); | ||
else if (key === 'COPYUID') // [uidvalidity, sourceUIDs, destUIDs] | ||
req.cbargs.push(info.textCode.val[2]); | ||
} | ||
req.cb && req.cb.apply(this, req.cbargs); | ||
@@ -1386,3 +1432,4 @@ } | ||
&& this._config.keepalive | ||
&& this.state === 'authenticated') { | ||
&& this.state === 'authenticated' | ||
&& !this._idle.enabled) { | ||
this._idle.enabled = true; | ||
@@ -1405,2 +1452,3 @@ this._doKeepaliveTimer(true); | ||
newKeywords: false, | ||
persistentUIDs: true, | ||
messages: { | ||
@@ -1602,3 +1650,4 @@ total: 0, | ||
&& this._sock | ||
&& this._sock.writable) { | ||
&& this._sock.writable | ||
&& this._idle.enabled) { | ||
this._idle.enabled = false; | ||
@@ -1681,3 +1730,6 @@ this.debug && this.debug('=> DONE'); | ||
throw new Error('OR must have exactly two arguments'); | ||
searchargs += ' OR ('; | ||
if (isOrChild) | ||
searchargs += 'OR ('; | ||
else | ||
searchargs += ' OR ('; | ||
searchargs += buildSearchQuery(args[0], extensions, info, true); | ||
@@ -1684,0 +1736,0 @@ searchargs += ') ('; |
@@ -17,3 +17,3 @@ var EventEmitter = require('events').EventEmitter, | ||
RE_LITERAL = /\{(\d+)\}$/, | ||
RE_UNTAGGED = /^\* (?:(OK|NO|BAD|BYE|FLAGS|LIST|LSUB|SEARCH|STATUS|CAPABILITY|NAMESPACE|PREAUTH|SORT|THREAD|ESEARCH|QUOTA|QUOTAROOT)|(\d+) (EXPUNGE|FETCH|RECENT|EXISTS))(?: (?:\[([^\]]+)\] )?(.+))?$/i, | ||
RE_UNTAGGED = /^\* (?:(OK|NO|BAD|BYE|FLAGS|ID|LIST|LSUB|SEARCH|STATUS|CAPABILITY|NAMESPACE|PREAUTH|SORT|THREAD|ESEARCH|QUOTA|QUOTAROOT)|(\d+) (EXPUNGE|FETCH|RECENT|EXISTS))(?: (?:\[([^\]]+)\] )?(.+))?$/i, | ||
RE_TAGGED = /^A(\d+) (OK|NO|BAD) (?:\[([^\]]+)\] )?(.+)$/i, | ||
@@ -253,2 +253,4 @@ RE_CONTINUE = /^\+(?: (?:\[([^\]]+)\] )?(.+))?$/i, | ||
val = parseBoxList(m[5], this._literals); | ||
else if (type === 'id') | ||
val = parseId(m[5], this._literals); | ||
else if (type === 'status') | ||
@@ -312,3 +314,3 @@ val = parseStatus(m[5], this._literals); | ||
else | ||
return { key: r[0], val: r[1] }; | ||
return { key: r[0], val: r.length === 2 ? r[1] : r.slice(1) }; | ||
} | ||
@@ -335,2 +337,13 @@ | ||
function parseId(text, literals) { | ||
var r = parseExpr(text, literals), | ||
id = {}; | ||
if (r[0] === null) | ||
return null; | ||
for (var i = 0, len = r[0].length; i < len; i += 2) | ||
id[r[0][i].toLowerCase()] = r[0][i + 1]; | ||
return id; | ||
} | ||
function parseQuota(text, literals) { | ||
@@ -562,3 +575,3 @@ var r = parseExpr(text, literals), | ||
date: new Date(list[0]), | ||
subject: list[1], | ||
subject: decodeWords(list[1], { buffer: undefined, encoding: undefined, consecutive: false, replaces: undefined, curReplace: undefined }), | ||
from: parseEnvelopeAddresses(list[2]), | ||
@@ -790,3 +803,3 @@ sender: parseEnvelopeAddresses(list[3]), | ||
var bytes, m, i, len, j, lenj, seq; | ||
var bytes, m, i, j, lenj, seq; | ||
// generate replacement substrings and their positions | ||
@@ -793,0 +806,0 @@ while (m = RE_ENCWORD.exec(str)) { |
{ "name": "imap", | ||
"version": "0.8.3", | ||
"version": "0.8.4", | ||
"author": "Brian White <mscdex@mscdex.net>", | ||
@@ -8,3 +8,3 @@ "description": "An IMAP module for node.js that makes communicating with IMAP servers easy", | ||
"utf7": "1.0.0", | ||
"readable-stream": "1.1.7" | ||
"readable-stream": "1.1.9" | ||
}, | ||
@@ -11,0 +11,0 @@ "scripts": { |
106
README.md
@@ -8,3 +8,5 @@ Description | ||
An upgrade guide from node-imap v0.7.x to v0.8.x can be found [here](https://github.com/mscdex/node-imap/wiki/API-changes-between-v0.7-and-v0.8). | ||
Requirements | ||
@@ -193,2 +195,3 @@ ============ | ||
* **permFlags** - _array_ - A list of flags that can be permanently added/removed to/from messages in this mailbox. | ||
* **persistentUIDs** - _boolean_ - Whether or not this mailbox has persistent UIDs. This should almost always be true for modern mailboxes and should only be false for legacy mail stores where supporting persistent UIDs was not technically feasible. | ||
* **messages** - _object_ - Contains various message counts for this mailbox: | ||
@@ -207,3 +210,3 @@ * **total** - _integer_ - Total number of messages in this mailbox. | ||
* **flags** - _array_ - A list of flags currently set on this message. | ||
* **date** - _string_ - The internal server date for the message. | ||
* **date** - _Date_ - The internal server date for the message. | ||
* **struct** - _array_ - The message's body structure **(only set if requested with fetch())**. See below for an explanation of the format of this property. | ||
@@ -422,3 +425,3 @@ * **size** - _integer_ - The RFC822 message size **(only set if requested with fetch())**. | ||
* **getBoxes**([< _string_ >nsPrefix,] < _function_ >callback) - _(void)_ - Obtains the full list of mailboxes. If `nsPrefix` is not specified, the main personal namespace is used. `callback` has 2 parameters: < _Error_ >err, < _object_ >boxes. `boxes` has the following format (with example values): | ||
* **getBoxes**([< _string_ >nsPrefix, ]< _function_ >callback) - _(void)_ - Obtains the full list of mailboxes. If `nsPrefix` is not specified, the main personal namespace is used. `callback` has 2 parameters: < _Error_ >err, < _object_ >boxes. `boxes` has the following format (with example values): | ||
@@ -492,11 +495,11 @@ ```javascript | ||
* **getSubscribedBoxes**([< _string_ >nsPrefix,] < _function_ >callback) - _(void)_ - Obtains the full list of subscribed mailboxes. If `nsPrefix` is not specified, the main personal namespace is used. `callback` has 2 parameters: < _Error_ >err, < _object_ >boxes. `boxes` has the same format as getBoxes above. | ||
* **getSubscribedBoxes**([< _string_ >nsPrefix, ]< _function_ >callback) - _(void)_ - Obtains the full list of subscribed mailboxes. If `nsPrefix` is not specified, the main personal namespace is used. `callback` has 2 parameters: < _Error_ >err, < _object_ >boxes. `boxes` has the same format as getBoxes above. | ||
* **expunge**(< _function_ >callback) - _(void)_ - Permanently removes all messages flagged as Deleted in the currently open mailbox. `callback` has 1 parameter: < _Error_ >err. **Note:** At least on Gmail, performing this operation with any currently open mailbox that is not the Spam or Trash mailbox will merely archive any messages marked as Deleted (by moving them to the 'All Mail' mailbox). | ||
* **expunge**([< _MessageSource_ >uids, ]< _function_ >callback) - _(void)_ - Permanently removes all messages flagged as Deleted in the currently open mailbox. If the server supports the 'UIDPLUS' capability, `uids` can be supplied to only remove messages that both have their uid in `uids` and have the \Deleted flag set. `callback` has 1 parameter: < _Error_ >err. **Note:** At least on Gmail, performing this operation with any currently open mailbox that is not the Spam or Trash mailbox will merely archive any messages marked as Deleted (by moving them to the 'All Mail' mailbox). | ||
* **append**(< _mixed_ >msgData, [< _object_ >options,] < _function_ >callback) - _(void)_ - Appends a message to selected mailbox. `msgData` is a string or Buffer containing an RFC-822 compatible MIME message. Valid `options` properties are: | ||
* **append**(< _mixed_ >msgData, [< _object_ >options, ]< _function_ >callback) - _(void)_ - Appends a message to selected mailbox. `msgData` is a string or Buffer containing an RFC-822 compatible MIME message. Valid `options` properties are: | ||
* **mailbox** - _string_ - The name of the mailbox to append the message to. **Default:** the currently open mailbox | ||
* **flags** - _mixed_ - A single flag (e.g. 'Seen') or an _array_ of flags (e.g. `['Seen', 'Flagged']`) to append to the message. **Default:** (no flags) | ||
* **date** - _date_ - What to use for message arrival date/time. **Default:** (current date/time) | ||
* **date** - _Date_ - What to use for message arrival date/time. **Default:** (current date/time) | ||
@@ -575,2 +578,3 @@ `callback` has 1 parameter: < _Error_ >err. | ||
* **struct** - _boolean_ - Fetch the message structure. **Default:** false | ||
* **envelope** - _boolean_ - Fetch the message envelope. **Default:** false | ||
* **size** - _boolean_ - Fetch the RFC822 size. **Default:** false | ||
@@ -581,4 +585,4 @@ * **modifiers** - _object_ - Fetch modifiers defined by IMAP extensions. **Default:** (none) | ||
* 'HEADER' - The message header | ||
* 'HEADER.FIELDS(TO FROM SUBJECT)' - Specific header fields only | ||
* 'HEADER.FIELDS.NOT(TO FROM SUBJECT)' - Header fields only that do not match the fields given | ||
* 'HEADER.FIELDS (TO FROM SUBJECT)' - Specific header fields only | ||
* 'HEADER.FIELDS.NOT (TO FROM SUBJECT)' - Header fields only that do not match the fields given | ||
* 'TEXT' - The message body | ||
@@ -588,4 +592,4 @@ * '' - The entire message (header + body) | ||
**Note:** You can also prefix `bodies` strings with part ids for multipart messages (e.g. '1.TEXT', '1.2.TEXT', '2.MIME', etc) | ||
**Note 2:** 'HEADER*' sections are only valid for parts whose content type is 'message/rfc822', including the root part. | ||
**Note:** You can also prefix `bodies` strings (i.e. 'TEXT', 'HEADER', 'HEADER.FIELDS', and 'HEADER.FIELDS.NOT' for `message/rfc822` messages and 'MIME' for any kind of message) with part ids. For example: '1.TEXT', '1.2.HEADER', '2.MIME', etc. | ||
**Note 2:** 'HEADER*' sections are only valid for parts whose content type is `message/rfc822`, including the root part (no part id). | ||
@@ -635,39 +639,2 @@ * **copy**(< _MessageSource_ >source, < _string_ >mailboxName, < _function_ >callback) - _(void)_ - Copies message(s) in the currently open mailbox to another mailbox. `callback` has 1 parameter: < _Error_ >err. | ||
* **RFC5256** | ||
* Server capability: SORT | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **sort**(< _array_ >sortCriteria, < _array_ >searchCriteria, < _function_ >callback) - _(void)_ - Performs a sorted search(). A seqno-based counterpart also exists for this function. `callback` has 2 parameters: < _Error_ >err, < _array_ >UIDs. Valid `sortCriteria` are (reverse sorting of individual criteria is done by prefixing the criteria with '-'): | ||
* 'ARRIVAL' - Internal date and time of the message. This differs from the ON criteria in search(), which uses just the internal date. | ||
* 'CC' - The mailbox of the **first** "cc" address. | ||
* 'DATE' - Message sent date and time. | ||
* 'FROM' - The mailbox of the **first** "from" address. | ||
* 'SIZE' - Size of the message in octets. | ||
* 'SUBJECT' - Base subject text. | ||
* 'TO' - The mailbox of the **first** "to" address. | ||
* Server capability: THREAD=REFERENCES, THREAD=ORDEREDSUBJECT | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **thread**(< _string_ >algorithm, < _array_ >searchCriteria, < _function_ >callback) - _(void)_ - Performs a regular search with `searchCriteria` and groups the resulting search results using the given `algorithm` (e.g. 'references', 'orderedsubject'). `callback` has 2 parameters: < _Error_ >err, < _array_ >UIDs. `UIDs` is a nested array. | ||
* **RFC4731** | ||
* Server capability: ESEARCH | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **esearch**(< _array_ >criteria, < _array_ >options, < _function_ >callback) - _(void)_ - A variant of search() that can return metadata about results. `callback` has 2 parameters: < _Error_ >err, < _object_ >info. `info` has possible keys: 'all', 'min', 'max', 'count'. Valid `options`: | ||
* 'ALL' - Retrieves UIDs in a compact form (e.g. [2, '10:11'] instead of search()'s [2, 10, 11]) that match the criteria. | ||
* 'MIN' - Retrieves the lowest UID that satisfies the criteria. | ||
* 'MAX' - Retrieves the highest UID that satisfies the criteria. | ||
* 'COUNT' - Retrieves the number of messages that satisfy the criteria. | ||
**Note:** specifying no `options` or [] for `options` is the same as ['ALL'] | ||
* **RFC2087** | ||
@@ -703,2 +670,10 @@ | ||
* **RFC4315** | ||
* Server capability: UIDPLUS | ||
* The callback passed to append() will receive an additional argument (the UID of the appended message): < _integer_ >appendedUID. | ||
* The callback passed to append()/seq.append() will receive an additional argument (the UID(s) of the copied message(s) in the destination mailbox): < _mixed_ >newUIDs. `newUIDs` can be an integer if just one message was copied, or a string for multiple messages (e.g. '100:103' or '100,125,130' or '100,200:201'). | ||
* **RFC4551** | ||
@@ -740,4 +715,41 @@ | ||
* **RFC4731** | ||
* Server capability: ESEARCH | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **esearch**(< _array_ >criteria, < _array_ >options, < _function_ >callback) - _(void)_ - A variant of search() that can return metadata about results. `callback` has 2 parameters: < _Error_ >err, < _object_ >info. `info` has possible keys: 'all', 'min', 'max', 'count'. Valid `options`: | ||
* 'ALL' - Retrieves UIDs in a compact form (e.g. [2, '10:11'] instead of search()'s [2, 10, 11]) that match the criteria. | ||
* 'MIN' - Retrieves the lowest UID that satisfies the criteria. | ||
* 'MAX' - Retrieves the highest UID that satisfies the criteria. | ||
* 'COUNT' - Retrieves the number of messages that satisfy the criteria. | ||
**Note:** specifying no `options` or [] for `options` is the same as ['ALL'] | ||
* **RFC5256** | ||
* Server capability: SORT | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **sort**(< _array_ >sortCriteria, < _array_ >searchCriteria, < _function_ >callback) - _(void)_ - Performs a sorted search(). A seqno-based counterpart also exists for this function. `callback` has 2 parameters: < _Error_ >err, < _array_ >UIDs. Valid `sortCriteria` are (reverse sorting of individual criteria is done by prefixing the criteria with '-'): | ||
* 'ARRIVAL' - Internal date and time of the message. This differs from the ON criteria in search(), which uses just the internal date. | ||
* 'CC' - The mailbox of the **first** "cc" address. | ||
* 'DATE' - Message sent date and time. | ||
* 'FROM' - The mailbox of the **first** "from" address. | ||
* 'SIZE' - Size of the message in octets. | ||
* 'SUBJECT' - Base subject text. | ||
* 'TO' - The mailbox of the **first** "to" address. | ||
* Server capability: THREAD=REFERENCES, THREAD=ORDEREDSUBJECT | ||
* Additional Connection instance methods (seqno-based counterpart exists): | ||
* **thread**(< _string_ >algorithm, < _array_ >searchCriteria, < _function_ >callback) - _(void)_ - Performs a regular search with `searchCriteria` and groups the resulting search results using the given `algorithm` (e.g. 'references', 'orderedsubject'). `callback` has 2 parameters: < _Error_ >err, < _array_ >UIDs. `UIDs` is a nested array. | ||
TODO | ||
@@ -744,0 +756,0 @@ ---- |
772700
7610
753
+ Addedreadable-stream@1.1.9(transitive)
- Removedreadable-stream@1.1.7(transitive)
Updatedreadable-stream@1.1.9