imapflow 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/commands/append.d.ts +1 -1
- package/dist/cjs/commands/append.js +15 -4
- package/dist/cjs/commands/compress.js +2 -2
- package/dist/cjs/commands/idle.js +2 -3
- package/dist/cjs/commands/status.js +2 -4
- package/dist/cjs/connection-deadline.d.ts +1 -1
- package/dist/cjs/connection-deadline.js +2 -4
- package/dist/cjs/download.js +22 -19
- package/dist/cjs/errors.d.ts +15 -0
- package/dist/cjs/errors.js +22 -0
- package/dist/cjs/handler/imap-compiler.d.ts +4 -4
- package/dist/cjs/handler/imap-compiler.js +18 -18
- package/dist/cjs/handler/imap-parser.js +28 -3
- package/dist/cjs/handler/imap-stream.js +9 -8
- package/dist/cjs/handler/limits.d.ts +1 -1
- package/dist/cjs/handler/limits.js +5 -7
- package/dist/cjs/handler/parser-instance.js +23 -38
- package/dist/cjs/handler/token-parser.d.ts +12 -0
- package/dist/cjs/handler/token-parser.js +44 -104
- package/dist/cjs/imap-flow.d.ts +4 -3
- package/dist/cjs/imap-flow.js +72 -72
- package/dist/cjs/package-info.d.ts +1 -1
- package/dist/cjs/package-info.js +1 -1
- package/dist/cjs/proxy-connection.js +2 -5
- package/dist/cjs/search-compiler.js +2 -3
- package/dist/cjs/tools.d.ts +2 -2
- package/dist/cjs/tools.js +8 -11
- package/dist/esm/commands/append.d.ts +1 -1
- package/dist/esm/commands/append.js +15 -4
- package/dist/esm/commands/compress.js +2 -2
- package/dist/esm/commands/idle.js +2 -3
- package/dist/esm/commands/status.js +2 -4
- package/dist/esm/connection-deadline.d.ts +1 -1
- package/dist/esm/connection-deadline.js +2 -4
- package/dist/esm/download.js +22 -19
- package/dist/esm/errors.d.ts +15 -0
- package/dist/esm/errors.js +21 -0
- package/dist/esm/handler/imap-compiler.d.ts +4 -4
- package/dist/esm/handler/imap-compiler.js +18 -18
- package/dist/esm/handler/imap-parser.js +28 -3
- package/dist/esm/handler/imap-stream.js +9 -8
- package/dist/esm/handler/limits.d.ts +1 -1
- package/dist/esm/handler/limits.js +5 -7
- package/dist/esm/handler/parser-instance.js +23 -38
- package/dist/esm/handler/token-parser.d.ts +12 -0
- package/dist/esm/handler/token-parser.js +44 -104
- package/dist/esm/imap-flow.d.ts +4 -3
- package/dist/esm/imap-flow.js +73 -73
- package/dist/esm/package-info.d.ts +1 -1
- package/dist/esm/package-info.js +1 -1
- package/dist/esm/proxy-connection.js +2 -5
- package/dist/esm/search-compiler.js +2 -3
- package/dist/esm/tools.d.ts +2 -2
- package/dist/esm/tools.js +9 -12
- package/package.json +3 -3
|
@@ -8,6 +8,7 @@ exports.ParserInstance = void 0;
|
|
|
8
8
|
const imap_formal_syntax_js_1 = __importDefault(require("./imap-formal-syntax.js"));
|
|
9
9
|
const token_parser_js_1 = require("./token-parser.js");
|
|
10
10
|
const limits_js_1 = require("./limits.js");
|
|
11
|
+
const errors_js_1 = require("../errors.js");
|
|
11
12
|
/**
|
|
12
13
|
* Parses a single IMAP response line into its structural components: tag, command,
|
|
13
14
|
* and attributes. Handles status responses (OK, NO, BAD, PREAUTH, BYE) with their
|
|
@@ -143,10 +144,7 @@ class ParserInstance {
|
|
|
143
144
|
async getElement(syntax) {
|
|
144
145
|
let match, element, errPos;
|
|
145
146
|
if (/^\s/.test(this.remainder)) {
|
|
146
|
-
|
|
147
|
-
error.code = 'ParserError1';
|
|
148
|
-
error.parserContext = this.errorContext();
|
|
149
|
-
throw error;
|
|
147
|
+
throw (0, errors_js_1.createImapError)(`Unexpected whitespace at position ${this.pos} [E1]`, 'ParserError1', { parserContext: this.errorContext() });
|
|
150
148
|
}
|
|
151
149
|
if ((match = this.remainder.match(/^\s*[^\s]+(?=\s|$)/))) {
|
|
152
150
|
element = match[0];
|
|
@@ -156,29 +154,24 @@ class ParserInstance {
|
|
|
156
154
|
// "Server Unavailable." instead of a proper IMAP tagged/untagged response.
|
|
157
155
|
// We detect this specific pattern and convert it into a synthetic BAD response
|
|
158
156
|
// so the rest of the parser can handle it gracefully.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
throw (0, errors_js_1.createImapError)(`Server returned an error: ${this.input}`, 'ParserErrorExchange', {
|
|
158
|
+
parserContext: {
|
|
159
|
+
...this.errorContext(element),
|
|
160
|
+
value: {
|
|
161
|
+
tag: '*',
|
|
162
|
+
command: 'BAD',
|
|
163
|
+
attributes: [{ type: 'TEXT', value: this.input }]
|
|
164
|
+
}
|
|
167
165
|
}
|
|
168
|
-
};
|
|
169
|
-
throw error;
|
|
166
|
+
});
|
|
170
167
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
throw error;
|
|
168
|
+
throw (0, errors_js_1.createImapError)(`Unexpected char at position ${this.pos + errPos} [E2: ${JSON.stringify(element.charAt(errPos))}]`, 'ParserError2', {
|
|
169
|
+
parserContext: this.errorContext(element)
|
|
170
|
+
});
|
|
175
171
|
}
|
|
176
172
|
}
|
|
177
173
|
else {
|
|
178
|
-
|
|
179
|
-
error.code = 'ParserError3';
|
|
180
|
-
error.parserContext = this.errorContext();
|
|
181
|
-
throw error;
|
|
174
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E3]`, 'ParserError3', { parserContext: this.errorContext() });
|
|
182
175
|
}
|
|
183
176
|
this.pos += match[0].length;
|
|
184
177
|
this.remainder = this.remainder.slice(match[0].length);
|
|
@@ -196,16 +189,12 @@ class ParserInstance {
|
|
|
196
189
|
// special case, empty + response
|
|
197
190
|
return;
|
|
198
191
|
}
|
|
199
|
-
|
|
200
|
-
error.code = 'ParserError4';
|
|
201
|
-
error.parserContext = this.errorContext();
|
|
202
|
-
throw error;
|
|
192
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E4]`, 'ParserError4', { parserContext: this.errorContext() });
|
|
203
193
|
}
|
|
204
194
|
if (imap_formal_syntax_js_1.default.verify(this.remainder.charAt(0), imap_formal_syntax_js_1.default.SP()) >= 0) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
throw error;
|
|
195
|
+
throw (0, errors_js_1.createImapError)(`Unexpected char at position ${this.pos} [E5: ${JSON.stringify(this.remainder.charAt(0))}]`, 'ParserError5', {
|
|
196
|
+
parserContext: this.errorContext(this.remainder)
|
|
197
|
+
});
|
|
209
198
|
}
|
|
210
199
|
this.pos++;
|
|
211
200
|
this.remainder = this.remainder.slice(1);
|
|
@@ -220,16 +209,12 @@ class ParserInstance {
|
|
|
220
209
|
*/
|
|
221
210
|
async getAttributes() {
|
|
222
211
|
if (!this.remainder.length) {
|
|
223
|
-
|
|
224
|
-
error.code = 'ParserError6';
|
|
225
|
-
error.parserContext = this.errorContext();
|
|
226
|
-
throw error;
|
|
212
|
+
throw (0, errors_js_1.createImapError)(`Unexpected end of input at position ${this.pos} [E6]`, 'ParserError6', { parserContext: this.errorContext() });
|
|
227
213
|
}
|
|
228
214
|
if (/^\s/.test(this.remainder)) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
throw error;
|
|
215
|
+
throw (0, errors_js_1.createImapError)(`Unexpected whitespace at position ${this.pos} [E7]`, 'ParserError7', {
|
|
216
|
+
parserContext: this.errorContext(this.remainder)
|
|
217
|
+
});
|
|
233
218
|
}
|
|
234
219
|
const tokenParser = new token_parser_js_1.TokenParser(this, this.pos, this.remainder, this.options);
|
|
235
220
|
return await tokenParser.getAttributes();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ImapFlowError, type ParserErrorCode } from '../errors.js';
|
|
1
2
|
import type { ImapAttributeList, ParserOptions } from './types.js';
|
|
2
3
|
import type { ParserInstance } from './parser-instance.js';
|
|
3
4
|
/**
|
|
@@ -58,6 +59,17 @@ export declare class TokenParser {
|
|
|
58
59
|
* from the input, i.e. when no pre-parsed literal buffers were supplied. Defaults to 1GB.
|
|
59
60
|
*/
|
|
60
61
|
constructor(parent: TokenParserParent | ParserInstance, startPos?: number | undefined, str?: string | null | undefined, options?: ParserOptions | undefined);
|
|
62
|
+
/**
|
|
63
|
+
* Builds a numbered parser error that carries a bounded copy of the input and the position
|
|
64
|
+
* (and character, when there is one) where parsing failed.
|
|
65
|
+
*
|
|
66
|
+
* @param message - The error message
|
|
67
|
+
* @param code - The numbered parser error code
|
|
68
|
+
* @param pos - Position of the failure in the original input
|
|
69
|
+
* @param chr - The offending character
|
|
70
|
+
* @returns The error to throw
|
|
71
|
+
*/
|
|
72
|
+
parserError(message: string, code: ParserErrorCode, pos: number, chr?: string | undefined): ImapFlowError;
|
|
61
73
|
/**
|
|
62
74
|
* Processes the input string and returns the parsed attributes as a flat array of typed objects.
|
|
63
75
|
* Each attribute is an object with a `type` (e.g., "ATOM", "STRING", "LITERAL", "SEQUENCE")
|
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.TokenParser = void 0;
|
|
8
8
|
const imap_formal_syntax_js_1 = __importDefault(require("./imap-formal-syntax.js"));
|
|
9
9
|
const limits_js_1 = require("./limits.js");
|
|
10
|
+
const errors_js_1 = require("../errors.js");
|
|
10
11
|
const STATE_ATOM = 0x001;
|
|
11
12
|
const STATE_LITERAL = 0x002;
|
|
12
13
|
const STATE_NORMAL = 0x003;
|
|
@@ -48,6 +49,23 @@ class TokenParser {
|
|
|
48
49
|
this.currentNode.type = 'TREE';
|
|
49
50
|
this.state = STATE_NORMAL;
|
|
50
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Builds a numbered parser error that carries a bounded copy of the input and the position
|
|
54
|
+
* (and character, when there is one) where parsing failed.
|
|
55
|
+
*
|
|
56
|
+
* @param message - The error message
|
|
57
|
+
* @param code - The numbered parser error code
|
|
58
|
+
* @param pos - Position of the failure in the original input
|
|
59
|
+
* @param chr - The offending character
|
|
60
|
+
* @returns The error to throw
|
|
61
|
+
*/
|
|
62
|
+
parserError(message, code, pos, chr) {
|
|
63
|
+
const parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos };
|
|
64
|
+
if (chr !== undefined) {
|
|
65
|
+
parserContext.chr = chr;
|
|
66
|
+
}
|
|
67
|
+
return (0, errors_js_1.createImapError)(message, code, { parserContext });
|
|
68
|
+
}
|
|
51
69
|
/**
|
|
52
70
|
* Processes the input string and returns the parsed attributes as a flat array of typed objects.
|
|
53
71
|
* Each attribute is an object with a `type` (e.g., "ATOM", "STRING", "LITERAL", "SEQUENCE")
|
|
@@ -71,10 +89,7 @@ class TokenParser {
|
|
|
71
89
|
}
|
|
72
90
|
// If the node was never closed, throw it
|
|
73
91
|
if (!node.isClosed) {
|
|
74
|
-
|
|
75
|
-
error.code = 'ParserError9';
|
|
76
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + this.str.length - 1 };
|
|
77
|
-
throw error;
|
|
92
|
+
throw this.parserError(`Unexpected end of input at position ${this.pos + this.str.length - 1} [E9]`, 'ParserError9', this.pos + this.str.length - 1);
|
|
78
93
|
}
|
|
79
94
|
let type = (node.type || '').toString().toUpperCase();
|
|
80
95
|
switch (type) {
|
|
@@ -145,11 +160,8 @@ class TokenParser {
|
|
|
145
160
|
node.depth = 0;
|
|
146
161
|
}
|
|
147
162
|
if (node.depth > MAX_NODE_DEPTH) {
|
|
148
|
-
let error = new Error('Too much nesting in IMAP string');
|
|
149
|
-
error.code = 'MAX_IMAP_NESTING_REACHED';
|
|
150
163
|
// A bounded prefix only, the error travels whole into logs and rejections
|
|
151
|
-
|
|
152
|
-
throw error;
|
|
164
|
+
throw (0, errors_js_1.createImapError)('Too much nesting in IMAP string', 'MAX_IMAP_NESTING_REACHED', { _imapStr: this.str.slice(0, limits_js_1.ERROR_CONTEXT_LENGTH) });
|
|
153
165
|
}
|
|
154
166
|
if (typeof startPos === 'number') {
|
|
155
167
|
node.startPos = startPos;
|
|
@@ -225,10 +237,7 @@ class TokenParser {
|
|
|
225
237
|
// error instead of reading a missing buffer or shifting every later literal by one
|
|
226
238
|
const takeLiteral = (literals) => {
|
|
227
239
|
if (!literals.length) {
|
|
228
|
-
|
|
229
|
-
error.code = 'ParserError35';
|
|
230
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
231
|
-
throw error;
|
|
240
|
+
throw this.parserError(`Literal without data at position ${this.pos + i} [E35]`, 'ParserError35', this.pos + i, chr);
|
|
232
241
|
}
|
|
233
242
|
return literals.shift();
|
|
234
243
|
};
|
|
@@ -240,10 +249,7 @@ class TokenParser {
|
|
|
240
249
|
// used to fall through into the default branch
|
|
241
250
|
const startAtom = () => {
|
|
242
251
|
if (!imap_formal_syntax_js_1.default['ATOM-CHAR']().includes(chr) && chr !== '\\' && chr !== '%' && chr.charCodeAt(0) < 0x80) {
|
|
243
|
-
|
|
244
|
-
error.code = 'ParserError13';
|
|
245
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
246
|
-
throw error;
|
|
252
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E13: ${JSON.stringify(chr)}]`, 'ParserError13', this.pos + i, chr);
|
|
247
253
|
}
|
|
248
254
|
this.currentNode = this.createNode(this.currentNode, this.pos + i);
|
|
249
255
|
this.currentNode.type = 'ATOM';
|
|
@@ -271,10 +277,7 @@ class TokenParser {
|
|
|
271
277
|
// ) closes a list
|
|
272
278
|
case ')':
|
|
273
279
|
if (this.currentNode.type !== 'LIST') {
|
|
274
|
-
|
|
275
|
-
error.code = 'ParserError10';
|
|
276
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
277
|
-
throw error;
|
|
280
|
+
throw this.parserError(`Unexpected list terminator ) at position ${this.pos + i} [E10]`, 'ParserError10', this.pos + i, chr);
|
|
278
281
|
}
|
|
279
282
|
this.currentNode.isClosed = true;
|
|
280
283
|
this.currentNode.endPos = this.pos + i;
|
|
@@ -284,10 +287,7 @@ class TokenParser {
|
|
|
284
287
|
// ] closes section group
|
|
285
288
|
case ']':
|
|
286
289
|
if (this.currentNode.type !== 'SECTION') {
|
|
287
|
-
|
|
288
|
-
error.code = 'ParserError11';
|
|
289
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
290
|
-
throw error;
|
|
290
|
+
throw this.parserError(`Unexpected section terminator ] at position ${this.pos + i} [E11]`, 'ParserError11', this.pos + i, chr);
|
|
291
291
|
}
|
|
292
292
|
this.currentNode.isClosed = true;
|
|
293
293
|
this.currentNode.endPos = this.pos + i;
|
|
@@ -328,10 +328,7 @@ class TokenParser {
|
|
|
328
328
|
startAtom();
|
|
329
329
|
break;
|
|
330
330
|
}
|
|
331
|
-
|
|
332
|
-
error.code = 'ParserError12';
|
|
333
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
334
|
-
throw error;
|
|
331
|
+
throw this.parserError(`Unexpected literal8 marker at position ${this.pos + i} [E12]`, 'ParserError12', this.pos + i, chr);
|
|
335
332
|
}
|
|
336
333
|
// Mark the next literal as literal8 type; consumed when '{' is encountered
|
|
337
334
|
this.expectedLiteralType = 'literal8';
|
|
@@ -491,16 +488,10 @@ class TokenParser {
|
|
|
491
488
|
chr !== ']' &&
|
|
492
489
|
!(chr === '*' && this.currentNode.value === '\\') &&
|
|
493
490
|
(!this.parent || !this.parent.command || !['NO', 'BAD', 'OK'].includes(this.parent.command.toUpperCase()))) {
|
|
494
|
-
|
|
495
|
-
error.code = 'ParserError16';
|
|
496
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
497
|
-
throw error;
|
|
491
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E16: ${JSON.stringify(chr)}]`, 'ParserError16', this.pos + i, chr);
|
|
498
492
|
}
|
|
499
493
|
else if (this.currentNode.value === '\\*') {
|
|
500
|
-
|
|
501
|
-
error.code = 'ParserError17';
|
|
502
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
503
|
-
throw error;
|
|
494
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E17: ${JSON.stringify(chr)}]`, 'ParserError17', this.pos + i, chr);
|
|
504
495
|
}
|
|
505
496
|
appendToToken(chr);
|
|
506
497
|
break;
|
|
@@ -518,10 +509,7 @@ class TokenParser {
|
|
|
518
509
|
if (chr === '\\') {
|
|
519
510
|
i++;
|
|
520
511
|
if (i >= len) {
|
|
521
|
-
|
|
522
|
-
error.code = 'ParserError18';
|
|
523
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i };
|
|
524
|
-
throw error;
|
|
512
|
+
throw this.parserError(`Unexpected end of input at position ${this.pos + i} [E18]`, 'ParserError18', this.pos + i);
|
|
525
513
|
}
|
|
526
514
|
chr = this.str.charAt(i);
|
|
527
515
|
}
|
|
@@ -530,10 +518,7 @@ class TokenParser {
|
|
|
530
518
|
case STATE_PARTIAL:
|
|
531
519
|
if (chr === '>') {
|
|
532
520
|
if (tokenLast === '.') {
|
|
533
|
-
|
|
534
|
-
error.code = 'ParserError19';
|
|
535
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
536
|
-
throw error;
|
|
521
|
+
throw this.parserError(`Unexpected end of partial at position ${this.pos + i} [E19]`, 'ParserError19', this.pos + i, chr);
|
|
537
522
|
}
|
|
538
523
|
this.currentNode.endPos = this.pos + i;
|
|
539
524
|
this.currentNode.isClosed = true;
|
|
@@ -543,22 +528,13 @@ class TokenParser {
|
|
|
543
528
|
break;
|
|
544
529
|
}
|
|
545
530
|
if (chr === '.' && (!tokenLength || tokenHasDot)) {
|
|
546
|
-
|
|
547
|
-
error.code = 'ParserError20';
|
|
548
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
549
|
-
throw error;
|
|
531
|
+
throw this.parserError(`Unexpected partial separator . at position ${this.pos + i} [E20]`, 'ParserError20', this.pos + i, chr);
|
|
550
532
|
}
|
|
551
533
|
if (!imap_formal_syntax_js_1.default.DIGIT().includes(chr) && chr !== '.') {
|
|
552
|
-
|
|
553
|
-
error.code = 'ParserError21';
|
|
554
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
555
|
-
throw error;
|
|
534
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E21: ${JSON.stringify(chr)}]`, 'ParserError21', this.pos + i, chr);
|
|
556
535
|
}
|
|
557
536
|
if (tokenLast === '0' && (tokenLength === 1 || tokenPrev === '.') && chr !== '.') {
|
|
558
|
-
|
|
559
|
-
error.code = 'ParserError22';
|
|
560
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
561
|
-
throw error;
|
|
537
|
+
throw this.parserError(`Invalid partial at position ${this.pos + i} [E22: ${JSON.stringify(chr)}]`, 'ParserError22', this.pos + i, chr);
|
|
562
538
|
}
|
|
563
539
|
appendToToken(chr);
|
|
564
540
|
break;
|
|
@@ -590,10 +566,7 @@ class TokenParser {
|
|
|
590
566
|
}
|
|
591
567
|
if (chr === '}') {
|
|
592
568
|
if (!('literalLength' in this.currentNode)) {
|
|
593
|
-
|
|
594
|
-
error.code = 'ParserError23';
|
|
595
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
596
|
-
throw error;
|
|
569
|
+
throw this.parserError(`Unexpected literal prefix end char } at position ${this.pos + i} [E23]`, 'ParserError23', this.pos + i, chr);
|
|
597
570
|
}
|
|
598
571
|
if (this.str.charAt(i + 1) === '\n') {
|
|
599
572
|
i++;
|
|
@@ -602,10 +575,7 @@ class TokenParser {
|
|
|
602
575
|
i += 2;
|
|
603
576
|
}
|
|
604
577
|
else {
|
|
605
|
-
|
|
606
|
-
error.code = 'ParserError24';
|
|
607
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
608
|
-
throw error;
|
|
578
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E24: ${JSON.stringify(chr)}]`, 'ParserError24', this.pos + i, chr);
|
|
609
579
|
}
|
|
610
580
|
this.currentNode.literalLength = Number(this.currentNode.literalLength);
|
|
611
581
|
if (!this.currentNode.literalLength) {
|
|
@@ -666,16 +636,10 @@ class TokenParser {
|
|
|
666
636
|
break;
|
|
667
637
|
}
|
|
668
638
|
if (!imap_formal_syntax_js_1.default.DIGIT().includes(chr)) {
|
|
669
|
-
|
|
670
|
-
error.code = 'ParserError25';
|
|
671
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
672
|
-
throw error;
|
|
639
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E25: ${JSON.stringify(chr)}]`, 'ParserError25', this.pos + i, chr);
|
|
673
640
|
}
|
|
674
641
|
if (this.currentNode.literalLength === '0') {
|
|
675
|
-
|
|
676
|
-
error.code = 'ParserError26';
|
|
677
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
678
|
-
throw error;
|
|
642
|
+
throw this.parserError(`Invalid literal at position ${this.pos + i} [E26]`, 'ParserError26', this.pos + i, chr);
|
|
679
643
|
}
|
|
680
644
|
this.currentNode.literalLength = (this.currentNode.literalLength || '') + chr;
|
|
681
645
|
break;
|
|
@@ -690,16 +654,10 @@ class TokenParser {
|
|
|
690
654
|
continueAsAtom();
|
|
691
655
|
break;
|
|
692
656
|
}
|
|
693
|
-
|
|
694
|
-
error.code = 'ParserError27';
|
|
695
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
696
|
-
throw error;
|
|
657
|
+
throw this.parserError(`Unexpected end of sequence at position ${this.pos + i} [E27: ${JSON.stringify(chr)}]`, 'ParserError27', this.pos + i, chr);
|
|
697
658
|
}
|
|
698
659
|
if (this.currentNode.value !== '*' && tokenLast === '*' && tokenPrev !== ':') {
|
|
699
|
-
|
|
700
|
-
error.code = 'ParserError28';
|
|
701
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
702
|
-
throw error;
|
|
660
|
+
throw this.parserError(`Unexpected end of sequence at position ${this.pos + i} [E28: ${JSON.stringify(chr)}]`, 'ParserError28', this.pos + i, chr);
|
|
703
661
|
}
|
|
704
662
|
this.currentNode.isClosed = true;
|
|
705
663
|
this.currentNode.endPos = this.pos + i - 1;
|
|
@@ -719,18 +677,12 @@ class TokenParser {
|
|
|
719
677
|
continueAsAtom();
|
|
720
678
|
break;
|
|
721
679
|
}
|
|
722
|
-
|
|
723
|
-
error.code = 'ParserError29';
|
|
724
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
725
|
-
throw error;
|
|
680
|
+
throw this.parserError(`Unexpected range separator : at position ${this.pos + i} [E29]`, 'ParserError29', this.pos + i, chr);
|
|
726
681
|
}
|
|
727
682
|
}
|
|
728
683
|
else if (chr === '*') {
|
|
729
684
|
if (![',', ':'].includes(tokenLast)) {
|
|
730
|
-
|
|
731
|
-
error.code = 'ParserError30';
|
|
732
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
733
|
-
throw error;
|
|
685
|
+
throw this.parserError(`Unexpected range wildcard at position ${this.pos + i} [E30]`, 'ParserError30', this.pos + i, chr);
|
|
734
686
|
}
|
|
735
687
|
}
|
|
736
688
|
else if (chr === ',') {
|
|
@@ -739,16 +691,10 @@ class TokenParser {
|
|
|
739
691
|
continueAsAtom();
|
|
740
692
|
break;
|
|
741
693
|
}
|
|
742
|
-
|
|
743
|
-
error.code = 'ParserError31';
|
|
744
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
745
|
-
throw error;
|
|
694
|
+
throw this.parserError(`Unexpected sequence separator , at position ${this.pos + i} [E31]`, 'ParserError31', this.pos + i, chr);
|
|
746
695
|
}
|
|
747
696
|
if (tokenLast === '*' && tokenPrev !== ':') {
|
|
748
|
-
|
|
749
|
-
error.code = 'ParserError32';
|
|
750
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
751
|
-
throw error;
|
|
697
|
+
throw this.parserError(`Unexpected sequence separator , at position ${this.pos + i} [E32]`, 'ParserError32', this.pos + i, chr);
|
|
752
698
|
}
|
|
753
699
|
}
|
|
754
700
|
else if (!RE_SINGLE_DIGIT.test(chr)) {
|
|
@@ -756,16 +702,10 @@ class TokenParser {
|
|
|
756
702
|
continueAsAtom();
|
|
757
703
|
break;
|
|
758
704
|
}
|
|
759
|
-
|
|
760
|
-
error.code = 'ParserError33';
|
|
761
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
762
|
-
throw error;
|
|
705
|
+
throw this.parserError(`Unexpected char at position ${this.pos + i} [E33: ${JSON.stringify(chr)}]`, 'ParserError33', this.pos + i, chr);
|
|
763
706
|
}
|
|
764
707
|
if (RE_SINGLE_DIGIT.test(chr) && tokenLast === '*') {
|
|
765
|
-
|
|
766
|
-
error.code = 'ParserError34';
|
|
767
|
-
error.parserContext = { ...(0, limits_js_1.boundedInput)(this.str), pos: this.pos + i, chr };
|
|
768
|
-
throw error;
|
|
708
|
+
throw this.parserError(`Unexpected number at position ${this.pos + i} [E34: ${JSON.stringify(chr)}]`, 'ParserError34', this.pos + i, chr);
|
|
769
709
|
}
|
|
770
710
|
appendToToken(chr);
|
|
771
711
|
break;
|
package/dist/cjs/imap-flow.d.ts
CHANGED
|
@@ -426,7 +426,7 @@ export declare class ImapFlow extends EventEmitter {
|
|
|
426
426
|
* Appends a new message to a mailbox
|
|
427
427
|
*
|
|
428
428
|
* @param path Mailbox path to upload the message to (unicode string). If value is an array then it is joined using current delimiter symbols. Namespace prefix is added automatically if required.
|
|
429
|
-
* @param content RFC822 formatted email message
|
|
429
|
+
* @param content RFC822 formatted email message, as a Buffer, Uint8Array or string
|
|
430
430
|
* @param flags an array of flags to be set for the uploaded message
|
|
431
431
|
* @param idate internal date to be set for the message
|
|
432
432
|
* @returns info about uploaded message
|
|
@@ -434,7 +434,7 @@ export declare class ImapFlow extends EventEmitter {
|
|
|
434
434
|
* @example
|
|
435
435
|
* await client.append('INBOX', rawMessageBuffer, ['\\Seen'], new Date(2000, 1, 1));
|
|
436
436
|
*/
|
|
437
|
-
append(path: string | string[], content: string | Buffer, flags?: string[] | undefined, idate?: Date | string | undefined): Promise<AppendResponseObject | false>;
|
|
437
|
+
append(path: string | string[], content: string | Buffer | Uint8Array, flags?: string[] | undefined, idate?: Date | string | undefined): Promise<AppendResponseObject | false>;
|
|
438
438
|
/**
|
|
439
439
|
* Copies messages from current mailbox to destination mailbox
|
|
440
440
|
*
|
|
@@ -562,7 +562,8 @@ export declare class ImapFlow extends EventEmitter {
|
|
|
562
562
|
* // download body part nr '1.2' from latest message
|
|
563
563
|
* let download = await client.download('*', '1.2');
|
|
564
564
|
* if (download.content) {
|
|
565
|
-
* download.
|
|
565
|
+
* // pipeline() rejects when the download fails, a plain .pipe() would not report it
|
|
566
|
+
* await stream.promises.pipeline(download.content, fs.createWriteStream(download.meta.filename));
|
|
566
567
|
* }
|
|
567
568
|
*/
|
|
568
569
|
download(range: SequenceString, part?: string | undefined, options?: DownloadOptions | undefined): Promise<DownloadObject | DownloadNotFound>;
|