@bobfrankston/rmfmail 1.2.164 → 1.2.166

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.
Files changed (52) hide show
  1. package/bin/mailx.js +100 -82
  2. package/bin/mailx.js.map +1 -1
  3. package/bin/mailx.ts +89 -71
  4. package/client/android-bootstrap.bundle.js +8 -5
  5. package/client/android-bootstrap.bundle.js.map +2 -2
  6. package/client/app.bundle.js +45 -0
  7. package/client/app.bundle.js.map +3 -3
  8. package/client/app.js +48 -0
  9. package/client/app.js.map +1 -1
  10. package/client/app.ts +47 -0
  11. package/client/compose/compose.bundle.js +15 -0
  12. package/client/compose/compose.bundle.js.map +2 -2
  13. package/client/compose/compose.js +14 -0
  14. package/client/compose/compose.js.map +1 -1
  15. package/client/compose/compose.ts +12 -0
  16. package/client/index.html +1 -0
  17. package/client/lib/api-client.js +7 -0
  18. package/client/lib/api-client.js.map +1 -1
  19. package/client/lib/api-client.ts +7 -0
  20. package/client/lib/mailxapi.js +7 -0
  21. package/package.json +5 -5
  22. package/packages/mailx-imap/index.d.ts.map +1 -1
  23. package/packages/mailx-imap/index.js +32 -7
  24. package/packages/mailx-imap/index.js.map +1 -1
  25. package/packages/mailx-imap/index.ts +33 -7
  26. package/packages/mailx-imap/package-lock.json +2 -2
  27. package/packages/mailx-imap/package.json +1 -1
  28. package/packages/mailx-service/index.d.ts +15 -0
  29. package/packages/mailx-service/index.d.ts.map +1 -1
  30. package/packages/mailx-service/index.js +15 -0
  31. package/packages/mailx-service/index.js.map +1 -1
  32. package/packages/mailx-service/index.ts +12 -0
  33. package/packages/mailx-service/jsonrpc.js +2 -0
  34. package/packages/mailx-service/jsonrpc.js.map +1 -1
  35. package/packages/mailx-service/jsonrpc.ts +2 -0
  36. package/packages/mailx-service/package.json +1 -1
  37. package/packages/mailx-settings/package.json +1 -1
  38. package/packages/mailx-store/package.json +1 -1
  39. package/packages/mailx-store-web/android-bootstrap.d.ts.map +1 -1
  40. package/packages/mailx-store-web/android-bootstrap.js +16 -6
  41. package/packages/mailx-store-web/android-bootstrap.js.map +1 -1
  42. package/packages/mailx-store-web/android-bootstrap.ts +17 -6
  43. package/packages/mailx-store-web/package.json +1 -1
  44. package/packages/mailx-store-web/sync-manager.d.ts.map +1 -1
  45. package/packages/mailx-store-web/sync-manager.js +20 -5
  46. package/packages/mailx-store-web/sync-manager.js.map +1 -1
  47. package/packages/mailx-store-web/sync-manager.ts +21 -5
  48. package/packages/mailx-types/mailx-api.d.ts +6 -0
  49. package/packages/mailx-types/mailx-api.d.ts.map +1 -1
  50. package/packages/mailx-types/mailx-api.ts +3 -0
  51. package/packages/mailx-types/package.json +1 -1
  52. /package/packages/mailx-imap/{node_modules.npmglobalize-stash-10468 → node_modules.npmglobalize-stash-61300}/.package-lock.json +0 -0
package/bin/mailx.js CHANGED
@@ -178,63 +178,13 @@ const isDaemon = hasFlag("daemon"); // internal: re-spawned detached process
178
178
  process.exit(0);
179
179
  }
180
180
  }
