@bobfrankston/mailx 1.0.38 → 1.0.39
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.
|
@@ -317,7 +317,33 @@ async function loadFolderTree(container) {
|
|
|
317
317
|
try {
|
|
318
318
|
const accounts = await getAccounts();
|
|
319
319
|
if (accounts.length === 0) {
|
|
320
|
-
container.innerHTML = `<div class="folder-loading"
|
|
320
|
+
container.innerHTML = `<div class="folder-loading" style="padding:1rem;line-height:1.8">
|
|
321
|
+
<strong>No accounts configured</strong><br>
|
|
322
|
+
Create <code>~/.mailx/settings.jsonc</code> with your email accounts.<br><br>
|
|
323
|
+
Minimal Gmail example:<br>
|
|
324
|
+
<code style="display:block;padding:0.5rem;background:var(--color-bg);border-radius:4px;margin:0.5rem 0;white-space:pre">{ "name": "Your Name",
|
|
325
|
+
"accounts": [
|
|
326
|
+
{ "email": "you@gmail.com" }
|
|
327
|
+
]
|
|
328
|
+
}</code>
|
|
329
|
+
Standard IMAP:<br>
|
|
330
|
+
<code style="display:block;padding:0.5rem;background:var(--color-bg);border-radius:4px;margin:0.5rem 0;white-space:pre">{ "name": "Your Name",
|
|
331
|
+
"accounts": [
|
|
332
|
+
{ "email": "you@example.com",
|
|
333
|
+
"password": "secret",
|
|
334
|
+
"imap": { "host": "imap.example.com" },
|
|
335
|
+
"smtp": { "host": "smtp.example.com" }
|
|
336
|
+
}
|
|
337
|
+
]
|
|
338
|
+
}</code>
|
|
339
|
+
<a href="https://github.com/BobFrankston/mailx#first-time-setup" target="_blank" style="color:var(--color-accent)">Full setup guide</a>
|
|
340
|
+
</div>`;
|
|
341
|
+
// Dismiss startup overlay
|
|
342
|
+
const overlay = document.getElementById("startup-overlay");
|
|
343
|
+
if (overlay) {
|
|
344
|
+
overlay.classList.add("hidden");
|
|
345
|
+
setTimeout(() => overlay.remove(), 400);
|
|
346
|
+
}
|
|
321
347
|
return;
|
|
322
348
|
}
|
|
323
349
|
// Clear loading state now that we have data
|
package/client/lib/api-client.js
CHANGED
|
@@ -30,7 +30,7 @@ async function api(path, options) {
|
|
|
30
30
|
// Network error — server is down
|
|
31
31
|
if (e.name === "AbortError")
|
|
32
32
|
throw e;
|
|
33
|
-
throw new Error("Server offline —
|
|
33
|
+
throw new Error("Server offline — run: mailx -server");
|
|
34
34
|
}
|
|
35
35
|
if (!res.ok) {
|
|
36
36
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/mailx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39",
|
|
4
4
|
"description": "Local-first email client with IMAP sync and standalone native app",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/mailx.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"postinstall": "node launcher/builder/postinstall.js"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@bobfrankston/iflow": "^1.0.
|
|
23
|
+
"@bobfrankston/iflow": "^1.0.10",
|
|
24
24
|
"@bobfrankston/miscinfo": "^1.0.6",
|
|
25
25
|
"@bobfrankston/oauthsupport": "^1.0.11",
|
|
26
26
|
"@bobfrankston/rust-builder": "^0.1.2",
|
|
@@ -41,10 +41,10 @@ console.error = (...args) => {
|
|
|
41
41
|
origErr(msg);
|
|
42
42
|
logStream.write(msg + "\n");
|
|
43
43
|
};
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const SERVER_VERSION =
|
|
47
|
-
const CLIENT_VERSION =
|
|
44
|
+
// Read version from root package.json (the published version)
|
|
45
|
+
const rootPkg = JSON.parse(fs.readFileSync(path.join(import.meta.dirname, "..", "..", "package.json"), "utf-8"));
|
|
46
|
+
const SERVER_VERSION = rootPkg.version;
|
|
47
|
+
const CLIENT_VERSION = rootPkg.version;
|
|
48
48
|
// ── Initialize ──
|
|
49
49
|
initLocalConfig();
|
|
50
50
|
const settings = loadSettings();
|
|
@@ -23,6 +23,22 @@ const LOCAL_DIR = path.join(process.env.USERPROFILE || process.env.HOME || ".",
|
|
|
23
23
|
const LOCAL_CONFIG_PATH = path.join(LOCAL_DIR, "config.jsonc");
|
|
24
24
|
const LEGACY_CONFIG_PATH = path.join(LOCAL_DIR, "config.json");
|
|
25
25
|
const DEFAULT_STORE_PATH = path.join(LOCAL_DIR, "mailxstore");
|
|
26
|
+
/** Resolve a path from config — relative to ~/.mailx/, ~ expands to home */
|
|
27
|
+
function resolvePath(p) {
|
|
28
|
+
if (!p)
|
|
29
|
+
return p;
|
|
30
|
+
const home = process.env.USERPROFILE || process.env.HOME || ".";
|
|
31
|
+
// Expand ~ to home directory
|
|
32
|
+
if (p.startsWith("~/") || p.startsWith("~\\"))
|
|
33
|
+
return path.join(home, p.slice(2));
|
|
34
|
+
if (p === "~")
|
|
35
|
+
return home;
|
|
36
|
+
// Absolute path — use as-is
|
|
37
|
+
if (path.isAbsolute(p))
|
|
38
|
+
return p;
|
|
39
|
+
// Relative — resolve from config directory (~/.mailx/)
|
|
40
|
+
return path.resolve(LOCAL_DIR, p);
|
|
41
|
+
}
|
|
26
42
|
function readLocalConfig() {
|
|
27
43
|
// Migrate config.json → config.jsonc
|
|
28
44
|
if (!fs.existsSync(LOCAL_CONFIG_PATH) && fs.existsSync(LEGACY_CONFIG_PATH)) {
|
|
@@ -35,10 +51,10 @@ function readLocalConfig() {
|
|
|
35
51
|
function getSharedDir() {
|
|
36
52
|
const config = readLocalConfig();
|
|
37
53
|
if (config.sharedDir)
|
|
38
|
-
return config.sharedDir;
|
|
54
|
+
return resolvePath(config.sharedDir);
|
|
39
55
|
// Legacy: derive from settingsPath
|
|
40
56
|
if (config.settingsPath)
|
|
41
|
-
return path.dirname(config.settingsPath);
|
|
57
|
+
return path.dirname(resolvePath(config.settingsPath));
|
|
42
58
|
return LOCAL_DIR;
|
|
43
59
|
}
|
|
44
60
|
// ── File helpers ──
|
|
@@ -276,7 +292,7 @@ export function saveSettings(settings) {
|
|
|
276
292
|
/** Get the local store base path */
|
|
277
293
|
export function getStorePath() {
|
|
278
294
|
const config = readLocalConfig();
|
|
279
|
-
return config.storePath
|
|
295
|
+
return config.storePath ? resolvePath(config.storePath) : DEFAULT_STORE_PATH;
|
|
280
296
|
}
|
|
281
297
|
/** Get the local data directory (DB, store, etc.) */
|
|
282
298
|
export function getConfigDir() {
|