sketchboard-app 1.0.6 → 1.0.7

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 (2) hide show
  1. package/bin/uninstall.js +69 -70
  2. package/package.json +1 -1
package/bin/uninstall.js CHANGED
@@ -2,96 +2,95 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- const readline = require("readline");
6
- const fs = require("fs");
7
- const path = require("path");
8
- const os = require("os");
5
+ const { spawnSync } = require("child_process");
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+ const os = require("os");
9
9
 
10
10
  const DATA_DIR = process.env.SKETCHBOARD_DATA || path.join(os.homedir(), ".sketchboard");
11
11
  const exists = fs.existsSync(DATA_DIR);
12
12
 
13
- // Non-interactive environment (CI/pipe) — skip prompt, keep data
14
- if (!process.stdin.isTTY) {
15
- process.exit(0);
16
- }
17
-
18
- // ── Count saved drawings ──────────────────────────────────────────────────────
13
+ // Count saved drawings
19
14
  let drawingCount = 0;
20
15
  try {
21
- const drawingsDir = path.join(DATA_DIR, "drawings");
22
- if (fs.existsSync(drawingsDir)) {
23
- drawingCount = fs.readdirSync(drawingsDir).filter((f) => f.endsWith(".json")).length;
16
+ const dir = path.join(DATA_DIR, "drawings");
17
+ if (fs.existsSync(dir)) {
18
+ drawingCount = fs.readdirSync(dir).filter((f) => f.endsWith(".json")).length;
24
19
  }
25
20
  } catch { /* ignore */ }
26
21
 
27
22
  // ── Banner ────────────────────────────────────────────────────────────────────
28
- const shortPath = DATA_DIR.length > 46 ? "..." + DATA_DIR.slice(-43) : DATA_DIR;
23
+ const shortPath = DATA_DIR.length > 48 ? "..." + DATA_DIR.slice(-45) : DATA_DIR;
29
24
 
30
- console.log(`
31
- ╔════════════════════════════════════════════════════╗
32
- ║ SketchBoard Uninstaller
33
- ╠════════════════════════════════════════════════════╣`);
25
+ process.stdout.write("\n");
26
+ process.stdout.write(" ╔════════════════════════════════════════════════════╗\n");
27
+ process.stdout.write(" ║ SketchBoard Uninstaller ║\n");
28
+ process.stdout.write(" ╠════════════════════════════════════════════════════╣\n");
34
29
 
35
30
  if (exists && drawingCount > 0) {
36
- console.log(` ║
37
- You have ${String(drawingCount).padEnd(3)} saved drawing(s) at: ║
38
- ║ ${shortPath.padEnd(50)} ║
39
- ║ ║`);
31
+ process.stdout.write(` ║ You have ${String(drawingCount)} saved drawing(s) stored at: ║\n`);
32
+ process.stdout.write(` ║ ${shortPath.padEnd(50)} ║\n`);
40
33
  } else if (exists) {
41
- console.log(` ║
42
- Data folder exists (no drawings saved yet): ║
43
- ║ ${shortPath.padEnd(50)} ║
44
- ║ ║`);
34
+ process.stdout.write(` ║ Data folder exists (no drawings yet): ║\n`);
35
+ process.stdout.write(` ${shortPath.padEnd(50)} ║\n`);
45
36
  } else {
46
- console.log(`
47
- ║ No data folder found — nothing to delete. ║
48
- ║ ║`);
37
+ process.stdout.write(" No data folder found — nothing to delete. ║\n");
49
38
  }
50
39
 
51
- console.log(` ╚════════════════════════════════════════════════════╝
52
- `);
53
-
54
- console.log(" How would you like to uninstall?\n");
55
- console.log(" [1] Soft uninstall — remove the app, keep your drawings (default)");
56
- console.log(" [2] Full uninstall — remove the app AND delete all drawings\n");
57
-
58
- // ── Prompt ────────────────────────────────────────────────────────────────────
59
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
60
-
61
- // Safety timeout if no answer in 30s, default to soft uninstall
62
- const timeout = setTimeout(() => {
63
- rl.close();
64
- console.log("\n (Timed out — defaulting to soft uninstall. Your drawings are safe.)\n");
65
- process.exit(0);
66
- }, 30_000);
67
-
68
- rl.question(" Your choice (1 or 2, press Enter for 1): ", (answer) => {
69
- clearTimeout(timeout);
70
- rl.close();
71
-
72
- const choice = answer.trim();
40
+ process.stdout.write(" ╚════════════════════════════════════════════════════╝\n");
41
+ process.stdout.write("\n");
42
+ process.stdout.write(" How would you like to uninstall?\n\n");
43
+ process.stdout.write(" [1] Soft uninstall — remove the app, keep your drawings (default)\n");
44
+ process.stdout.write(" [2] Full uninstall — remove the app AND delete all drawings\n\n");
45
+ process.stdout.write(" Your choice (1 or 2, press Enter for 1): ");
46
+
47
+ // ── Read from the real console (works even when npm pipes stdin) ──────────────
48
+ function readFromConsole() {
49
+ if (process.platform === "win32") {
50
+ // On Windows, PowerShell's $Host.UI.ReadLine() reads directly from the
51
+ // console window regardless of stdin redirection by npm.
52
+ const result = spawnSync(
53
+ "powershell.exe",
54
+ ["-NoProfile", "-Command", "$Host.UI.ReadLine()"],
55
+ { stdio: ["inherit", "pipe", "inherit"], timeout: 30_000 },
56
+ );
57
+ if (result.error || result.status !== 0) return "";
58
+ return (result.stdout || "").toString().trim();
59
+ } else {
60
+ // On Unix, read directly from /dev/tty (bypasses piped stdin).
61
+ const result = spawnSync(
62
+ "bash",
63
+ ["-c", "read -r ans </dev/tty && printf '%s' \"$ans\""],
64
+ { stdio: ["inherit", "pipe", "inherit"], timeout: 30_000 },
65
+ );
66
+ if (result.error || result.status !== 0) return "";
67
+ return (result.stdout || "").toString().trim();
68
+ }
69
+ }
73
70
 
74
- if (choice === "2") {
75
- console.log();
76
- if (exists) {
77
- try {
78
- fs.rmSync(DATA_DIR, { recursive: true, force: true });
79
- console.log(` Deleted ${DATA_DIR}`);
80
- if (drawingCount > 0) {
81
- console.log(` ✓ ${drawingCount} drawing(s) removed`);
82
- }
83
- } catch (err) {
84
- console.error(` Could not delete ${DATA_DIR}: ${err.message}`);
85
- console.error(" You can delete it manually in File Explorer.\n");
71
+ const answer = readFromConsole();
72
+ process.stdout.write("\n");
73
+
74
+ // ── Act on the answer ─────────────────────────────────────────────────────────
75
+ if (answer === "2") {
76
+ if (exists) {
77
+ try {
78
+ fs.rmSync(DATA_DIR, { recursive: true, force: true });
79
+ process.stdout.write(` ✓ Deleted ${DATA_DIR}\n`);
80
+ if (drawingCount > 0) {
81
+ process.stdout.write(` ${drawingCount} drawing(s) permanently removed\n`);
86
82
  }
87
- } else {
88
- console.log(" (No data folder found nothing to delete)");
83
+ } catch (err) {
84
+ process.stderr.write(` Could not delete ${DATA_DIR}: ${err.message}\n`);
85
+ process.stderr.write(" You can delete it manually in File Explorer.\n");
89
86
  }
90
- console.log("\n Proceeding with full uninstall...\n");
91
87
  } else {
92
- console.log("\n Your drawings are safe.");
93
- console.log(" Proceeding with soft uninstall...\n");
88
+ process.stdout.write(" (No data folder to delete)\n");
94
89
  }
90
+ process.stdout.write(" Proceeding with full uninstall...\n\n");
91
+ } else {
92
+ process.stdout.write(" Your drawings are safe.\n");
93
+ process.stdout.write(" Proceeding with soft uninstall...\n\n");
94
+ }
95
95
 
96
- process.exit(0);
97
- });
96
+ process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sketchboard-app",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "SketchBoard — local-first whiteboard app. Run with: npx sketchboard-app",
5
5
  "main": "server.js",
6
6
  "bin": {