@mcesystems/adb-kit 1.0.91 → 1.0.93

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,230 +1,230 @@
1
- # @mcesystems/adb-kit
2
-
3
- ## 1. Description
4
-
5
- **What it does:** ADB (Android Debug Bridge) toolkit for device management. Provides a TypeScript wrapper around adbkit for Android device operations: listing devices, reading device properties, installing/uninstalling apps, checking and waiting for USB debugging, and port forwarding.
6
-
7
- **When it's used:** Use this package when your application needs to communicate with Android devices over ADB—for example device management tools, test runners, or installers that target Android hardware.
8
-
9
- ## 2. Install
10
-
11
- ```bash
12
- npm install @mcesystems/adb-kit
13
- ```
14
-
15
- **Requirements:** Node.js 18+, Android device with USB debugging enabled, and ADB binaries (see Resources).
16
-
17
- ## 3. Resources
18
-
19
- This package needs ADB binaries to run. You can obtain them in one of these ways:
20
-
21
- **Option A – Export script (recommended for distribution)**
22
- Bundle ADB for your app using the provided script:
23
-
24
- ```bash
25
- npx export-adb-resources /path/to/your-app/resources/adb-kit
26
-
27
- # All platforms
28
- npx export-adb-resources /path/to/your-app/resources/adb-kit --all
29
- ```
30
-
31
- See [scripts/README.md](./scripts/README.md) for arguments, options, output layout, and prerequisites.
32
-
33
- **Option B – Development**
34
- - **Windows / macOS:** Set `AdbBinPath` to your ADB binary directory, or have `adb` on system PATH.
35
- - **Linux:** Install via package manager (e.g. `sudo apt install adb`).
36
-
37
- The package resolves ADB in this order: `AdbBinPath` env, then bundled resources under `dist/resources/bin/<platform>/`, then system PATH.
38
-
39
- ## 4. Examples
40
-
41
- **Create a device kit and read properties**
42
-
43
- ```typescript
44
- import { AdbDeviceKit } from '@mcesystems/adb-kit';
45
-
46
- const device = new AdbDeviceKit('device-serial-number', 1);
47
- const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
48
- const allProps = await device.getAllDeviceProperties();
49
- const devices = await device.listDevices();
50
- ```
51
-
52
- **Install/uninstall and check app**
53
-
54
- ```typescript
55
- await device.installApp('/path/to/app.apk');
56
- const isInstalled = await device.isAppInstalled('com.example.app');
57
- await device.uninstallApp('com.example.app');
58
- ```
59
-
60
- **USB debugging**
61
-
62
- ```typescript
63
- const hasDebugging = await device.hasUsbDebugging();
64
- const { promise, events } = device.waitForUsbDebugging(30000); // 30s timeout
65
- events.on("usbDebuggingOff", () => console.log("Enable USB debugging on device"));
66
- events.on("usbDebuggingNeedsAlwaysAllow", () => console.log("Tap Always allow on device"));
67
- events.on("usbDebuggingAuthorized", () => console.log("Device ready"));
68
- const ok = await promise;
69
- ```
70
-
71
- **Port forwarding**
72
-
73
- ```typescript
74
- const localPort = await device.startPortForward('tcp:8080');
75
- ```
76
-
77
- **Low-level clients**
78
-
79
- ```typescript
80
- const client = await device.getClient();
81
- const deviceClient = await device.getDeviceClient();
82
- ```
83
-
84
- **First connected Android properties**
85
-
86
- One-shot example that discovers the first connected Android device and prints a curated set of its properties (manufacturer, model, brand, Android version, etc.).
87
-
88
- ```bash
89
- # From packages/adb-kit
90
- pnpm example:first-android-properties
91
- ```
92
-
93
- See [src/examples/first-connected-android-properties.ts](./src/examples/first-connected-android-properties.ts) for the script.
94
-
95
- **USB debugging robustness example**
96
-
97
- Interactive example that runs the same flow 5 times to verify `waitForUsbDebugging` handling: start without USB debugging (device not found), short 5s timeout (user lets it pass), then wait up to 30s while the user enables USB debugging, show device recognized, then user disables USB debugging and repeats.
98
-
99
- ```bash
100
- # From packages/adb-kit (set ADB_DEVICE_SERIAL if USB debugging is off)
101
- pnpm example:usb-debugging
102
- ```
103
-
104
- See [src/examples/usb-debugging-robustness.ts](./src/examples/usb-debugging-robustness.ts) for the script.
105
-
106
- **USB debugging playground**
107
-
108
- Interactive playground to observe status events while you toggle USB debugging on/off or revoke authorizations. Prints events in real time as you change device settings.
109
-
110
- ```bash
111
- # From packages/adb-kit (set ADB_DEVICE_SERIAL if USB debugging is off)
112
- pnpm example:usb-debugging-playground
113
- ```
114
-
115
- See [src/examples/usb-debugging-playground.ts](./src/examples/usb-debugging-playground.ts) for the script.
116
-
117
- For more scenarios and step-by-step explanations, see [Example.md](./Example.md).
118
-
119
- ## 5. API
120
-
121
- ### AdbDeviceKit
122
-
123
- **Constructor**
124
-
125
- - **Input:** `deviceId: string`, `port: number`
126
- - **Output:** new `AdbDeviceKit` instance bound to that device and logical port.
127
-
128
- **listDevices()**
129
-
130
- - **Input:** none
131
- - **Output:** `Promise<AdbDevice[]>` — list of connected devices (`AdbDevice`: `{ id: string; type: AdbDeviceType }`).
132
-
133
- **getDeviceProperties(properties)**
134
-
135
- - **Input:** `properties: DeviceProperty[]` — e.g. `['Manufacturer', 'Model']`
136
- - **Output:** `Promise<string[]>` — values in the same order as `properties`; failed props are `""`.
137
-
138
- **getAllDeviceProperties()**
139
-
140
- - **Input:** none
141
- - **Output:** `Promise<Record<string, string>>` — all device properties from `getprop`.
142
-
143
- **installApp(appPath)**
144
-
145
- - **Input:** `appPath: string` — path to APK
146
- - **Output:** `Promise<void>` — resolves when install finishes; rejects on failure.
147
-
148
- **uninstallApp(packageName)**
149
-
150
- - **Input:** `packageName: string` — e.g. `'com.example.app'`
151
- - **Output:** `Promise<void>` — resolves when uninstall finishes; rejects on failure.
152
-
153
- **isAppInstalled(packageName)**
154
-
155
- - **Input:** `packageName: string`
156
- - **Output:** `Promise<boolean>` — whether the package is installed.
157
-
158
- **hasUsbDebugging()**
159
-
160
- - **Input:** none
161
- - **Output:** `Promise<boolean>` — whether this device appears in the ADB device list.
162
-
163
- **waitForUsbDebugging(timeout?, numberOfAllowedAttempts?)**
164
-
165
- - **Input:** `timeout?: number` (default `120000` ms), `numberOfAllowedAttempts?: number` (default `5`, accepted for backward compatibility; give-up is determined by timeout and tracker end only)
166
- - **Output:** `{ promise: Promise<boolean>; events: EventEmitter }` — await `promise` for the result (`true` when device is ready, `false` when tracking ends without device; rejects on timeout, device removal, or connection error). Subscribe to `events` for state changes:
167
- - `usbDebuggingOff` — waiting started (USB debugging not enabled on device)
168
- - `usbDebuggingNeedsAlwaysAllow` — device visible but user must tap "Always allow" on device
169
- - `usbDebuggingAuthorized` — device ready
170
-
171
- **startPortForward(serviceName)**
172
-
173
- - **Input:** `serviceName: string` — e.g. `'tcp:8080'`
174
- - **Output:** `Promise<number | null>` — local port number used for forwarding, or `null` if forwarding failed. Reuses same port on repeated calls.
175
-
176
- **getClient()**
177
-
178
- - **Input:** none
179
- - **Output:** `Promise<AdbClient>` — underlying adbkit client.
180
-
181
- **getDeviceClient()**
182
-
183
- - **Input:** none
184
- - **Output:** `Promise<DeviceClient>` — adbkit device client for this device.
185
-
186
- **getDeviceId()**
187
-
188
- - **Input:** none
189
- - **Output:** `string` — device serial (last segment after `\` on Windows).
190
-
191
- **getPort()**
192
-
193
- - **Input:** none
194
- - **Output:** `number` — logical port passed to the constructor.
195
-
196
- ### DeviceProperty
197
-
198
- Supported property names for `getDeviceProperties()`:
199
- `Manufacturer`, `Name`, `Model`, `Brand`, `Device`, `Android Version`, `Platform`, `CPU`, `CPU.abi2`, `Description`, `Fingerprint`, `GSM Flexversion`, `GSM IMEI`, `Locale Language`, `Locale Region`, `Wifi Channels`, `Board Platform`, `Product Board`, `Display ID`, `Version Incremental`, `Version SDK`, `Version Codename`, `Version Release`, `Build Date`, `Build Type`, `Build User`.
200
-
201
- ## 6. Flow
202
-
203
- Example flow: wait for device, read identity, install an app, then forward a port.
204
-
205
- ```typescript
206
- import { AdbDeviceKit } from '@mcesystems/adb-kit';
207
-
208
- const deviceId = 'ABC123'; // from your device discovery
209
- const device = new AdbDeviceKit(deviceId, 1);
210
-
211
- // 1. Wait for USB debugging (e.g. after user enables it)
212
- const { promise } = device.waitForUsbDebugging(60000);
213
- await promise;
214
-
215
- // 2. Identify device
216
- const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
217
- console.log(`Device: ${manufacturer} ${model}`);
218
-
219
- // 3. Install app
220
- await device.installApp('./build/app.apk');
221
-
222
- // 4. Forward a device service to a local port
223
- const localPort = await device.startPortForward('tcp:8080');
224
- console.log(`Service reachable at localhost:${localPort}`);
225
- ```
226
-
227
- ## 7. TODO
228
-
229
- - [ ] Optional: Re-authorize handling when ADB reports vendor keys not set (revoke and re-authorize device).
230
- - [ ] Optional: Add Example.md with more detailed scenarios and explanations.
1
+ # @mcesystems/adb-kit
2
+
3
+ ## 1. Description
4
+
5
+ **What it does:** ADB (Android Debug Bridge) toolkit for device management. Provides a TypeScript wrapper around adbkit for Android device operations: listing devices, reading device properties, installing/uninstalling apps, checking and waiting for USB debugging, and port forwarding.
6
+
7
+ **When it's used:** Use this package when your application needs to communicate with Android devices over ADB—for example device management tools, test runners, or installers that target Android hardware.
8
+
9
+ ## 2. Install
10
+
11
+ ```bash
12
+ npm install @mcesystems/adb-kit
13
+ ```
14
+
15
+ **Requirements:** Node.js 18+, Android device with USB debugging enabled, and ADB binaries (see Resources).
16
+
17
+ ## 3. Resources
18
+
19
+ This package needs ADB binaries to run. You can obtain them in one of these ways:
20
+
21
+ **Option A – Export script (recommended for distribution)**
22
+ Bundle ADB for your app using the provided script:
23
+
24
+ ```bash
25
+ npx export-adb-resources /path/to/your-app/resources/adb-kit
26
+
27
+ # All platforms
28
+ npx export-adb-resources /path/to/your-app/resources/adb-kit --all
29
+ ```
30
+
31
+ See [scripts/README.md](./scripts/README.md) for arguments, options, output layout, and prerequisites.
32
+
33
+ **Option B – Development**
34
+ - **Windows / macOS:** Set `AdbBinPath` to your ADB binary directory, or have `adb` on system PATH.
35
+ - **Linux:** Install via package manager (e.g. `sudo apt install adb`).
36
+
37
+ The package resolves ADB in this order: `AdbBinPath` env, then bundled resources under `dist/resources/bin/<platform>/`, then system PATH.
38
+
39
+ ## 4. Examples
40
+
41
+ **Create a device kit and read properties**
42
+
43
+ ```typescript
44
+ import { AdbDeviceKit } from '@mcesystems/adb-kit';
45
+
46
+ const device = new AdbDeviceKit('device-serial-number', 1);
47
+ const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
48
+ const allProps = await device.getAllDeviceProperties();
49
+ const devices = await device.listDevices();
50
+ ```
51
+
52
+ **Install/uninstall and check app**
53
+
54
+ ```typescript
55
+ await device.installApp('/path/to/app.apk');
56
+ const isInstalled = await device.isAppInstalled('com.example.app');
57
+ await device.uninstallApp('com.example.app');
58
+ ```
59
+
60
+ **USB debugging**
61
+
62
+ ```typescript
63
+ const hasDebugging = await device.hasUsbDebugging();
64
+ const { promise, events } = device.waitForUsbDebugging(30000); // 30s timeout
65
+ events.on("usbDebuggingOff", () => console.log("Enable USB debugging on device"));
66
+ events.on("usbDebuggingNeedsAlwaysAllow", () => console.log("Tap Always allow on device"));
67
+ events.on("usbDebuggingAuthorized", () => console.log("Device ready"));
68
+ const ok = await promise;
69
+ ```
70
+
71
+ **Port forwarding**
72
+
73
+ ```typescript
74
+ const localPort = await device.startPortForward('tcp:8080');
75
+ ```
76
+
77
+ **Low-level clients**
78
+
79
+ ```typescript
80
+ const client = await device.getClient();
81
+ const deviceClient = await device.getDeviceClient();
82
+ ```
83
+
84
+ **First connected Android properties**
85
+
86
+ One-shot example that discovers the first connected Android device and prints a curated set of its properties (manufacturer, model, brand, Android version, etc.).
87
+
88
+ ```bash
89
+ # From packages/adb-kit
90
+ pnpm example:first-android-properties
91
+ ```
92
+
93
+ See [src/examples/first-connected-android-properties.ts](./src/examples/first-connected-android-properties.ts) for the script.
94
+
95
+ **USB debugging robustness example**
96
+
97
+ Interactive example that runs the same flow 5 times to verify `waitForUsbDebugging` handling: start without USB debugging (device not found), short 5s timeout (user lets it pass), then wait up to 30s while the user enables USB debugging, show device recognized, then user disables USB debugging and repeats.
98
+
99
+ ```bash
100
+ # From packages/adb-kit (set ADB_DEVICE_SERIAL if USB debugging is off)
101
+ pnpm example:usb-debugging
102
+ ```
103
+
104
+ See [src/examples/usb-debugging-robustness.ts](./src/examples/usb-debugging-robustness.ts) for the script.
105
+
106
+ **USB debugging playground**
107
+
108
+ Interactive playground to observe status events while you toggle USB debugging on/off or revoke authorizations. Prints events in real time as you change device settings.
109
+
110
+ ```bash
111
+ # From packages/adb-kit (set ADB_DEVICE_SERIAL if USB debugging is off)
112
+ pnpm example:usb-debugging-playground
113
+ ```
114
+
115
+ See [src/examples/usb-debugging-playground.ts](./src/examples/usb-debugging-playground.ts) for the script.
116
+
117
+ For more scenarios and step-by-step explanations, see [Example.md](./Example.md).
118
+
119
+ ## 5. API
120
+
121
+ ### AdbDeviceKit
122
+
123
+ **Constructor**
124
+
125
+ - **Input:** `deviceId: string`, `port: number`
126
+ - **Output:** new `AdbDeviceKit` instance bound to that device and logical port.
127
+
128
+ **listDevices()**
129
+
130
+ - **Input:** none
131
+ - **Output:** `Promise<AdbDevice[]>` — list of connected devices (`AdbDevice`: `{ id: string; type: AdbDeviceType }`).
132
+
133
+ **getDeviceProperties(properties)**
134
+
135
+ - **Input:** `properties: DeviceProperty[]` — e.g. `['Manufacturer', 'Model']`
136
+ - **Output:** `Promise<string[]>` — values in the same order as `properties`; failed props are `""`.
137
+
138
+ **getAllDeviceProperties()**
139
+
140
+ - **Input:** none
141
+ - **Output:** `Promise<Record<string, string>>` — all device properties from `getprop`.
142
+
143
+ **installApp(appPath)**
144
+
145
+ - **Input:** `appPath: string` — path to APK
146
+ - **Output:** `Promise<void>` — resolves when install finishes; rejects on failure.
147
+
148
+ **uninstallApp(packageName)**
149
+
150
+ - **Input:** `packageName: string` — e.g. `'com.example.app'`
151
+ - **Output:** `Promise<void>` — resolves when uninstall finishes; rejects on failure.
152
+
153
+ **isAppInstalled(packageName)**
154
+
155
+ - **Input:** `packageName: string`
156
+ - **Output:** `Promise<boolean>` — whether the package is installed.
157
+
158
+ **hasUsbDebugging()**
159
+
160
+ - **Input:** none
161
+ - **Output:** `Promise<boolean>` — whether this device appears in the ADB device list.
162
+
163
+ **waitForUsbDebugging(timeout?, numberOfAllowedAttempts?)**
164
+
165
+ - **Input:** `timeout?: number` (default `120000` ms), `numberOfAllowedAttempts?: number` (default `5`, accepted for backward compatibility; give-up is determined by timeout and tracker end only)
166
+ - **Output:** `{ promise: Promise<boolean>; events: EventEmitter }` — await `promise` for the result (`true` when device is ready, `false` when tracking ends without device; rejects on timeout, device removal, or connection error). Subscribe to `events` for state changes:
167
+ - `usbDebuggingOff` — waiting started (USB debugging not enabled on device)
168
+ - `usbDebuggingNeedsAlwaysAllow` — device visible but user must tap "Always allow" on device
169
+ - `usbDebuggingAuthorized` — device ready
170
+
171
+ **startPortForward(serviceName)**
172
+
173
+ - **Input:** `serviceName: string` — e.g. `'tcp:8080'`
174
+ - **Output:** `Promise<number | null>` — local port number used for forwarding, or `null` if forwarding failed. Reuses same port on repeated calls.
175
+
176
+ **getClient()**
177
+
178
+ - **Input:** none
179
+ - **Output:** `Promise<AdbClient>` — underlying adbkit client.
180
+
181
+ **getDeviceClient()**
182
+
183
+ - **Input:** none
184
+ - **Output:** `Promise<DeviceClient>` — adbkit device client for this device.
185
+
186
+ **getDeviceId()**
187
+
188
+ - **Input:** none
189
+ - **Output:** `string` — device serial (last segment after `\` on Windows).
190
+
191
+ **getPort()**
192
+
193
+ - **Input:** none
194
+ - **Output:** `number` — logical port passed to the constructor.
195
+
196
+ ### DeviceProperty
197
+
198
+ Supported property names for `getDeviceProperties()`:
199
+ `Manufacturer`, `Name`, `Model`, `Brand`, `Device`, `Android Version`, `Platform`, `CPU`, `CPU.abi2`, `Description`, `Fingerprint`, `GSM Flexversion`, `GSM IMEI`, `Locale Language`, `Locale Region`, `Wifi Channels`, `Board Platform`, `Product Board`, `Display ID`, `Version Incremental`, `Version SDK`, `Version Codename`, `Version Release`, `Build Date`, `Build Type`, `Build User`.
200
+
201
+ ## 6. Flow
202
+
203
+ Example flow: wait for device, read identity, install an app, then forward a port.
204
+
205
+ ```typescript
206
+ import { AdbDeviceKit } from '@mcesystems/adb-kit';
207
+
208
+ const deviceId = 'ABC123'; // from your device discovery
209
+ const device = new AdbDeviceKit(deviceId, 1);
210
+
211
+ // 1. Wait for USB debugging (e.g. after user enables it)
212
+ const { promise } = device.waitForUsbDebugging(60000);
213
+ await promise;
214
+
215
+ // 2. Identify device
216
+ const [manufacturer, model] = await device.getDeviceProperties(['Manufacturer', 'Model']);
217
+ console.log(`Device: ${manufacturer} ${model}`);
218
+
219
+ // 3. Install app
220
+ await device.installApp('./build/app.apk');
221
+
222
+ // 4. Forward a device service to a local port
223
+ const localPort = await device.startPortForward('tcp:8080');
224
+ console.log(`Service reachable at localhost:${localPort}`);
225
+ ```
226
+
227
+ ## 7. TODO
228
+
229
+ - [ ] Optional: Re-authorize handling when ADB reports vendor keys not set (revoke and re-authorize device).
230
+ - [ ] Optional: Add Example.md with more detailed scenarios and explanations.
package/dist/index.js CHANGED
@@ -31486,7 +31486,7 @@ var AdbDeviceKit = class {
31486
31486
  return client;
31487
31487
  }
31488
31488
  async listDevices() {
31489
- const devices = await this.client.listDevices();
31489
+ const devices = await this.client.listDevices().filter((device) => device.type === "device");
31490
31490
  return devices;
31491
31491
  }
31492
31492
  async getProperty(adbDevice, property) {
@@ -31549,13 +31549,23 @@ var AdbDeviceKit = class {
31549
31549
  waitForUsbDebugging(timeout2 = 12e4, _numberOfAllowedAttempts = 5) {
31550
31550
  const events = new import_node_events.EventEmitter();
31551
31551
  const promise = (async () => {
31552
- if (await this.hasUsbDebugging()) {
31552
+ const device = (await this.client.listDevices()).find(
31553
+ (device2) => device2.id === this.deviceId
31554
+ );
31555
+ logDetail(`Device: ${device?.id} (${device?.type})`);
31556
+ if (device?.type === "device") {
31553
31557
  logDetail("USB debugging is already enabled");
31554
31558
  return true;
31555
31559
  }
31556
31560
  const trackingClient = this.createTrackingClient();
31557
31561
  const tracker = await trackingClient.trackDevices();
31558
- events.emit(USB_DEBUGGING_EVENT_OFF);
31562
+ setTimeout(() => {
31563
+ if (device?.type === "unauthorized") {
31564
+ events.emit(USB_DEBUGGING_EVENT_NEEDS_ALWAYS_ALLOW);
31565
+ } else {
31566
+ events.emit(USB_DEBUGGING_EVENT_OFF);
31567
+ }
31568
+ }, 0);
31559
31569
  let settled = false;
31560
31570
  return new Promise((resolve, reject) => {
31561
31571
  const timeoutId = setTimeout(() => {
@@ -31582,14 +31592,14 @@ var AdbDeviceKit = class {
31582
31592
  reject(result.err);
31583
31593
  }
31584
31594
  };
31585
- const handleAddOrChange = (device) => {
31586
- if (!this.matchesDeviceId(device)) return;
31587
- if (device.type === "unauthorized") {
31595
+ const handleAddOrChange = (device2) => {
31596
+ if (!this.matchesDeviceId(device2)) return;
31597
+ if (device2.type === "unauthorized") {
31588
31598
  logDetail("Device needs 'Always allow' authorization");
31589
31599
  events.emit(USB_DEBUGGING_EVENT_NEEDS_ALWAYS_ALLOW);
31590
31600
  return;
31591
31601
  }
31592
- if (device.type === "device") {
31602
+ if (device2.type === "device") {
31593
31603
  logDetail("Device authorized");
31594
31604
  events.emit(USB_DEBUGGING_EVENT_AUTHORIZED);
31595
31605
  settle({ type: "resolve", value: true });