@yume-chan/adb 0.0.19 → 0.0.21

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 (197) hide show
  1. package/CHANGELOG.json +57 -0
  2. package/CHANGELOG.md +26 -1
  3. package/README.md +222 -103
  4. package/esm/adb.d.ts +28 -45
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +34 -213
  7. package/esm/adb.js.map +1 -1
  8. package/esm/banner.d.ts +17 -0
  9. package/esm/banner.d.ts.map +1 -0
  10. package/esm/banner.js +67 -0
  11. package/esm/banner.js.map +1 -0
  12. package/esm/commands/base.d.ts.map +1 -1
  13. package/esm/commands/base.js.map +1 -1
  14. package/esm/commands/framebuffer.d.ts +9 -0
  15. package/esm/commands/framebuffer.d.ts.map +1 -1
  16. package/esm/commands/framebuffer.js +27 -3
  17. package/esm/commands/framebuffer.js.map +1 -1
  18. package/esm/commands/power.d.ts +1 -1
  19. package/esm/commands/power.d.ts.map +1 -1
  20. package/esm/commands/power.js +2 -2
  21. package/esm/commands/power.js.map +1 -1
  22. package/esm/commands/reverse.d.ts +17 -18
  23. package/esm/commands/reverse.d.ts.map +1 -1
  24. package/esm/commands/reverse.js +53 -48
  25. package/esm/commands/reverse.js.map +1 -1
  26. package/esm/commands/subprocess/command.d.ts +1 -1
  27. package/esm/commands/subprocess/command.d.ts.map +1 -1
  28. package/esm/commands/subprocess/command.js +15 -13
  29. package/esm/commands/subprocess/command.js.map +1 -1
  30. package/esm/commands/subprocess/protocols/none.d.ts +3 -8
  31. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  32. package/esm/commands/subprocess/protocols/none.js +16 -16
  33. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  34. package/esm/commands/subprocess/protocols/shell.d.ts +3 -9
  35. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  36. package/esm/commands/subprocess/protocols/shell.js +63 -57
  37. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  38. package/esm/commands/subprocess/protocols/types.d.ts +1 -2
  39. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  40. package/esm/commands/sync/list.js +2 -2
  41. package/esm/commands/sync/push.d.ts +14 -3
  42. package/esm/commands/sync/push.d.ts.map +1 -1
  43. package/esm/commands/sync/push.js +9 -9
  44. package/esm/commands/sync/push.js.map +1 -1
  45. package/esm/commands/sync/request.js +2 -2
  46. package/esm/commands/sync/request.js.map +1 -1
  47. package/esm/commands/sync/response.d.ts +5 -3
  48. package/esm/commands/sync/response.d.ts.map +1 -1
  49. package/esm/commands/sync/response.js +7 -5
  50. package/esm/commands/sync/response.js.map +1 -1
  51. package/esm/commands/sync/socket.d.ts +8 -14
  52. package/esm/commands/sync/socket.d.ts.map +1 -1
  53. package/esm/commands/sync/socket.js +35 -32
  54. package/esm/commands/sync/socket.js.map +1 -1
  55. package/esm/commands/sync/stat.js +4 -4
  56. package/esm/commands/sync/stat.js.map +1 -1
  57. package/esm/commands/sync/sync.d.ts +26 -18
  58. package/esm/commands/sync/sync.d.ts.map +1 -1
  59. package/esm/commands/sync/sync.js +36 -25
  60. package/esm/commands/sync/sync.js.map +1 -1
  61. package/esm/commands/tcpip.d.ts +2 -2
  62. package/esm/commands/tcpip.d.ts.map +1 -1
  63. package/esm/commands/tcpip.js +4 -2
  64. package/esm/commands/tcpip.js.map +1 -1
  65. package/esm/{auth.d.ts → daemon/auth.d.ts} +12 -11
  66. package/esm/daemon/auth.d.ts.map +1 -0
  67. package/esm/{auth.js → daemon/auth.js} +31 -22
  68. package/esm/daemon/auth.js.map +1 -0
  69. package/esm/{crypto.d.ts → daemon/crypto.d.ts} +5 -5
  70. package/esm/daemon/crypto.d.ts.map +1 -0
  71. package/esm/{crypto.js → daemon/crypto.js} +24 -28
  72. package/esm/daemon/crypto.js.map +1 -0
  73. package/esm/{backend.d.ts → daemon/device.d.ts} +2 -2
  74. package/esm/daemon/device.d.ts.map +1 -0
  75. package/esm/daemon/device.js +2 -0
  76. package/esm/daemon/device.js.map +1 -0
  77. package/esm/{socket → daemon}/dispatcher.d.ts +12 -30
  78. package/esm/daemon/dispatcher.d.ts.map +1 -0
  79. package/esm/{socket → daemon}/dispatcher.js +80 -78
  80. package/esm/daemon/dispatcher.js.map +1 -0
  81. package/esm/daemon/index.d.ts +8 -0
  82. package/esm/daemon/index.d.ts.map +1 -0
  83. package/esm/daemon/index.js +8 -0
  84. package/esm/daemon/index.js.map +1 -0
  85. package/esm/{packet.d.ts → daemon/packet.d.ts} +4 -4
  86. package/esm/daemon/packet.d.ts.map +1 -0
  87. package/esm/{packet.js → daemon/packet.js} +2 -2
  88. package/esm/{packet.js.map → daemon/packet.js.map} +1 -1
  89. package/esm/{socket → daemon}/socket.d.ts +15 -19
  90. package/esm/daemon/socket.d.ts.map +1 -0
  91. package/esm/{socket → daemon}/socket.js +49 -42
  92. package/esm/daemon/socket.js.map +1 -0
  93. package/esm/daemon/transport.d.ts +53 -0
  94. package/esm/daemon/transport.d.ts.map +1 -0
  95. package/esm/daemon/transport.js +186 -0
  96. package/esm/daemon/transport.js.map +1 -0
  97. package/esm/features.js +1 -1
  98. package/esm/features.js.map +1 -1
  99. package/esm/index.d.ts +3 -5
  100. package/esm/index.d.ts.map +1 -1
  101. package/esm/index.js +3 -5
  102. package/esm/index.js.map +1 -1
  103. package/esm/server/client.d.ts +78 -0
  104. package/esm/server/client.d.ts.map +1 -0
  105. package/esm/server/client.js +328 -0
  106. package/esm/server/client.js.map +1 -0
  107. package/esm/server/index.d.ts +3 -0
  108. package/esm/server/index.d.ts.map +1 -0
  109. package/esm/server/index.js +3 -0
  110. package/esm/server/index.js.map +1 -0
  111. package/esm/server/transport.d.ts +19 -0
  112. package/esm/server/transport.d.ts.map +1 -0
  113. package/esm/server/transport.js +44 -0
  114. package/esm/server/transport.js.map +1 -0
  115. package/esm/utils/auto-reset-event.d.ts +1 -2
  116. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  117. package/esm/utils/auto-reset-event.js +12 -12
  118. package/esm/utils/auto-reset-event.js.map +1 -1
  119. package/esm/utils/base64.js +5 -5
  120. package/esm/utils/base64.js.map +1 -1
  121. package/esm/utils/conditional-variable.d.ts +1 -2
  122. package/esm/utils/conditional-variable.d.ts.map +1 -1
  123. package/esm/utils/conditional-variable.js +10 -10
  124. package/esm/utils/conditional-variable.js.map +1 -1
  125. package/esm/utils/hex.d.ts +3 -0
  126. package/esm/utils/hex.d.ts.map +1 -0
  127. package/esm/utils/hex.js +55 -0
  128. package/esm/utils/hex.js.map +1 -0
  129. package/esm/utils/index.d.ts +2 -0
  130. package/esm/utils/index.d.ts.map +1 -1
  131. package/esm/utils/index.js +2 -0
  132. package/esm/utils/index.js.map +1 -1
  133. package/esm/utils/no-op.d.ts +7 -0
  134. package/esm/utils/no-op.d.ts.map +1 -0
  135. package/esm/utils/no-op.js +12 -0
  136. package/esm/utils/no-op.js.map +1 -0
  137. package/package.json +12 -12
  138. package/src/adb.ts +75 -274
  139. package/src/banner.ts +82 -0
  140. package/src/commands/base.ts +1 -1
  141. package/src/commands/framebuffer.ts +31 -3
  142. package/src/commands/power.ts +10 -10
  143. package/src/commands/reverse.ts +77 -82
  144. package/src/commands/subprocess/command.ts +24 -25
  145. package/src/commands/subprocess/protocols/none.ts +29 -30
  146. package/src/commands/subprocess/protocols/shell.ts +87 -89
  147. package/src/commands/subprocess/protocols/types.ts +1 -2
  148. package/src/commands/sync/list.ts +7 -7
  149. package/src/commands/sync/pull.ts +4 -4
  150. package/src/commands/sync/push.ts +28 -16
  151. package/src/commands/sync/request.ts +4 -4
  152. package/src/commands/sync/response.ts +13 -11
  153. package/src/commands/sync/socket.ts +48 -46
  154. package/src/commands/sync/stat.ts +5 -5
  155. package/src/commands/sync/sync.ts +55 -43
  156. package/src/commands/tcpip.ts +6 -4
  157. package/src/{auth.ts → daemon/auth.ts} +62 -43
  158. package/src/{crypto.ts → daemon/crypto.ts} +33 -41
  159. package/src/{backend.ts → daemon/device.ts} +1 -1
  160. package/src/{socket → daemon}/dispatcher.ts +103 -109
  161. package/src/daemon/index.ts +7 -0
  162. package/src/{packet.ts → daemon/packet.ts} +6 -6
  163. package/src/{socket → daemon}/socket.ts +77 -67
  164. package/src/daemon/transport.ts +281 -0
  165. package/src/index.ts +3 -5
  166. package/src/server/client.ts +473 -0
  167. package/src/server/index.ts +2 -0
  168. package/src/server/transport.ts +77 -0
  169. package/src/utils/auto-reset-event.ts +16 -16
  170. package/src/utils/base64.ts +5 -5
  171. package/src/utils/conditional-variable.ts +14 -14
  172. package/src/utils/hex.ts +58 -0
  173. package/src/utils/index.ts +2 -0
  174. package/src/utils/no-op.ts +12 -0
  175. package/tsconfig.build.json +12 -1
  176. package/tsconfig.build.tsbuildinfo +1 -1
  177. package/esm/auth.d.ts.map +0 -1
  178. package/esm/auth.js.map +0 -1
  179. package/esm/backend.d.ts.map +0 -1
  180. package/esm/backend.js +0 -2
  181. package/esm/backend.js.map +0 -1
  182. package/esm/commands/install.d.ts +0 -10
  183. package/esm/commands/install.d.ts.map +0 -1
  184. package/esm/commands/install.js +0 -29
  185. package/esm/commands/install.js.map +0 -1
  186. package/esm/crypto.d.ts.map +0 -1
  187. package/esm/crypto.js.map +0 -1
  188. package/esm/packet.d.ts.map +0 -1
  189. package/esm/socket/dispatcher.d.ts.map +0 -1
  190. package/esm/socket/dispatcher.js.map +0 -1
  191. package/esm/socket/index.d.ts +0 -3
  192. package/esm/socket/index.d.ts.map +0 -1
  193. package/esm/socket/index.js +0 -3
  194. package/esm/socket/index.js.map +0 -1
  195. package/esm/socket/socket.d.ts.map +0 -1
  196. package/esm/socket/socket.js.map +0 -1
  197. 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;IACpB,OAAO,GAAG,KAAK,CAAC;IACP,MAAM,GAAgB,EAAE,CAAC;IAEnC,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"}
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;IAElC,IAAI,CAAC,SAAwB;QACzB,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;IAED,SAAS;QACL,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;IAED,OAAO;QACH,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,3 @@
1
+ export declare function hexToNumber(data: Uint8Array): number;
2
+ export declare function numberToHex(value: number): Uint8Array;
3
+ //# sourceMappingURL=hex.d.ts.map
@@ -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"}
@@ -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"}
@@ -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
@@ -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"}
@@ -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.js.map
@@ -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.19",
3
+ "version": "0.0.21",
4
4
  "description": "TypeScript implementation of Android Debug Bridge (ADB) protocol.",
