adb-sqlite-viewer 1.0.5 → 1.0.6

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 CHANGED
@@ -1,151 +1,86 @@
1
- # SQLite DevTools for Mobile (React Native)
1
+ # ADB SQLite DevTools
2
2
 
3
- A browser-based tool for inspecting SQLite databases on Android devices. Browse tables, view schemas, and execute SQL queries directly on your device.
3
+ Inspect SQLite databases on Android devices. Browse tables, view schemas, and run SQL queries all from your browser.
4
4
 
5
- ## Four Ways to Use
5
+ ## Quick Start (npm)
6
6
 
7
- ### Option 1: Desktop App (Easiest)
8
-
9
- Download the installer from [Releases](https://github.com/amitwinit/SQLite-DevTools-Mobile-ReactNative/releases) and run it. The app bundles the ADB bridge server — it starts automatically when you launch the app. No separate downloads, no terminal commands.
10
-
11
- **Requirements:**
12
- - Windows (NSIS installer)
13
- - `adb` on your PATH (Android SDK Platform-Tools)
14
- - Android device with USB debugging enabled
15
-
16
- ### Option 2: Hosted Version + ADB Bridge (Best for React Native Developers)
7
+ ```bash
8
+ npm install --save-dev adb-sqlite-viewer
9
+ npx sqlite-viewer
10
+ ```
17
11
 
18
- Use the deployed version at **[amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative](https://amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative/)** together with the **ADB Bridge** a small localhost server that wraps `adb shell` commands. This lets you inspect databases while ADB stays running for React Native development.
12
+ Opens a local server at `http://127.0.0.1:8085` with the full UI and ADB bridge built in. One command, no extra downloads.
19
13
 
20
- **Setup:**
14
+ ```bash
15
+ # Custom port
16
+ npx sqlite-viewer --port 3000
17
+ ```
21
18
 
22
- 1. Download `adb-bridge.exe` from [Releases](https://github.com/amitwinit/SQLite-DevTools-Mobile-ReactNative/releases), or build it yourself:
23
- ```bash
24
- cd bridge
25
- npm install
26
- npm run build # produces adb-bridge.exe
27
- ```
19
+ **Requirements:** `adb` on your PATH ([Android SDK Platform-Tools](https://developer.android.com/tools/releases/platform-tools)) and a USB-connected Android device with debugging enabled.
28
20
 
29
- 2. Run the bridge:
30
- ```bash
31
- # Either run the exe directly:
32
- adb-bridge.exe
21
+ ## All Options
33
22
 
34
- # Or with Node.js:
35
- cd bridge && node server.js
36
- ```
23
+ ### npm Package (Recommended for dev workflows)
37
24
 
38
- 3. Open the hosted website it auto-detects the bridge and connects through it.
25
+ Install into any project and run alongside your app:
39
26
 
40
- **How it works:**
41
- ```
42
- Hosted website (HTTPS) ──HTTP──> localhost:15555 (bridge) ──> adb shell ──> Device
27
+ ```bash
28
+ npm install --save-dev adb-sqlite-viewer
43
29
  ```
44
- The website detects the bridge on startup and routes all commands through HTTP instead of WebUSB. No need to kill ADB.
45
-
46
- ### Option 3: Hosted Version with WebUSB (No Setup Required)
47
30
 
48
- Use the deployed version at **[amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative](https://amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative/)**
31
+ Add to your `package.json` scripts:
49
32
 
50
- This version uses **WebUSB** to communicate with your Android device directly from the browser. No backend server needed.
51
-
52
- **Requirements:**
53
- - Chrome or Edge (WebUSB is not supported in Firefox/Safari)
54
- - Android device with USB debugging enabled
55
- - You must **stop the local ADB server** first: `adb kill-server`
33
+ ```json
34
+ {
35
+ "scripts": {
36
+ "sqlite-viewer": "sqlite-viewer"
37
+ }
38
+ }
39
+ ```
56
40
 
57
- **Important:** WebUSB and the local ADB server cannot use the USB interface at the same time. If you are actively developing a React Native app and need ADB running, use **Option 1** or **Option 2** instead.
41
+ Then `npm run sqlite-viewer` opens the viewer. Works great alongside React Native, Flutter, or any Android project.
58
42
 
59
- **Steps:**
60
- 1. Run `adb kill-server` in your terminal
61
- 2. Open the hosted URL in Chrome/Edge
62
- 3. Click **Connect Device** and select your phone from the USB picker
63
- 4. Approve the USB debugging prompt on your phone (first time only)
64
- 5. Select a package and database, then start querying
43
+ ### Desktop App
65
44
 
66
- ### Option 4: Local Flask Server (Legacy)
45
+ Download the Windows installer from [Releases](https://github.com/amitwinit/SQLite-DevTools-Mobile-ReactNative/releases). Double-click to launch — the bridge server starts automatically.
67
46
 
68
- If you are developing a React Native app and need ADB running alongside, use the local Flask backend. Both tools share the same ADB server so there is no conflict.
47
+ ### Hosted Version + ADB Bridge
69
48
 
70
- **Setup:**
49
+ Use the deployed version at **[amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative](https://amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative/)** together with the standalone ADB Bridge.
71
50
 
72
- 1. Install Python dependencies:
73
- ```bash
74
- pip install -r requirements.txt
75
- ```
51
+ 1. Download `adb-bridge.exe` from [Releases](https://github.com/amitwinit/SQLite-DevTools-Mobile-ReactNative/releases)
52
+ 2. Run `adb-bridge.exe`
53
+ 3. Open the hosted website — it auto-detects the bridge
76
54
 
77
- 2. Copy and configure environment:
78
- ```bash
79
- cp .env.example .env
80
- ```
55
+ ```
56
+ Website (HTTPS) ──HTTP──> localhost:15555 (bridge) ──> adb shell ──> Device
57
+ ```
81
58
 
82
- Update `.env` with your configuration:
83
- - `DEVICE_SERIAL` — run `adb devices` to find it
84
- - `PACKAGE_NAME` — your app's package name
85
- - `DB_NAME` — the SQLite database filename
86
- - `PYTHON_TOOLS_PATH` — path to the python_tools directory
59
+ ### Hosted Version with WebUSB (No install required)
87
60
 
88
- 3. Run the server:
89
- ```bash
90
- python app.py
91
- ```
61
+ Open **[amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative](https://amitwinit.github.io/SQLite-DevTools-Mobile-ReactNative/)** in Chrome/Edge. Uses WebUSB to talk directly to the device — no server needed.
92
62
 
93
- 4. Open http://localhost:5001 in any browser
63
+ **Note:** Requires `adb kill-server` first (WebUSB and ADB can't share the USB interface). Not suitable when you need ADB running for development.
94
64
 
95
65
  ## When to Use Which
96
66
 
97
- | Scenario | Use |
98
- |----------|-----|
99
- | Just want it to work, one click | Desktop App (Option 1) |
100
- | Active React Native development | Desktop App (Option 1) or ADB Bridge (Option 2) |
101
- | Quick DB inspection, no local setup | WebUSB (Option 3) |
102
- | Sharing with teammates who don't have Python | WebUSB (Option 3) |
103
- | Need ADB for other tools simultaneously | Desktop App (Option 1) or ADB Bridge (Option 2) |
104
-
105
- ## Environment Variables (Option 4)
106
-
107
- ### Application Configuration
108
- - `PACKAGE_NAME`: Android app package name
109
- - `DB_NAME`: Database name on the device
110
- - `DEVICE_SERIAL`: ADB device serial number
111
- - `PYTHON_TOOLS_PATH`: Path to python_tools directory
112
-
113
- ### Flask Server Configuration
114
- - `FLASK_HOST`: Flask server host (default: 0.0.0.0)
115
- - `FLASK_PORT`: Flask server port (default: 5001)
116
- - `FLASK_DEBUG`: Enable debug mode (default: True)
117
-
118
- ### Cache Configuration
119
- - `USE_CACHE`: Enable database caching (default: True)
120
- - `FORCE_LOCAL`: Force local database operations (default: False)
67
+ | Scenario | Recommended |
68
+ |----------|-------------|
69
+ | Active development (React Native, Flutter, etc.) | `npx sqlite-viewer` or Desktop App |
70
+ | Quick one-off DB inspection | WebUSB (hosted version) |
71
+ | CI or shared dev environment | `npx sqlite-viewer` |
72
+ | No Node.js installed | Desktop App or WebUSB |
121
73
 
122
74
  ## Development
123
75
 
124
- To work on the WebUSB frontend:
125
-
126
76
  ```bash
127
77
  npm install
128
- npm run dev
129
- ```
130
-
131
- To build for production (GitHub Pages):
132
-
133
- ```bash
134
- npm run build
78
+ npm run dev # Vite dev server
79
+ npm run build # Build for GitHub Pages
80
+ npm run electron:dev # Build + launch Electron app
81
+ npm run electron:build # Build Electron installer
135
82
  ```
136
83
 
137
- The built files go to `dist/` and are deployed to GitHub Pages automatically on push to `main`.
138
-
139
- To run the Electron desktop app in development:
140
-
141
- ```bash
142
- npm run electron:dev
143
- ```
144
-
145
- To build the Electron installer:
146
-
147
- ```bash
148
- npm run electron:build
149
- ```
84
+ ## License
150
85
 
151
- The installer is output to `electron-dist/`.
86
+ MIT
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "adb-bridge",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "description": "Localhost HTTP bridge that wraps adb shell commands for the SQLite DevTools website",
6
+ "scripts": {
7
+ "start": "node server.js",
8
+ "build": "pkg server.js --target node20-win-x64 --output adb-bridge.exe"
9
+ },
10
+ "devDependencies": {
11
+ "@yao-pkg/pkg": "^5.11.0"
12
+ }
13
+ }
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+
3
+ const { execFile } = require("child_process");
4
+ const https = require("https");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const os = require("os");
8
+
9
+ const CACHE_DIR = path.join(os.homedir(), ".adb-sqlite-viewer");
10
+ const PLATFORM_TOOLS_DIR = path.join(CACHE_DIR, "platform-tools");
11
+
12
+ const DOWNLOAD_URLS = {
13
+ win32: "https://dl.google.com/android/repository/platform-tools-latest-windows.zip",
14
+ darwin: "https://dl.google.com/android/repository/platform-tools-latest-darwin.zip",
15
+ linux: "https://dl.google.com/android/repository/platform-tools-latest-linux.zip",
16
+ };
17
+
18
+ const ADB_BIN = process.platform === "win32" ? "adb.exe" : "adb";
19
+
20
+ /** Check if adb works at the given path. Returns version string or null. */
21
+ function tryAdb(adbPath) {
22
+ return new Promise((resolve) => {
23
+ execFile(adbPath, ["version"], { timeout: 5000 }, (err, stdout) => {
24
+ if (err) return resolve(null);
25
+ resolve(stdout.split("\n")[0].trim());
26
+ });
27
+ });
28
+ }
29
+
30
+ /** Download a file via HTTPS, following redirects. */
31
+ function download(url, dest) {
32
+ return new Promise((resolve, reject) => {
33
+ const file = fs.createWriteStream(dest);
34
+ const request = (u) => {
35
+ https.get(u, (res) => {
36
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
37
+ file.close();
38
+ request(res.headers.location);
39
+ return;
40
+ }
41
+ if (res.statusCode !== 200) {
42
+ file.close();
43
+ fs.unlinkSync(dest);
44
+ reject(new Error(`Download failed: HTTP ${res.statusCode}`));
45
+ return;
46
+ }
47
+ const total = parseInt(res.headers["content-length"], 10) || 0;
48
+ let downloaded = 0;
49
+ res.on("data", (chunk) => {
50
+ downloaded += chunk.length;
51
+ if (total > 0) {
52
+ const pct = Math.round((downloaded / total) * 100);
53
+ process.stdout.write(`\r Downloading... ${pct}%`);
54
+ }
55
+ });
56
+ res.pipe(file);
57
+ file.on("finish", () => {
58
+ file.close();
59
+ if (total > 0) process.stdout.write("\n");
60
+ resolve();
61
+ });
62
+ }).on("error", (err) => {
63
+ file.close();
64
+ fs.unlinkSync(dest);
65
+ reject(err);
66
+ });
67
+ };
68
+ request(url);
69
+ });
70
+ }
71
+
72
+ /** Extract a zip file using OS tools. */
73
+ function extractZip(zipPath, destDir) {
74
+ return new Promise((resolve, reject) => {
75
+ const cmd = process.platform === "win32"
76
+ ? `tar -xf "${zipPath}" -C "${destDir}"`
77
+ : `unzip -q -o "${zipPath}" -d "${destDir}"`;
78
+ execFile(cmd.split(" ")[0], cmd.split(" ").slice(1), { shell: true, timeout: 60000 }, (err) => {
79
+ if (err) reject(new Error(`Extract failed: ${err.message}`));
80
+ else resolve();
81
+ });
82
+ });
83
+ }
84
+
85
+ /**
86
+ * Ensure adb is available. Checks PATH, then cached download, then downloads.
87
+ * Prepends the adb directory to process.env.PATH if needed.
88
+ * Returns the adb version string.
89
+ */
90
+ async function ensureAdb() {
91
+ // 1. Check system PATH
92
+ const systemVersion = await tryAdb("adb");
93
+ if (systemVersion) {
94
+ return systemVersion;
95
+ }
96
+
97
+ // 2. Check cached download
98
+ const cachedAdb = path.join(PLATFORM_TOOLS_DIR, ADB_BIN);
99
+ if (fs.existsSync(cachedAdb)) {
100
+ const cachedVersion = await tryAdb(cachedAdb);
101
+ if (cachedVersion) {
102
+ prependToPath(PLATFORM_TOOLS_DIR);
103
+ return cachedVersion;
104
+ }
105
+ }
106
+
107
+ // 3. Download from Google
108
+ const url = DOWNLOAD_URLS[process.platform];
109
+ if (!url) {
110
+ throw new Error(`Unsupported platform: ${process.platform}. Install adb manually.`);
111
+ }
112
+
113
+ console.log(" adb not found. Downloading Android Platform-Tools...");
114
+
115
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
116
+ const zipPath = path.join(CACHE_DIR, "platform-tools.zip");
117
+
118
+ await download(url, zipPath);
119
+ console.log(" Extracting...");
120
+ await extractZip(zipPath, CACHE_DIR);
121
+
122
+ // Clean up zip
123
+ try { fs.unlinkSync(zipPath); } catch {}
124
+
125
+ // Verify
126
+ if (!fs.existsSync(cachedAdb)) {
127
+ throw new Error("Download succeeded but adb binary not found in extracted files.");
128
+ }
129
+
130
+ // Make executable on Unix
131
+ if (process.platform !== "win32") {
132
+ fs.chmodSync(cachedAdb, 0o755);
133
+ }
134
+
135
+ const version = await tryAdb(cachedAdb);
136
+ if (!version) {
137
+ throw new Error("Downloaded adb binary is not working.");
138
+ }
139
+
140
+ prependToPath(PLATFORM_TOOLS_DIR);
141
+ console.log(` Downloaded: ${version}`);
142
+ return version;
143
+ }
144
+
145
+ function prependToPath(dir) {
146
+ const sep = process.platform === "win32" ? ";" : ":";
147
+ process.env.PATH = dir + sep + (process.env.PATH || "");
148
+ }
149
+
150
+ module.exports = { ensureAdb };
package/cli/server.cjs CHANGED
@@ -4,7 +4,8 @@ const http = require("http");
4
4
  const path = require("path");
5
5
  const fs = require("fs");
6
6
  const { exec } = require("child_process");
7
- const { handleRequest: bridgeHandler, checkAdb } = require("../bridge/server.js");
7
+ const { handleRequest: bridgeHandler } = require("../bridge/server.js");
8
+ const { ensureAdb } = require("./ensure-adb.cjs");
8
9
 
9
10
  const DIST_DIR = path.join(__dirname, "..", "dist");
10
11
 
@@ -86,13 +87,13 @@ async function start(port) {
86
87
  process.exit(1);
87
88
  }
88
89
 
89
- // Check adb (warn only WebUSB still works without it)
90
+ // Ensure adb is available (downloads if needed)
90
91
  try {
91
- const version = await checkAdb();
92
- console.log(`Found: ${version}`);
92
+ const version = await ensureAdb();
93
+ console.log(` adb: ${version}`);
93
94
  } catch (err) {
94
- console.warn(`WARNING: ${err.message}`);
95
- console.warn("ADB bridge features will not work.");
95
+ console.warn(` WARNING: ${err.message}`);
96
+ console.warn(" ADB bridge features will not work.");
96
97
  }
97
98
 
98
99
  const server = http.createServer(requestHandler);
package/electron/main.cjs CHANGED
@@ -5,6 +5,14 @@ const path = require("path");
5
5
  let bridge = null;
6
6
  let mainWindow = null;
7
7
 
8
+ function setupBundledAdb() {
9
+ if (app.isPackaged) {
10
+ const toolsDir = path.join(process.resourcesPath, "tools");
11
+ const sep = process.platform === "win32" ? ";" : ":";
12
+ process.env.PATH = toolsDir + sep + (process.env.PATH || "");
13
+ }
14
+ }
15
+
8
16
  function getBridgePath() {
9
17
  if (app.isPackaged) {
10
18
  return path.join(process.resourcesPath, "bridge", "server.js");
@@ -73,6 +81,7 @@ function createWindow() {
73
81
  }
74
82
 
75
83
  app.whenReady().then(async () => {
84
+ setupBundledAdb();
76
85
  try {
77
86
  console.log("Starting ADB bridge server...");
78
87
  await startBridge();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adb-sqlite-viewer",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "ADB SQLite database viewer for Android — inspect tables, schemas, and run queries on-device",
5
5
  "type": "module",
6
6
  "main": "electron/main.cjs",
@@ -10,6 +10,7 @@
10
10
  "files": [
11
11
  "cli/",
12
12
  "bridge/server.js",
13
+ "bridge/package.json",
13
14
  "dist/"
14
15
  ],
15
16
  "scripts": {
@@ -66,6 +67,10 @@
66
67
  {
67
68
  "from": "bridge/package.json",
68
69
  "to": "bridge/package.json"
70
+ },
71
+ {
72
+ "from": "tools/",
73
+ "to": "tools/"
69
74
  }
70
75
  ],
71
76
  "win": {