@yume-chan/adb 0.0.19 → 0.0.20
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/CHANGELOG.json +33 -0
- package/CHANGELOG.md +15 -1
- package/README.md +220 -103
- package/esm/adb.d.ts +24 -44
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +14 -203
- package/esm/adb.js.map +1 -1
- package/esm/banner.d.ts +17 -0
- package/esm/banner.d.ts.map +1 -0
- package/esm/banner.js +67 -0
- package/esm/banner.js.map +1 -0
- package/esm/commands/power.d.ts +1 -1
- package/esm/commands/power.js +2 -2
- package/esm/commands/reverse.d.ts +17 -18
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js +53 -48
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/protocols/none.d.ts +3 -8
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/none.js +16 -16
- package/esm/commands/subprocess/protocols/none.js.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts +3 -9
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +48 -42
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/protocols/types.d.ts +1 -2
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
- package/esm/commands/sync/list.js +2 -2
- package/esm/commands/sync/push.d.ts +14 -3
- package/esm/commands/sync/push.d.ts.map +1 -1
- package/esm/commands/sync/push.js +8 -8
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.js +1 -1
- package/esm/commands/sync/response.d.ts +3 -3
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +3 -3
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/socket.d.ts +8 -13
- package/esm/commands/sync/socket.d.ts.map +1 -1
- package/esm/commands/sync/socket.js +32 -29
- package/esm/commands/sync/socket.js.map +1 -1
- package/esm/commands/sync/stat.js +2 -2
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +11 -18
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +19 -23
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/commands/tcpip.d.ts +2 -2
- package/esm/commands/tcpip.d.ts.map +1 -1
- package/esm/commands/tcpip.js +4 -2
- package/esm/commands/tcpip.js.map +1 -1
- package/esm/{auth.d.ts → daemon/auth.d.ts} +1 -2
- package/esm/daemon/auth.d.ts.map +1 -0
- package/esm/{auth.js → daemon/auth.js} +14 -14
- package/esm/daemon/auth.js.map +1 -0
- package/esm/daemon/connection.d.ts +11 -0
- package/esm/daemon/connection.d.ts.map +1 -0
- package/esm/daemon/connection.js +2 -0
- package/esm/daemon/connection.js.map +1 -0
- package/esm/{crypto.d.ts → daemon/crypto.d.ts} +5 -5
- package/esm/daemon/crypto.d.ts.map +1 -0
- package/esm/{crypto.js → daemon/crypto.js} +23 -27
- package/esm/daemon/crypto.js.map +1 -0
- package/esm/{backend.d.ts → daemon/device.d.ts} +2 -2
- package/esm/daemon/device.d.ts.map +1 -0
- package/esm/daemon/device.js +2 -0
- package/esm/daemon/device.js.map +1 -0
- package/esm/{socket → daemon}/dispatcher.d.ts +8 -26
- package/esm/daemon/dispatcher.d.ts.map +1 -0
- package/esm/{socket → daemon}/dispatcher.js +65 -63
- package/esm/daemon/dispatcher.js.map +1 -0
- package/esm/daemon/index.d.ts +8 -0
- package/esm/daemon/index.d.ts.map +1 -0
- package/esm/daemon/index.js +8 -0
- package/esm/daemon/index.js.map +1 -0
- package/esm/{packet.d.ts → daemon/packet.d.ts} +4 -4
- package/esm/daemon/packet.d.ts.map +1 -0
- package/esm/{packet.js → daemon/packet.js} +1 -1
- package/esm/daemon/packet.js.map +1 -0
- package/esm/{socket → daemon}/socket.d.ts +15 -17
- package/esm/daemon/socket.d.ts.map +1 -0
- package/esm/{socket → daemon}/socket.js +38 -35
- package/esm/daemon/socket.js.map +1 -0
- package/esm/daemon/transport.d.ts +45 -0
- package/esm/daemon/transport.d.ts.map +1 -0
- package/esm/daemon/transport.js +184 -0
- package/esm/daemon/transport.js.map +1 -0
- package/esm/index.d.ts +3 -5
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -5
- package/esm/index.js.map +1 -1
- package/esm/server/client.d.ts +78 -0
- package/esm/server/client.d.ts.map +1 -0
- package/esm/server/client.js +329 -0
- package/esm/server/client.js.map +1 -0
- package/esm/server/index.d.ts +3 -0
- package/esm/server/index.d.ts.map +1 -0
- package/esm/server/index.js +3 -0
- package/esm/server/index.js.map +1 -0
- package/esm/server/transport.d.ts +19 -0
- package/esm/server/transport.d.ts.map +1 -0
- package/esm/server/transport.js +44 -0
- package/esm/server/transport.js.map +1 -0
- package/esm/utils/auto-reset-event.d.ts +1 -2
- package/esm/utils/auto-reset-event.d.ts.map +1 -1
- package/esm/utils/auto-reset-event.js +12 -12
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.js +5 -5
- package/esm/utils/base64.js.map +1 -1
- package/esm/utils/conditional-variable.d.ts +1 -2
- package/esm/utils/conditional-variable.d.ts.map +1 -1
- package/esm/utils/conditional-variable.js +10 -10
- package/esm/utils/conditional-variable.js.map +1 -1
- package/esm/utils/hex.d.ts +3 -0
- package/esm/utils/hex.d.ts.map +1 -0
- package/esm/utils/hex.js +55 -0
- package/esm/utils/hex.js.map +1 -0
- package/esm/utils/index.d.ts +2 -0
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +2 -0
- package/esm/utils/index.js.map +1 -1
- package/esm/utils/no-op.d.ts +7 -0
- package/esm/utils/no-op.d.ts.map +1 -0
- package/esm/utils/no-op.js +12 -0
- package/esm/utils/no-op.js.map +1 -0
- package/package.json +11 -10
- package/src/adb.ts +41 -252
- package/src/banner.ts +82 -0
- package/src/commands/power.ts +2 -2
- package/src/commands/reverse.ts +68 -73
- package/src/commands/subprocess/protocols/none.ts +17 -18
- package/src/commands/subprocess/protocols/shell.ts +54 -56
- package/src/commands/subprocess/protocols/types.ts +1 -2
- package/src/commands/sync/list.ts +2 -2
- package/src/commands/sync/push.ts +22 -10
- package/src/commands/sync/request.ts +1 -1
- package/src/commands/sync/response.ts +6 -6
- package/src/commands/sync/socket.ts +37 -35
- package/src/commands/sync/sync.ts +25 -28
- package/src/commands/tcpip.ts +6 -4
- package/src/{auth.ts → daemon/auth.ts} +17 -17
- package/src/{crypto.ts → daemon/crypto.ts} +25 -33
- package/src/{backend.ts → daemon/device.ts} +1 -1
- package/src/{socket → daemon}/dispatcher.ts +71 -78
- package/src/daemon/index.ts +7 -0
- package/src/{packet.ts → daemon/packet.ts} +5 -5
- package/src/{socket → daemon}/socket.ts +50 -44
- package/src/daemon/transport.ts +269 -0
- package/src/index.ts +3 -5
- package/src/server/client.ts +476 -0
- package/src/server/index.ts +2 -0
- package/src/server/transport.ts +77 -0
- package/src/utils/auto-reset-event.ts +12 -12
- package/src/utils/conditional-variable.ts +10 -10
- package/src/utils/hex.ts +58 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/no-op.ts +12 -0
- package/tsconfig.build.json +12 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/auth.d.ts.map +0 -1
- package/esm/auth.js.map +0 -1
- package/esm/backend.d.ts.map +0 -1
- package/esm/backend.js +0 -2
- package/esm/backend.js.map +0 -1
- package/esm/commands/install.d.ts +0 -10
- package/esm/commands/install.d.ts.map +0 -1
- package/esm/commands/install.js +0 -29
- package/esm/commands/install.js.map +0 -1
- package/esm/crypto.d.ts.map +0 -1
- package/esm/crypto.js.map +0 -1
- package/esm/packet.d.ts.map +0 -1
- package/esm/packet.js.map +0 -1
- package/esm/socket/dispatcher.d.ts.map +0 -1
- package/esm/socket/dispatcher.js.map +0 -1
- package/esm/socket/index.d.ts +0 -3
- package/esm/socket/index.d.ts.map +0 -1
- package/esm/socket/index.js +0 -3
- package/esm/socket/index.js.map +0 -1
- package/esm/socket/socket.d.ts.map +0 -1
- package/esm/socket/socket.js.map +0 -1
- package/src/socket/index.ts +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-variable.js","sourceRoot":"","sources":["../../src/utils/conditional-variable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQnD,MAAM,OAAO,mBAAmB;
|
|
1
|
+
{"version":3,"file":"conditional-variable.js","sourceRoot":"","sources":["../../src/utils/conditional-variable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQnD,MAAM,OAAO,mBAAmB;IAC5B,OAAO,GAAG,KAAK,CAAC;IACP,MAAM,GAAgB,EAAE,CAAC;IAE3B,IAAI,CAAC,SAAwB;QAChC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,EAAE,EAAE;gBACzC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;aAC5B;SACJ;QAED,MAAM,QAAQ,GAAG,IAAI,eAAe,EAAQ,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC5B,CAAC;IAEM,SAAS;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,KAAK,EAAE;YACP,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE;gBACnB,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;aAC5B;SACJ;aAAM;YACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;SACxB;IACL,CAAC;IAEM,OAAO;QACV,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;YAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAChB,IAAI,KAAK,CAAC,2CAA2C,CAAC,CACzD,CAAC;SACL;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3B,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../../src/utils/hex.ts"],"names":[],"mappings":"AA8BA,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMpD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,cAmBxC"}
|
package/esm/utils/hex.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function hexCharToNumber(char) {
|
|
2
|
+
if (char < 48) {
|
|
3
|
+
throw new Error(`Invalid hex char ${char}`);
|
|
4
|
+
}
|
|
5
|
+
if (char < 58) {
|
|
6
|
+
// 0-9
|
|
7
|
+
return char - 48;
|
|
8
|
+
}
|
|
9
|
+
if (char < 65) {
|
|
10
|
+
throw new Error(`Invalid hex char ${char}`);
|
|
11
|
+
}
|
|
12
|
+
if (char < 71) {
|
|
13
|
+
// A-F
|
|
14
|
+
return char - 55;
|
|
15
|
+
}
|
|
16
|
+
if (char < 97) {
|
|
17
|
+
throw new Error(`Invalid hex char ${char}`);
|
|
18
|
+
}
|
|
19
|
+
if (char < 103) {
|
|
20
|
+
// a-f
|
|
21
|
+
return char - 87;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`Invalid hex char ${char}`);
|
|
24
|
+
}
|
|
25
|
+
// It's 22x faster than converting `data` to string then `Number.parseInt`
|
|
26
|
+
// https://jsbench.me/dglha94ozl/1
|
|
27
|
+
export function hexToNumber(data) {
|
|
28
|
+
let result = 0;
|
|
29
|
+
for (let i = 0; i < data.length; i += 1) {
|
|
30
|
+
result = (result << 4) | hexCharToNumber(data[i]);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
export function numberToHex(value) {
|
|
35
|
+
const result = new Uint8Array(4);
|
|
36
|
+
let index = 3;
|
|
37
|
+
while (index >= 0 && value > 0) {
|
|
38
|
+
const digit = value & 0xf;
|
|
39
|
+
value >>= 4;
|
|
40
|
+
if (digit < 10) {
|
|
41
|
+
result[index] = digit + 48;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
result[index] = digit + 87;
|
|
45
|
+
}
|
|
46
|
+
index -= 1;
|
|
47
|
+
}
|
|
48
|
+
while (index >= 0) {
|
|
49
|
+
// '0'
|
|
50
|
+
result[index] = 48;
|
|
51
|
+
index -= 1;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=hex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../src/utils/hex.ts"],"names":[],"mappings":"AAAA,SAAS,eAAe,CAAC,IAAY;IACjC,IAAI,IAAI,GAAG,EAAE,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;KAC/C;IACD,IAAI,IAAI,GAAG,EAAE,EAAE;QACX,MAAM;QACN,OAAO,IAAI,GAAG,EAAE,CAAC;KACpB;IAED,IAAI,IAAI,GAAG,EAAE,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;KAC/C;IACD,IAAI,IAAI,GAAG,EAAE,EAAE;QACX,MAAM;QACN,OAAO,IAAI,GAAG,EAAE,CAAC;KACpB;IAED,IAAI,IAAI,GAAG,EAAE,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;KAC/C;IACD,IAAI,IAAI,GAAG,GAAG,EAAE;QACZ,MAAM;QACN,OAAO,IAAI,GAAG,EAAE,CAAC;KACpB;IAED,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,0EAA0E;AAC1E,kCAAkC;AAClC,MAAM,UAAU,WAAW,CAAC,IAAgB;IACxC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;QACrC,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC;KACtD;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACrC,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE;QAC5B,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;QAC1B,KAAK,KAAK,CAAC,CAAC;QACZ,IAAI,KAAK,GAAG,EAAE,EAAE;YACZ,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;SAC9B;aAAM;YACH,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;SAC9B;QACD,KAAK,IAAI,CAAC,CAAC;KACd;IACD,OAAO,KAAK,IAAI,CAAC,EAAE;QACf,MAAM;QACN,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC;KACd;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/esm/utils/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export { decodeUtf8, encodeUtf8 } from "@yume-chan/struct";
|
|
|
2
2
|
export * from "./auto-reset-event.js";
|
|
3
3
|
export * from "./base64.js";
|
|
4
4
|
export * from "./conditional-variable.js";
|
|
5
|
+
export * from "./hex.js";
|
|
6
|
+
export * from "./no-op.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/utils/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
package/esm/utils/index.js
CHANGED
package/esm/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const NOOP: () => void;
|
|
2
|
+
/**
|
|
3
|
+
* When used in `Promise#catch`, means the promise should never throw errors.
|
|
4
|
+
* An explicit way to suppress ESLint floating promise warnings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function unreachable(...args: unknown[]): never;
|
|
7
|
+
//# sourceMappingURL=no-op.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-op.d.ts","sourceRoot":"","sources":["../../src/utils/no-op.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,YAEhB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAGrD"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const NOOP = () => {
|
|
2
|
+
// no-op
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* When used in `Promise#catch`, means the promise should never throw errors.
|
|
6
|
+
* An explicit way to suppress ESLint floating promise warnings.
|
|
7
|
+
*/
|
|
8
|
+
export function unreachable(...args) {
|
|
9
|
+
// Trigger runtime's unhandled rejection event.
|
|
10
|
+
throw new Error("Unreachable. Arguments:\n" + args.join("\n"));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=no-op.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-op.js","sourceRoot":"","sources":["../../src/utils/no-op.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE;IACrB,QAAQ;AACZ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAG,IAAe;IAC1C,+CAA+C;IAC/C,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/adb",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "TypeScript implementation of Android Debug Bridge (ADB) protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adb",
|
|
@@ -26,23 +26,24 @@
|
|
|
26
26
|
"types": "esm/index.d.ts",
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@yume-chan/async": "^2.2.0",
|
|
29
|
-
"@yume-chan/dataview-bigint-polyfill": "^0.0.
|
|
30
|
-
"@yume-chan/event": "^0.0.
|
|
31
|
-
"@yume-chan/stream-extra": "^0.0.
|
|
32
|
-
"@yume-chan/struct": "^0.0.
|
|
33
|
-
"tslib": "^2.
|
|
29
|
+
"@yume-chan/dataview-bigint-polyfill": "^0.0.20",
|
|
30
|
+
"@yume-chan/event": "^0.0.20",
|
|
31
|
+
"@yume-chan/stream-extra": "^0.0.20",
|
|
32
|
+
"@yume-chan/struct": "^0.0.20",
|
|
33
|
+
"tslib": "^2.5.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@jest/globals": "^29.5.0",
|
|
37
|
-
"@types/node": "^
|
|
37
|
+
"@types/node": "^20.2.1",
|
|
38
38
|
"@yume-chan/eslint-config": "^1.0.0",
|
|
39
39
|
"@yume-chan/tsconfig": "^1.0.0",
|
|
40
40
|
"cross-env": "^7.0.3",
|
|
41
|
-
"eslint": "^8.
|
|
41
|
+
"eslint": "^8.41.0",
|
|
42
42
|
"jest": "^29.5.0",
|
|
43
|
-
"prettier": "^2.8.
|
|
43
|
+
"prettier": "^2.8.8",
|
|
44
44
|
"ts-jest": "^29.0.4",
|
|
45
|
-
"typescript": "^
|
|
45
|
+
"typescript": "^5.0.3",
|
|
46
|
+
"web-streams-polyfill": "^4.0.0-beta.3"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
|
48
49
|
"build": "tsc -b tsconfig.build.json",
|
package/src/adb.ts
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import { PromiseResolver } from "@yume-chan/async";
|
|
2
1
|
import type { Consumable, ReadableWritablePair } from "@yume-chan/stream-extra";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
ConsumableWritableStream,
|
|
6
|
-
DecodeUtf8Stream,
|
|
7
|
-
GatherStringStream,
|
|
8
|
-
WritableStream,
|
|
9
|
-
} from "@yume-chan/stream-extra";
|
|
2
|
+
import { DecodeUtf8Stream, GatherStringStream } from "@yume-chan/stream-extra";
|
|
3
|
+
import type { ValueOrPromise } from "@yume-chan/struct";
|
|
10
4
|
|
|
11
|
-
import type {
|
|
12
|
-
import {
|
|
13
|
-
ADB_DEFAULT_AUTHENTICATORS,
|
|
14
|
-
AdbAuthenticationProcessor,
|
|
15
|
-
} from "./auth.js";
|
|
5
|
+
import type { AdbBanner } from "./banner.js";
|
|
16
6
|
import type { AdbFrameBuffer } from "./commands/index.js";
|
|
17
7
|
import {
|
|
18
8
|
AdbPower,
|
|
@@ -23,185 +13,60 @@ import {
|
|
|
23
13
|
escapeArg,
|
|
24
14
|
framebuffer,
|
|
25
15
|
} from "./commands/index.js";
|
|
26
|
-
import { AdbFeature } from "./features.js";
|
|
27
|
-
import type { AdbPacketData, AdbPacketInit } from "./packet.js";
|
|
28
|
-
import { AdbCommand, calculateChecksum } from "./packet.js";
|
|
29
|
-
import type {
|
|
30
|
-
AdbIncomingSocketHandler,
|
|
31
|
-
AdbSocket,
|
|
32
|
-
Closeable,
|
|
33
|
-
} from "./socket/index.js";
|
|
34
|
-
import { AdbPacketDispatcher } from "./socket/index.js";
|
|
35
|
-
import { decodeUtf8, encodeUtf8 } from "./utils/index.js";
|
|
16
|
+
import type { AdbFeature } from "./features.js";
|
|
36
17
|
|
|
37
|
-
export
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
Features = "features",
|
|
18
|
+
export interface AdbSocket
|
|
19
|
+
extends ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>,
|
|
20
|
+
Closeable {
|
|
21
|
+
readonly service: string;
|
|
42
22
|
}
|
|
43
23
|
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* It's possible to call `authenticate` multiple times on a single connection,
|
|
49
|
-
* every time the device receives a `CNXN` packet, it resets its internal state,
|
|
50
|
-
* and starts a new authentication process.
|
|
51
|
-
*/
|
|
52
|
-
public static async authenticate(
|
|
53
|
-
connection: ReadableWritablePair<
|
|
54
|
-
AdbPacketData,
|
|
55
|
-
Consumable<AdbPacketInit>
|
|
56
|
-
>,
|
|
57
|
-
credentialStore: AdbCredentialStore,
|
|
58
|
-
authenticators = ADB_DEFAULT_AUTHENTICATORS
|
|
59
|
-
): Promise<Adb> {
|
|
60
|
-
// Initially, set to highest-supported version and payload size.
|
|
61
|
-
let version = 0x01000001;
|
|
62
|
-
// Android 4: 4K, Android 7: 256K, Android 9: 1M
|
|
63
|
-
let maxPayloadSize = 1024 * 1024;
|
|
24
|
+
export type AdbIncomingSocketHandler = (
|
|
25
|
+
socket: AdbSocket
|
|
26
|
+
) => ValueOrPromise<void>;
|
|
64
27
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
credentialStore
|
|
69
|
-
);
|
|
28
|
+
export interface Closeable {
|
|
29
|
+
close(): ValueOrPromise<void>;
|
|
30
|
+
}
|
|
70
31
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const abortController = new AbortController();
|
|
74
|
-
const pipe = connection.readable
|
|
75
|
-
.pipeTo(
|
|
76
|
-
new WritableStream({
|
|
77
|
-
async write(packet) {
|
|
78
|
-
switch (packet.command) {
|
|
79
|
-
case AdbCommand.Connect:
|
|
80
|
-
version = Math.min(version, packet.arg0);
|
|
81
|
-
maxPayloadSize = Math.min(
|
|
82
|
-
maxPayloadSize,
|
|
83
|
-
packet.arg1
|
|
84
|
-
);
|
|
85
|
-
resolver.resolve(decodeUtf8(packet.payload));
|
|
86
|
-
break;
|
|
87
|
-
case AdbCommand.Auth: {
|
|
88
|
-
const response = await authProcessor.process(
|
|
89
|
-
packet
|
|
90
|
-
);
|
|
91
|
-
await sendPacket(response);
|
|
92
|
-
break;
|
|
93
|
-
}
|
|
94
|
-
default:
|
|
95
|
-
// Maybe the previous ADB client exited without reading all packets,
|
|
96
|
-
// so they are still waiting in OS internal buffer.
|
|
97
|
-
// Just ignore them.
|
|
98
|
-
// Because a `Connect` packet will reset the device,
|
|
99
|
-
// Eventually there will be `Connect` and `Auth` response packets.
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
}),
|
|
104
|
-
{
|
|
105
|
-
// Don't cancel the source ReadableStream on AbortSignal abort.
|
|
106
|
-
preventCancel: true,
|
|
107
|
-
signal: abortController.signal,
|
|
108
|
-
}
|
|
109
|
-
)
|
|
110
|
-
.catch((e) => {
|
|
111
|
-
resolver.reject(e);
|
|
112
|
-
});
|
|
32
|
+
export interface AdbTransport extends Closeable {
|
|
33
|
+
readonly serial: string;
|
|
113
34
|
|
|
114
|
-
|
|
115
|
-
async function sendPacket(init: AdbPacketData) {
|
|
116
|
-
// Always send checksum in auth steps
|
|
117
|
-
// Because we don't know if the device needs it or not.
|
|
118
|
-
(init as AdbPacketInit).checksum = calculateChecksum(init.payload);
|
|
119
|
-
(init as AdbPacketInit).magic = init.command ^ 0xffffffff;
|
|
120
|
-
await ConsumableWritableStream.write(writer, init as AdbPacketInit);
|
|
121
|
-
}
|
|
35
|
+
readonly maxPayloadSize: number;
|
|
122
36
|
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
// https://android.googlesource.com/platform/packages/modules/adb/+/79010dc6d5ca7490c493df800d4421730f5466ca/transport.cpp#1252
|
|
126
|
-
// There are some other feature constants, but some of them are only used by ADB server, not devices (daemons).
|
|
127
|
-
const features = [
|
|
128
|
-
AdbFeature.ShellV2,
|
|
129
|
-
AdbFeature.Cmd,
|
|
130
|
-
AdbFeature.StatV2,
|
|
131
|
-
AdbFeature.ListV2,
|
|
132
|
-
AdbFeature.FixedPushMkdir,
|
|
133
|
-
"apex",
|
|
134
|
-
AdbFeature.Abb,
|
|
135
|
-
// only tells the client the symlink timestamp issue in `adb push --sync` has been fixed.
|
|
136
|
-
// No special handling required.
|
|
137
|
-
"fixed_push_symlink_timestamp",
|
|
138
|
-
AdbFeature.AbbExec,
|
|
139
|
-
"remount_shell",
|
|
140
|
-
"track_app",
|
|
141
|
-
"sendrecv_v2",
|
|
142
|
-
"sendrecv_v2_brotli",
|
|
143
|
-
"sendrecv_v2_lz4",
|
|
144
|
-
"sendrecv_v2_zstd",
|
|
145
|
-
"sendrecv_v2_dry_run_send",
|
|
146
|
-
].join(",");
|
|
37
|
+
readonly banner: AdbBanner;
|
|
147
38
|
|
|
148
|
-
|
|
149
|
-
command: AdbCommand.Connect,
|
|
150
|
-
arg0: version,
|
|
151
|
-
arg1: maxPayloadSize,
|
|
152
|
-
// The terminating `;` is required in formal definition
|
|
153
|
-
// But ADB daemon (all versions) can still work without it
|
|
154
|
-
payload: encodeUtf8(`host::features=${features};`),
|
|
155
|
-
});
|
|
39
|
+
readonly disconnected: Promise<void>;
|
|
156
40
|
|
|
157
|
-
|
|
158
|
-
} finally {
|
|
159
|
-
// When failed, release locks on `connection` so the caller can try again.
|
|
160
|
-
// When success, also release locks so `AdbPacketDispatcher` can use them.
|
|
161
|
-
abortController.abort();
|
|
162
|
-
writer.releaseLock();
|
|
41
|
+
connect(service: string): ValueOrPromise<AdbSocket>;
|
|
163
42
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
43
|
+
addReverseTunnel(
|
|
44
|
+
handler: AdbIncomingSocketHandler,
|
|
45
|
+
address?: string
|
|
46
|
+
): ValueOrPromise<string>;
|
|
167
47
|
|
|
168
|
-
|
|
169
|
-
}
|
|
48
|
+
removeReverseTunnel(address: string): ValueOrPromise<void>;
|
|
170
49
|
|
|
171
|
-
|
|
50
|
+
clearReverseTunnels(): ValueOrPromise<void>;
|
|
51
|
+
}
|
|
172
52
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
53
|
+
export class Adb implements Closeable {
|
|
54
|
+
public readonly transport: AdbTransport;
|
|
176
55
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return this._protocolVersion;
|
|
56
|
+
public get serial() {
|
|
57
|
+
return this.transport.serial;
|
|
180
58
|
}
|
|
181
59
|
|
|
182
|
-
private _maxPayloadSize: number;
|
|
183
60
|
public get maxPayloadSize() {
|
|
184
|
-
return this.
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private _product: string | undefined;
|
|
188
|
-
public get product() {
|
|
189
|
-
return this._product;
|
|
61
|
+
return this.transport.maxPayloadSize;
|
|
190
62
|
}
|
|
191
63
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return this._model;
|
|
64
|
+
public get banner() {
|
|
65
|
+
return this.transport.banner;
|
|
195
66
|
}
|
|
196
67
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return this._device;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
private _features: AdbFeature[] = [];
|
|
203
|
-
public get features() {
|
|
204
|
-
return this._features;
|
|
68
|
+
public get disconnected() {
|
|
69
|
+
return this.transport.disconnected;
|
|
205
70
|
}
|
|
206
71
|
|
|
207
72
|
public readonly subprocess: AdbSubprocess;
|
|
@@ -209,35 +74,8 @@ export class Adb implements Closeable {
|
|
|
209
74
|
public readonly reverse: AdbReverseCommand;
|
|
210
75
|
public readonly tcpip: AdbTcpIpCommand;
|
|
211
76
|
|
|
212
|
-
public constructor(
|
|
213
|
-
|
|
214
|
-
AdbPacketData,
|
|
215
|
-
Consumable<AdbPacketInit>
|
|
216
|
-
>,
|
|
217
|
-
version: number,
|
|
218
|
-
maxPayloadSize: number,
|
|
219
|
-
banner: string
|
|
220
|
-
) {
|
|
221
|
-
this.parseBanner(banner);
|
|
222
|
-
|
|
223
|
-
let calculateChecksum: boolean;
|
|
224
|
-
let appendNullToServiceString: boolean;
|
|
225
|
-
if (version >= VERSION_OMIT_CHECKSUM) {
|
|
226
|
-
calculateChecksum = false;
|
|
227
|
-
appendNullToServiceString = false;
|
|
228
|
-
} else {
|
|
229
|
-
calculateChecksum = true;
|
|
230
|
-
appendNullToServiceString = true;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
this.dispatcher = new AdbPacketDispatcher(connection, {
|
|
234
|
-
calculateChecksum,
|
|
235
|
-
appendNullToServiceString,
|
|
236
|
-
maxPayloadSize,
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
this._protocolVersion = version;
|
|
240
|
-
this._maxPayloadSize = maxPayloadSize;
|
|
77
|
+
public constructor(transport: AdbTransport) {
|
|
78
|
+
this.transport = transport;
|
|
241
79
|
|
|
242
80
|
this.subprocess = new AdbSubprocess(this);
|
|
243
81
|
this.power = new AdbPower(this);
|
|
@@ -245,54 +83,12 @@ export class Adb implements Closeable {
|
|
|
245
83
|
this.tcpip = new AdbTcpIpCommand(this);
|
|
246
84
|
}
|
|
247
85
|
|
|
248
|
-
private parseBanner(banner: string): void {
|
|
249
|
-
const pieces = banner.split("::");
|
|
250
|
-
if (pieces.length > 1) {
|
|
251
|
-
const props = pieces[1]!;
|
|
252
|
-
for (const prop of props.split(";")) {
|
|
253
|
-
if (!prop) {
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const keyValue = prop.split("=");
|
|
258
|
-
if (keyValue.length !== 2) {
|
|
259
|
-
continue;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
const [key, value] = keyValue;
|
|
263
|
-
switch (key) {
|
|
264
|
-
case AdbPropKey.Product:
|
|
265
|
-
this._product = value;
|
|
266
|
-
break;
|
|
267
|
-
case AdbPropKey.Model:
|
|
268
|
-
this._model = value;
|
|
269
|
-
break;
|
|
270
|
-
case AdbPropKey.Device:
|
|
271
|
-
this._device = value;
|
|
272
|
-
break;
|
|
273
|
-
case AdbPropKey.Features:
|
|
274
|
-
this._features = value!.split(",") as AdbFeature[];
|
|
275
|
-
break;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
86
|
public supportsFeature(feature: AdbFeature): boolean {
|
|
282
|
-
return this.
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Add a handler for incoming socket.
|
|
287
|
-
* @param handler A function to call with new incoming sockets. It must return `true` if it accepts the socket.
|
|
288
|
-
* @returns A function to remove the handler.
|
|
289
|
-
*/
|
|
290
|
-
public onIncomingSocket(handler: AdbIncomingSocketHandler) {
|
|
291
|
-
return this.dispatcher.onIncomingSocket(handler);
|
|
87
|
+
return this.banner.features.includes(feature);
|
|
292
88
|
}
|
|
293
89
|
|
|
294
90
|
public async createSocket(service: string): Promise<AdbSocket> {
|
|
295
|
-
return this.
|
|
91
|
+
return this.transport.connect(service);
|
|
296
92
|
}
|
|
297
93
|
|
|
298
94
|
public async createSocketAndWait(service: string): Promise<string> {
|
|
@@ -331,14 +127,7 @@ export class Adb implements Closeable {
|
|
|
331
127
|
return framebuffer(this);
|
|
332
128
|
}
|
|
333
129
|
|
|
334
|
-
/**
|
|
335
|
-
* Close the ADB connection.
|
|
336
|
-
*
|
|
337
|
-
* Note that it won't close the streams from backends.
|
|
338
|
-
* The streams are both physically and logically intact,
|
|
339
|
-
* and can be reused.
|
|
340
|
-
*/
|
|
341
130
|
public async close(): Promise<void> {
|
|
342
|
-
await this.
|
|
131
|
+
await this.transport.close();
|
|
343
132
|
}
|
|
344
133
|
}
|
package/src/banner.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { AdbFeature } from "./features.js";
|
|
2
|
+
|
|
3
|
+
export enum AdbBannerKey {
|
|
4
|
+
Product = "ro.product.name",
|
|
5
|
+
Model = "ro.product.model",
|
|
6
|
+
Device = "ro.product.device",
|
|
7
|
+
Features = "features",
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class AdbBanner {
|
|
11
|
+
public static parse(banner: string) {
|
|
12
|
+
let product: string | undefined;
|
|
13
|
+
let model: string | undefined;
|
|
14
|
+
let device: string | undefined;
|
|
15
|
+
let features: AdbFeature[] = [];
|
|
16
|
+
|
|
17
|
+
const pieces = banner.split("::");
|
|
18
|
+
if (pieces.length > 1) {
|
|
19
|
+
const props = pieces[1]!;
|
|
20
|
+
for (const prop of props.split(";")) {
|
|
21
|
+
if (!prop) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const keyValue = prop.split("=");
|
|
26
|
+
if (keyValue.length !== 2) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const [key, value] = keyValue;
|
|
31
|
+
switch (key) {
|
|
32
|
+
case AdbBannerKey.Product:
|
|
33
|
+
product = value;
|
|
34
|
+
break;
|
|
35
|
+
case AdbBannerKey.Model:
|
|
36
|
+
model = value;
|
|
37
|
+
break;
|
|
38
|
+
case AdbBannerKey.Device:
|
|
39
|
+
device = value;
|
|
40
|
+
break;
|
|
41
|
+
case AdbBannerKey.Features:
|
|
42
|
+
features = value!.split(",") as AdbFeature[];
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return new AdbBanner(product, model, device, features);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#product: string | undefined;
|
|
52
|
+
public get product() {
|
|
53
|
+
return this.#product;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
#model: string | undefined;
|
|
57
|
+
public get model() {
|
|
58
|
+
return this.#model;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#device: string | undefined;
|
|
62
|
+
public get device() {
|
|
63
|
+
return this.#device;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#features: AdbFeature[] = [];
|
|
67
|
+
public get features() {
|
|
68
|
+
return this.#features;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
public constructor(
|
|
72
|
+
product: string | undefined,
|
|
73
|
+
model: string | undefined,
|
|
74
|
+
device: string | undefined,
|
|
75
|
+
features: AdbFeature[]
|
|
76
|
+
) {
|
|
77
|
+
this.#product = product;
|
|
78
|
+
this.#model = model;
|
|
79
|
+
this.#device = device;
|
|
80
|
+
this.#features = features;
|
|
81
|
+
}
|
|
82
|
+
}
|
package/src/commands/power.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
import { AdbCommandBase } from "./base.js";
|
|
7
7
|
|
|
8
8
|
export class AdbPower extends AdbCommandBase {
|
|
9
|
-
public reboot(
|
|
10
|
-
return this.adb.createSocketAndWait(`reboot:${
|
|
9
|
+
public reboot(mode = "") {
|
|
10
|
+
return this.adb.createSocketAndWait(`reboot:${mode}`);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
public bootloader() {
|