181
- if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
182
- const unregister = hasFlag("unregister-mailto");
183
- // C124: Linux registration a .desktop entry claiming the mailto:
184
- // scheme + xdg-mime default. No exe-launcher needed (unlike Windows):
185
- // Linux pickers read Name= from the .desktop file directly.
186
- if (process.platform === "linux") {
187
- const appsDir = path.join(os.homedir(), ".local", "share", "applications");
188
- const desktopPath = path.join(appsDir, "rmfmail.desktop");
189
- if (unregister) {
190
- try {
191
- fs.unlinkSync(desktopPath);
192
- }
193
- catch { /* not registered */ }
194
- try {
195
- execSync(`update-desktop-database "${appsDir}"`);
196
- }
197
- catch { /* optional tool */ }
198
- console.log("Unregistered rmfmail mailto: handler.");
199
- process.exit(0);
200
- }
201
- const __mailtoJs = path.join(import.meta.dirname, "mailx.js");
202
- const __iconPng = path.join(import.meta.dirname, "..", "client", "icon.png");
203
- // Exec quoting follows the Desktop Entry spec: quoted absolute paths,
204
- // bare %u field code (quoting %u breaks argument expansion).
205
- const desktopEntry = [
206
- "[Desktop Entry]",
207
- "Type=Application",
208
- "Name=rmfmail",
209
- "Comment=rmfmail email client",
210
- `Exec="${process.execPath}" "${__mailtoJs}" --mailto %u`,
211
- `Icon=${__iconPng}`,
212
- "Terminal=false",
213
- "MimeType=x-scheme-handler/mailto;",
214
- "Categories=Network;Email;",
215
- "",
216
- ].join("\n");
217
- fs.mkdirSync(appsDir, { recursive: true });
218
- fs.writeFileSync(desktopPath, desktopEntry);
219
- try {
220
- execSync("xdg-mime default rmfmail.desktop x-scheme-handler/mailto");
221
- }
222
- catch (e) {
223
- console.error(`xdg-mime failed (${e.message}) — handler installed but not set as default. Set it in your DE's default-apps settings.`);
224
- }
225
- try {
226
- execSync(`update-desktop-database "${appsDir}"`);
227
- }
228
- catch { /* optional tool */ }
229
- console.log(`Registered rmfmail as mailto: handler (${desktopPath}).`);
230
- process.exit(0);
231
- }
232
- if (process.platform !== "win32") {
233
- // macOS needs a real .app bundle with CFBundleURLTypes — LaunchServices
234
- // won't register a bare script. Tracked as the macOS half of C124.
235
- console.error("--register-mailto / --unregister-mailto: macOS registration not implemented yet (needs an .app bundle — TODO C124).");
236
- process.exit(1);
237
- }
181
+ /** Windows mailto: registration registry keys via reg.exe. Shared by the
182
+ * `-register-mailto` CLI flag and the Settings → "Make default email app"
183
+ * menu action (injected into MailxService; the registry work stays HERE in
184
+ * the platform launcher packages/ stay cross-platform). Returns the
185
+ * outcome text instead of printing so both callers can surface it. */
186
+ function registerMailtoWindows(unregister) {
187
+ const lines = [];
238
188
  // Registered command points at the rmfmailto.exe launcher (per-app
239
189
  // binary at %LOCALAPPDATA%\rmfmail\bin\rmfmailto.exe). The exe has its
240
190
  // own VERSIONINFO with FileDescription="rmfmail" so the Win11 "Select
@@ -252,18 +202,17 @@ if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
252
202
  try {
253
203
  fs.mkdirSync(__perAppBin, { recursive: true });
254
204
  fs.copyFileSync(__pkgRmfmailtoExe, __rmfmailtoExe);
255
- console.log(`Installed rmfmailto.exe to ${__rmfmailtoExe}`);
205
+ lines.push(`Installed rmfmailto.exe to ${__rmfmailtoExe}`);
256
206
  }
257
207
  catch (e) {
258
- console.error(`Failed to copy rmfmailto.exe to per-app dir: ${e.message}`);
208
+ lines.push(`Failed to copy rmfmailto.exe to per-app dir: ${e.message}`);
259
209
  // Fall through and try registering the in-package path so
260
210
  // mailto still works, just from inside node_modules.
261
211
  }
262
212
  }
263
213
  const __launcherExe = fs.existsSync(__rmfmailtoExe) ? __rmfmailtoExe : __pkgRmfmailtoExe;
264
214
  if (!fs.existsSync(__launcherExe)) {
265
- console.error(`rmfmailto.exe not found at ${__launcherExe} — package may have been built without it. Re-run 'npm run build' on the build machine.`);
266
- process.exit(1);
215
+ return { ok: false, message: `rmfmailto.exe not found at ${__launcherExe} — package may have been built without it. Re-run 'npm run build' on the build machine.` };
267
216
  }
