@pome-sh/cli 0.7.0 → 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/dist/build-info.json +3 -3
- package/dist/src/cli/docs-topics.js +5 -3
- package/dist/src/runner/runTask.d.ts +14 -0
- package/dist/src/task/taskSchema.d.ts +52 -16
- package/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +27 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js +12 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/task.d.ts +18 -0
- package/node_modules/@pome-sh/shared-types/package.json +1 -1
- package/node_modules/@pome-sh/shared-types/trace-contract.json +1 -1
- package/node_modules/@pome-sh/twin-gmail/CHANGELOG.md +21 -0
- package/node_modules/@pome-sh/twin-gmail/HOSTED.md +37 -15
- package/node_modules/@pome-sh/twin-gmail/LIMITS.md +10 -0
- package/node_modules/@pome-sh/twin-gmail/README.md +52 -11
- package/node_modules/@pome-sh/twin-gmail/dist/fixtures/mcp-tools-list.canonical.json +242 -7
- package/node_modules/@pome-sh/twin-gmail/dist/src/db.js +6 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/db.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.d.ts +41 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.js +138 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/filters.d.ts +10 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/{domain-search.js → domain/filters.js} +52 -36
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/filters.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/{domain.d.ts → domain/gmail-domain.d.ts} +45 -34
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/gmail-domain.js +174 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/gmail-domain.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.d.ts +8 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.js +122 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.d.ts +4 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.js +5 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.d.ts +40 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.js +122 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.d.ts +49 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.js +276 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.d.ts +19 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.js +179 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.d.ts +27 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.js +98 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/errors.js +2 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/errors.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.d.ts +21 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.js +52 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.d.ts +1 -6
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.js +0 -11
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.d.ts +4 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.js +3 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.d.ts +48 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.js +23 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.d.ts +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.js +39 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-drafts.js +4 -5
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-drafts.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.d.ts +2 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.js +4 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-messages.js +7 -8
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-messages.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-resources.js +20 -21
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-resources.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes.d.ts +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.d.ts +2 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.js +4 -6
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.d.ts +4 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.js +179 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.d.ts +61 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.js +318 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.d.ts +3 -61
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.js +2 -503
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.d.ts +13 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.js +3 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/server.js +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/server.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/storage.js +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/storage.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.d.ts +2 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.js +1 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/types.d.ts +1 -0
- package/node_modules/@pome-sh/twin-gmail/fidelity.inventory.json +42 -435
- package/node_modules/@pome-sh/twin-gmail/fixtures/README.md +4 -4
- package/node_modules/@pome-sh/twin-gmail/fixtures/mcp-tools-list.canonical.json +242 -7
- package/node_modules/@pome-sh/twin-gmail/fixtures/mcp-tools-list.meta.json +3 -3
- package/node_modules/@pome-sh/twin-gmail/package.json +3 -2
- package/node_modules/hono/dist/cjs/client/utils.js +1 -1
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/cjs/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +8 -3
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/body.js +6 -0
- package/node_modules/hono/dist/cjs/utils/url.js +1 -1
- package/node_modules/hono/dist/client/utils.js +1 -1
- package/node_modules/hono/dist/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -3
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/helper/websocket/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/combine/index.d.ts +1 -1
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/body.js +6 -0
- package/node_modules/hono/dist/utils/url.js +1 -1
- package/node_modules/hono/package.json +3 -3
- package/package.json +3 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain-search.d.ts +0 -5
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain-search.js.map +0 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain.js +0 -407
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain.js.map +0 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.d.ts +0 -75
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.js +0 -282
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.js.map +0 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { invalidArgument, notFound } from "../errors.js";
|
|
3
|
+
import { nextId } from "../storage.js";
|
|
4
|
+
export function createLabel(domain, email, name, color) {
|
|
5
|
+
const mailboxId = domain.mailboxId(email);
|
|
6
|
+
if (!name.trim())
|
|
7
|
+
invalidArgument("Label name is required");
|
|
8
|
+
return domain.db.transaction(() => {
|
|
9
|
+
const id = nextId(domain.db, mailboxId, "label_counter", "Label");
|
|
10
|
+
try {
|
|
11
|
+
domain.db
|
|
12
|
+
.prepare("INSERT INTO labels(mailbox_id, id, name, type, text_color, background_color) VALUES (?, ?, ?, 'user', ?, ?)")
|
|
13
|
+
.run(mailboxId, id, name.trim(), color?.textColor ?? null, color?.backgroundColor ?? null);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
invalidArgument(`Label already exists: ${name}`);
|
|
17
|
+
}
|
|
18
|
+
return { id, name: name.trim() };
|
|
19
|
+
}).immediate();
|
|
20
|
+
}
|
|
21
|
+
export function listUserLabels(domain, email) {
|
|
22
|
+
const mailboxId = domain.mailboxId(email);
|
|
23
|
+
const rows = domain.db
|
|
24
|
+
.prepare(`SELECT l.id, l.name, l.text_color, l.background_color,
|
|
25
|
+
COUNT(DISTINCT m.thread_id) AS threads_total,
|
|
26
|
+
COUNT(DISTINCT CASE WHEN unread.message_id IS NOT NULL THEN m.thread_id END) AS threads_unread
|
|
27
|
+
FROM labels l
|
|
28
|
+
LEFT JOIN message_labels ml
|
|
29
|
+
ON ml.mailbox_id = l.mailbox_id AND ml.label_id = l.id
|
|
30
|
+
LEFT JOIN messages m
|
|
31
|
+
ON m.mailbox_id = ml.mailbox_id AND m.id = ml.message_id
|
|
32
|
+
LEFT JOIN message_labels unread
|
|
33
|
+
ON unread.mailbox_id = m.mailbox_id
|
|
34
|
+
AND unread.message_id = m.id
|
|
35
|
+
AND unread.label_id = 'UNREAD'
|
|
36
|
+
WHERE l.mailbox_id = ? AND l.type = 'user'
|
|
37
|
+
GROUP BY l.mailbox_id, l.id
|
|
38
|
+
ORDER BY l.name COLLATE NOCASE, l.id`)
|
|
39
|
+
.all(mailboxId);
|
|
40
|
+
return rows.map((row) => ({
|
|
41
|
+
id: row.id,
|
|
42
|
+
name: row.name,
|
|
43
|
+
...(row.text_color || row.background_color
|
|
44
|
+
? {
|
|
45
|
+
color: {
|
|
46
|
+
...(row.text_color ? { textColor: row.text_color } : {}),
|
|
47
|
+
...(row.background_color ? { backgroundColor: row.background_color } : {}),
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
: {}),
|
|
51
|
+
threadsTotal: row.threads_total,
|
|
52
|
+
threadsUnread: row.threads_unread,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
/** Batch label list with counts (replaces per-label N+1 from rest-store). */
|
|
56
|
+
export function labels(domain, email) {
|
|
57
|
+
const mailboxId = domain.mailboxId(email);
|
|
58
|
+
const rows = domain.db
|
|
59
|
+
.prepare(`SELECT l.id, l.name, l.type, l.text_color, l.background_color,
|
|
60
|
+
COUNT(DISTINCT ml.message_id) AS messagesTotal,
|
|
61
|
+
COUNT(DISTINCT CASE WHEN unread.message_id IS NOT NULL THEN ml.message_id END) AS messagesUnread,
|
|
62
|
+
COUNT(DISTINCT m.thread_id) AS threadsTotal,
|
|
63
|
+
COUNT(DISTINCT CASE WHEN unread.message_id IS NOT NULL THEN m.thread_id END) AS threadsUnread
|
|
64
|
+
FROM labels l
|
|
65
|
+
LEFT JOIN message_labels ml
|
|
66
|
+
ON ml.mailbox_id = l.mailbox_id AND ml.label_id = l.id
|
|
67
|
+
LEFT JOIN messages m
|
|
68
|
+
ON m.mailbox_id = ml.mailbox_id AND m.id = ml.message_id
|
|
69
|
+
LEFT JOIN message_labels unread
|
|
70
|
+
ON unread.mailbox_id = ml.mailbox_id
|
|
71
|
+
AND unread.message_id = ml.message_id
|
|
72
|
+
AND unread.label_id = 'UNREAD'
|
|
73
|
+
WHERE l.mailbox_id = ?
|
|
74
|
+
GROUP BY l.mailbox_id, l.id
|
|
75
|
+
ORDER BY CASE l.type WHEN 'system' THEN 0 ELSE 1 END, l.name COLLATE NOCASE, l.id`)
|
|
76
|
+
.all(mailboxId);
|
|
77
|
+
return rows.map((row) => ({
|
|
78
|
+
id: row.id,
|
|
79
|
+
name: row.name,
|
|
80
|
+
type: row.type,
|
|
81
|
+
textColor: row.text_color,
|
|
82
|
+
backgroundColor: row.background_color,
|
|
83
|
+
messagesTotal: row.messagesTotal,
|
|
84
|
+
messagesUnread: row.messagesUnread,
|
|
85
|
+
threadsTotal: row.threadsTotal,
|
|
86
|
+
threadsUnread: row.threadsUnread,
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
export function label(domain, email, labelId) {
|
|
90
|
+
const found = labels(domain, email).find((item) => item.id === labelId);
|
|
91
|
+
if (!found)
|
|
92
|
+
notFound("Label");
|
|
93
|
+
return found;
|
|
94
|
+
}
|
|
95
|
+
export function updateLabel(domain, email, labelId, input, replace) {
|
|
96
|
+
const mailboxId = domain.mailboxId(email);
|
|
97
|
+
const current = label(domain, email, labelId);
|
|
98
|
+
if (current.type !== "user")
|
|
99
|
+
invalidArgument("System labels cannot be modified");
|
|
100
|
+
const name = replace ? input.name : input.name ?? current.name;
|
|
101
|
+
if (!name?.trim())
|
|
102
|
+
invalidArgument("Label name is required");
|
|
103
|
+
const textColor = input.color?.textColor ?? (replace ? null : current.textColor);
|
|
104
|
+
const backgroundColor = input.color?.backgroundColor ?? (replace ? null : current.backgroundColor);
|
|
105
|
+
try {
|
|
106
|
+
domain.db
|
|
107
|
+
.prepare("UPDATE labels SET name = ?, text_color = ?, background_color = ? WHERE mailbox_id = ? AND id = ?")
|
|
108
|
+
.run(name.trim(), textColor, backgroundColor, mailboxId, labelId);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
invalidArgument(`Label already exists: ${name}`);
|
|
112
|
+
}
|
|
113
|
+
return label(domain, email, labelId);
|
|
114
|
+
}
|
|
115
|
+
export function deleteLabel(domain, email, labelId) {
|
|
116
|
+
const mailboxId = domain.mailboxId(email);
|
|
117
|
+
const current = label(domain, email, labelId);
|
|
118
|
+
if (current.type !== "user")
|
|
119
|
+
invalidArgument("System labels cannot be deleted");
|
|
120
|
+
domain.db.prepare("DELETE FROM labels WHERE mailbox_id = ? AND id = ?").run(mailboxId, labelId);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=labels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/domain/labels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { SemanticMessage } from "../types.js";
|
|
2
|
+
import type { GmailDomain } from "./gmail-domain.js";
|
|
3
|
+
export declare function getRaw(domain: GmailDomain, email: string, messageId: string): Buffer;
|
|
4
|
+
export declare function getMessage(domain: GmailDomain, email: string, messageId: string): SemanticMessage;
|
|
5
|
+
export declare function getThread(domain: GmailDomain, email: string, threadId: string): {
|
|
6
|
+
id: string;
|
|
7
|
+
labelIds: string[];
|
|
8
|
+
messages: SemanticMessage[];
|
|
9
|
+
};
|
|
10
|
+
export declare function insertMessage(domain: GmailDomain, email: string, raw: Uint8Array | string, options?: {
|
|
11
|
+
threadId?: string;
|
|
12
|
+
labels?: string[];
|
|
13
|
+
incoming?: boolean;
|
|
14
|
+
}): SemanticMessage;
|
|
15
|
+
export declare function sendMessage(domain: GmailDomain, email: string, raw: Uint8Array | string, options?: {
|
|
16
|
+
threadId?: string;
|
|
17
|
+
}): {
|
|
18
|
+
sender: SemanticMessage;
|
|
19
|
+
deliveries: Array<{
|
|
20
|
+
mailboxEmail: string;
|
|
21
|
+
message: SemanticMessage;
|
|
22
|
+
}>;
|
|
23
|
+
};
|
|
24
|
+
export declare function modifyMessageLabels(domain: GmailDomain, email: string, messageId: string, add?: string[], remove?: string[]): SemanticMessage;
|
|
25
|
+
export declare function modifyThreadLabels(domain: GmailDomain, email: string, threadId: string, add?: string[], remove?: string[]): {
|
|
26
|
+
id: string;
|
|
27
|
+
labelIds: string[];
|
|
28
|
+
messages: SemanticMessage[];
|
|
29
|
+
};
|
|
30
|
+
export declare function deleteMessage(domain: GmailDomain, email: string, messageId: string): void;
|
|
31
|
+
export declare function batchDeleteMessages(domain: GmailDomain, email: string, messageIds: string[]): void;
|
|
32
|
+
export declare function deleteThread(domain: GmailDomain, email: string, threadId: string): void;
|
|
33
|
+
export declare function headers(domain: GmailDomain, email: string, messageId: string): Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
value: string;
|
|
36
|
+
}>;
|
|
37
|
+
export declare function attachment(domain: GmailDomain, email: string, messageId: string, attachmentId: string): {
|
|
38
|
+
size: number;
|
|
39
|
+
data: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function applyInternalDateSource(domain: GmailDomain, email: string, messageId: string, source: "receivedTime" | "dateHeader"): SemanticMessage;
|
|
42
|
+
export declare function searchMessages(domain: GmailDomain, email: string, query?: string, options?: {
|
|
43
|
+
includeTrash?: boolean;
|
|
44
|
+
}): SemanticMessage[];
|
|
45
|
+
export declare function searchThreads(domain: GmailDomain, email: string, query?: string, options?: {
|
|
46
|
+
includeTrash?: boolean;
|
|
47
|
+
}): ReturnType<typeof getThread>[];
|
|
48
|
+
export declare function removeEmptyThread(domain: GmailDomain, mailboxId: number, threadId: string): void;
|
|
49
|
+
export declare function acceptedRaw(raw: Uint8Array | string): Buffer;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import { invalidArgument, notFound } from "../errors.js";
|
|
3
|
+
import { checkFault } from "../faults.js";
|
|
4
|
+
import { canonicalRaw, decodeGmailRaw, parseMime, stripBcc } from "../mime.js";
|
|
5
|
+
import { matchesSearch } from "../search-match.js";
|
|
6
|
+
import { SEARCH_MAILBOX_MESSAGE_BUDGET, validateSearchQuery } from "../search-parse.js";
|
|
7
|
+
import { addHistory, assertLabels, insertStoredMessage, rawMessage, semanticMessage, } from "../storage.js";
|
|
8
|
+
import { applyInboundFilters } from "./filters.js";
|
|
9
|
+
import { batchSearchDocuments, batchSemanticMessages, searchNow } from "./hydrate.js";
|
|
10
|
+
import { compileSearchToSql } from "./search-sql.js";
|
|
11
|
+
export function getRaw(domain, email, messageId) {
|
|
12
|
+
return rawMessage(domain.db, domain.mailboxId(email), messageId);
|
|
13
|
+
}
|
|
14
|
+
export function getMessage(domain, email, messageId) {
|
|
15
|
+
return semanticMessage(domain.db, domain.mailboxId(email), messageId);
|
|
16
|
+
}
|
|
17
|
+
export function getThread(domain, email, threadId) {
|
|
18
|
+
const mailboxId = domain.mailboxId(email);
|
|
19
|
+
const rows = domain.db
|
|
20
|
+
.prepare("SELECT id FROM messages WHERE mailbox_id = ? AND thread_id = ? ORDER BY internal_date, id")
|
|
21
|
+
.all(mailboxId, threadId);
|
|
22
|
+
if (!rows.length)
|
|
23
|
+
notFound("Thread");
|
|
24
|
+
const messages = batchSemanticMessages(domain.db, mailboxId, rows.map((row) => row.id));
|
|
25
|
+
return {
|
|
26
|
+
id: threadId,
|
|
27
|
+
labelIds: [...new Set(messages.flatMap((message) => message.labelIds))].sort(),
|
|
28
|
+
messages,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function insertMessage(domain, email, raw, options = {}) {
|
|
32
|
+
const mailboxId = domain.mailboxId(email);
|
|
33
|
+
const bytes = acceptedRaw(raw);
|
|
34
|
+
return domain.db.transaction(() => {
|
|
35
|
+
const message = insertStoredMessage(domain.db, mailboxId, bytes, {
|
|
36
|
+
threadId: options.threadId,
|
|
37
|
+
labels: options.labels ?? (options.incoming ? ["INBOX"] : []),
|
|
38
|
+
deliveredTo: options.incoming ? email : undefined,
|
|
39
|
+
});
|
|
40
|
+
if (options.incoming)
|
|
41
|
+
applyInboundFilters(domain.db, mailboxId, message.id);
|
|
42
|
+
return semanticMessage(domain.db, mailboxId, message.id);
|
|
43
|
+
}).immediate();
|
|
44
|
+
}
|
|
45
|
+
export function sendMessage(domain, email, raw, options = {}) {
|
|
46
|
+
checkFault(domain.db, "messages.send");
|
|
47
|
+
const senderMailboxId = domain.mailboxId(email);
|
|
48
|
+
const bytes = acceptedRaw(raw);
|
|
49
|
+
const parsed = parseMime(bytes);
|
|
50
|
+
assertAcceptedFrom(domain, senderMailboxId, parsed.from);
|
|
51
|
+
return domain.db.transaction(() => {
|
|
52
|
+
const recipientEmails = [...new Set([...parsed.to, ...parsed.cc, ...parsed.bcc].map((item) => item.toLowerCase()))];
|
|
53
|
+
const selfDelivery = deliveryMode(domain) === "seeded-mailboxes" && recipientEmails.includes(email.toLowerCase());
|
|
54
|
+
const sender = insertStoredMessage(domain.db, senderMailboxId, bytes, {
|
|
55
|
+
threadId: options.threadId,
|
|
56
|
+
labels: selfDelivery ? ["INBOX", "SENT"] : ["SENT"],
|
|
57
|
+
});
|
|
58
|
+
if (selfDelivery)
|
|
59
|
+
applyInboundFilters(domain.db, senderMailboxId, sender.id);
|
|
60
|
+
const deliveries = [];
|
|
61
|
+
if (deliveryMode(domain) === "seeded-mailboxes") {
|
|
62
|
+
const visibleRaw = stripBcc(bytes);
|
|
63
|
+
for (const recipient of recipientEmails) {
|
|
64
|
+
if (recipient === email.toLowerCase())
|
|
65
|
+
continue;
|
|
66
|
+
const mailbox = domain.db
|
|
67
|
+
.prepare("SELECT id, email FROM mailboxes WHERE email = ? COLLATE NOCASE")
|
|
68
|
+
.get(recipient);
|
|
69
|
+
if (!mailbox)
|
|
70
|
+
continue;
|
|
71
|
+
const copy = insertStoredMessage(domain.db, mailbox.id, visibleRaw, {
|
|
72
|
+
labels: ["INBOX"],
|
|
73
|
+
deliveredTo: mailbox.email,
|
|
74
|
+
});
|
|
75
|
+
applyInboundFilters(domain.db, mailbox.id, copy.id);
|
|
76
|
+
deliveries.push({ mailboxEmail: mailbox.email, message: semanticMessage(domain.db, mailbox.id, copy.id) });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { sender: semanticMessage(domain.db, senderMailboxId, sender.id), deliveries };
|
|
80
|
+
}).immediate();
|
|
81
|
+
}
|
|
82
|
+
export function modifyMessageLabels(domain, email, messageId, add = [], remove = []) {
|
|
83
|
+
const mailboxId = domain.mailboxId(email);
|
|
84
|
+
return domain.db.transaction(() => {
|
|
85
|
+
const before = semanticMessage(domain.db, mailboxId, messageId);
|
|
86
|
+
if (before.labelIds.includes("DRAFT") && (add.some((id) => id !== "DRAFT") || remove.includes("DRAFT"))) {
|
|
87
|
+
invalidArgument("Draft messages may only carry the DRAFT label");
|
|
88
|
+
}
|
|
89
|
+
if (!before.labelIds.includes("DRAFT") && add.includes("DRAFT")) {
|
|
90
|
+
invalidArgument("The DRAFT label is managed by draft operations");
|
|
91
|
+
}
|
|
92
|
+
assertLabels(domain.db, mailboxId, [...add, ...remove]);
|
|
93
|
+
// TRASH and SPAM are mutually exclusive (Gmail system labels).
|
|
94
|
+
const addSet = new Set(add);
|
|
95
|
+
const removeSet = new Set(remove);
|
|
96
|
+
if (addSet.has("TRASH"))
|
|
97
|
+
removeSet.add("SPAM");
|
|
98
|
+
if (addSet.has("SPAM"))
|
|
99
|
+
removeSet.add("TRASH");
|
|
100
|
+
const actualRemove = [...removeSet].filter((label) => before.labelIds.includes(label));
|
|
101
|
+
const actualAdd = [...addSet].filter((label) => !before.labelIds.includes(label));
|
|
102
|
+
for (const label of actualRemove) {
|
|
103
|
+
domain.db
|
|
104
|
+
.prepare("DELETE FROM message_labels WHERE mailbox_id = ? AND message_id = ? AND label_id = ?")
|
|
105
|
+
.run(mailboxId, messageId, label);
|
|
106
|
+
}
|
|
107
|
+
for (const label of actualAdd) {
|
|
108
|
+
domain.db
|
|
109
|
+
.prepare("INSERT OR IGNORE INTO message_labels(mailbox_id, message_id, label_id) VALUES (?, ?, ?)")
|
|
110
|
+
.run(mailboxId, messageId, label);
|
|
111
|
+
}
|
|
112
|
+
if (actualAdd.length)
|
|
113
|
+
addHistory(domain.db, mailboxId, messageId, before.threadId, "labelAdded", actualAdd);
|
|
114
|
+
if (actualRemove.length) {
|
|
115
|
+
addHistory(domain.db, mailboxId, messageId, before.threadId, "labelRemoved", actualRemove);
|
|
116
|
+
}
|
|
117
|
+
return semanticMessage(domain.db, mailboxId, messageId);
|
|
118
|
+
}).immediate();
|
|
119
|
+
}
|
|
120
|
+
export function modifyThreadLabels(domain, email, threadId, add = [], remove = []) {
|
|
121
|
+
return domain.db.transaction(() => {
|
|
122
|
+
const thread = getThread(domain, email, threadId);
|
|
123
|
+
for (const message of thread.messages)
|
|
124
|
+
modifyMessageLabels(domain, email, message.id, add, remove);
|
|
125
|
+
return getThread(domain, email, threadId);
|
|
126
|
+
}).immediate();
|
|
127
|
+
}
|
|
128
|
+
export function deleteMessage(domain, email, messageId) {
|
|
129
|
+
const mailboxId = domain.mailboxId(email);
|
|
130
|
+
domain.db.transaction(() => {
|
|
131
|
+
const message = semanticMessage(domain.db, mailboxId, messageId);
|
|
132
|
+
domain.db.prepare("DELETE FROM messages WHERE mailbox_id = ? AND id = ?").run(mailboxId, messageId);
|
|
133
|
+
addHistory(domain.db, mailboxId, messageId, message.threadId, "messageDeleted");
|
|
134
|
+
removeEmptyThread(domain, mailboxId, message.threadId);
|
|
135
|
+
}).immediate();
|
|
136
|
+
}
|
|
137
|
+
export function batchDeleteMessages(domain, email, messageIds) {
|
|
138
|
+
const mailboxId = domain.mailboxId(email);
|
|
139
|
+
domain.db.transaction(() => {
|
|
140
|
+
for (const messageId of messageIds) {
|
|
141
|
+
const exists = domain.db
|
|
142
|
+
.prepare("SELECT thread_id FROM messages WHERE mailbox_id = ? AND id = ?")
|
|
143
|
+
.get(mailboxId, messageId);
|
|
144
|
+
if (!exists)
|
|
145
|
+
continue;
|
|
146
|
+
domain.db.prepare("DELETE FROM messages WHERE mailbox_id = ? AND id = ?").run(mailboxId, messageId);
|
|
147
|
+
addHistory(domain.db, mailboxId, messageId, exists.thread_id, "messageDeleted");
|
|
148
|
+
removeEmptyThread(domain, mailboxId, exists.thread_id);
|
|
149
|
+
}
|
|
150
|
+
}).immediate();
|
|
151
|
+
}
|
|
152
|
+
export function deleteThread(domain, email, threadId) {
|
|
153
|
+
const mailboxId = domain.mailboxId(email);
|
|
154
|
+
domain.db.transaction(() => {
|
|
155
|
+
const thread = getThread(domain, email, threadId);
|
|
156
|
+
domain.db.prepare("DELETE FROM threads WHERE mailbox_id = ? AND id = ?").run(mailboxId, threadId);
|
|
157
|
+
for (const message of thread.messages) {
|
|
158
|
+
addHistory(domain.db, mailboxId, message.id, threadId, "messageDeleted");
|
|
159
|
+
}
|
|
160
|
+
}).immediate();
|
|
161
|
+
}
|
|
162
|
+
export function headers(domain, email, messageId) {
|
|
163
|
+
const mailboxId = domain.mailboxId(email);
|
|
164
|
+
const row = domain.db
|
|
165
|
+
.prepare("SELECT headers_json FROM messages WHERE mailbox_id = ? AND id = ?")
|
|
166
|
+
.get(mailboxId, messageId);
|
|
167
|
+
if (!row)
|
|
168
|
+
notFound("Message");
|
|
169
|
+
return JSON.parse(row.headers_json);
|
|
170
|
+
}
|
|
171
|
+
export function attachment(domain, email, messageId, attachmentId) {
|
|
172
|
+
const mailboxId = domain.mailboxId(email);
|
|
173
|
+
const row = domain.db
|
|
174
|
+
.prepare("SELECT size, data FROM attachments WHERE mailbox_id = ? AND message_id = ? AND id = ?")
|
|
175
|
+
.get(mailboxId, messageId, attachmentId);
|
|
176
|
+
if (!row)
|
|
177
|
+
notFound("Attachment");
|
|
178
|
+
return { size: row.size, data: Buffer.from(row.data).toString("base64url") };
|
|
179
|
+
}
|
|
180
|
+
export function applyInternalDateSource(domain, email, messageId, source) {
|
|
181
|
+
const mailboxId = domain.mailboxId(email);
|
|
182
|
+
if (source === "receivedTime") {
|
|
183
|
+
const history = domain.db
|
|
184
|
+
.prepare(`SELECT created_at FROM history
|
|
185
|
+
WHERE mailbox_id = ? AND message_id = ? AND event_type = 'messageAdded'
|
|
186
|
+
ORDER BY id DESC LIMIT 1`)
|
|
187
|
+
.get(mailboxId, messageId);
|
|
188
|
+
if (history) {
|
|
189
|
+
domain.db
|
|
190
|
+
.prepare("UPDATE messages SET internal_date = ? WHERE mailbox_id = ? AND id = ?")
|
|
191
|
+
.run(Date.parse(history.created_at), mailboxId, messageId);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return semanticMessage(domain.db, mailboxId, messageId);
|
|
195
|
+
}
|
|
196
|
+
export function searchMessages(domain, email, query = "", options = {}) {
|
|
197
|
+
const mailboxId = domain.mailboxId(email);
|
|
198
|
+
const ast = validateSearchQuery(query);
|
|
199
|
+
const explicitAnywhere = /\bin:(anywhere|trash|spam|draft)\b/i.test(query);
|
|
200
|
+
const plan = compileSearchToSql(ast, {
|
|
201
|
+
includeTrash: options.includeTrash,
|
|
202
|
+
explicitAnywhere,
|
|
203
|
+
});
|
|
204
|
+
let candidateIds;
|
|
205
|
+
let sqlExact = false;
|
|
206
|
+
if (plan) {
|
|
207
|
+
const where = plan.clauses.length ? `AND ${plan.clauses.join(" AND ")}` : "";
|
|
208
|
+
candidateIds = domain.db
|
|
209
|
+
.prepare(`SELECT id FROM messages
|
|
210
|
+
WHERE mailbox_id = ? ${where}
|
|
211
|
+
ORDER BY internal_date DESC, id DESC`)
|
|
212
|
+
.all(mailboxId, ...plan.params).map((row) => row.id);
|
|
213
|
+
sqlExact = plan.exact;
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
const messageCount = domain.db.prepare("SELECT COUNT(*) AS count FROM messages WHERE mailbox_id = ?").get(mailboxId).count;
|
|
217
|
+
if (messageCount > SEARCH_MAILBOX_MESSAGE_BUDGET) {
|
|
218
|
+
invalidArgument(`Mailbox exceeds in-memory search budget (${SEARCH_MAILBOX_MESSAGE_BUDGET} messages); reduce mailbox size or wait for SQL-backed search`);
|
|
219
|
+
}
|
|
220
|
+
candidateIds = domain.db
|
|
221
|
+
.prepare("SELECT id FROM messages WHERE mailbox_id = ? ORDER BY internal_date DESC, id DESC")
|
|
222
|
+
.all(mailboxId).map((row) => row.id);
|
|
223
|
+
}
|
|
224
|
+
// Enforce the mailbox search budget for both the JS-filter path and the SQL
|
|
225
|
+
// prefilter path — SQL exact matches can still return huge result sets.
|
|
226
|
+
if (candidateIds.length > SEARCH_MAILBOX_MESSAGE_BUDGET) {
|
|
227
|
+
invalidArgument(`Mailbox exceeds in-memory search budget (${SEARCH_MAILBOX_MESSAGE_BUDGET} messages); reduce mailbox size or wait for SQL-backed search`);
|
|
228
|
+
}
|
|
229
|
+
const messages = batchSemanticMessages(domain.db, mailboxId, candidateIds);
|
|
230
|
+
if (sqlExact)
|
|
231
|
+
return messages;
|
|
232
|
+
const now = searchNow(domain.db);
|
|
233
|
+
const documents = batchSearchDocuments(domain.db, mailboxId, messages);
|
|
234
|
+
return messages.filter((message, index) => {
|
|
235
|
+
if (!explicitAnywhere && !options.includeTrash && message.labelIds.some((id) => ["TRASH", "SPAM", "DRAFT"].includes(id))) {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
return matchesSearch(ast, documents[index], now);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
export function searchThreads(domain, email, query = "", options = {}) {
|
|
242
|
+
const matches = searchMessages(domain, email, query, options);
|
|
243
|
+
return [...new Set(matches.map((message) => message.threadId))].map((threadId) => getThread(domain, email, threadId));
|
|
244
|
+
}
|
|
245
|
+
export function removeEmptyThread(domain, mailboxId, threadId) {
|
|
246
|
+
const member = domain.db
|
|
247
|
+
.prepare("SELECT 1 FROM messages WHERE mailbox_id = ? AND thread_id = ? LIMIT 1")
|
|
248
|
+
.get(mailboxId, threadId);
|
|
249
|
+
if (!member) {
|
|
250
|
+
domain.db.prepare("DELETE FROM threads WHERE mailbox_id = ? AND id = ?").run(mailboxId, threadId);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
export function acceptedRaw(raw) {
|
|
254
|
+
return typeof raw === "string"
|
|
255
|
+
? raw.includes("\n")
|
|
256
|
+
? canonicalRaw(raw)
|
|
257
|
+
: decodeGmailRaw(raw)
|
|
258
|
+
: canonicalRaw(raw);
|
|
259
|
+
}
|
|
260
|
+
function deliveryMode(domain) {
|
|
261
|
+
const row = domain.db
|
|
262
|
+
.prepare("SELECT value FROM gmail_config WHERE key = 'delivery_mode'")
|
|
263
|
+
.get();
|
|
264
|
+
return row.value;
|
|
265
|
+
}
|
|
266
|
+
function assertAcceptedFrom(domain, mailboxId, from) {
|
|
267
|
+
if (!from)
|
|
268
|
+
invalidArgument("From header is required");
|
|
269
|
+
const accepted = domain.db
|
|
270
|
+
.prepare(`SELECT 1 FROM send_as
|
|
271
|
+
WHERE mailbox_id = ? AND email = ? COLLATE NOCASE AND verification_status = 'accepted'`)
|
|
272
|
+
.get(mailboxId, from);
|
|
273
|
+
if (!accepted)
|
|
274
|
+
invalidArgument("From address is not an accepted send-as identity");
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/domain/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SearchNode } from "../search-parse.js";
|
|
2
|
+
export type SqlSearchPlan = {
|
|
3
|
+
/** SQL fragment after `WHERE mailbox_id = ?` (leading AND clauses). */
|
|
4
|
+
clauses: string[];
|
|
5
|
+
params: unknown[];
|
|
6
|
+
/**
|
|
7
|
+
* When true, SQL constraints are semantically exact for the AST (label/is/in/size/date).
|
|
8
|
+
* Text/LIKE terms set this false so JS match still runs on candidates.
|
|
9
|
+
*/
|
|
10
|
+
exact: boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Private SQL prefilter for conjunctive search ASTs.
|
|
14
|
+
* Returns null when the query needs a full in-memory scan (OR/NOT/AROUND/free-text).
|
|
15
|
+
*/
|
|
16
|
+
export declare function compileSearchToSql(ast: SearchNode, options?: {
|
|
17
|
+
includeTrash?: boolean;
|
|
18
|
+
explicitAnywhere?: boolean;
|
|
19
|
+
}): SqlSearchPlan | null;
|