5
5
  "keywords": [
6
6
  "adb",
@@ -26,23 +26,23 @@
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.19",
30
- "@yume-chan/event": "^0.0.19",
31
- "@yume-chan/stream-extra": "^0.0.19",
32
- "@yume-chan/struct": "^0.0.19",
33
- "tslib": "^2.4.1"
29
+ "@yume-chan/dataview-bigint-polyfill": "^0.0.21",
30
+ "@yume-chan/event": "^0.0.21",
31
+ "@yume-chan/stream-extra": "^0.0.21",
32
+ "@yume-chan/struct": "^0.0.21",
33
+ "tslib": "^2.6.0"
34
34
  },
35
35
  "devDependencies": {
36
- "@jest/globals": "^29.5.0",
37
- "@types/node": "^18.15.0",
36
+ "@jest/globals": "^29.6.1",
37
+ "@types/node": "^20.4.0",
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.36.0",
41
+ "eslint": "^8.44.0",
42
42
  "jest": "^29.5.0",
43
- "prettier": "^2.8.4",
44
- "ts-jest": "^29.0.4",
45
- "typescript": "^4.9.4"
43
+ "prettier": "^3.0.0",
44
+ "ts-jest": "^29.1.1",
45
+ "typescript": "^5.1.6"
46
46
  },