268
217
  // reg.exe value for `\"path\" \"%1\"` — double-backslash escapes for
269
218
  // cmd.exe's shell layer, which strips one level before the value reaches
@@ -322,17 +271,17 @@ if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
322
271
  if (/mailx\.js|rmfmail/i.test(out)) {
323
272
  try {
324
273
  execSync(`reg delete "${key}" /f`, { stdio: "pipe" });
325
- console.log(` cleaned leftover ${oldExe} mailto handler`);
274
+ lines.push(` cleaned leftover ${oldExe} mailto handler`);
326
275
  }
327
276
  catch { /* */ }
328
277
  }
329
278
  }
330
279
  catch { /* not present — fine */ }
331
280
  }
332
- console.log("rmfmail unregistered as a mailto: handler.");
333
- console.log("Note: if rmfmail was the active default in Settings → Default apps → Email,");
334
- console.log("Windows may keep the prior selection in UserChoice until you pick another app.");
335
- process.exit(0);
281
+ lines.push("rmfmail unregistered as a mailto: handler.");
282
+ lines.push("Note: if rmfmail was the active default in Settings → Default apps → Email,");
283
+ lines.push("Windows may keep the prior selection in UserChoice until you pick another app.");
284
+ return { ok: true, message: lines.join("\n") };
336
285
  }
337
286
  // Prepass: same defensive cleanup as --unregister, restricted to
338
287
  // rmfmail/mailx-related leftover keys. Without this, registering on
@@ -345,13 +294,14 @@ if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
345
294
  if (/mailx\.js|rmfmail/i.test(out)) {
346
295
  try {
347
296
  execSync(`reg delete "${key}" /f`, { stdio: "pipe" });
348
- console.log(` cleaned leftover ${oldExe} mailto handler`);
297
+ lines.push(` cleaned leftover ${oldExe} mailto handler`);
349
298
  }
350
299
  catch { /* */ }
351
300
  }
352
301
  }
353
302
  catch { /* not present — fine */ }
354
303
  }
304
+ let failed = 0;
355
305
  for (const [keyPath, name, data] of keys) {
356
306
  const valueArg = name ? `/v "${name}"` : "/ve";
357
307
  const dataArg = data ? `/d "${data}"` : "";
@@ -361,21 +311,83 @@ if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
361
311
  execSync(cmdLine, { stdio: "pipe" });
362
312
  }
