fluxmail 0.0.1 → 0.2.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/README.md +37 -10
- package/dist/accounts/googleAuth.d.ts +31 -0
- package/dist/accounts/googleAuth.d.ts.map +1 -0
- package/dist/accounts/googleAuth.js +147 -0
- package/dist/accounts/googleAuth.js.map +1 -0
- package/dist/accounts/registry.d.ts +37 -0
- package/dist/accounts/registry.d.ts.map +1 -0
- package/dist/accounts/registry.js +278 -0
- package/dist/accounts/registry.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +629 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +40 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +15 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +15 -0
- package/dist/context.js.map +1 -0
- package/dist/http/app.d.ts +16 -0
- package/dist/http/app.d.ts.map +1 -0
- package/dist/http/app.js +118 -0
- package/dist/http/app.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/licensing/activation.d.ts +5 -0
- package/dist/licensing/activation.d.ts.map +1 -0
- package/dist/licensing/activation.js +11 -0
- package/dist/licensing/activation.js.map +1 -0
- package/dist/licensing/client.d.ts +52 -0
- package/dist/licensing/client.d.ts.map +1 -0
- package/dist/licensing/client.js +75 -0
- package/dist/licensing/client.js.map +1 -0
- package/dist/licensing/entitlements.d.ts +55 -0
- package/dist/licensing/entitlements.d.ts.map +1 -0
- package/dist/licensing/entitlements.js +116 -0
- package/dist/licensing/entitlements.js.map +1 -0
- package/dist/licensing/lease.d.ts +47 -0
- package/dist/licensing/lease.d.ts.map +1 -0
- package/dist/licensing/lease.js +103 -0
- package/dist/licensing/lease.js.map +1 -0
- package/dist/licensing/refresher.d.ts +46 -0
- package/dist/licensing/refresher.d.ts.map +1 -0
- package/dist/licensing/refresher.js +150 -0
- package/dist/licensing/refresher.js.map +1 -0
- package/dist/mcp/buildServer.d.ts +28 -0
- package/dist/mcp/buildServer.d.ts.map +1 -0
- package/dist/mcp/buildServer.js +414 -0
- package/dist/mcp/buildServer.js.map +1 -0
- package/dist/scheduler/sendScheduler.d.ts +38 -0
- package/dist/scheduler/sendScheduler.d.ts.map +1 -0
- package/dist/scheduler/sendScheduler.js +128 -0
- package/dist/scheduler/sendScheduler.js.map +1 -0
- package/dist/service/emailService.d.ts +139 -0
- package/dist/service/emailService.d.ts.map +1 -0
- package/dist/service/emailService.js +380 -0
- package/dist/service/emailService.js.map +1 -0
- package/dist/storage/apiKeys.d.ts +27 -0
- package/dist/storage/apiKeys.d.ts.map +1 -0
- package/dist/storage/apiKeys.js +49 -0
- package/dist/storage/apiKeys.js.map +1 -0
- package/dist/storage/crypto.d.ts +4 -0
- package/dist/storage/crypto.d.ts.map +1 -0
- package/dist/storage/crypto.js +21 -0
- package/dist/storage/crypto.js.map +1 -0
- package/dist/storage/db.d.ts +1041 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +211 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/imapState.d.ts +15 -0
- package/dist/storage/imapState.d.ts.map +1 -0
- package/dist/storage/imapState.js +89 -0
- package/dist/storage/imapState.js.map +1 -0
- package/dist/storage/members.d.ts +29 -0
- package/dist/storage/members.d.ts.map +1 -0
- package/dist/storage/members.js +67 -0
- package/dist/storage/members.js.map +1 -0
- package/dist/storage/scheduledSends.d.ts +60 -0
- package/dist/storage/scheduledSends.d.ts.map +1 -0
- package/dist/storage/scheduledSends.js +169 -0
- package/dist/storage/scheduledSends.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +49 -15
- package/bin/fluxmail.js +0 -4
- package/src/cli.js +0 -36
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { and, eq, lte, or } from 'drizzle-orm';
|
|
3
|
+
import { EmailError } from '@fluxmail/core';
|
|
4
|
+
import { scheduledSends } from './db.js';
|
|
5
|
+
function toRow(r) {
|
|
6
|
+
return { ...r, status: r.status };
|
|
7
|
+
}
|
|
8
|
+
export function createScheduledSend(db, input) {
|
|
9
|
+
const id = `sch_${randomBytes(6).toString('hex')}`;
|
|
10
|
+
const createdAt = Date.now();
|
|
11
|
+
return db.transaction((tx) => {
|
|
12
|
+
const existing = tx
|
|
13
|
+
.select()
|
|
14
|
+
.from(scheduledSends)
|
|
15
|
+
.where(and(eq(scheduledSends.accountId, input.accountId), eq(scheduledSends.draftId, input.draftId), eq(scheduledSends.status, 'pending')))
|
|
16
|
+
.get();
|
|
17
|
+
if (existing) {
|
|
18
|
+
throw new EmailError('invalid_request', `Draft ${input.draftId} is already scheduled to send at ${new Date(existing.sendAt).toISOString()}; cancel it first to reschedule`);
|
|
19
|
+
}
|
|
20
|
+
const row = {
|
|
21
|
+
id,
|
|
22
|
+
accountId: input.accountId,
|
|
23
|
+
draftId: input.draftId,
|
|
24
|
+
sendAt: input.sendAt,
|
|
25
|
+
createdAt,
|
|
26
|
+
status: 'pending',
|
|
27
|
+
attempts: 0,
|
|
28
|
+
lastError: null,
|
|
29
|
+
sentMessageId: null,
|
|
30
|
+
sentThreadId: null,
|
|
31
|
+
subject: input.subject ?? null,
|
|
32
|
+
toRecipients: input.toRecipients ?? null,
|
|
33
|
+
claimToken: null,
|
|
34
|
+
claimUntil: null,
|
|
35
|
+
};
|
|
36
|
+
tx.insert(scheduledSends).values(row).run();
|
|
37
|
+
return toRow(row);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function getScheduledSend(db, id) {
|
|
41
|
+
const row = db.select().from(scheduledSends).where(eq(scheduledSends.id, id)).get();
|
|
42
|
+
return row ? toRow(row) : undefined;
|
|
43
|
+
}
|
|
44
|
+
/** All schedules, pending first by due time, then the rest newest-first. */
|
|
45
|
+
export function listScheduledSends(db, accountId) {
|
|
46
|
+
const rows = accountId
|
|
47
|
+
? db.select().from(scheduledSends).where(eq(scheduledSends.accountId, accountId)).all()
|
|
48
|
+
: db.select().from(scheduledSends).all();
|
|
49
|
+
return rows.map(toRow).sort((a, b) => {
|
|
50
|
+
if ((a.status === 'pending') !== (b.status === 'pending'))
|
|
51
|
+
return a.status === 'pending' ? -1 : 1;
|
|
52
|
+
return a.status === 'pending' ? a.sendAt - b.sendAt : b.createdAt - a.createdAt;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export function listPending(db) {
|
|
56
|
+
return db.select().from(scheduledSends).where(eq(scheduledSends.status, 'pending')).all().map(toRow);
|
|
57
|
+
}
|
|
58
|
+
export function listActive(db) {
|
|
59
|
+
return db
|
|
60
|
+
.select()
|
|
61
|
+
.from(scheduledSends)
|
|
62
|
+
.where(or(eq(scheduledSends.status, 'pending'), eq(scheduledSends.status, 'sending')))
|
|
63
|
+
.all()
|
|
64
|
+
.map(toRow);
|
|
65
|
+
}
|
|
66
|
+
export function findPendingByDraft(db, accountId, draftId) {
|
|
67
|
+
const row = db
|
|
68
|
+
.select()
|
|
69
|
+
.from(scheduledSends)
|
|
70
|
+
.where(and(eq(scheduledSends.accountId, accountId), eq(scheduledSends.draftId, draftId), eq(scheduledSends.status, 'pending')))
|
|
71
|
+
.get();
|
|
72
|
+
return row ? toRow(row) : undefined;
|
|
73
|
+
}
|
|
74
|
+
export function markSent(db, id, result) {
|
|
75
|
+
db.update(scheduledSends)
|
|
76
|
+
.set({ status: 'sent', sentMessageId: result.id, sentThreadId: result.threadId, lastError: null })
|
|
77
|
+
.where(eq(scheduledSends.id, id))
|
|
78
|
+
.run();
|
|
79
|
+
}
|
|
80
|
+
/** Atomically claim a due row so only one scheduler process can dispatch it. */
|
|
81
|
+
export function claimScheduledSend(db, id, now, leaseMs) {
|
|
82
|
+
const token = randomBytes(12).toString('hex');
|
|
83
|
+
const result = db
|
|
84
|
+
.update(scheduledSends)
|
|
85
|
+
.set({ status: 'sending', claimToken: token, claimUntil: now + leaseMs })
|
|
86
|
+
.where(and(eq(scheduledSends.id, id), or(eq(scheduledSends.status, 'pending'), and(eq(scheduledSends.status, 'sending'), lte(scheduledSends.claimUntil, now)))))
|
|
87
|
+
.run();
|
|
88
|
+
if (result.changes === 0)
|
|
89
|
+
return undefined;
|
|
90
|
+
return { row: getScheduledSend(db, id), token };
|
|
91
|
+
}
|
|
92
|
+
export function completeClaim(db, id, token, result) {
|
|
93
|
+
db.update(scheduledSends)
|
|
94
|
+
.set({
|
|
95
|
+
status: 'sent',
|
|
96
|
+
sentMessageId: result.id,
|
|
97
|
+
sentThreadId: result.threadId,
|
|
98
|
+
lastError: null,
|
|
99
|
+
claimToken: null,
|
|
100
|
+
claimUntil: null,
|
|
101
|
+
})
|
|
102
|
+
.where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
|
|
103
|
+
.run();
|
|
104
|
+
}
|
|
105
|
+
export function failClaim(db, id, token, error) {
|
|
106
|
+
db.update(scheduledSends)
|
|
107
|
+
.set({ status: 'failed', lastError: error, claimToken: null, claimUntil: null })
|
|
108
|
+
.where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
|
|
109
|
+
.run();
|
|
110
|
+
}
|
|
111
|
+
export function retryClaim(db, id, token, error) {
|
|
112
|
+
const row = getScheduledSend(db, id);
|
|
113
|
+
if (!row || row.claimToken !== token)
|
|
114
|
+
return;
|
|
115
|
+
db.update(scheduledSends)
|
|
116
|
+
.set({
|
|
117
|
+
status: 'pending',
|
|
118
|
+
attempts: row.attempts + 1,
|
|
119
|
+
lastError: error,
|
|
120
|
+
claimToken: null,
|
|
121
|
+
claimUntil: null,
|
|
122
|
+
})
|
|
123
|
+
.where(and(eq(scheduledSends.id, id), eq(scheduledSends.claimToken, token)))
|
|
124
|
+
.run();
|
|
125
|
+
}
|
|
126
|
+
export function listClaimable(db, now) {
|
|
127
|
+
return db
|
|
128
|
+
.select()
|
|
129
|
+
.from(scheduledSends)
|
|
130
|
+
.where(or(eq(scheduledSends.status, 'pending'), and(eq(scheduledSends.status, 'sending'), lte(scheduledSends.claimUntil, now))))
|
|
131
|
+
.all()
|
|
132
|
+
.map(toRow);
|
|
133
|
+
}
|
|
134
|
+
export function markFailed(db, id, error) {
|
|
135
|
+
db.update(scheduledSends).set({ status: 'failed', lastError: error }).where(eq(scheduledSends.id, id)).run();
|
|
136
|
+
}
|
|
137
|
+
/** Record why a pending send is held (e.g. plan quota) without consuming an attempt. */
|
|
138
|
+
export function holdPending(db, id, error) {
|
|
139
|
+
db.update(scheduledSends)
|
|
140
|
+
.set({ lastError: error })
|
|
141
|
+
.where(and(eq(scheduledSends.id, id), eq(scheduledSends.status, 'pending')))
|
|
142
|
+
.run();
|
|
143
|
+
}
|
|
144
|
+
/** Record a retryable failure: bump attempts, keep the row pending. */
|
|
145
|
+
export function recordAttempt(db, id, error) {
|
|
146
|
+
const row = db.select().from(scheduledSends).where(eq(scheduledSends.id, id)).get();
|
|
147
|
+
if (!row)
|
|
148
|
+
return;
|
|
149
|
+
db.update(scheduledSends)
|
|
150
|
+
.set({ attempts: row.attempts + 1, lastError: error })
|
|
151
|
+
.where(eq(scheduledSends.id, id))
|
|
152
|
+
.run();
|
|
153
|
+
}
|
|
154
|
+
/** Only pending schedules can be canceled; returns false otherwise. */
|
|
155
|
+
export function cancelScheduledSend(db, id) {
|
|
156
|
+
const result = db
|
|
157
|
+
.update(scheduledSends)
|
|
158
|
+
.set({ status: 'canceled' })
|
|
159
|
+
.where(and(eq(scheduledSends.id, id), eq(scheduledSends.status, 'pending')))
|
|
160
|
+
.run();
|
|
161
|
+
return result.changes > 0;
|
|
162
|
+
}
|
|
163
|
+
export function countPending(db) {
|
|
164
|
+
const rows = listActive(db);
|
|
165
|
+
if (!rows.length)
|
|
166
|
+
return { pending: 0 };
|
|
167
|
+
return { pending: rows.length, nextSendAt: Math.min(...rows.map((r) => r.sendAt)) };
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=scheduledSends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduledSends.js","sourceRoot":"","sources":["../../src/storage/scheduledSends.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,OAAO,QAAmB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
3
|
+
if (typeof manifest.version !== 'string' || manifest.version.length === 0) {
|
|
4
|
+
throw new Error('The fluxmail package manifest must define a version.');
|
|
5
|
+
}
|
|
6
|
+
export const VERSION = manifest.version;
|
|
7
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAoB,CAAC;AAElH,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC1E,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,25 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fluxmail",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "Fluxmail
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Fluxmail MCP server: unified email tools over Gmail and IMAP/SMTP",
|
|
5
|
+
"homepage": "https://github.com/churichard/fluxmail-mcp#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/churichard/fluxmail-mcp.git",
|
|
9
|
+
"directory": "packages/server"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/churichard/fluxmail-mcp/issues"
|
|
13
|
+
},
|
|
5
14
|
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
6
17
|
"bin": {
|
|
7
|
-
"fluxmail": "
|
|
18
|
+
"fluxmail": "./dist/cli.js"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
8
25
|
},
|
|
9
26
|
"files": [
|
|
10
|
-
"
|
|
11
|
-
"src"
|
|
27
|
+
"dist"
|
|
12
28
|
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
13
32
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
33
|
+
"node": ">=20.19"
|
|
15
34
|
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@hono/node-server": "^1.14.3",
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.13.0",
|
|
38
|
+
"better-sqlite3": "^11.10.0",
|
|
39
|
+
"commander": "^13.1.0",
|
|
40
|
+
"drizzle-orm": "^0.45.2",
|
|
41
|
+
"google-auth-library": "10.5.0",
|
|
42
|
+
"hono": "^4.7.11",
|
|
43
|
+
"zod": "^3.25.67",
|
|
44
|
+
"@fluxmail/core": "0.2.0",
|
|
45
|
+
"@fluxmail/provider-imap": "0.2.0",
|
|
46
|
+
"@fluxmail/provider-gmail": "0.2.0"
|
|
18
47
|
},
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
50
|
+
"@types/node": "^22.15.0",
|
|
51
|
+
"imapflow": "^1.4.7"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.json",
|
|
55
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"dev": "tsc -p tsconfig.json --watch"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/bin/fluxmail.js
DELETED
package/src/cli.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
|
|
3
|
-
const require = createRequire(import.meta.url);
|
|
4
|
-
const { version } = require("../package.json");
|
|
5
|
-
|
|
6
|
-
const HELP = `fluxmail — CLI
|
|
7
|
-
|
|
8
|
-
Usage:
|
|
9
|
-
fluxmail <command> [options]
|
|
10
|
-
|
|
11
|
-
Commands:
|
|
12
|
-
help Show this help
|
|
13
|
-
version Print the version
|
|
14
|
-
|
|
15
|
-
Options:
|
|
16
|
-
-h, --help Show this help
|
|
17
|
-
-v, --version Print the version
|
|
18
|
-
`;
|
|
19
|
-
|
|
20
|
-
export function run(argv = []) {
|
|
21
|
-
const [command] = argv;
|
|
22
|
-
|
|
23
|
-
if (argv.includes("-v") || argv.includes("--version") || command === "version") {
|
|
24
|
-
console.log(version);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!command || argv.includes("-h") || argv.includes("--help") || command === "help") {
|
|
29
|
-
console.log(HELP);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
console.error(`fluxmail: unknown command '${command}'`);
|
|
34
|
-
console.error("Run 'fluxmail help' for usage.");
|
|
35
|
-
process.exitCode = 1;
|
|
36
|
-
}
|