47
47
  "scripts": {
48
48
  "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
- AbortController,
5
- ConsumableWritableStream,
6
- DecodeUtf8Stream,
7
- GatherStringStream,
8
- WritableStream,
9
- } from "@yume-chan/stream-extra";
2
+ import { ConcatStringStream, DecodeUtf8Stream } from "@yume-chan/stream-extra";
3
+ import type { ValueOrPromise } from "@yume-chan/struct";
10
4
 
11
- import type { AdbCredentialStore } from "./auth.js";
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,221 +13,69 @@ 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 enum AdbPropKey {
38
- Product = "ro.product.name",
39
- Model = "ro.product.model",
40
- Device = "ro.product.device",
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 const VERSION_OMIT_CHECKSUM = 0x01000001;
45
-
46
- export class Adb implements Closeable {
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;
64
-
65
- const resolver = new PromiseResolver<string>();
66
- const authProcessor = new AdbAuthenticationProcessor(
67
- authenticators,
68
- credentialStore
69
- );
24
+ export type AdbIncomingSocketHandler = (
25
+ socket: AdbSocket,
26
+ ) => ValueOrPromise<void>;
70
27
 
71
- // Here is similar to `AdbPacketDispatcher`,
72
- // But the received packet types and send packet processing are different.
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
- });
113
-
114
- const writer = connection.writable.getWriter();
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
- }
28
+ export interface Closeable {
29
+ close(): ValueOrPromise<void>;
30
+ }
122
31
 