363
313
  catch (e) {
364
- console.error(` failed: ${cmdLine}\n ${e.message}`);
365
- }
366
- }
367
- console.log("rmfmail registered as a mailto: handler.");
368
- console.log("");
369
- console.log("To make it the default in Windows 11:");
370
- console.log(" Settings Apps Default apps search \"rmfmail\" → click rmfmail");
371
- console.log(" → \"Set default\" for the mailto link type.");
372
- console.log("");
373
- console.log("Win11 enforces a hash on `HKCU\\...\\UrlAssociations\\mailto\\UserChoice`,");
374
- console.log("so the only programmatic ways to flip the active default are MSIX packaging");
375
- console.log("(parked under C46) or a hash-aware tool like SetUserFTA. The picker may");
376
- console.log("warn \"app must be from the Store\" click \"More options\" / \"Choose another");
377
- console.log("app on this PC\" to reach rmfmail.");
378
- process.exit(0);
314
+ failed++;
315
+ lines.push(` failed: ${cmdLine}\n ${e.message}`);
316
+ }
317
+ }
318
+ lines.push("rmfmail registered as a mailto: handler.");
319
+ lines.push("");
320
+ lines.push("To make it the default in Windows 11:");
321
+ lines.push(" Settings Apps → Default apps → search \"rmfmail\" click rmfmail");
322
+ lines.push(" → \"Set default\" for the mailto link type.");
323
+ lines.push("");
324
+ lines.push("Win11 enforces a hash on `HKCU\\...\\UrlAssociations\\mailto\\UserChoice`,");
325
+ lines.push("so the only programmatic ways to flip the active default are MSIX packaging");
326
+ lines.push("(parked under C46) or a hash-aware tool like SetUserFTA. The picker may");
327
+ lines.push("warn \"app must be from the Store\" click \"More options\" / \"Choose another");
328
+ lines.push("app on this PC\" to reach rmfmail.");
329
+ return { ok: failed === 0, message: lines.join("\n") };
330
+ }
331
+ if (hasFlag("register-mailto") || hasFlag("unregister-mailto")) {
332
+ const unregister = hasFlag("unregister-mailto");
333
+ // C124: Linux registration — a .desktop entry claiming the mailto:
334
+ // scheme + xdg-mime default. No exe-launcher needed (unlike Windows):
335
+ // Linux pickers read Name= from the .desktop file directly.
336
+ if (process.platform === "linux") {
337
+ const appsDir = path.join(os.homedir(), ".local", "share", "applications");
338
+ const desktopPath = path.join(appsDir, "rmfmail.desktop");
339
+ if (unregister) {
340
+ try {
341
+ fs.unlinkSync(desktopPath);
342
+ }
343
+ catch { /* not registered */ }
344
+ try {
345
+ execSync(`update-desktop-database "${appsDir}"`);
346
+ }
347
+ catch { /* optional tool */ }
348
+ console.log("Unregistered rmfmail mailto: handler.");
349
+ process.exit(0);
350
+ }
351
+ const __mailtoJs = path.join(import.meta.dirname, "mailx.js");
352
+ const __iconPng = path.join(import.meta.dirname, "..", "client", "icon.png");
353
+ // Exec quoting follows the Desktop Entry spec: quoted absolute paths,
354
+ // bare %u field code (quoting %u breaks argument expansion).
355
+ const desktopEntry = [
356
+ "[Desktop Entry]",
357
+ "Type=Application",
358
+ "Name=rmfmail",
359
+ "Comment=rmfmail email client",
360
+ `Exec="${process.execPath}" "${__mailtoJs}" --mailto %u`,
361
+ `Icon=${__iconPng}`,
362
+ "Terminal=false",
363
+ "MimeType=x-scheme-handler/mailto;",
364
+ "Categories=Network;Email;",
365
+ "",
366
+ ].join("\n");
367
+ fs.mkdirSync(appsDir, { recursive: true });
368
+ fs.writeFileSync(desktopPath, desktopEntry);
369
+ try {
370
+ execSync("xdg-mime default rmfmail.desktop x-scheme-handler/mailto");
371
+ }
372
+ catch (e) {
373
+ console.error(`xdg-mime failed (${e.message}) — handler installed but not set as default. Set it in your DE's default-apps settings.`);
374
+ }
375
+ try {
376
+ execSync(`update-desktop-database "${appsDir}"`);
377
+ }
378
+ catch { /* optional tool */ }
379
+ console.log(`Registered rmfmail as mailto: handler (${desktopPath}).`);
380
+ process.exit(0);
381
+ }
382
+ if (process.platform !== "win32") {
383
+ // macOS needs a real .app bundle with CFBundleURLTypes — LaunchServices
384
+ // won't register a bare script. Tracked as the macOS half of C124.
385
+ console.error("--register-mailto / --unregister-mailto: macOS registration not implemented yet (needs an .app bundle — TODO C124).");
386
+ process.exit(1);
387
+ }
388
+ const r = registerMailtoWindows(unregister);
389
+ console.log(r.message);
390
+ process.exit(r.ok ? 0 : 1);
379
391
  }
380
392
  // Read our own version once — used for the instance file + upgrade check below.
381
393
  const __selfRoot = path.join(import.meta.dirname, "..");
@@ -2114,6 +2126,12 @@ RFC 5322 with CRLF line endings. Bodies are quoted-printable encoded (readable i
2114
2126
  // shell can SIGTERM it without name-based sweeps (cross-platform —
2115
2127
  // see memory: feedback_cross_platform_strong_rule). Remove on
2116
2128
  // resolution so the file doesn't accumulate stale PIDs.
2129
+ // Settings → "Make rmfmail the default email app" runs the same
2130
+ // registration the -register-mailto CLI flag does. Windows-only —
2131
+ // Linux/mac users still go through the CLI (xdg / TODO C124).
2132
+ if (process.platform === "win32") {
2133
+ svc.setMailtoRegisterFn(async () => registerMailtoWindows(false));
2134
+ }
2117
2135
  svc.setPopupFn(async (opts) => {
2118
2136
  // Own WebView2 profile so a reminder popup can never share (and
2119
2137
  // crash) the main window's browser process — see S67 note on the