@wirecat/cli-memo 0.131.24 → 0.131.26
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/README.md +9 -12
- package/dist/actions/actions.d.ts +1 -1
- package/dist/actions/actions.d.ts.map +1 -1
- package/dist/actions/actions.js +27 -8
- package/dist/actions/actions.js.map +1 -1
- package/dist/actions/command.d.ts +1 -1
- package/dist/actions/command.d.ts.map +1 -1
- package/dist/actions/command.js +1 -12
- package/dist/actions/command.js.map +1 -1
- package/dist/app.d.ts +1 -1
- package/dist/bin/memo.js +2 -2
- package/dist/bundle/{all-profiles-ZCJTYGOL.js → all-profiles-VULFSNYE.js} +9 -9
- package/dist/bundle/{anthropic-7WVLAKTX.js → anthropic-VXQ6ST2U.js} +6 -6
- package/dist/bundle/{app-server-6G3SXEHO.js → app-server-HQPELIPY.js} +42 -42
- package/dist/bundle/auto-3R4RFJGK.js +86 -0
- package/dist/bundle/{bun-JVBDJKBB.js → bun-2NMWL5YB.js} +2 -2
- package/dist/bundle/{bun-sqlite-P4I7NVMQ.js → bun-sqlite-CT544OXO.js} +5 -5
- package/dist/bundle/{chunk-EGG3PGCM.js → chunk-254TXVLA.js} +2 -2
- package/dist/bundle/{chunk-FXHN2UZW.js → chunk-2ND2XYME.js} +33 -17
- package/dist/bundle/{chunk-5YCNCXL5.js → chunk-3CVDHJER.js} +1 -1
- package/dist/bundle/{chunk-ALGIPJ6L.js → chunk-3ZJE5TIG.js} +2 -2
- package/dist/bundle/{chunk-3KNXQZMO.js → chunk-4ENVJFRM.js} +29 -29
- package/dist/bundle/{chunk-NAH473ZR.js → chunk-5FPQGUJA.js} +1 -1
- package/dist/bundle/{chunk-ZOYGY2PN.js → chunk-6PRRZC7Z.js} +3 -3
- package/dist/bundle/{chunk-CM2H7NRC.js → chunk-6TJCRDNZ.js} +4 -4
- package/dist/bundle/{chunk-AWGV4VOA.js → chunk-7ISENDNK.js} +12 -12
- package/dist/bundle/{chunk-UY2VH3QK.js → chunk-7LMTWOTP.js} +2 -2
- package/dist/bundle/{chunk-2IRCJT4O.js → chunk-A4NZ2XOG.js} +8 -8
- package/dist/bundle/{chunk-R3LNQ3I4.js → chunk-A6PITALJ.js} +4 -2
- package/dist/bundle/{chunk-EACY2ULS.js → chunk-AGMYCYSG.js} +306 -187
- package/dist/bundle/{chunk-EB7LKK4K.js → chunk-ARDUJR5Z.js} +1 -1
- package/dist/bundle/{chunk-UA2C4BCH.js → chunk-BELLQAWL.js} +9 -9
- package/dist/bundle/{chunk-LWIMGWKB.js → chunk-BO4FN4UB.js} +3 -3
- package/dist/bundle/{chunk-3MER7NE6.js → chunk-CRC3AW6N.js} +4 -4
- package/dist/bundle/{chunk-UVR6U55E.js → chunk-CUWI6JIX.js} +6 -6
- package/dist/bundle/{chunk-VLPMB3UU.js → chunk-CW3NJ764.js} +4 -4
- package/dist/bundle/{chunk-ND3GBFEY.js → chunk-DKKWZMR7.js} +2 -2
- package/dist/bundle/{chunk-BTQSFPIM.js → chunk-DUHXWFCB.js} +5 -5
- package/dist/bundle/{chunk-CCHHEMPM.js → chunk-EB2IULWB.js} +3 -2
- package/dist/bundle/{chunk-R2LJDDZP.js → chunk-FHY664YS.js} +4 -4
- package/dist/bundle/{chunk-JY4LVWGZ.js → chunk-G2BB5WY5.js} +15 -8
- package/dist/bundle/chunk-GJBK3M6X.js +452 -0
- package/dist/bundle/{chunk-ZDOVR4PA.js → chunk-GOEHJK2R.js} +7 -7
- package/dist/bundle/{chunk-GQOXFZBX.js → chunk-GPYGMETC.js} +286 -282
- package/dist/bundle/{chunk-DIMX5AEE.js → chunk-H6O6IQND.js} +5 -5
- package/dist/bundle/{chunk-ELKYINWL.js → chunk-HN3EDDVX.js} +13 -13
- package/dist/bundle/{chunk-GSEDSGJF.js → chunk-HVVBSM2C.js} +753 -648
- package/dist/bundle/{chunk-JCCL7RGH.js → chunk-I7PL5WX2.js} +4 -4
- package/dist/bundle/{chunk-LNXFM4FD.js → chunk-IJ34FAES.js} +45 -26
- package/dist/bundle/{chunk-MPVW7BQZ.js → chunk-IUM5XZWV.js} +6 -6
- package/dist/bundle/{chunk-GRXVN2X7.js → chunk-J57DDKF4.js} +1 -1
- package/dist/bundle/{chunk-INTF3YPV.js → chunk-KFDPW2AR.js} +2 -2
- package/dist/bundle/{chunk-AIGMYGEL.js → chunk-KMZRXGTF.js} +1 -1
- package/dist/bundle/{chunk-MROFZXAB.js → chunk-KTDNFSXC.js} +22 -22
- package/dist/bundle/{chunk-ILHTNOIV.js → chunk-KV4267S4.js} +1 -1
- package/dist/bundle/{chunk-VVEFQEWP.js → chunk-LJZFMXDC.js} +22 -22
- package/dist/bundle/{chunk-OQK2IKPB.js → chunk-LMN7SYX4.js} +1 -1
- package/dist/bundle/{chunk-RTESJ5O2.js → chunk-M4QN77GH.js} +4 -4
- package/dist/bundle/{chunk-M43DAAZ7.js → chunk-M6O4DH5F.js} +1 -1
- package/dist/bundle/{chunk-UXCDBNAY.js → chunk-MQAHMAJB.js} +2 -2
- package/dist/bundle/{chunk-XF3LZ32F.js → chunk-NAM2Y63Z.js} +3 -3
- package/dist/bundle/{chunk-UPXUE27A.js → chunk-NH2JSH24.js} +6 -6
- package/dist/bundle/{chunk-3U7OUQV2.js → chunk-OYB3FUYQ.js} +1 -1
- package/dist/bundle/{chunk-J6D34BFP.js → chunk-PWA3RNXN.js} +260 -263
- package/dist/bundle/{chunk-KQSHIQSV.js → chunk-QFW4MJIH.js} +239 -242
- package/dist/bundle/{chunk-CPJEQK4V.js → chunk-QKQ7A4L7.js} +46 -46
- package/dist/bundle/{chunk-N5H6I7WQ.js → chunk-S3RBWUUA.js} +6 -6
- package/dist/bundle/{chunk-Q6MFBH6Q.js → chunk-SY7M2DLJ.js} +9 -9
- package/dist/bundle/{chunk-EKTZEF3Q.js → chunk-TKVRZZE3.js} +3 -27
- package/dist/bundle/{chunk-SKTGBVYC.js → chunk-TPFWNOPG.js} +4 -4
- package/dist/bundle/{chunk-F2ED6KG6.js → chunk-TXANQZEG.js} +3 -3
- package/dist/bundle/{chunk-T4LW6UYQ.js → chunk-TZ7WDQPD.js} +40 -34
- package/dist/bundle/{chunk-AIVUS6WA.js → chunk-UZXCBBDC.js} +15 -12
- package/dist/bundle/{chunk-XSI5NYGB.js → chunk-VL3YCTZD.js} +8 -8
- package/dist/bundle/{chunk-ZLZE5P6M.js → chunk-WRZ7JDA2.js} +8 -8
- package/dist/bundle/{chunk-EW3XTUPB.js → chunk-XBIPSSKI.js} +4 -4
- package/dist/bundle/{chunk-JDDVGGUV.js → chunk-XKGXVVYV.js} +10 -10
- package/dist/bundle/{chunk-ITQBXFMC.js → chunk-YFBKS5BW.js} +3 -3
- package/dist/bundle/{chunk-PQLBPYJR.js → chunk-YPF6OS37.js} +1 -1
- package/dist/bundle/{chunk-IC2TL7RW.js → chunk-Z3YGDBBS.js} +2 -2
- package/dist/bundle/{chunk-IJC6MFLP.js → chunk-ZR3BPBS6.js} +10 -10
- package/dist/bundle/command-contract-RQMIQKBS.js +32 -0
- package/dist/bundle/{decode-YHX3DQG2.js → decode-7VB3CHK2.js} +5 -5
- package/dist/bundle/{dispatch-MELZFYOS.js → dispatch-CU5KGRQL.js} +8 -8
- package/dist/bundle/{echarts-FBVAP7BR.js → echarts-45D6USAX.js} +2 -2
- package/dist/bundle/{embed-CQJ42S5C.js → embed-KU2RGB24.js} +6 -6
- package/dist/bundle/{embedder-EDXLEJ27.js → embedder-E7YZDZ5Y.js} +9 -9
- package/dist/bundle/{entry-HZEA7QFK.js → entry-N42HJMIN.js} +7 -7
- package/dist/bundle/failure-R355OCVE.js +66 -0
- package/dist/bundle/{failure-RBNZBCZJ.js → failure-TUXXI6JT.js} +2 -2
- package/dist/bundle/{first-run-JZQN7R6M.js → first-run-Y5YNAAO3.js} +11 -11
- package/dist/bundle/first-screen-SNPGBQFZ.js +30 -0
- package/dist/bundle/{instructions-NYVYNWVU.js → instructions-6EFSPC7C.js} +1 -1
- package/dist/bundle/mcp-6Z7UKX7E.js +90 -0
- package/dist/bundle/{mcp-MNI62HHE.js → mcp-PPVOM4SE.js} +2 -2
- package/dist/bundle/memo.js +16 -16
- package/dist/bundle/{node-2QE6UPGS.js → node-OXC26QXO.js} +2 -2
- package/dist/bundle/{node-sqlite-SDHZJNY7.js → node-sqlite-FNTICDEN.js} +6 -6
- package/dist/bundle/{oauth-FFUJREKS.js → oauth-4JFOFCBB.js} +7 -7
- package/dist/bundle/{open-NT2GYX6N.js → open-WXFCCY7S.js} +5 -5
- package/dist/bundle/{openai-IQA2XR6Z.js → openai-TPQKQNM7.js} +10 -10
- package/dist/bundle/{process-HIEJXYW6.js → process-YWPAOI6G.js} +1 -1
- package/dist/bundle/{chunk-DMQ3342A.js → program-WFUPN7XO.js} +9769 -2059
- package/dist/bundle/{prompt-IOZAME2R.js → prompt-HJUH4EP4.js} +5 -5
- package/dist/bundle/{recognize-2XOAZJ5N.js → recognize-DAIRHALM.js} +4 -4
- package/dist/bundle/{remote-2LE7OTDA.js → remote-MJLWTLAX.js} +7 -7
- package/dist/bundle/{rerank-UKOVVZM6.js → rerank-VAK5HSJE.js} +7 -7
- package/dist/bundle/{serve-S2UHPEBP.js → serve-M2A66WOW.js} +9 -9
- package/dist/bundle/server-33FB7QXW.js +48 -0
- package/dist/bundle/server-AIPDQO57.js +61 -0
- package/dist/bundle/{server-BG4WWQHY.js → server-NN2CBVSX.js} +57 -57
- package/dist/bundle/{state-F5KT3CBD.js → state-6TBUXJOX.js} +6 -6
- package/dist/bundle/{store-WBUUS7FO.js → store-TJCL3QBY.js} +13 -13
- package/dist/bundle/store-maintenance-command-NKJV5A3G.js +48 -0
- package/dist/bundle/update-OXR3SNM2.js +69 -0
- package/dist/config.d.ts +15 -29
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -36
- package/dist/config.js.map +1 -1
- package/dist/context/command.d.ts.map +1 -1
- package/dist/context/command.js +6 -2
- package/dist/context/command.js.map +1 -1
- package/dist/context/context.d.ts +2 -0
- package/dist/context/context.d.ts.map +1 -1
- package/dist/context/context.js +15 -0
- package/dist/context/context.js.map +1 -1
- package/dist/doctor/command.d.ts +0 -12
- package/dist/doctor/command.d.ts.map +1 -1
- package/dist/doctor/command.js +19 -24
- package/dist/doctor/command.js.map +1 -1
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +3 -9
- package/dist/examples.js.map +1 -1
- package/dist/failure.d.ts +2 -2
- package/dist/mail/command.d.ts.map +1 -1
- package/dist/mail/command.js +2 -87
- package/dist/mail/command.js.map +1 -1
- package/dist/mail/findings-command.d.ts.map +1 -1
- package/dist/mail/findings-command.js +1 -1
- package/dist/mail/findings-command.js.map +1 -1
- package/dist/mail/messages-command.d.ts.map +1 -1
- package/dist/mail/messages-command.js +9 -2
- package/dist/mail/messages-command.js.map +1 -1
- package/dist/mail/moved.d.ts +1 -1
- package/dist/mail/moved.d.ts.map +1 -1
- package/dist/mail/moved.js +3 -0
- package/dist/mail/moved.js.map +1 -1
- package/dist/mail/review-command.d.ts +1 -1
- package/dist/mail/review-command.d.ts.map +1 -1
- package/dist/mail/review-command.js +5 -8
- package/dist/mail/review-command.js.map +1 -1
- package/dist/program.js +1 -1
- package/dist/program.js.map +1 -1
- package/dist/read-only.d.ts +1 -1
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +1 -25
- package/dist/reasons.js.map +1 -1
- package/dist/review/command.d.ts +0 -1
- package/dist/review/command.d.ts.map +1 -1
- package/dist/review/command.js +2 -10
- package/dist/review/command.js.map +1 -1
- package/dist/review/kinds.d.ts +4 -21
- package/dist/review/kinds.d.ts.map +1 -1
- package/dist/review/kinds.js +13 -174
- package/dist/review/kinds.js.map +1 -1
- package/dist/review/review.js +2 -2
- package/dist/review/review.js.map +1 -1
- package/dist/review/status.js +2 -2
- package/dist/review/status.js.map +1 -1
- package/dist/run/auto.js +3 -3
- package/dist/run/auto.js.map +1 -1
- package/dist/run/import.d.ts +2 -2
- package/dist/run/import.d.ts.map +1 -1
- package/dist/run/import.js +24 -121
- package/dist/run/import.js.map +1 -1
- package/dist/schedule/command.d.ts +2 -2
- package/dist/schedule/command.d.ts.map +1 -1
- package/dist/schedule/command.js +9 -4
- package/dist/schedule/command.js.map +1 -1
- package/dist/search/command.js +1 -1
- package/dist/store/source-list.d.ts +1 -6
- package/dist/store/source-list.d.ts.map +1 -1
- package/dist/store/source-list.js +11 -46
- package/dist/store/source-list.js.map +1 -1
- package/dist/tasks/command.js +1 -1
- package/dist/tasks/command.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/scenarios/set-up.md +3 -3
- package/skills/cli-memo/SKILL.md +13 -21
- package/skills/mail-triage/SKILL.md +28 -16
- package/dist/bundle/auto-JWPM5654.js +0 -86
- package/dist/bundle/chunk-MLMSQK76.js +0 -103
- package/dist/bundle/command-contract-543RRFNU.js +0 -32
- package/dist/bundle/failure-62G7QSPX.js +0 -66
- package/dist/bundle/first-screen-56V3UOQE.js +0 -30
- package/dist/bundle/mcp-Y6IPYDS2.js +0 -90
- package/dist/bundle/program-DEMRKCZY.js +0 -10972
- package/dist/bundle/server-3YNOEPWU.js +0 -61
- package/dist/bundle/server-EZWQ5KP4.js +0 -48
- package/dist/bundle/setup-2X7ADKFH.js +0 -973
- package/dist/bundle/store-maintenance-command-KLST56XF.js +0 -48
- package/dist/bundle/update-WH4CGJGP.js +0 -69
- package/dist/mail/accounts.d.ts +0 -7
- package/dist/mail/accounts.d.ts.map +0 -1
- package/dist/mail/accounts.js +0 -28
- package/dist/mail/accounts.js.map +0 -1
- package/dist/mail/backfill-headers.d.ts +0 -11
- package/dist/mail/backfill-headers.d.ts.map +0 -1
- package/dist/mail/backfill-headers.js +0 -84
- package/dist/mail/backfill-headers.js.map +0 -1
- package/dist/mail/domain-age.d.ts +0 -26
- package/dist/mail/domain-age.d.ts.map +0 -1
- package/dist/mail/domain-age.js +0 -151
- package/dist/mail/domain-age.js.map +0 -1
- package/dist/mail/gmail.d.ts +0 -39
- package/dist/mail/gmail.d.ts.map +0 -1
- package/dist/mail/gmail.js +0 -325
- package/dist/mail/gmail.js.map +0 -1
- package/dist/mail/himalaya.d.ts +0 -22
- package/dist/mail/himalaya.d.ts.map +0 -1
- package/dist/mail/himalaya.js +0 -113
- package/dist/mail/himalaya.js.map +0 -1
- package/dist/mail/mbox.d.ts +0 -9
- package/dist/mail/mbox.d.ts.map +0 -1
- package/dist/mail/mbox.js +0 -230
- package/dist/mail/mbox.js.map +0 -1
- package/dist/mail/repair.d.ts +0 -7
- package/dist/mail/repair.d.ts.map +0 -1
- package/dist/mail/repair.js +0 -54
- package/dist/mail/repair.js.map +0 -1
- package/dist/mail/rule-store.d.ts +0 -12
- package/dist/mail/rule-store.d.ts.map +0 -1
- package/dist/mail/rule-store.js +0 -83
- package/dist/mail/rule-store.js.map +0 -1
- package/dist/mail/setup-command.d.ts +0 -4
- package/dist/mail/setup-command.d.ts.map +0 -1
- package/dist/mail/setup-command.js +0 -41
- package/dist/mail/setup-command.js.map +0 -1
- package/dist/mail/setup.d.ts +0 -19
- package/dist/mail/setup.d.ts.map +0 -1
- package/dist/mail/setup.js +0 -95
- package/dist/mail/setup.js.map +0 -1
- package/dist/mail/slices.d.ts +0 -6
- package/dist/mail/slices.d.ts.map +0 -1
- package/dist/mail/slices.js +0 -7
- package/dist/mail/slices.js.map +0 -1
- package/dist/mail/source.d.ts +0 -7
- package/dist/mail/source.d.ts.map +0 -1
- package/dist/mail/source.js +0 -119
- package/dist/mail/source.js.map +0 -1
- package/dist/mail/sync.d.ts +0 -21
- package/dist/mail/sync.d.ts.map +0 -1
- package/dist/mail/sync.js +0 -24
- package/dist/mail/sync.js.map +0 -1
- /package/dist/bundle/{chunk-CWOKGEL3.js → chunk-DF7NE4ZG.js} +0 -0
- /package/dist/bundle/{chunk-NUN6OGOV.js → chunk-LU3WKZBA.js} +0 -0
package/dist/mail/mbox.js
DELETED
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import { createReadStream } from "node:fs";
|
|
2
|
-
import { open, stat } from "node:fs/promises";
|
|
3
|
-
import { CliError } from "@wirecat/cli-base";
|
|
4
|
-
import { headersOf, systemLabel } from "@wirecat/cli-core/mail";
|
|
5
|
-
const unfold = (text) => text.replace(/\r?\n[ \t]+/g, " ");
|
|
6
|
-
const field = (unfolded, name) => new RegExp(`^${name}:[ \\t]*(.*?)\\r?$`, "im").exec(unfolded)?.[1];
|
|
7
|
-
const NEWLINE = 10;
|
|
8
|
-
const CR = 13;
|
|
9
|
-
const SEPARATOR = Buffer.from("\nFrom ");
|
|
10
|
-
const MAX_HEADER = 256 * 1024;
|
|
11
|
-
const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
12
|
-
/** Takeout's own marks, not labels the owner gave: read state and "not in Inbox". */
|
|
13
|
-
const PSEUDO_LABELS = new Set(["Opened", "Unread", "Archived"]);
|
|
14
|
-
/**
|
|
15
|
-
* `Mon Jul 24 10:00:00 +0000 2023`: asctime, with the zone Takeout writes. Without one it is UTC, as the mbox format
|
|
16
|
-
* defines it: https://www.rfc-editor.org/rfc/rfc4155#appendix-A
|
|
17
|
-
*/
|
|
18
|
-
const separatorDate = (rest) => {
|
|
19
|
-
const match = /(\w{3}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2})(?: ([+-])(\d{2})(\d{2}))? (\d{4})/.exec(rest);
|
|
20
|
-
if (match === null)
|
|
21
|
-
return undefined;
|
|
22
|
-
const [, month = "", day, hour, minute, second, sign, offsetHours, offsetMinutes, year] = match;
|
|
23
|
-
if (!MONTHS.includes(month))
|
|
24
|
-
return undefined;
|
|
25
|
-
const local = Date.UTC(Number(year), MONTHS.indexOf(month), Number(day), Number(hour), Number(minute), Number(second));
|
|
26
|
-
const offset = sign === undefined ? 0 : (Number(offsetHours) * 60 + Number(offsetMinutes)) * 60_000;
|
|
27
|
-
return local - (sign === "-" ? -offset : offset);
|
|
28
|
-
};
|
|
29
|
-
/** RFC 2047 encoded words, which Takeout uses for labels outside ASCII. */
|
|
30
|
-
const decodeWords = (text) => text
|
|
31
|
-
.replace(/(\?=)\s+(=\?)/g, "$1$2")
|
|
32
|
-
.replace(/=\?([^?]+)\?([bBqQ])\?([^?]*)\?=/g, (_, charset, encoding, data) => {
|
|
33
|
-
const bytes = encoding.toUpperCase() === "B"
|
|
34
|
-
? Buffer.from(data, "base64")
|
|
35
|
-
: Buffer.from(data
|
|
36
|
-
.replace(/_/g, " ")
|
|
37
|
-
.replace(/=([0-9A-Fa-f]{2})/g, (_hex, hex) => String.fromCharCode(parseInt(hex, 16))), "latin1");
|
|
38
|
-
try {
|
|
39
|
-
return new TextDecoder(charset).decode(bytes);
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
return bytes.toString("utf8");
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
const splitLabels = (value) => {
|
|
46
|
-
const labels = [];
|
|
47
|
-
let current = "";
|
|
48
|
-
let quoted = false;
|
|
49
|
-
for (const c of value) {
|
|
50
|
-
if (c === '"')
|
|
51
|
-
quoted = !quoted;
|
|
52
|
-
else if (c === "," && !quoted) {
|
|
53
|
-
labels.push(current);
|
|
54
|
-
current = "";
|
|
55
|
-
}
|
|
56
|
-
else
|
|
57
|
-
current += c;
|
|
58
|
-
}
|
|
59
|
-
labels.push(current);
|
|
60
|
-
return labels.map((label) => label.trim()).filter(Boolean);
|
|
61
|
-
};
|
|
62
|
-
/** RFC 5322 requires the zone; `Date.parse` would read a date without one in this computer's zone. */
|
|
63
|
-
const ZONED = /(?:[+-]\d{4}|\b(?:UT|GMT|[ECMP][SD]T|[A-IK-Z]))\s*(?:\([^)]*\))?\s*$/i;
|
|
64
|
-
const headerDate = (value) => value !== undefined && ZONED.test(value.trim()) ? Date.parse(value) : Number.NaN;
|
|
65
|
-
const entryOf = (separator, header, start, body) => {
|
|
66
|
-
const [, sender = "", rest = ""] = /^From (\S+) ?(.*)$/.exec(separator) ?? [];
|
|
67
|
-
const messageId = /^(\d+)@/.exec(sender)?.[1];
|
|
68
|
-
// The id is what joins this archive to the IMAP account; never invented, so a wrong guess fails here.
|
|
69
|
-
if (messageId === undefined)
|
|
70
|
-
throw new CliError("invalid_response", `the mbox email at byte ${start} has no Gmail message id: its "From " line should read "From <digits>@xxx <date>"`);
|
|
71
|
-
const unfolded = unfold(header);
|
|
72
|
-
const date = separatorDate(rest) ?? headerDate(field(unfolded, "Date"));
|
|
73
|
-
if (Number.isNaN(date))
|
|
74
|
-
throw new CliError("invalid_response", `the mbox email at byte ${start} has no readable date: neither its "From " line nor a Date header with a zone`);
|
|
75
|
-
const written = field(unfolded, "X-Gmail-Labels");
|
|
76
|
-
const raw = written === undefined ? undefined : splitLabels(decodeWords(written));
|
|
77
|
-
const labels = raw === undefined ? undefined : [...new Set(raw.filter((name) => !PSEUDO_LABELS.has(name)).map(systemLabel))].sort();
|
|
78
|
-
const seen = raw?.includes("Unread") ? false : raw?.includes("Opened") ? true : undefined;
|
|
79
|
-
const threadId = field(unfolded, "X-GM-THRID")?.trim();
|
|
80
|
-
return {
|
|
81
|
-
item: {
|
|
82
|
-
uid: messageId,
|
|
83
|
-
messageId,
|
|
84
|
-
threadId: threadId || messageId,
|
|
85
|
-
receivedAt: new Date(date).toISOString(),
|
|
86
|
-
...(labels === undefined ? {} : { labels, flagged: labels.includes("Starred") }),
|
|
87
|
-
...(seen === undefined ? {} : { seen }),
|
|
88
|
-
headers: headersOf(header),
|
|
89
|
-
},
|
|
90
|
-
start,
|
|
91
|
-
body,
|
|
92
|
-
end: -1,
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
/**
|
|
96
|
-
* One pass over the file: a "From " line after a blank line starts an email. Only headers are kept in memory;
|
|
97
|
-
* bodies are skipped with a byte search, so a 20 GB archive costs one read and no more memory than its headers.
|
|
98
|
-
*/
|
|
99
|
-
const scan = async (path, chunkSize) => {
|
|
100
|
-
const entries = [];
|
|
101
|
-
let base = 0;
|
|
102
|
-
let pos = 0;
|
|
103
|
-
let bodyFrom = 0;
|
|
104
|
-
let inHeaders = true;
|
|
105
|
-
let separator;
|
|
106
|
-
let start = 0;
|
|
107
|
-
let body = 0;
|
|
108
|
-
let lines = [];
|
|
109
|
-
let headerBytes = 0;
|
|
110
|
-
const take = (buf, eof) => {
|
|
111
|
-
for (;;) {
|
|
112
|
-
if (inHeaders) {
|
|
113
|
-
let nl = buf.indexOf(NEWLINE, pos);
|
|
114
|
-
if (nl === -1) {
|
|
115
|
-
if (!eof || pos >= buf.length)
|
|
116
|
-
return Math.max(0, pos - 2);
|
|
117
|
-
nl = buf.length;
|
|
118
|
-
}
|
|
119
|
-
let line = buf.subarray(pos, nl);
|
|
120
|
-
if (line.at(-1) === CR)
|
|
121
|
-
line = line.subarray(0, -1);
|
|
122
|
-
if (separator === undefined) {
|
|
123
|
-
separator = line.toString("latin1");
|
|
124
|
-
if (!separator.startsWith("From "))
|
|
125
|
-
throw new CliError("validation_error", `${path} is not an mbox file: byte ${base + pos} starts no "From " line`);
|
|
126
|
-
start = base + pos;
|
|
127
|
-
body = base + nl + 1;
|
|
128
|
-
}
|
|
129
|
-
else if (line.length === 0) {
|
|
130
|
-
entries.push(entryOf(separator, Buffer.concat(lines).toString("utf8"), start, body));
|
|
131
|
-
lines = [];
|
|
132
|
-
headerBytes = 0;
|
|
133
|
-
inHeaders = false;
|
|
134
|
-
bodyFrom = nl;
|
|
135
|
-
}
|
|
136
|
-
else if (headerBytes < MAX_HEADER) {
|
|
137
|
-
lines.push(Buffer.from(line), Buffer.from("\n"));
|
|
138
|
-
headerBytes += line.length + 1;
|
|
139
|
-
}
|
|
140
|
-
pos = nl + 1;
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
const at = buf.indexOf(SEPARATOR, bodyFrom);
|
|
144
|
-
if (at === -1) {
|
|
145
|
-
const next = Math.max(bodyFrom, buf.length - (SEPARATOR.length - 1));
|
|
146
|
-
const keep = Math.max(0, next - 2);
|
|
147
|
-
bodyFrom = next - keep;
|
|
148
|
-
return keep;
|
|
149
|
-
}
|
|
150
|
-
const blank = buf[at - 1] === NEWLINE || (buf[at - 1] === CR && buf[at - 2] === NEWLINE);
|
|
151
|
-
if (!blank) {
|
|
152
|
-
bodyFrom = at + 1;
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
const last = entries.at(-1);
|
|
156
|
-
if (last)
|
|
157
|
-
last.end = base + at + 1;
|
|
158
|
-
inHeaders = true;
|
|
159
|
-
separator = undefined;
|
|
160
|
-
pos = at + 1;
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
let carry = Buffer.alloc(0);
|
|
164
|
-
for await (const chunk of createReadStream(path, { highWaterMark: chunkSize })) {
|
|
165
|
-
const buf = carry.length ? Buffer.concat([carry, chunk]) : chunk;
|
|
166
|
-
const keep = take(buf, false);
|
|
167
|
-
base += keep;
|
|
168
|
-
pos -= keep;
|
|
169
|
-
carry = buf.subarray(keep);
|
|
170
|
-
}
|
|
171
|
-
take(carry, true);
|
|
172
|
-
if (inHeaders && separator !== undefined)
|
|
173
|
-
entries.push(entryOf(separator, Buffer.concat(lines).toString("utf8"), start, body));
|
|
174
|
-
const last = entries.at(-1);
|
|
175
|
-
if (last && last.end === -1)
|
|
176
|
-
last.end = base + carry.length;
|
|
177
|
-
for (const entry of entries)
|
|
178
|
-
entry.item.size = entry.end - entry.start;
|
|
179
|
-
return entries;
|
|
180
|
-
};
|
|
181
|
-
/** The email as Gmail stored it: the blank line mbox adds after it removed, and mboxrd's `>From ` undone. */
|
|
182
|
-
const asStored = (bytes) => {
|
|
183
|
-
const text = bytes.toString("latin1");
|
|
184
|
-
const trimmed = /\r?\n\r?\n$/.test(text) ? text.replace(/\r?\n$/, "") : text;
|
|
185
|
-
return Buffer.from(trimmed.replace(/^>(>*From )/gm, "$1"), "latin1");
|
|
186
|
-
};
|
|
187
|
-
/**
|
|
188
|
-
* A Google Takeout mbox of Gmail: the same message and thread ids IMAP reports, so its emails and the
|
|
189
|
-
* account's IMAP emails are one set. Spam and Trash are left out, as IMAP's All Mail leaves them out.
|
|
190
|
-
*/
|
|
191
|
-
export const mboxSource = (path, { chunkSize = 1024 * 1024 } = {}) => {
|
|
192
|
-
let index;
|
|
193
|
-
const indexed = () => {
|
|
194
|
-
index ??= scan(path, chunkSize).then((entries) => new Map(entries.map((entry) => [entry.item.messageId, entry])));
|
|
195
|
-
return index;
|
|
196
|
-
};
|
|
197
|
-
return {
|
|
198
|
-
list: async (since, folder) => [...(await indexed()).values()]
|
|
199
|
-
.filter(({ item }) => Date.parse(item.receivedAt) >= since.getTime() &&
|
|
200
|
-
!item.labels?.some((label) => label === "Spam" || label === "Trash"))
|
|
201
|
-
.map(({ item }) => ({ ...item, folder })),
|
|
202
|
-
stamp: async () => {
|
|
203
|
-
const { size, mtimeMs } = await stat(path);
|
|
204
|
-
return { size, mtimeMs };
|
|
205
|
-
},
|
|
206
|
-
fetchRaw: async (quick) => {
|
|
207
|
-
const items = quick;
|
|
208
|
-
const entries = await indexed();
|
|
209
|
-
const handle = await open(path);
|
|
210
|
-
try {
|
|
211
|
-
const read = [];
|
|
212
|
-
for (const item of items) {
|
|
213
|
-
const entry = entries.get(item.messageId);
|
|
214
|
-
if (entry === undefined) {
|
|
215
|
-
read.push(new CliError("not_found", `email ${item.messageId} is not in the mbox file`));
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
const bytes = Buffer.alloc(entry.end - entry.body);
|
|
219
|
-
await handle.read(bytes, 0, bytes.length, entry.body);
|
|
220
|
-
read.push(asStored(bytes));
|
|
221
|
-
}
|
|
222
|
-
return read;
|
|
223
|
-
}
|
|
224
|
-
finally {
|
|
225
|
-
await handle.close();
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
//# sourceMappingURL=mbox.js.map
|
package/dist/mail/mbox.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mbox.js","sourceRoot":"","sources":["../../src/mail/mbox.ts"],"names":[],"mappings":"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"}
|
package/dist/mail/repair.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { MessageStore } from "@wirecat/cli-core/store";
|
|
2
|
-
/**
|
|
3
|
-
* Once per account: email text saved before memo read an HTML text/plain part as HTML is converted in place, from
|
|
4
|
-
* what the store holds. Runs inside sync, saving 50 emails per transaction so other CLIs are not locked out.
|
|
5
|
-
*/
|
|
6
|
-
export declare const repairHtmlText: (store: MessageStore, address: string, now?: number) => Promise<number | undefined>;
|
|
7
|
-
//# sourceMappingURL=repair.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/mail/repair.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,YAAY,EAAc,MAAM,yBAAyB,CAAA;AAMnF;;;GAGG;AACH,eAAO,MAAM,cAAc,UAClB,YAAY,WACV,MAAM,mBAEd,OAAO,CAAC,MAAM,GAAG,SAAS,CAwC5B,CAAA"}
|
package/dist/mail/repair.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { ENVELOPE, htmlToText, looksLikeHtml } from "@wirecat/cli-core/mail";
|
|
2
|
-
import { pause, slicesOf } from "./slices.js";
|
|
3
|
-
const REPAIRED = "mail_text_repair";
|
|
4
|
-
const VERSION = "html-text-1";
|
|
5
|
-
/**
|
|
6
|
-
* Once per account: email text saved before memo read an HTML text/plain part as HTML is converted in place, from
|
|
7
|
-
* what the store holds. Runs inside sync, saving 50 emails per transaction so other CLIs are not locked out.
|
|
8
|
-
*/
|
|
9
|
-
export const repairHtmlText = async (store, address, now = Date.now()) => {
|
|
10
|
-
const key = { provider: "email", account: address.toLowerCase() };
|
|
11
|
-
if ((await store.sync.syncState(key, REPAIRED))?.value === VERSION)
|
|
12
|
-
return undefined;
|
|
13
|
-
const stored = await store.accounts.storedAccount(key).catch(() => null);
|
|
14
|
-
if (stored === null)
|
|
15
|
-
return undefined;
|
|
16
|
-
const refs = (await store.mail.emailRefs({ accountId: stored.id })).filter(({ deleted, mailboxes }) => !deleted && !mailboxes.some(({ kind }) => kind === ENVELOPE));
|
|
17
|
-
let repaired = 0;
|
|
18
|
-
const slices = slicesOf(refs);
|
|
19
|
-
for (const [at, slice] of slices.entries()) {
|
|
20
|
-
const inputs = [];
|
|
21
|
-
for (const { externalId } of slice) {
|
|
22
|
-
const email = await store.mail.email(stored.id, externalId);
|
|
23
|
-
if (email === null || !email.bodyText || !looksLikeHtml(email.bodyText))
|
|
24
|
-
continue;
|
|
25
|
-
const [placed] = await store.mail.inThreads(stored.id, [externalId]);
|
|
26
|
-
if (placed === undefined)
|
|
27
|
-
continue;
|
|
28
|
-
inputs.push({
|
|
29
|
-
accountId: stored.id,
|
|
30
|
-
externalId: placed.threadExternalId,
|
|
31
|
-
now,
|
|
32
|
-
emails: [
|
|
33
|
-
{
|
|
34
|
-
externalId,
|
|
35
|
-
subject: email.subject,
|
|
36
|
-
from: email.fromAddress === null ? null : { address: email.fromAddress, name: email.fromName },
|
|
37
|
-
sentAt: email.sentAt,
|
|
38
|
-
bodyText: htmlToText(email.bodyText),
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
const last = at === slices.length - 1;
|
|
44
|
-
// A converted email no longer looks like HTML, so a run cut short skips what earlier slices saved.
|
|
45
|
-
await store.mail.saveThreads(inputs, last ? [{ accountId: stored.id, name: REPAIRED, value: VERSION }] : undefined);
|
|
46
|
-
repaired += inputs.length;
|
|
47
|
-
if (!last)
|
|
48
|
-
await pause();
|
|
49
|
-
}
|
|
50
|
-
if (slices.length === 0)
|
|
51
|
-
await store.sync.setSyncState(key, REPAIRED, VERSION);
|
|
52
|
-
return repaired;
|
|
53
|
-
};
|
|
54
|
-
//# sourceMappingURL=repair.js.map
|
package/dist/mail/repair.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/mail/repair.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { type MailRule } from "@wirecat/cli-core/mail";
|
|
2
|
-
import type { MessageStore } from "@wirecat/cli-core/store";
|
|
3
|
-
import type { MailAccountConfig } from "./accounts.js";
|
|
4
|
-
/**
|
|
5
|
-
* Rules lived in config.json until 0.32.0. The first run that opens the store copies them in, checks they all
|
|
6
|
-
* arrived, and only then drops them from the config, after a backup beside it; a run killed halfway repeats the
|
|
7
|
-
* copy, which replaces each rule by its conditions.
|
|
8
|
-
*/
|
|
9
|
-
export declare const moveConfigRules: (store: MessageStore, env: NodeJS.ProcessEnv, say: (line: string) => void) => Promise<void>;
|
|
10
|
-
/** One account's rules, read once per opened store and moved there from the config first if needed. */
|
|
11
|
-
export declare const rulesOf: (store: MessageStore, account: Pick<MailAccountConfig, "address">, env: NodeJS.ProcessEnv, say: (line: string) => void) => Promise<MailRule[]>;
|
|
12
|
-
//# sourceMappingURL=rule-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rule-store.d.ts","sourceRoot":"","sources":["../../src/mail/rule-store.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,QAAQ,EAId,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAEvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAStD;;;;GAIG;AACH,eAAO,MAAM,eAAe,UACnB,YAAY,OACd,MAAM,CAAC,UAAU,OACjB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAC1B,OAAO,CAAC,IAAI,CAuCd,CAAA;AAqBD,uGAAuG;AACvG,eAAO,MAAM,OAAO,UACX,YAAY,WACV,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,OACtC,MAAM,CAAC,UAAU,OACjB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAC1B,OAAO,CAAC,QAAQ,EAAE,CAgBpB,CAAA"}
|
package/dist/mail/rule-store.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { chmodSync, copyFileSync, existsSync } from "node:fs";
|
|
2
|
-
import { ENVELOPE, envelopeBox, ruleInput, storedMailRule, storedMailRuleSet, } from "@wirecat/cli-core/mail";
|
|
3
|
-
import { configPath, loadConfig, updateConfig } from "../config.js";
|
|
4
|
-
const accountKey = (address) => ({ provider: "email", account: address.toLowerCase() });
|
|
5
|
-
const accountIdOf = (store, address) => store.accounts.saveAccount(accountKey(address), { name: address });
|
|
6
|
-
const PROTECTED_REASON = /never remove/i;
|
|
7
|
-
/**
|
|
8
|
-
* Rules lived in config.json until 0.32.0. The first run that opens the store copies them in, checks they all
|
|
9
|
-
* arrived, and only then drops them from the config, after a backup beside it; a run killed halfway repeats the
|
|
10
|
-
* copy, which replaces each rule by its conditions.
|
|
11
|
-
*/
|
|
12
|
-
export const moveConfigRules = async (store, env, say) => {
|
|
13
|
-
const accounts = (loadConfig(env).mail?.accounts ?? []).filter(({ rules }) => (rules?.length ?? 0) > 0);
|
|
14
|
-
if (accounts.length === 0)
|
|
15
|
-
return;
|
|
16
|
-
const path = configPath(env);
|
|
17
|
-
const backup = `${path}.${new Date().toISOString().replace(/[:.]/g, "-")}.before-rules-in-store`;
|
|
18
|
-
if (existsSync(path)) {
|
|
19
|
-
copyFileSync(path, backup);
|
|
20
|
-
chmodSync(backup, 0o600);
|
|
21
|
-
}
|
|
22
|
-
const moved = new Map();
|
|
23
|
-
for (const account of accounts) {
|
|
24
|
-
const rules = account.rules ?? [];
|
|
25
|
-
const accountId = await accountIdOf(store, account.address);
|
|
26
|
-
for (const rule of rules)
|
|
27
|
-
await store.mail.rules.upsert(accountId, ruleInput({ ...rule, ...(PROTECTED_REASON.test(rule.reason ?? "") ? { protected: true } : {}) }), Date.now());
|
|
28
|
-
const inStore = new Set((await store.mail.rules.list(accountId)).map(({ conditions }) => JSON.stringify(conditions)));
|
|
29
|
-
const missing = rules.filter((rule) => !inStore.has(JSON.stringify(ruleInput(rule).conditions)));
|
|
30
|
-
if (missing.length)
|
|
31
|
-
throw new Error(`${missing.length} of ${account.name}'s rules did not reach the store`);
|
|
32
|
-
await assignEnvelopes(store, accountId);
|
|
33
|
-
moved.set(account.name, rules.length);
|
|
34
|
-
}
|
|
35
|
-
updateConfig((config) => ({
|
|
36
|
-
...config,
|
|
37
|
-
mail: {
|
|
38
|
-
...config.mail,
|
|
39
|
-
accounts: (config.mail?.accounts ?? []).map(({ rules: _, ...account }) => account),
|
|
40
|
-
},
|
|
41
|
-
}), env);
|
|
42
|
-
for (const [name, count] of moved)
|
|
43
|
-
say(`memo: moved ${count} mail rules of ${name} from the config into the store; the old config is ${backup}\n`);
|
|
44
|
-
};
|
|
45
|
-
/** Envelope emails recorded before 0.32.0 know their rule only by the mailbox it gave them. */
|
|
46
|
-
const assignEnvelopes = async (store, accountId) => {
|
|
47
|
-
const byBox = new Map();
|
|
48
|
-
for (const stored of await store.mail.rules.list(accountId)) {
|
|
49
|
-
const rule = storedMailRule(stored);
|
|
50
|
-
if (rule?.action === ENVELOPE && rule.id !== undefined)
|
|
51
|
-
byBox.set(envelopeBox(rule.match).externalId, rule.id);
|
|
52
|
-
}
|
|
53
|
-
if (byBox.size === 0)
|
|
54
|
-
return;
|
|
55
|
-
const emails = new Map();
|
|
56
|
-
for (const { externalId, mailboxes } of await store.mail.emailRefs({ accountId }))
|
|
57
|
-
for (const box of mailboxes) {
|
|
58
|
-
const ruleId = byBox.get(box.externalId);
|
|
59
|
-
if (ruleId !== undefined)
|
|
60
|
-
emails.set(ruleId, [...(emails.get(ruleId) ?? []), externalId]);
|
|
61
|
-
}
|
|
62
|
-
for (const [ruleId, ids] of emails)
|
|
63
|
-
await store.mail.rules.assign(accountId, ruleId, ids, Date.now());
|
|
64
|
-
};
|
|
65
|
-
const loaded = new WeakMap();
|
|
66
|
-
/** One account's rules, read once per opened store and moved there from the config first if needed. */
|
|
67
|
-
export const rulesOf = async (store, account, env, say) => {
|
|
68
|
-
const key = account.address.toLowerCase();
|
|
69
|
-
const byAccount = loaded.get(store) ?? new Map();
|
|
70
|
-
loaded.set(store, byAccount);
|
|
71
|
-
const cached = byAccount.get(key);
|
|
72
|
-
if (cached !== undefined)
|
|
73
|
-
return cached;
|
|
74
|
-
await moveConfigRules(store, env, say);
|
|
75
|
-
const { rules, unreadable } = await storedMailRuleSet(store, account);
|
|
76
|
-
// mail reports these in its sync answer; a build that reads them would decide mail differently.
|
|
77
|
-
if (unreadable.length)
|
|
78
|
-
say(`memo: ${unreadable.length} stored mail rules of ${account.address} are left out, this memo does not know their ` +
|
|
79
|
-
`${[...new Set(unreadable.map(({ why }) => why))].join(", ")}; update memo\n`);
|
|
80
|
-
byAccount.set(key, rules);
|
|
81
|
-
return rules;
|
|
82
|
-
};
|
|
83
|
-
//# sourceMappingURL=rule-store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rule-store.js","sourceRoot":"","sources":["../../src/mail/rule-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-command.d.ts","sourceRoot":"","sources":["../../src/mail/setup-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAG1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWxC,eAAO,MAAM,gBAAgB,SAAU,OAAO,WAAW,OAAO,OAAO,MAAM,CAAC,UAAU,KAAG,IA2C1F,CAAA"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { CliError } from "@wirecat/cli-base";
|
|
2
|
-
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
-
import { grantsAuthority, LOCAL_READ, LOCAL_WRITE } from "@wirecat/cli-core/cli";
|
|
4
|
-
import { answers, itemAnswer } from "../answer.js";
|
|
5
|
-
import { loadConfig } from "../config.js";
|
|
6
|
-
import { collect, oneOf } from "../options.js";
|
|
7
|
-
export const mailSetupCommand = (mail, streams, env) => {
|
|
8
|
-
const { print } = answers(mail, streams, env);
|
|
9
|
-
grantsAuthority(annotate(mail.command("add"), {
|
|
10
|
-
effects: LOCAL_WRITE,
|
|
11
|
-
examples: ["memo mail add work you@example.test --kind imap"],
|
|
12
|
-
}))
|
|
13
|
-
.description("add an explicit account after matching its Himalaya email")
|
|
14
|
-
.argument("[account]", "one Himalaya account name; omission lists choices and changes nothing")
|
|
15
|
-
.argument("[address]", "must match the email configured for this Himalaya account")
|
|
16
|
-
.option("--kind <kind>", "gmail or imap", oneOf(["gmail", "imap"]), "gmail")
|
|
17
|
-
.option("--folder <folder>", "mail folder to import; repeat for several", collect)
|
|
18
|
-
.option("--json", "print the added account as JSON")
|
|
19
|
-
.action(async (account, address, given) => {
|
|
20
|
-
const { addMailAccount } = await import("./setup.js");
|
|
21
|
-
print(given.json, itemAnswer(await addMailAccount(env, {
|
|
22
|
-
...(account ? { name: account } : {}),
|
|
23
|
-
...(address ? { address } : {}),
|
|
24
|
-
mode: given.kind,
|
|
25
|
-
...(given.folder ? { folders: given.folder } : {}),
|
|
26
|
-
})));
|
|
27
|
-
});
|
|
28
|
-
annotate(mail.command("check"), { effects: LOCAL_READ, examples: ["memo mail check work"] })
|
|
29
|
-
.description("check one Memo account against Himalaya's configured identity")
|
|
30
|
-
.argument("[account]", "one Memo account name; omission lists choices and changes nothing")
|
|
31
|
-
.option("--json", "print the checked account as JSON")
|
|
32
|
-
.action(async (account, given) => {
|
|
33
|
-
const accounts = loadConfig(env).mail?.accounts ?? [];
|
|
34
|
-
const saved = accounts.find((one) => one.name === account);
|
|
35
|
-
if (!saved)
|
|
36
|
-
throw new CliError("validation_error", `name one Memo account explicitly; choices: ${accounts.map((one) => one.name).join(", ") || "none"}`);
|
|
37
|
-
const { checkMailAccount } = await import("./setup.js");
|
|
38
|
-
print(given.json, itemAnswer(await checkMailAccount(env, { name: saved.name, address: saved.address })));
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
//# sourceMappingURL=setup-command.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup-command.js","sourceRoot":"","sources":["../../src/mail/setup-command.ts"],"names":[],"mappings":"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"}
|
package/dist/mail/setup.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type Config } from "../config.js";
|
|
2
|
-
type Account = NonNullable<Config["mail"]>["accounts"][number];
|
|
3
|
-
export declare const checkMailAccount: (env: NodeJS.ProcessEnv, input: {
|
|
4
|
-
name?: string;
|
|
5
|
-
address?: string;
|
|
6
|
-
config?: string;
|
|
7
|
-
}) => Promise<{
|
|
8
|
-
name: string;
|
|
9
|
-
address: string;
|
|
10
|
-
}>;
|
|
11
|
-
export declare const addMailAccount: (env: NodeJS.ProcessEnv, input: {
|
|
12
|
-
name?: string;
|
|
13
|
-
address?: string;
|
|
14
|
-
config?: string;
|
|
15
|
-
mode: "gmail" | "imap";
|
|
16
|
-
folders?: string[];
|
|
17
|
-
}) => Promise<Account>;
|
|
18
|
-
export {};
|
|
19
|
-
//# sourceMappingURL=setup.d.ts.map
|
package/dist/mail/setup.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/mail/setup.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,cAAc,CAAA;AAGxD,KAAK,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAmD9D,eAAO,MAAM,gBAAgB,QACtB,MAAM,CAAC,UAAU,SACf;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1D,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAwC3C,CAAA;AAED,eAAO,MAAM,cAAc,QACpB,MAAM,CAAC,UAAU,SACf;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,KACtG,OAAO,CAAC,OAAO,CAYjB,CAAA"}
|
package/dist/mail/setup.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { CliError } from "@wirecat/cli-base";
|
|
4
|
-
import { parse } from "smol-toml";
|
|
5
|
-
import { updateConfig } from "../config.js";
|
|
6
|
-
import { himalaya } from "./himalaya.js";
|
|
7
|
-
const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
8
|
-
const ADDRESS = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
9
|
-
// Himalaya 2.2.1's SASL tables (`src/config.rs`): PLAIN names its login `authcid` or `username`, the rest `username`.
|
|
10
|
-
const SASL = ["plain", "login", "oauthbearer", "xoauth2", "scram-sha-256"];
|
|
11
|
-
const loginOf = (account, backend) => {
|
|
12
|
-
const sasl = object(object(account[backend]).sasl);
|
|
13
|
-
for (const mechanism of SASL) {
|
|
14
|
-
const { username, authcid } = object(sasl[mechanism]);
|
|
15
|
-
if (username !== undefined || authcid !== undefined)
|
|
16
|
-
return username ?? authcid;
|
|
17
|
-
}
|
|
18
|
-
return undefined;
|
|
19
|
-
};
|
|
20
|
-
/** Himalaya sends mail without `email` set, so many accounts name their address only as the IMAP or SMTP login. */
|
|
21
|
-
const addressOf = (account, config) => account.email ??
|
|
22
|
-
account.from ??
|
|
23
|
-
config.email ??
|
|
24
|
-
config.from ??
|
|
25
|
-
[loginOf(account, "imap"), loginOf(account, "smtp")].find((login) => typeof login === "string" && ADDRESS.test(login));
|
|
26
|
-
const shown = (path, env) => {
|
|
27
|
-
const home = env.HOME ?? env.USERPROFILE;
|
|
28
|
-
return home && path.startsWith(`${home}/`) ? `~${path.slice(home.length)}` : path;
|
|
29
|
-
};
|
|
30
|
-
const configuration = (env, given) => {
|
|
31
|
-
const home = env.HOME ?? env.USERPROFILE;
|
|
32
|
-
if (!home)
|
|
33
|
-
throw new CliError("configuration_error", "HOME is required for Himalaya configuration discovery");
|
|
34
|
-
const explicit = given ?? env.HIMALAYA_CONFIG;
|
|
35
|
-
if (explicit) {
|
|
36
|
-
const path = explicit.replace(/^~(?=\/|$)/, home);
|
|
37
|
-
if (path.includes(":") && !/^[A-Za-z]:[\\/]/.test(path))
|
|
38
|
-
throw new CliError("validation_error", "give one Himalaya config file for account setup");
|
|
39
|
-
return path;
|
|
40
|
-
}
|
|
41
|
-
const candidates = [
|
|
42
|
-
join(env.XDG_CONFIG_HOME ?? join(home, ".config"), "himalaya", "config.toml"),
|
|
43
|
-
join(home, ".himalayarc"),
|
|
44
|
-
];
|
|
45
|
-
const found = candidates.find((path) => existsSync(path));
|
|
46
|
-
if (!found)
|
|
47
|
-
throw new CliError("configuration_error", "set up Himalaya first, or set HIMALAYA_CONFIG to its file");
|
|
48
|
-
return found;
|
|
49
|
-
};
|
|
50
|
-
export const checkMailAccount = async (env, input) => {
|
|
51
|
-
const path = configuration(env, input.config);
|
|
52
|
-
const output = await himalaya(env)(["account", "list", "--json", "--config", path]);
|
|
53
|
-
let listed;
|
|
54
|
-
try {
|
|
55
|
-
listed = JSON.parse(output);
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
throw new CliError("invalid_response", "Himalaya account list did not return JSON");
|
|
59
|
-
}
|
|
60
|
-
const rows = object(listed).accounts;
|
|
61
|
-
if (!Array.isArray(rows) || rows.some((row) => typeof object(row).name !== "string"))
|
|
62
|
-
throw new CliError("invalid_response", "Himalaya account list returned no accounts array");
|
|
63
|
-
const names = rows.map((row) => String(object(row).name));
|
|
64
|
-
if (!input.name || !names.includes(input.name))
|
|
65
|
-
throw new CliError("validation_error", `name one Himalaya account explicitly; choices: ${names.join(", ") || "none"}`);
|
|
66
|
-
let config;
|
|
67
|
-
try {
|
|
68
|
-
config = parse(readFileSync(path, "utf8"));
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
throw new CliError("configuration_error", "the selected Himalaya TOML configuration cannot be read");
|
|
72
|
-
}
|
|
73
|
-
const account = object(object(config.accounts)[input.name]);
|
|
74
|
-
const configured = addressOf(account, config);
|
|
75
|
-
if (configured === undefined)
|
|
76
|
-
throw new CliError("configuration_error", `Himalaya's account ${input.name} names no email address, and its login is not one. ` +
|
|
77
|
-
`Add this line under [accounts.${input.name}] in ${shown(path, env)}: email = "you@example.com"`);
|
|
78
|
-
if (typeof configured !== "string" || !ADDRESS.test(configured))
|
|
79
|
-
throw new CliError("configuration_error", `the email in Himalaya's accounts.${input.name} is not an address; fix it in ${shown(path, env)}`);
|
|
80
|
-
if (!input.address || input.address.toLowerCase() !== configured.toLowerCase())
|
|
81
|
-
throw new CliError("validation_error", `the address must match the selected Himalaya account's email`);
|
|
82
|
-
return { name: input.name, address: configured };
|
|
83
|
-
};
|
|
84
|
-
export const addMailAccount = async (env, input) => {
|
|
85
|
-
const checked = await checkMailAccount(env, input);
|
|
86
|
-
const account = { ...checked, mode: input.mode, ...(input.folders ? { folders: input.folders } : {}) };
|
|
87
|
-
updateConfig((config) => {
|
|
88
|
-
const accounts = config.mail?.accounts ?? [];
|
|
89
|
-
if (accounts.some((one) => one.name === checked.name || one.address.toLowerCase() === checked.address.toLowerCase()))
|
|
90
|
-
throw new CliError("validation_error", "this account name or email is already in Memo; use mail check");
|
|
91
|
-
return { ...config, mail: { ...config.mail, accounts: [...accounts, account] } };
|
|
92
|
-
}, env);
|
|
93
|
-
return account;
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=setup.js.map
|
package/dist/mail/setup.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/mail/setup.ts"],"names":[],"mappings":"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"}
|