123
- let banner: string;
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(",");
32
+ export interface AdbTransport extends Closeable {
33
+ readonly serial: string;
147
34
 
148
- await sendPacket({
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
- });
35
+ readonly maxPayloadSize: number;
156
36
 
157
- banner = await resolver.promise;
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();
37
+ readonly banner: AdbBanner;
163
38
 
164
- // Wait until pipe stops (`ReadableStream` lock released)
165
- await pipe;
166
- }
39
+ readonly disconnected: Promise<void>;
167
40
 
168
- return new Adb(connection, version, maxPayloadSize, banner);
169
- }
41
+ connect(service: string): ValueOrPromise<AdbSocket>;
170
42
 
171
- private readonly dispatcher: AdbPacketDispatcher;
43
+ addReverseTunnel(
44
+ handler: AdbIncomingSocketHandler,
45
+ address?: string,
46
+ ): ValueOrPromise<string>;
172
47
 
173
- public get disconnected() {
174
- return this.dispatcher.disconnected;
175
- }
48
+ removeReverseTunnel(address: string): ValueOrPromise<void>;
176
49
 
177
- private _protocolVersion: number;
178
- public get protocolVersion() {
179
- return this._protocolVersion;
180
- }
50
+ clearReverseTunnels(): ValueOrPromise<void>;
51
+ }
181
52
 
