@ -68,6 +68,9 @@ function ImapConnection (options) {
util . inherits ( ImapConnection , EventEmitter ) ;
exports . ImapConnection = ImapConnection ;
/* Namespace for seqno-based commands */
ImapConnection . prototype . seq = { } ;
ImapConnection . prototype . connect = function ( loginCb ) {
var self = this ,
fnInit = function ( ) {
@ -599,16 +602,28 @@ ImapConnection.prototype.renameBox = function(oldname, newname, cb) {
this . _send ( 'RENAME "' + escape ( oldname ) + '" "' + escape ( newname ) + '"' , cb ) ;
} ;
ImapConnection . prototype . seq . search = function ( options , cb ) {
this . _search ( '' , options , cb ) ;
} ;
ImapConnection . prototype . search = function ( options , cb ) {
this . _search ( 'UID ' , options , cb ) ;
} ;
ImapConnection . prototype . _search = function ( which , options , cb ) {
if ( this . _state . status !== STATES . BOXSELECTED )
throw new Error ( 'No mailbox is currently selected' ) ;
if ( ! Array . isArray ( options ) )
throw new Error ( 'Expected array for search options' ) ;
this . _send ( ' UID SEARCH'
this . _send ( which + ' SEARCH'
+ buildSearchQuery ( options , this . capabilities ) , cb ) ;
} ;
ImapConnection . prototype . seq . fetch = function ( seqnos , options ) {
return this . _fetch ( '' , seqnos , options ) ;
} ;
ImapConnection . prototype . fetch = function ( uids , options ) {
return this . _fetch ( 'UID ' , uids , options ) ;
} ;
ImapConnection . prototype . _fetch = function ( which , uids , options ) {
if ( this . _state . status !== STATES . BOXSELECTED )
throw new Error ( 'No mailbox is currently selected' ) ;
@ -618,11 +633,7 @@ ImapConnection.prototype.fetch = function(uids, options) {
if ( ! Array . isArray ( uids ) )
uids = [ uids ] ;
try {
validateUIDList ( uids ) ;
} catch ( e ) {
throw e ;
}
validateUIDList ( uids ) ;
var opts = {
markSeen : false ,
@ -630,7 +641,7 @@ ImapConnection.prototype.fetch = function(uids, options) {
struct : true ,
headers : true , // \_______ at most one of these can be used for any given
// _______ fetch request
body : false // /
body : false // /
}
} , toFetch , bodyRange = '' , self = this ;
if ( typeof options !== 'object' )
@ -679,7 +690,8 @@ ImapConnection.prototype.fetch = function(uids, options) {
if ( this . capabilities . indexOf ( 'X-GM-EXT-1' ) > - 1 )
extensions = 'X-GM-THRID X-GM-MSGID X-GM-LABELS ' ;
this . _send ( 'UID FETCH ' + uids . join ( ',' ) + ' (' + extensions + 'FLAGS INTERNALDATE'
this . _send ( which + 'FETCH ' + uids . join ( ',' ) + ' (' + extensions
+ 'FLAGS INTERNALDATE'
+ ( opts . request . struct ? ' BODYSTRUCTURE' : '' )
+ ( typeof toFetch === 'string' ? ' BODY'
+ ( ! opts . markSeen ? '.PEEK' : '' )
@ -698,54 +710,64 @@ ImapConnection.prototype.fetch = function(uids, options) {
return imapFetcher ;
} ;
ImapConnection . prototype . seq . addFlags = function ( seqnos , flags , cb ) {
this . _store ( '' , seqnos , flags , true , cb ) ;
} ;
ImapConnection . prototype . addFlags = function ( uids , flags , cb ) {
try {
this . _store ( uids , flags , true , cb ) ;
} catch ( err ) {
throw err ;
}
this . _store ( 'UID ' , uids , flags , true , cb ) ;
} ;
ImapConnection . prototype . seq . delFlags = function ( seqnos , flags , cb ) {
this . _store ( '' , seqnos , flags , false , cb ) ;
} ;
ImapConnection . prototype . delFlags = function ( uids , flags , cb ) {
try {
this . _store ( uids , flags , false , cb ) ;
} catch ( err ) {
throw err ;
}
this . _store ( 'UID ' , uids , flags , false , cb ) ;
} ;
ImapConnection . prototype . seq . addKeywords = function ( seqnos , flags , cb ) {
return this . _addKeywords ( '' , seqnos , flags , cb ) ;
} ;
ImapConnection . prototype . addKeywords = function ( uids , flags , cb ) {
return this . _addKeywords ( 'UID ' , uids , flags , cb ) ;
} ;
ImapConnection . prototype . _addKeywords = function ( which , uids , flags , cb ) {
if ( ! this . _state . box . _newKeywords )
throw new Error ( 'This mailbox does not allow new keywords to be added' ) ;
try {
this . _store ( uids , flags , true , cb ) ;
} catch ( err ) {
throw err ;
}
this . _store ( which , uids , flags , true , cb ) ;
} ;
ImapConnection . prototype . seq . delKeywords = function ( seqnos , flags , cb ) {
this . _store ( '' , seqnos , flags , false , cb ) ;
} ;
ImapConnection . prototype . delKeywords = function ( uids , flags , cb ) {
try {
this . _store ( uids , flags , false , cb ) ;
} catch ( err ) {
throw err ;
}
this . _store ( 'UID ' , uids , flags , false , cb ) ;
} ;
ImapConnection . prototype . seq . copy = function ( seqnos , boxTo , cb ) {
return this . _copy ( '' , seqnos , boxTo , cb ) ;
} ;
ImapConnection . prototype . copy = function ( uids , boxTo , cb ) {
return this . _copy ( 'UID ' , uids , boxTo , cb ) ;
} ;
ImapConnection . prototype . _copy = function ( which , uids , boxTo , cb ) {
if ( this . _state . status !== STATES . BOXSELECTED )
throw new Error ( 'No mailbox is currently selected' ) ;
if ( ! Array . isArray ( uids ) )
uids = [ uids ] ;
try {
validateUIDList ( uids ) ;
} catch ( e ) {
throw e ;
}
this . _send ( 'UID COPY ' + uids . join ( ',' ) + ' "' + escape ( boxTo ) + '"' , cb ) ;
validateUIDList ( uids ) ;
this . _send ( which + 'COPY ' + uids . join ( ',' ) + ' "' + escape ( boxTo ) + '"' , cb ) ;
} ;
ImapConnection . prototype . seq . move = function ( seqnos , boxTo , cb ) {
return this . _move ( '' , seqnos , boxTo , cb ) ;
} ;
ImapConnection . prototype . move = function ( uids , boxTo , cb ) {
return this . _move ( 'UID ' , uids , boxTo , cb ) ;
} ;
ImapConnection . prototype . _move = function ( which , uids , boxTo , cb ) {
var self = this ;
if ( this . _state . status !== STATES . BOXSELECTED )
throw new Error ( 'No mailbox is currently selected' ) ;
@ -753,7 +775,8 @@ ImapConnection.prototype.move = function(uids, boxTo, cb) {
throw new Error ( 'Cannot move message: '
+ 'server does not allow deletion of messages' ) ;
} else {
self . copy ( uids , boxTo , function ( err , reentryCount , deletedUIDs , counter ) {
self . _copy ( which , uids , boxTo , function ( err , reentryCount , deletedUIDs ,
counter ) {
if ( err ) {
cb ( err ) ;
return ;
@ -806,20 +829,18 @@ ImapConnection.prototype._fnTmrConn = function(loginCb) {
this . _state . conn . destroy ( ) ;
}
ImapConnection . prototype . _store = function ( uids, flags , isAdding , cb ) {
ImapConnection . prototype . _store = function ( which, uids, flags , isAdding , cb ) {
var isKeywords = ( arguments . callee . caller === this . addKeywords
|| arguments . callee . caller === this . delKeywords ) ;
if ( this . _state . status !== STATES . BOXSELECTED )
throw new Error ( 'No mailbox is currently selected' ) ;
if ( typeof uids === 'undefined' )
throw new Error ( 'The message ID(s) must be specified' ) ;
if ( ! Array . isArray ( uids ) )
uids = [ uids ] ;
try {
validateUIDList ( uids ) ;
} catch ( e ) {
throw e ;
}
validateUIDList ( uids ) ;
if ( ( ! Array . isArray ( flags ) && typeof flags !== 'string' )
|| ( Array . isArray ( flags ) && flags . length === 0 ) )
throw new Error ( ( isKeywords ? 'Keywords' : 'Flags' )
@ -846,7 +867,7 @@ ImapConnection.prototype._store = function(uids, flags, isAdding, cb) {
flags = flags . join ( ' ' ) ;
cb = arguments [ arguments . length - 1 ] ;
this . _send ( ' UID STORE ' + uids . join ( ',' ) + ' ' + ( isAdding ? '+' : '-' )
this . _send ( which + ' STORE ' + uids . join ( ',' ) + ' ' + ( isAdding ? '+' : '-' )
+ 'FLAGS.SILENT (' + flags + ')' , cb ) ;
} ;
@ -1046,11 +1067,7 @@ function buildSearchQuery(options, extensions, isOrChild) {
if ( ! args )
throw new Error ( 'Incorrect number of arguments for search option: '
+ criteria ) ;
try {
validateUIDList ( args ) ;
} catch ( e ) {
throw e ;
}
validateUIDList ( args ) ;
searchargs += modifier + criteria + ' ' + args . join ( ',' ) ;
break ;
// -- Extensions criteria --
@ -1107,7 +1124,7 @@ function validateUIDList(uids) {
}
intval = parseInt ( '' + uids [ i ] ) ;
if ( isNaN ( intval ) ) {
throw new Error ( 'Message ID must be an integer, "*", or a range: '
throw new Error ( 'Message ID /number must be an integer, "*", or a range: '
+ uids [ i ] ) ;
} else if ( typeof uids [ i ] !== 'number' )
uids [ i ] = intval ;