@bobfrankston/mailx 1.0.139 → 1.0.141

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/bin/mailx.js CHANGED
@@ -3,8 +3,8 @@
3
3
  * mailx -- email client
4
4
  *
5
5
  * Usage:
6
- * mailx Start server + open in msger (or browser fallback)
7
- * mailx --server Start server + open browser (skip msger)
6
+ * mailx Start server + open in msger
7
+ * mailx --server Start server + open msger (same as default)
8
8
  * mailx --no-browser Start server only (headless)
9
9
  * mailx --external Bind to all interfaces
10
10
  * mailx --verbose Show detailed startup info
@@ -18,6 +18,7 @@ import fs from "node:fs";
18
18
  import path from "node:path";
19
19
  import net from "node:net";
20
20
  import { ports } from "@bobfrankston/miscinfo";
21
+ import { showMessageBox } from "@bobfrankston/msger";
21
22
  const PORT = ports.mailx;
22
23
  const args = process.argv.slice(2);
23
24
  // Normalize: accept both -flag and --flag
@@ -30,7 +31,7 @@ const addMode = hasFlag("add");
30
31
  const testMode = hasFlag("test");
31
32
  const rebuildMode = hasFlag("rebuild");
32
33
  // Validate arguments
33
- const knownFlags = ["server", "no-browser", "verbose", "external", "kill", "v", "version", "setup", "add", "test", "rebuild", "native-imap"];
34
+ const knownFlags = ["server", "no-browser", "verbose", "external", "kill", "v", "version", "setup", "add", "test", "rebuild", "native-imap", "log"];
34
35
  for (const arg of args) {
35
36
  const flag = arg.replace(/^--?/, "");
36
37
  if (arg.startsWith("-") && !knownFlags.includes(flag)) {
@@ -147,7 +148,7 @@ if (hasFlag("v") || hasFlag("version")) {
147
148
  };
148
149
  try {
149
150
  const pkg = JSON.parse(fs.readFileSync(`${root}/package.json`, "utf-8"));
150
- console.log(`mailx v${pkg.version}`);
151
+ console.log(`\x1b[1;97;44m mailx v${pkg.version} \x1b[0m`);
151
152
  }
152
153
  catch {
153
154
  console.log("mailx (version unknown)");
@@ -169,26 +170,9 @@ function isPortInUse(port) {
169
170
  socket.once("error", () => resolve(false));
170
171
  });
171
172
  }
172
- function openBrowser(url) {
173
- import("node:child_process").then(({ exec }) => {
174
- if (process.platform === "win32")
175
- exec(`start "" "${url}"`);
176
- else if (process.platform === "darwin")
177
- exec(`open "${url}"`);
178
- else
179
- exec(`xdg-open "${url}"`);
180
- });
181
- }
182
- /** Launch msger pointing at the server URL; fall back to browser if msger not found */
173
+ /** Launch msger pointing at the server URL */
183
174
  function launchMsger(url) {
184
- import("node:child_process").then(({ spawn }) => {
185
- const child = spawn("msger", ["-url", url], { detached: true, stdio: "ignore" });
186
- child.on("error", () => {
187
- log("msger not found — opening in browser");
188
- openBrowser(url);
189
- });
190
- child.unref();
191
- });
175
+ showMessageBox({ url, detach: true, size: { width: 1400, height: 900 } });
192
176
  }
193
177
  async function prompt(question) {
194
178
  const readline = await import("readline");
@@ -507,19 +491,27 @@ async function main() {
507
491
  // Check if server is already running
508
492
  const inUse = await isPortInUse(PORT);
509
493
  if (inUse) {
510
- console.log(`mailx server already running on port ${PORT}`);
511
494
  const url = `http://127.0.0.1:${PORT}`;
512
- if (!noBrowser) {
513
- if (serverMode)
514
- openBrowser(url);
515
- else
516
- launchMsger(url);
517
- }
495
+ if (!noBrowser)
496
+ launchMsger(url);
518
497
  return;
519
498
  }
499
+ // Redirect console to log file — keep terminal clean
500
+ // Server also logs, but this catches CLI startup messages
501
+ if (!verbose) {
502
+ const home = process.env.USERPROFILE || process.env.HOME || ".";
503
+ const logDir = path.join(home, ".mailx", "logs");
504
+ fs.mkdirSync(logDir, { recursive: true });
505
+ const logDate = new Date().toISOString().slice(0, 10);
506
+ const logPath = path.join(logDir, `mailx-${logDate}.log`);
507
+ const logStream = fs.createWriteStream(logPath, { flags: "a" });
508
+ const origLog = console.log;
509
+ const origErr = console.error;
510
+ console.log = (...a) => { logStream.write(a.join(" ") + "\n"); };
511
+ console.error = (...a) => { logStream.write("ERROR " + a.join(" ") + "\n"); };
512
+ }
520
513
  // Start Express server in-process
521
514
  console.log("Starting mailx server...");
522
- log(`Loading server from: ${path.join(import.meta.dirname, "..", "packages", "mailx-server", "index.js")}`);
523
515
  if (hasFlag("external"))
524
516
  process.argv.push("--external");
525
517
  await import("../packages/mailx-server/index.js");
@@ -531,14 +523,7 @@ async function main() {
531
523
  if (await isPortInUse(PORT))
532
524
  break;
533
525
  }
534
- if (serverMode) {
535
- openBrowser(url);
536
- console.log("mailx opened (browser)");
537
- }
538
- else {
539
- launchMsger(url);
540
- console.log("mailx opened");
541
- }
526
+ launchMsger(url);
542
527
  }
543
528
  // Keep process alive — server is running
544
529
  await new Promise(() => { });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/mailx",
3
- "version": "1.0.139",
3
+ "version": "1.0.141",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -17,13 +17,13 @@
17
17
  "start": "node --watch packages/mailx-server/index.js",
18
18
  "start:prod": "node packages/mailx-server/index.js",
19
19
  "release": "npmglobalize",
20
- "postinstall": "node launcher/builder/postinstall.js"
20
+ "postinstall": "node bin/postinstall.js"
21
21
  },
22
22
  "dependencies": {
23
23
  "@bobfrankston/iflow": "^1.0.52",
24
24
  "@bobfrankston/miscinfo": "^1.0.7",
25
25
  "@bobfrankston/oauthsupport": "^1.0.20",
26
- "@bobfrankston/rust-builder": "^0.1.3",
26
+ "@bobfrankston/msger": "^0.1.195",
27
27
  "@capacitor/android": "^8.3.0",
28
28
  "@capacitor/cli": "^8.3.0",
29
29
  "@capacitor/core": "^8.3.0",
@@ -57,7 +57,7 @@
57
57
  "@bobfrankston/iflow": "file:../MailApps/iflow",
58
58
  "@bobfrankston/miscinfo": "file:../../projects/npm/miscinfo",
59
59
  "@bobfrankston/oauthsupport": "file:../../projects/oauth/oauthsupport",
60
- "@bobfrankston/rust-builder": "file:../../utils/rust-builder",
60
+ "@bobfrankston/msger": "file:../../utils/msgx/msger",
61
61
  "@capacitor/android": "^8.3.0",
62
62
  "@capacitor/cli": "^8.3.0",
63
63
  "@capacitor/core": "^8.3.0",
@@ -9,7 +9,7 @@ import * as fs from "node:fs";
9
9
  import { MailxDB } from "@bobfrankston/mailx-store";
10
10
  import { ImapManager } from "@bobfrankston/mailx-imap";
11
11
  import { createApiRouter } from "@bobfrankston/mailx-api";
12
- import { loadSettings, loadAccountsAsync, getConfigDir, getStorePath, getStorageInfo, initLocalConfig } from "@bobfrankston/mailx-settings";
12
+ import { loadSettings, loadAccountsAsync, getConfigDir, getStorePath, getStorageInfo } from "@bobfrankston/mailx-settings";
13
13
  import { ports } from "@bobfrankston/miscinfo";
14
14
  import { createServer } from "node:http";
15
15
  const PORT = ports.mailx;
@@ -45,7 +45,8 @@ console.error = (...args) => {
45
45
  const rootPkg = JSON.parse(fs.readFileSync(path.join(import.meta.dirname, "..", "..", "package.json"), "utf-8"));
46
46
  const SERVER_VERSION = rootPkg.version;
47
47
  // ── Initialize ──
48
- initLocalConfig();
48
+ // No initLocalConfig() here — config is created when user adds an account (initCloudConfig).
49
+ // On fresh install, loadSettings() returns defaults and the setup form handles configuration.
49
50
  let settings = loadSettings();
50
51
  if (settings.accounts.length === 0) {
51
52
  // Try cloud API fallback (Google Drive, OneDrive) if filesystem mount not available
Binary file
Binary file
@@ -1,11 +0,0 @@
1
- {
2
- "platforms": {
3
- "windows": true,
4
- "wsl": true,
5
- "arm64": false
6
- },
7
- "options": {
8
- "release": true,
9
- "verbose": true
10
- }
11
- }
@@ -1,73 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * mailx postinstall:
4
- * 1. Link workspace packages so Node can resolve them after npm install
5
- * 2. Set binary permissions on Linux/Mac
6
- */
7
- import fs from "node:fs";
8
- import path from "node:path";
9
- import { fileURLToPath } from "url";
10
-
11
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
- const root = path.join(__dirname, "..", "..");
13
-
14
- // Link workspace packages into node_modules so imports resolve
15
- const nodeModules = path.join(root, "node_modules", "@bobfrankston");
16
- const packagesDir = path.join(root, "packages");
17
- if (fs.existsSync(packagesDir)) {
18
- fs.mkdirSync(nodeModules, { recursive: true });
19
- for (const pkg of fs.readdirSync(packagesDir)) {
20
- const pkgDir = path.join(packagesDir, pkg);
21
- const pkgJson = path.join(pkgDir, "package.json");
22
- if (!fs.existsSync(pkgJson)) continue;
23
- try {
24
- const meta = JSON.parse(fs.readFileSync(pkgJson, "utf-8"));
25
- const name = meta.name?.replace("@bobfrankston/", "");
26
- if (!name) continue;
27
- const link = path.join(nodeModules, name);
28
- // Remove stale junction/symlink that may point to wrong location
29
- try { fs.unlinkSync(link); } catch { try { fs.rmSync(link, { recursive: true }); } catch { /* */ } }
30
- // Create junction (Windows) or symlink (Unix) to local packages dir
31
- if (process.platform === "win32") {
32
- fs.symlinkSync(pkgDir, link, "junction");
33
- } else {
34
- fs.symlinkSync(pkgDir, link, "dir");
35
- }
36
- } catch { /* skip */ }
37
- }
38
- }
39
-
40
- // Set binary permissions
41
- try {
42
- const { runPostinstall } = await import("@bobfrankston/rust-builder/postinstall");
43
- const path = await import("path");
44
- const { fileURLToPath } = await import("url");
45
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
46
-
47
- runPostinstall({
48
- binaryName: "mailx-app",
49
- binDir: path.join(__dirname, "..", "bin"),
50
- binaries: {
51
- win32: "mailx-app.exe",
52
- darwin: "mailx-app",
53
- darwinArm64: "mailx-app-arm64",
54
- linux: "mailx-app-linux",
55
- linuxArm64: "mailx-app-linux-aarch64",
56
- },
57
- });
58
- } catch {
59
- // rust-builder not available (e.g., local dev with file: deps)
60
- // On Windows, nothing to do. On Linux/Mac, try chmod directly.
61
- if (process.platform !== "win32") {
62
- const fs = await import("fs");
63
- const path = await import("path");
64
- const { fileURLToPath } = await import("url");
65
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
66
- const arch = process.arch;
67
- const name = process.platform === "darwin"
68
- ? (arch === "arm64" ? "mailx-app-arm64" : "mailx-app")
69
- : (arch === "arm64" ? "mailx-app-linux-aarch64" : "mailx-app-linux");
70
- const bin = path.join(__dirname, "..", "bin", name);
71
- try { fs.chmodSync(bin, 0o755); } catch { /* binary may not exist */ }
72
- }
73
- }
Binary file