182
- private _maxPayloadSize: number;
183
- public get maxPayloadSize() {
184
- return this._maxPayloadSize;
185
- }
53
+ export class Adb implements Closeable {
54
+ readonly transport: AdbTransport;
186
55
 
187
- private _product: string | undefined;
188
- public get product() {
189
- return this._product;
56
+ get serial() {
57
+ return this.transport.serial;
190
58
  }
191
59
 
192
- private _model: string | undefined;
193
- public get model() {
194
- return this._model;
60
+ get maxPayloadSize() {
61
+ return this.transport.maxPayloadSize;
195
62
  }
196
63
 
197
- private _device: string | undefined;
198
- public get device() {
199
- return this._device;
64
+ get banner() {
65
+ return this.transport.banner;
200
66
  }
201
67
 
202
- private _features: AdbFeature[] = [];
203
- public get features() {
204
- return this._features;
68
+ get disconnected() {
69
+ return this.transport.disconnected;
205
70
  }
206
71
 
207
- public readonly subprocess: AdbSubprocess;
208
- public readonly power: AdbPower;
209
- public readonly reverse: AdbReverseCommand;
210
- public readonly tcpip: AdbTcpIpCommand;
211
-
212
- public constructor(
213
- connection: ReadableWritablePair<
214
- AdbPacketData,
215
- Consumable<AdbPacketInit>
216
- >,
217
- version: number,
218
- maxPayloadSize: number,
219
- banner: string
220
- ) {
221
- this.parseBanner(banner);
72
+ readonly subprocess: AdbSubprocess;
73
+ readonly power: AdbPower;
74
+ readonly reverse: AdbReverseCommand;
75
+ readonly tcpip: AdbTcpIpCommand;
222
76
 
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
+ constructor(transport: AdbTransport) {
78
+ this.transport = transport;
241
79
 
242
80
  this.subprocess = new AdbSubprocess(this);
243
81
  this.power = new AdbPower(this);
@@ -245,66 +83,22 @@ 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
- public supportsFeature(feature: AdbFeature): boolean {
282
- return this._features.includes(feature);
86
+ supportsFeature(feature: AdbFeature): boolean {
87
+ return this.banner.features.includes(feature);
283
88
  }
284
89
 
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);
90
+ async createSocket(service: string): Promise<AdbSocket> {
91
+ return this.transport.connect(service);
292
92
  }
293
93
 
294
- public async createSocket(service: string): Promise<AdbSocket> {
295
- return this.dispatcher.createSocket(service);
296
- }
297
-
298
- public async createSocketAndWait(service: string): Promise<string> {
94
+ async createSocketAndWait(service: string): Promise<string> {
299
95
  const socket = await this.createSocket(service);
300
- const gatherStream = new GatherStringStream();
301
- await socket.readable
96
+ return await socket.readable
302
97
  .pipeThrough(new DecodeUtf8Stream())
303
- .pipeTo(gatherStream);
304
- return gatherStream.result;
98
+ .pipeThrough(new ConcatStringStream());
305
99
  }
306
100
 
307
- public async getProp(key: string): Promise<string> {
101
+ async getProp(key: string): Promise<string> {
308
102
  const stdout = await this.subprocess.spawnAndWaitLegacy([
309
103
  "getprop",
310
104
  key,
@@ -312,33 +106,40 @@ export class Adb implements Closeable {
312
106
  return stdout.trim();
313
107
  }
314
108
 
315
- public async rm(...filenames: string[]): Promise<string> {
109
+ async rm(
110
+ filenames: string | string[],
111
+ options?: { recursive?: boolean; force?: boolean },
112
+ ): Promise<string> {
113
+ const args = ["rm"];
114
+ if (options?.recursive) {
115
+ args.push("-r");
116
+ }
117
+ if (options?.force) {
118
+ args.push("-f");
119
+ }
120
+ if (Array.isArray(filenames)) {
121
+ for (const filename of filenames) {
122
+ args.push(escapeArg(filename));
123
+ }
124
+ } else {
125
+ args.push(escapeArg(filenames));
126
+ }
316
127
  // https://android.googlesource.com/platform/packages/modules/adb/+/1a0fb8846d4e6b671c8aa7f137a8c21d7b248716/client/adb_install.cpp#984
317
- const stdout = await this.subprocess.spawnAndWaitLegacy([
318
- "rm",
319
- ...filenames.map((arg) => escapeArg(arg)),
320
- "</dev/null",
321
- ]);
128
+ args.push("</dev/null");
129
+ const stdout = await this.subprocess.spawnAndWaitLegacy(args);
322
130
  return stdout;
323
131
  }
324
132
 
325
- public async sync(): Promise<AdbSync> {
133
+ async sync(): Promise<AdbSync> {
326
134
  const socket = await this.createSocket("sync:");
327
135
  return new AdbSync(this, socket);
328
136
  }
329
137
 
330
- public async framebuffer(): Promise<AdbFrameBuffer> {
138
+ async framebuffer(): Promise<AdbFrameBuffer> {
331
139
  return framebuffer(this);
332
140
  }
333
141
 
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
- public async close(): Promise<void> {
342
- await this.dispatcher.close();
142
+ async close(): Promise<void> {
143
+ await this.transport.close();
343
144
  }
344
145
  }