imapflow 1.0.148 → 1.0.149
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/.github/workflows/stale.yml +24 -0
- package/CHANGELOG.md +7 -0
- package/lib/imap-flow.js +79 -2
- package/lib/tools.js +46 -0
- package/lib/types.d.ts +19 -1
- package/package.json +9 -9
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: 'Close stale issues and PRs'
|
|
2
|
+
on:
|
|
3
|
+
schedule:
|
|
4
|
+
- cron: '30 1 * * *'
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
stale:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/stale@v8
|
|
11
|
+
with:
|
|
12
|
+
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
|
|
13
|
+
stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.'
|
|
14
|
+
close-issue-message: 'This issue was closed because it has been stalled for 15 days with no activity.'
|
|
15
|
+
close-pr-message: 'This PR was closed because it has been stalled for 20 days with no activity.'
|
|
16
|
+
days-before-issue-stale: 30
|
|
17
|
+
days-before-pr-stale: 45
|
|
18
|
+
days-before-issue-close: 15
|
|
19
|
+
days-before-pr-close: 20
|
|
20
|
+
stale-issue-label: 'no-issue-activity'
|
|
21
|
+
exempt-issue-labels: 'pending,work-in-progress'
|
|
22
|
+
stale-pr-label: 'no-pr-activity'
|
|
23
|
+
exempt-pr-labels: 'awaiting-approval,work-in-progress'
|
|
24
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.149](https://github.com/postalsys/imapflow/compare/v1.0.148...v1.0.149) (2024-01-31)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **flag-colors:** added a method to set Flag Color. The color is also included in the Fetch response structure ([d840951](https://github.com/postalsys/imapflow/commit/d8409513075b864e9131665af3f1670a0714d05c))
|
|
9
|
+
|
|
3
10
|
## [1.0.148](https://github.com/postalsys/imapflow/compare/v1.0.147...v1.0.148) (2024-01-16)
|
|
4
11
|
|
|
5
12
|
|
package/lib/imap-flow.js
CHANGED
|
@@ -29,7 +29,17 @@ const { PassThrough } = require('stream');
|
|
|
29
29
|
|
|
30
30
|
const { proxyConnection } = require('./proxy-connection');
|
|
31
31
|
|
|
32
|
-
const {
|
|
32
|
+
const {
|
|
33
|
+
comparePaths,
|
|
34
|
+
updateCapabilities,
|
|
35
|
+
getFolderTree,
|
|
36
|
+
formatMessageResponse,
|
|
37
|
+
getDecoder,
|
|
38
|
+
packMessageRange,
|
|
39
|
+
normalizePath,
|
|
40
|
+
expandRange,
|
|
41
|
+
getColorFlags
|
|
42
|
+
} = require('./tools');
|
|
33
43
|
|
|
34
44
|
const imapCommands = require('./imap-commands.js');
|
|
35
45
|
|
|
@@ -1177,6 +1187,10 @@ class ImapFlow extends EventEmitter {
|
|
|
1177
1187
|
|
|
1178
1188
|
updateEvent.flags = message.flags;
|
|
1179
1189
|
|
|
1190
|
+
if (message.flagColor) {
|
|
1191
|
+
updateEvent.flagColor = message.flagColor;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1180
1194
|
this.emit('flags', updateEvent);
|
|
1181
1195
|
}
|
|
1182
1196
|
}
|
|
@@ -1926,6 +1940,68 @@ class ImapFlow extends EventEmitter {
|
|
|
1926
1940
|
return await this.run('STORE', range, flags, queryOpts);
|
|
1927
1941
|
}
|
|
1928
1942
|
|
|
1943
|
+
/**
|
|
1944
|
+
* Sets a colored flag for an email. Only supported by mail clients like Apple Mail
|
|
1945
|
+
*
|
|
1946
|
+
* @param {SequenceString | Number[] | SearchObject} range Range to filter the messages
|
|
1947
|
+
* @param {string} The color to set. One of 'red', 'orange', 'yellow', 'green', 'blue', 'purple', and 'grey'
|
|
1948
|
+
* @param {Object} [options]
|
|
1949
|
+
* @param {Boolean} [options.uid] If `true` then uses UID {@link SequenceString} instead of sequence numbers
|
|
1950
|
+
* @param {BigInt} [options.unchangedSince] If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
|
|
1951
|
+
* @returns {Promise<Boolean>} Did the operation succeed or not
|
|
1952
|
+
*
|
|
1953
|
+
* @example
|
|
1954
|
+
* let mailbox = await client.mailboxOpen('INBOX');
|
|
1955
|
+
* // add a purple flag for all emails
|
|
1956
|
+
* await client.setFlagColor('1:*', 'Purple');
|
|
1957
|
+
*/
|
|
1958
|
+
async setFlagColor(range, color, options) {
|
|
1959
|
+
options = options || {};
|
|
1960
|
+
|
|
1961
|
+
range = await this.resolveRange(range, options);
|
|
1962
|
+
if (!range) {
|
|
1963
|
+
return false;
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
let flagChanges = getColorFlags(color);
|
|
1967
|
+
if (!flagChanges) {
|
|
1968
|
+
return false;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
let addResults;
|
|
1972
|
+
let removeResults;
|
|
1973
|
+
|
|
1974
|
+
if (flagChanges.add && flagChanges.add.length) {
|
|
1975
|
+
let queryOpts = Object.assign(
|
|
1976
|
+
{
|
|
1977
|
+
operation: 'add'
|
|
1978
|
+
},
|
|
1979
|
+
options,
|
|
1980
|
+
{
|
|
1981
|
+
useLabels: false, // override if set
|
|
1982
|
+
// prevent triggering a premature Flags change notification
|
|
1983
|
+
silent: flagChanges.remove && flagChanges.remove.length
|
|
1984
|
+
}
|
|
1985
|
+
);
|
|
1986
|
+
|
|
1987
|
+
addResults = await this.run('STORE', range, flagChanges.add, queryOpts);
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
if (flagChanges.remove && flagChanges.remove.length) {
|
|
1991
|
+
let queryOpts = Object.assign(
|
|
1992
|
+
{
|
|
1993
|
+
operation: 'remove'
|
|
1994
|
+
},
|
|
1995
|
+
options,
|
|
1996
|
+
{ useLabels: false } // override if set
|
|
1997
|
+
);
|
|
1998
|
+
|
|
1999
|
+
removeResults = await this.run('STORE', range, flagChanges.remove, queryOpts);
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
return addResults || removeResults || false;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
1929
2005
|
/**
|
|
1930
2006
|
* Delete messages from currently opened mailbox. Method does not indicate info about deleted messages,
|
|
1931
2007
|
* instead you should be using {@link ImapFlow#expunge} event for this
|
|
@@ -2077,7 +2153,7 @@ class ImapFlow extends EventEmitter {
|
|
|
2077
2153
|
* @typedef {Object} FetchQueryObject
|
|
2078
2154
|
* @global
|
|
2079
2155
|
* @property {Boolean} [uid] if `true` then include UID in the response
|
|
2080
|
-
* @property {Boolean} [flags] if `true` then include flags Set in the response
|
|
2156
|
+
* @property {Boolean} [flags] if `true` then include flags Set in the response. Also adds `flagColor` to the response if the message is flagged.
|
|
2081
2157
|
* @property {Boolean} [bodyStructure] if `true` then include parsed BODYSTRUCTURE object in the response
|
|
2082
2158
|
* @property {Boolean} [envelope] if `true` then include parsed ENVELOPE object in the response
|
|
2083
2159
|
* @property {Boolean} [internalDate] if `true` then include internal date value in the response
|
|
@@ -2148,6 +2224,7 @@ class ImapFlow extends EventEmitter {
|
|
|
2148
2224
|
* @property {Set<string>} [labels] a Set of labels. Only present if server supports `X-GM-EXT-1` extension
|
|
2149
2225
|
* @property {Number} [size] message size
|
|
2150
2226
|
* @property {Set<string>} [flags] a set of message flags
|
|
2227
|
+
* @property {String} [flagColor] flag color like "red", or "yellow". This value is derived from the `flags` Set and it uses the same color rules as Apple Mail
|
|
2151
2228
|
* @property {MessageEnvelopeObject} [envelope] message envelope
|
|
2152
2229
|
* @property {MessageStructureObject} [bodyStructure] message body structure
|
|
2153
2230
|
* @property {Date} [internalDate] message internal date
|
package/lib/tools.js
CHANGED
|
@@ -8,6 +8,8 @@ const { createHash } = require('crypto');
|
|
|
8
8
|
const { JPDecoder } = require('./jp-decoder');
|
|
9
9
|
const iconv = require('iconv-lite');
|
|
10
10
|
|
|
11
|
+
const FLAG_COLORS = ['red', 'orange', 'yellow', 'green', 'blue', 'purple', 'grey'];
|
|
12
|
+
|
|
11
13
|
module.exports = {
|
|
12
14
|
encodePath(connection, path) {
|
|
13
15
|
path = (path || '').toString();
|
|
@@ -191,6 +193,43 @@ module.exports = {
|
|
|
191
193
|
return tree;
|
|
192
194
|
},
|
|
193
195
|
|
|
196
|
+
getFlagColor(flags) {
|
|
197
|
+
if (!flags.has('\\Flagged')) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const bit0 = flags.has('$MailFlagBit0') ? 1 : 0;
|
|
202
|
+
const bit1 = flags.has('$MailFlagBit1') ? 2 : 0;
|
|
203
|
+
const bit2 = flags.has('$MailFlagBit2') ? 4 : 0;
|
|
204
|
+
|
|
205
|
+
const color = bit0 | bit1 | bit2; // eslint-disable-line no-bitwise
|
|
206
|
+
|
|
207
|
+
return FLAG_COLORS[color] || 'red'; // default to red for the unused \b111
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
getColorFlags(color) {
|
|
211
|
+
const colorCode = color ? FLAG_COLORS.indexOf((color || '').toString().toLowerCase().trim()) : null;
|
|
212
|
+
if (colorCode < 0 && colorCode !== null) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const bits = [];
|
|
217
|
+
bits[0] = colorCode & 1; // eslint-disable-line no-bitwise
|
|
218
|
+
bits[1] = colorCode & 2; // eslint-disable-line no-bitwise
|
|
219
|
+
bits[2] = colorCode & 4; // eslint-disable-line no-bitwise
|
|
220
|
+
|
|
221
|
+
let result = { add: colorCode ? ['\\Flagged'] : [], remove: colorCode ? [] : ['\\Flagged'] };
|
|
222
|
+
|
|
223
|
+
for (let i = 0; i < bits.length; i++) {
|
|
224
|
+
if (bits[i]) {
|
|
225
|
+
result.add.push(`$MailFlagBit${i}`);
|
|
226
|
+
} else {
|
|
227
|
+
result.remove.push(`$MailFlagBit${i}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
},
|
|
232
|
+
|
|
194
233
|
async formatMessageResponse(untagged, mailbox) {
|
|
195
234
|
let map = {};
|
|
196
235
|
|
|
@@ -351,6 +390,13 @@ module.exports = {
|
|
|
351
390
|
map.id = map.emailId || createHash('md5').update([path, mailbox.uidValidity.toString(), map.uid.toString()].join(':')).digest('hex');
|
|
352
391
|
}
|
|
353
392
|
|
|
393
|
+
if (map.flags) {
|
|
394
|
+
let flagColor = module.exports.getFlagColor(map.flags);
|
|
395
|
+
if (flagColor) {
|
|
396
|
+
map.flagColor = flagColor;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
354
400
|
return map;
|
|
355
401
|
},
|
|
356
402
|
|
package/lib/types.d.ts
CHANGED
|
@@ -364,6 +364,22 @@ declare module "imapflow" {
|
|
|
364
364
|
unchangedSince?: bigint;
|
|
365
365
|
useLabels?: boolean;
|
|
366
366
|
}): Promise<Boolean>;
|
|
367
|
+
/**
|
|
368
|
+
* Sets a colored flag for an email. Only supported by mail clients like Apple Mail
|
|
369
|
+
* @example
|
|
370
|
+
* let mailbox = await client.mailboxOpen('INBOX');
|
|
371
|
+
* // add a purple flag for all emails
|
|
372
|
+
* await client.setFlagColor('1:*', 'Purple');
|
|
373
|
+
* @param range - Range to filter the messages
|
|
374
|
+
* @param The - color to set. One of 'red', 'orange', 'yellow', 'green', 'blue', 'purple', and 'grey'
|
|
375
|
+
* @param [options.uid] - If `true` then uses UID {@link SequenceString} instead of sequence numbers
|
|
376
|
+
* @param [options.unchangedSince] - If set then only messages with a lower or equal `modseq` value are updated. Ignored if server does not support `CONDSTORE` extension.
|
|
377
|
+
* @returns Did the operation succeed or not
|
|
378
|
+
*/
|
|
379
|
+
setFlagColor(range: SequenceString | Number[] | SearchObject, The: string, options?: {
|
|
380
|
+
uid?: boolean;
|
|
381
|
+
unchangedSince?: bigint;
|
|
382
|
+
}): Promise<Boolean>;
|
|
367
383
|
/**
|
|
368
384
|
* Delete messages from currently opened mailbox. Method does not indicate info about deleted messages,
|
|
369
385
|
* instead you should be using {@link ImapFlow#expunge} event for this
|
|
@@ -832,7 +848,7 @@ declare type CopyResponseObject = {
|
|
|
832
848
|
|
|
833
849
|
/**
|
|
834
850
|
* @property [uid] - if `true` then include UID in the response
|
|
835
|
-
* @property [flags] - if `true` then include flags Set in the response
|
|
851
|
+
* @property [flags] - if `true` then include flags Set in the response. Also adds `flagColor` to the response if the message is flagged.
|
|
836
852
|
* @property [bodyStructure] - if `true` then include parsed BODYSTRUCTURE object in the response
|
|
837
853
|
* @property [envelope] - if `true` then include parsed ENVELOPE object in the response
|
|
838
854
|
* @property [internalDate] - if `true` then include internal date value in the response
|
|
@@ -935,6 +951,7 @@ declare type MessageStructureObject = {
|
|
|
935
951
|
* @property [labels] - a Set of labels. Only present if server supports `X-GM-EXT-1` extension
|
|
936
952
|
* @property [size] - message size
|
|
937
953
|
* @property [flags] - a set of message flags
|
|
954
|
+
* @property [flagColor] - flag color like "red", or "yellow". This value is derived from the `flags` Set and it uses the same color rules as Apple Mail
|
|
938
955
|
* @property [envelope] - message envelope
|
|
939
956
|
* @property [bodyStructure] - message body structure
|
|
940
957
|
* @property [internalDate] - message internal date
|
|
@@ -951,6 +968,7 @@ declare type FetchMessageObject = {
|
|
|
951
968
|
labels?: Set<string>;
|
|
952
969
|
size?: number;
|
|
953
970
|
flags?: Set<string>;
|
|
971
|
+
flagColor?: string;
|
|
954
972
|
envelope?: MessageEnvelopeObject;
|
|
955
973
|
bodyStructure?: MessageStructureObject;
|
|
956
974
|
internalDate?: Date;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "imapflow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.149",
|
|
4
4
|
"description": "IMAP Client for Node",
|
|
5
5
|
"main": "./lib/imap-flow.js",
|
|
6
6
|
"scripts": {
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://imapflow.com/",
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@babel/eslint-parser": "7.
|
|
32
|
-
"@babel/eslint-plugin": "7.
|
|
31
|
+
"@babel/eslint-parser": "7.23.9",
|
|
32
|
+
"@babel/eslint-plugin": "7.23.5",
|
|
33
33
|
"@babel/plugin-syntax-class-properties": "7.12.13",
|
|
34
|
-
"@babel/preset-env": "7.23.
|
|
35
|
-
"@types/node": "20.
|
|
36
|
-
"eslint": "8.
|
|
34
|
+
"@babel/preset-env": "7.23.9",
|
|
35
|
+
"@types/node": "20.11.13",
|
|
36
|
+
"eslint": "8.56.0",
|
|
37
37
|
"eslint-config-nodemailer": "1.2.0",
|
|
38
|
-
"eslint-config-prettier": "9.
|
|
38
|
+
"eslint-config-prettier": "9.1.0",
|
|
39
39
|
"grunt": "1.6.1",
|
|
40
40
|
"grunt-cli": "1.4.3",
|
|
41
41
|
"grunt-contrib-nodeunit": "5.0.0",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"libmime": "5.2.1",
|
|
53
53
|
"libqp": "2.0.1",
|
|
54
54
|
"mailsplit": "5.4.0",
|
|
55
|
-
"nodemailer": "6.9.
|
|
56
|
-
"pino": "8.
|
|
55
|
+
"nodemailer": "6.9.8",
|
|
56
|
+
"pino": "8.17.2",
|
|
57
57
|
"socks": "2.7.1"
|
|
58
58
|
}
|
|
59
59
|
}
|