@zaclinley/dsh-mailharbor 0.7.1 → 0.8.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 +27 -0
- package/lib/client.js +561 -128
- package/lib/client.js.map +2 -2
- package/lib/index.js +79 -3
- package/lib/index.js.map +2 -2
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -225,6 +225,7 @@ var init_imap = __esm({
|
|
|
225
225
|
mailboxCache = null;
|
|
226
226
|
countCache = /* @__PURE__ */ new Map();
|
|
227
227
|
pageCache = /* @__PURE__ */ new Map();
|
|
228
|
+
readCache = /* @__PURE__ */ new Map();
|
|
228
229
|
keepalive = null;
|
|
229
230
|
static MAILBOX_TTL_MS = 6e4;
|
|
230
231
|
constructor(settings, credentials, options = {}) {
|
|
@@ -426,6 +427,9 @@ var init_imap = __esm({
|
|
|
426
427
|
});
|
|
427
428
|
}
|
|
428
429
|
async read(mailbox, uid) {
|
|
430
|
+
const cacheKey = `${mailbox}:${String(uid)}`;
|
|
431
|
+
const cached = this.readCache.get(cacheKey);
|
|
432
|
+
if (cached !== void 0 && Date.now() - cached.at < 3e5) return cached.message;
|
|
429
433
|
return this.run(async (client) => {
|
|
430
434
|
const lock = await client.getMailboxLock(mailbox);
|
|
431
435
|
try {
|
|
@@ -440,7 +444,7 @@ var init_imap = __esm({
|
|
|
440
444
|
const parsed = await simpleParser2(message.source);
|
|
441
445
|
const base = toMessage(message);
|
|
442
446
|
const html = typeof parsed.html === "string" ? parsed.html : Buffer.isBuffer(parsed.html) ? parsed.html.toString("utf8") : null;
|
|
443
|
-
|
|
447
|
+
const detail = {
|
|
444
448
|
...base,
|
|
445
449
|
text: typeof parsed.text === "string" ? parsed.text : "",
|
|
446
450
|
html: html === "" ? null : html,
|
|
@@ -448,6 +452,12 @@ var init_imap = __esm({
|
|
|
448
452
|
inReplyTo: normalizeId2(parsed.inReplyTo),
|
|
449
453
|
references: String(parsed.references ?? "").split(/\s+/).map(normalizeId2).filter((item) => item !== "")
|
|
450
454
|
};
|
|
455
|
+
this.readCache.set(cacheKey, { at: Date.now(), message: detail });
|
|
456
|
+
if (this.readCache.size > 40) {
|
|
457
|
+
const oldest = this.readCache.keys().next().value;
|
|
458
|
+
if (oldest !== void 0) this.readCache.delete(oldest);
|
|
459
|
+
}
|
|
460
|
+
return detail;
|
|
451
461
|
} finally {
|
|
452
462
|
lock.release();
|
|
453
463
|
}
|
|
@@ -537,6 +547,7 @@ var init_imap = __esm({
|
|
|
537
547
|
async dispose() {
|
|
538
548
|
this.disposed = true;
|
|
539
549
|
this.pageCache.clear();
|
|
550
|
+
this.readCache.clear();
|
|
540
551
|
this.stopKeepalive();
|
|
541
552
|
await this.reset("dispose");
|
|
542
553
|
}
|
|
@@ -878,6 +889,27 @@ async function pickDirectory(defaultPath) {
|
|
|
878
889
|
throw new Error("\u5F53\u524D\u73AF\u5883\u65E0\u6CD5\u6253\u5F00\u76EE\u5F55\u9009\u62E9\u5668\uFF0C\u8BF7\u624B\u52A8\u8F93\u5165\u8DEF\u5F84");
|
|
879
890
|
}
|
|
880
891
|
}
|
|
892
|
+
async function openPath(path) {
|
|
893
|
+
try {
|
|
894
|
+
const require2 = createRequire(import.meta.url);
|
|
895
|
+
const electron = require2("electron");
|
|
896
|
+
if (electron.shell !== void 0) {
|
|
897
|
+
const error = await electron.shell.openPath(path);
|
|
898
|
+
if (error !== "") throw new Error(error);
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
} catch {
|
|
902
|
+
}
|
|
903
|
+
if (process.platform === "darwin") {
|
|
904
|
+
await run("open", [path]);
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
if (process.platform === "win32") {
|
|
908
|
+
await run("explorer", [path]);
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
await run("xdg-open", [path]);
|
|
912
|
+
}
|
|
881
913
|
|
|
882
914
|
// src/host/backup.ts
|
|
883
915
|
init_address();
|
|
@@ -1760,7 +1792,7 @@ var SEARCH_SYSTEM = `\u4F60\u662F\u90AE\u4EF6\u641C\u7D22\u52A9\u624B\u3002\u628
|
|
|
1760
1792
|
var TASK_SYSTEM = `\u4F60\u662F\u4EFB\u52A1\u63D0\u53D6\u52A9\u624B\u3002\u4ECE\u90AE\u4EF6\u4E2D\u63D0\u53D6\u9700\u8981\u7528\u6237\u5904\u7406\u7684\u5177\u4F53\u4E8B\u9879\u3002
|
|
1761
1793
|
|
|
1762
1794
|
\u53EA\u8F93\u51FA\u4E00\u4E2A JSON \u6570\u7EC4\uFF0C\u4E0D\u8981\u8F93\u51FA\u89E3\u91CA\u3001Markdown \u6216\u4EE3\u7801\u5757\u6807\u8BB0\u3002\u6BCF\u4E2A\u5143\u7D20\uFF1A
|
|
1763
|
-
{"title": "\u4EFB\u52A1\u6807\u9898\uFF08\u52A8\u8BCD\u5F00\u5934\uFF0C\u5C3D\u91CF\u5177\u4F53\uFF09", "due": "YYYY-MM-DD \u6216\u7A7A\u5B57\u7B26\u4E32", "priority": 0 \u5230 9 \u7684\u6574\u6570, "owner": "\
|
|
1795
|
+
{"title": "\u4EFB\u52A1\u6807\u9898\uFF08\u52A8\u8BCD\u5F00\u5934\uFF0C\u5C3D\u91CF\u5177\u4F53\uFF09", "due": "YYYY-MM-DD \u6216\u7A7A\u5B57\u7B26\u4E32", "priority": 0 \u5230 9 \u7684\u6574\u6570, "owner": "\u8FD9\u4E2A\u4E8B\u8BE5\u8054\u7CFB\u8C01\uFF08\u90AE\u4EF6\u91CC\u7684\u8054\u7CFB\u4EBA\uFF09\u6216\u7A7A\u5B57\u7B26\u4E32", "notes": "\u4E00\u53E5\u6765\u6E90\u4F9D\u636E"}
|
|
1764
1796
|
|
|
1765
1797
|
\u89C4\u5219\uFF1A
|
|
1766
1798
|
- \u53EA\u63D0\u53D6\u90AE\u4EF6\u91CC\u660E\u786E\u8981\u6C42\u3001\u6216\u660E\u663E\u9700\u8981\u8DDF\u8FDB\u7684\u4E8B\u9879
|
|
@@ -2171,6 +2203,14 @@ var ProjectStore = class {
|
|
|
2171
2203
|
this.flush();
|
|
2172
2204
|
return project;
|
|
2173
2205
|
}
|
|
2206
|
+
remove(id) {
|
|
2207
|
+
const data = this.load();
|
|
2208
|
+
const index = data.projects.findIndex((project) => project.id === id);
|
|
2209
|
+
if (index < 0) return false;
|
|
2210
|
+
data.projects.splice(index, 1);
|
|
2211
|
+
this.flush();
|
|
2212
|
+
return true;
|
|
2213
|
+
}
|
|
2174
2214
|
addThread(id, thread) {
|
|
2175
2215
|
const project = this.get(id);
|
|
2176
2216
|
if (project === void 0) return void 0;
|
|
@@ -2309,7 +2349,7 @@ ${conversation.trim()}
|
|
|
2309
2349
|
}
|
|
2310
2350
|
|
|
2311
2351
|
// src/host/version.ts
|
|
2312
|
-
var VERSION = "0.
|
|
2352
|
+
var VERSION = "0.8.0";
|
|
2313
2353
|
|
|
2314
2354
|
// src/host/api.ts
|
|
2315
2355
|
init_smtp();
|
|
@@ -2958,6 +2998,37 @@ function buildRouter(runtime) {
|
|
|
2958
2998
|
});
|
|
2959
2999
|
return { project: projectView(result.project), warnings: result.warnings };
|
|
2960
3000
|
});
|
|
3001
|
+
router.patch("/projects/:id", async ({ params, body }) => {
|
|
3002
|
+
const payload = await body();
|
|
3003
|
+
const name2 = String(payload.name ?? "").trim();
|
|
3004
|
+
if (name2 === "") throw new HttpError(400, "\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
3005
|
+
const project = runtime.projects().update(String(params.id ?? ""), { name: name2 });
|
|
3006
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
3007
|
+
return { project: projectView(project) };
|
|
3008
|
+
});
|
|
3009
|
+
router.delete("/projects/:id", ({ params }) => {
|
|
3010
|
+
const id = String(params.id ?? "");
|
|
3011
|
+
const project = runtime.projects().get(id);
|
|
3012
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
3013
|
+
const removed = runtime.projects().remove(id);
|
|
3014
|
+
const unlinked = runtime.tasks().clearProject(id);
|
|
3015
|
+
return {
|
|
3016
|
+
ok: removed,
|
|
3017
|
+
path: project.path,
|
|
3018
|
+
unlinkedTasks: unlinked,
|
|
3019
|
+
workspaceKept: project.workspaceId !== ""
|
|
3020
|
+
};
|
|
3021
|
+
});
|
|
3022
|
+
router.post("/projects/:id/open", async ({ params }) => {
|
|
3023
|
+
const project = runtime.projects().get(String(params.id ?? ""));
|
|
3024
|
+
if (project === void 0) throw new HttpError(404, "\u9879\u76EE\u4E0D\u5B58\u5728");
|
|
3025
|
+
try {
|
|
3026
|
+
await openPath(project.path);
|
|
3027
|
+
return { path: project.path };
|
|
3028
|
+
} catch (error) {
|
|
3029
|
+
throw new HttpError(400, error instanceof Error ? error.message : String(error));
|
|
3030
|
+
}
|
|
3031
|
+
});
|
|
2961
3032
|
router.post("/projects/:id/messages", async ({ params, body }) => {
|
|
2962
3033
|
const payload = await body();
|
|
2963
3034
|
const account = accountFromPayload(runtime, payload);
|
|
@@ -3854,6 +3925,11 @@ var TaskStore = class {
|
|
|
3854
3925
|
if (task === void 0) throw new Error("\u4EFB\u52A1\u66F4\u65B0\u5931\u8D25");
|
|
3855
3926
|
return task;
|
|
3856
3927
|
}
|
|
3928
|
+
/** Unlink tasks when their project is deleted. */
|
|
3929
|
+
clearProject(projectId) {
|
|
3930
|
+
const result = this.open().prepare("UPDATE tasks SET project_id = NULL, dirty = 1, updated_at = ? WHERE project_id = ?").run(now(), projectId);
|
|
3931
|
+
return Number(result.changes);
|
|
3932
|
+
}
|
|
3857
3933
|
remove(id) {
|
|
3858
3934
|
const current = this.get(id);
|
|
3859
3935
|
if (current === void 0) return false;
|