@yume-chan/adb 1.1.0 → 2.0.0

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.md +20 -0
  2. package/LICENSE +1 -1
  3. package/esm/adb.d.ts +7 -6
  4. package/esm/adb.d.ts.map +1 -1
  5. package/esm/adb.js +22 -22
  6. package/esm/adb.js.map +1 -1
  7. package/esm/banner.js.map +1 -1
  8. package/esm/commands/base.d.ts +3 -2
  9. package/esm/commands/base.d.ts.map +1 -1
  10. package/esm/commands/base.js +6 -3
  11. package/esm/commands/base.js.map +1 -1
  12. package/esm/commands/framebuffer.d.ts +6 -6
  13. package/esm/commands/power.d.ts +2 -2
  14. package/esm/commands/power.d.ts.map +1 -1
  15. package/esm/commands/power.js +4 -4
  16. package/esm/commands/power.js.map +1 -1
  17. package/esm/commands/reverse.d.ts +3 -4
  18. package/esm/commands/reverse.d.ts.map +1 -1
  19. package/esm/commands/reverse.js +5 -10
  20. package/esm/commands/reverse.js.map +1 -1
  21. package/esm/commands/subprocess/index.d.ts +3 -2
  22. package/esm/commands/subprocess/index.d.ts.map +1 -1
  23. package/esm/commands/subprocess/index.js +3 -2
  24. package/esm/commands/subprocess/index.js.map +1 -1
  25. package/esm/commands/subprocess/none/index.d.ts +5 -0
  26. package/esm/commands/subprocess/none/index.d.ts.map +1 -0
  27. package/esm/commands/subprocess/none/index.js +5 -0
  28. package/esm/commands/subprocess/none/index.js.map +1 -0
  29. package/esm/commands/subprocess/none/process.d.ts +13 -0
  30. package/esm/commands/subprocess/none/process.d.ts.map +1 -0
  31. package/esm/commands/subprocess/none/process.js +36 -0
  32. package/esm/commands/subprocess/none/process.js.map +1 -0
  33. package/esm/commands/subprocess/none/pty.d.ts +15 -0
  34. package/esm/commands/subprocess/none/pty.d.ts.map +1 -0
  35. package/esm/commands/subprocess/none/pty.js +29 -0
  36. package/esm/commands/subprocess/none/pty.js.map +1 -0
  37. package/esm/commands/subprocess/none/service.d.ts +10 -0
  38. package/esm/commands/subprocess/none/service.d.ts.map +1 -0
  39. package/esm/commands/subprocess/none/service.js +32 -0
  40. package/esm/commands/subprocess/none/service.js.map +1 -0
  41. package/esm/commands/subprocess/none/spawner.d.ts +19 -0
  42. package/esm/commands/subprocess/none/spawner.d.ts.map +1 -0
  43. package/esm/commands/subprocess/none/spawner.js +26 -0
  44. package/esm/commands/subprocess/none/spawner.js.map +1 -0
  45. package/esm/commands/subprocess/pty.d.ts +10 -0
  46. package/esm/commands/subprocess/pty.d.ts.map +1 -0
  47. package/esm/commands/subprocess/pty.js +2 -0
  48. package/esm/commands/subprocess/pty.js.map +1 -0
  49. package/esm/commands/subprocess/service.d.ts +11 -0
  50. package/esm/commands/subprocess/service.d.ts.map +1 -0
  51. package/esm/commands/subprocess/service.js +25 -0
  52. package/esm/commands/subprocess/service.js.map +1 -0
  53. package/esm/commands/subprocess/shell/index.d.ts +6 -0
  54. package/esm/commands/subprocess/shell/index.d.ts.map +1 -0
  55. package/esm/commands/subprocess/shell/index.js +6 -0
  56. package/esm/commands/subprocess/shell/index.js.map +1 -0
  57. package/esm/commands/subprocess/shell/process.d.ts +15 -0
  58. package/esm/commands/subprocess/shell/process.d.ts.map +1 -0
  59. package/esm/commands/subprocess/{protocols/shell.js → shell/process.js} +27 -54
  60. package/esm/commands/subprocess/shell/process.js.map +1 -0
  61. package/esm/commands/subprocess/shell/pty.d.ts +15 -0
  62. package/esm/commands/subprocess/shell/pty.d.ts.map +1 -0
  63. package/esm/commands/subprocess/shell/pty.js +76 -0
  64. package/esm/commands/subprocess/shell/pty.js.map +1 -0
  65. package/esm/commands/subprocess/shell/service.d.ts +14 -0
  66. package/esm/commands/subprocess/shell/service.d.ts.map +1 -0
  67. package/esm/commands/subprocess/shell/service.js +41 -0
  68. package/esm/commands/subprocess/shell/service.js.map +1 -0
  69. package/esm/commands/subprocess/shell/shared.d.ts +19 -0
  70. package/esm/commands/subprocess/shell/shared.d.ts.map +1 -0
  71. package/esm/commands/subprocess/shell/shared.js +15 -0
  72. package/esm/commands/subprocess/shell/shared.js.map +1 -0
  73. package/esm/commands/subprocess/shell/spawner.d.ts +24 -0
  74. package/esm/commands/subprocess/shell/spawner.d.ts.map +1 -0
  75. package/esm/commands/subprocess/shell/spawner.js +38 -0
  76. package/esm/commands/subprocess/shell/spawner.js.map +1 -0
  77. package/esm/commands/subprocess/utils.d.ts +1 -0
  78. package/esm/commands/subprocess/utils.d.ts.map +1 -1
  79. package/esm/commands/subprocess/utils.js +37 -0
  80. package/esm/commands/subprocess/utils.js.map +1 -1
  81. package/esm/commands/sync/list.d.ts +12 -8
  82. package/esm/commands/sync/list.d.ts.map +1 -1
  83. package/esm/commands/sync/list.js +5 -7
  84. package/esm/commands/sync/list.js.map +1 -1
  85. package/esm/commands/sync/pull.d.ts +4 -4
  86. package/esm/commands/sync/pull.d.ts.map +1 -1
  87. package/esm/commands/sync/pull.js +2 -7
  88. package/esm/commands/sync/pull.js.map +1 -1
  89. package/esm/commands/sync/push.d.ts +4 -4
  90. package/esm/commands/sync/request.d.ts +1 -1
  91. package/esm/commands/sync/response.d.ts +5 -5
  92. package/esm/commands/sync/response.d.ts.map +1 -1
  93. package/esm/commands/sync/response.js +2 -1
  94. package/esm/commands/sync/response.js.map +1 -1
  95. package/esm/commands/sync/stat.d.ts +4 -4
  96. package/esm/commands/sync/sync.d.ts +2 -2
  97. package/esm/commands/sync/sync.js +1 -1
  98. package/esm/commands/sync/sync.js.map +1 -1
  99. package/esm/commands/tcpip.d.ts +2 -2
  100. package/esm/commands/tcpip.js +2 -2
  101. package/esm/daemon/dispatcher.d.ts.map +1 -1
  102. package/esm/daemon/dispatcher.js.map +1 -1
  103. package/esm/daemon/packet.d.ts +6 -4
  104. package/esm/daemon/packet.d.ts.map +1 -1
  105. package/esm/daemon/packet.js +3 -5
  106. package/esm/daemon/packet.js.map +1 -1
  107. package/esm/daemon/socket.d.ts +2 -2
  108. package/esm/daemon/socket.d.ts.map +1 -1
  109. package/esm/daemon/socket.js +1 -1
  110. package/esm/daemon/socket.js.map +1 -1
  111. package/esm/device-observer.d.ts +4 -4
  112. package/esm/device-observer.d.ts.map +1 -1
  113. package/esm/server/client.d.ts +10 -38
  114. package/esm/server/client.d.ts.map +1 -1
  115. package/esm/server/client.js +9 -126
  116. package/esm/server/client.js.map +1 -1
  117. package/esm/server/commands/index.d.ts +3 -0
  118. package/esm/server/commands/index.d.ts.map +1 -0
  119. package/esm/server/commands/index.js +3 -0
  120. package/esm/server/commands/index.js.map +1 -0
  121. package/esm/server/commands/m-dns.d.ts +12 -0
  122. package/esm/server/commands/m-dns.d.ts.map +1 -0
  123. package/esm/server/commands/m-dns.js +38 -0
  124. package/esm/server/commands/m-dns.js.map +1 -0
  125. package/esm/server/commands/wireless.d.ts +27 -0
  126. package/esm/server/commands/wireless.d.ts.map +1 -0
  127. package/esm/server/commands/wireless.js +82 -0
  128. package/esm/server/commands/wireless.js.map +1 -0
  129. package/esm/server/observer.d.ts +2 -1
  130. package/esm/server/observer.d.ts.map +1 -1
  131. package/esm/server/observer.js +69 -47
  132. package/esm/server/observer.js.map +1 -1
  133. package/esm/server/stream.d.ts +1 -1
  134. package/esm/server/transport.d.ts.map +1 -1
  135. package/esm/server/transport.js +2 -2
  136. package/esm/server/transport.js.map +1 -1
  137. package/package.json +8 -8
  138. package/src/adb.ts +29 -28
  139. package/src/banner.ts +4 -4
  140. package/src/commands/base.ts +6 -3
  141. package/src/commands/power.ts +6 -6
  142. package/src/commands/reverse.ts +9 -12
  143. package/src/commands/subprocess/index.ts +3 -2
  144. package/src/commands/subprocess/none/index.ts +4 -0
  145. package/src/commands/subprocess/none/process.ts +56 -0
  146. package/src/commands/subprocess/none/pty.ts +45 -0
  147. package/src/commands/subprocess/none/service.ts +42 -0
  148. package/src/commands/subprocess/none/spawner.ts +68 -0
  149. package/src/commands/subprocess/pty.ts +15 -0
  150. package/src/commands/subprocess/service.ts +32 -0
  151. package/src/commands/subprocess/shell/index.ts +5 -0
  152. package/src/commands/subprocess/shell/process.ts +127 -0
  153. package/src/commands/subprocess/shell/pty.ts +112 -0
  154. package/src/commands/subprocess/shell/service.ts +58 -0
  155. package/src/commands/subprocess/shell/shared.ts +25 -0
  156. package/src/commands/subprocess/shell/spawner.ts +90 -0
  157. package/src/commands/subprocess/utils.ts +41 -0
  158. package/src/commands/sync/list.ts +7 -17
  159. package/src/commands/sync/pull.ts +2 -8
  160. package/src/commands/sync/response.ts +6 -4
  161. package/src/commands/sync/sync.ts +1 -1
  162. package/src/commands/tcpip.ts +2 -2
  163. package/src/daemon/dispatcher.ts +7 -4
  164. package/src/daemon/packet.ts +4 -8
  165. package/src/daemon/socket.ts +6 -6
  166. package/src/device-observer.ts +4 -4
  167. package/src/server/client.ts +23 -142
  168. package/src/server/commands/index.ts +2 -0
  169. package/src/server/commands/m-dns.ts +43 -0
  170. package/src/server/commands/wireless.ts +94 -0
  171. package/src/server/observer.ts +94 -66
  172. package/src/server/transport.ts +21 -20
  173. package/tsconfig.build.tsbuildinfo +1 -1
  174. package/esm/commands/subprocess/command.d.ts +0 -58
  175. package/esm/commands/subprocess/command.d.ts.map +0 -1
  176. package/esm/commands/subprocess/command.js +0 -89
  177. package/esm/commands/subprocess/command.js.map +0 -1
  178. package/esm/commands/subprocess/protocols/index.d.ts +0 -4
  179. package/esm/commands/subprocess/protocols/index.d.ts.map +0 -1
  180. package/esm/commands/subprocess/protocols/index.js +0 -4
  181. package/esm/commands/subprocess/protocols/index.js.map +0 -1
  182. package/esm/commands/subprocess/protocols/none.d.ts +0 -32
  183. package/esm/commands/subprocess/protocols/none.d.ts.map +0 -1
  184. package/esm/commands/subprocess/protocols/none.js +0 -61
  185. package/esm/commands/subprocess/protocols/none.js.map +0 -1
  186. package/esm/commands/subprocess/protocols/shell.d.ts +0 -42
  187. package/esm/commands/subprocess/protocols/shell.d.ts.map +0 -1
  188. package/esm/commands/subprocess/protocols/shell.js.map +0 -1
  189. package/esm/commands/subprocess/protocols/types.d.ts +0 -49
  190. package/esm/commands/subprocess/protocols/types.d.ts.map +0 -1
  191. package/esm/commands/subprocess/protocols/types.js +0 -2
  192. package/esm/commands/subprocess/protocols/types.js.map +0 -1
  193. package/src/commands/subprocess/command.ts +0 -141
  194. package/src/commands/subprocess/protocols/index.ts +0 -3
  195. package/src/commands/subprocess/protocols/none.ts +0 -81
  196. package/src/commands/subprocess/protocols/shell.ts +0 -171
  197. package/src/commands/subprocess/protocols/types.ts +0 -63
@@ -1,7 +1,9 @@
1
1
  import { getUint32LittleEndian } from "@yume-chan/no-data-view";
2
- import type { AsyncExactReadable, StructLike } from "@yume-chan/struct";
2
+ import type { AsyncExactReadable, StructDeserializer } from "@yume-chan/struct";
3
3
  import { decodeUtf8, string, struct, u32 } from "@yume-chan/struct";
4
4
 
5
+ import { unreachable } from "../../utils/no-op.js";
6
+
5
7
  function encodeAsciiUnchecked(value: string): Uint8Array {
6
8
  const result = new Uint8Array(value.length);
7
9
  for (let i = 0; i < value.length; i += 1) {
@@ -49,7 +51,7 @@ export const AdbSyncFailResponse = struct(
49
51
  export async function adbSyncReadResponse<T>(
50
52
  stream: AsyncExactReadable,
51
53
  id: number | string,
52
- type: StructLike<T>,
54
+ type: StructDeserializer<T>,
53
55
  ): Promise<T> {
54
56
  if (typeof id === "string") {
55
57
  id = adbSyncEncodeId(id);
@@ -72,7 +74,7 @@ export async function adbSyncReadResponse<T>(
72
74
  export async function* adbSyncReadResponses<T>(
73
75
  stream: AsyncExactReadable,
74
76
  id: number | string,
75
- type: StructLike<T>,
77
+ type: StructDeserializer<T>,
76
78
  ): AsyncGenerator<T, void, void> {
77
79
  if (typeof id === "string") {
78
80
  id = adbSyncEncodeId(id);
@@ -83,7 +85,7 @@ export async function* adbSyncReadResponses<T>(
83
85
  switch (getUint32LittleEndian(buffer, 0)) {
84
86
  case AdbSyncResponseId.Fail:
85
87
  await AdbSyncFailResponse.deserialize(stream);
86
- throw new Error("Unreachable");
88
+ unreachable();
87
89
  case AdbSyncResponseId.Done:
88
90
  // `DONE` responses' size are always same as the request's normal response.
89
91
  //
@@ -151,7 +151,7 @@ export class AdbSync {
151
151
  // It may fail if `filename` already exists.
152
152
  // Ignore the result.
153
153
  // TODO: sync: test push mkdir workaround (need an Android 8 device)
154
- await this._adb.subprocess.spawnAndWait([
154
+ await this._adb.subprocess.noneProtocol.spawnWait([
155
155
  "mkdir",
156
156
  "-p",
157
157
  escapeArg(dirname(options.filename)),
@@ -1,4 +1,4 @@
1
- import { AdbCommandBase } from "./base.js";
1
+ import { AdbServiceBase } from "./base.js";
2
2
 
3
3
  /**
4
4
  * ADB daemon checks for the following properties in the order of
@@ -27,7 +27,7 @@ function parsePort(value: string): number | undefined {
27
27
  return Number.parseInt(value, 10);
28
28
  }
29
29
 
30
- export class AdbTcpIpCommand extends AdbCommandBase {
30
+ export class AdbTcpIpService extends AdbServiceBase {
31
31
  async getListenAddresses(): Promise<AdbTcpIpListenAddresses> {
32
32
  const serviceListenAddresses = await this.adb.getProp(
33
33
  "service.adb.listen_addrs",
@@ -101,18 +101,21 @@ export class AdbPacketDispatcher implements Closeable {
101
101
  */
102
102
  readonly #sockets = new Map<number, AdbDaemonSocketController>();
103
103
 
104
- #writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
104
+ readonly #writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
105
105
 
106
106
  readonly options: AdbPacketDispatcherOptions;
107
107
 
108
108
  #closed = false;
109
- #disconnected = new PromiseResolver<void>();
109
+ readonly #disconnected = new PromiseResolver<void>();
110
110
  get disconnected() {
111
111
  return this.#disconnected.promise;
112
112
  }
113
113
 
114
- #incomingSocketHandlers = new Map<string, AdbIncomingSocketHandler>();
115
- #readAbortController = new AbortController();
114
+ readonly #incomingSocketHandlers = new Map<
115
+ string,
116
+ AdbIncomingSocketHandler
117
+ >();
118
+ readonly #readAbortController = new AbortController();
116
119
 
117
120
  constructor(
118
121
  connection: ReadableWritablePair<
@@ -1,6 +1,6 @@
1
1
  import { Consumable, TransformStream } from "@yume-chan/stream-extra";
2
2
  import type { StructInit, StructValue } from "@yume-chan/struct";
3
- import { buffer, s32, struct, u32 } from "@yume-chan/struct";
3
+ import { buffer, extend, s32, struct, u32 } from "@yume-chan/struct";
4
4
 
5
5
  export const AdbCommand = {
6
6
  Auth: 0x48545541, // 'AUTH'
@@ -29,13 +29,9 @@ export type AdbPacketHeader = StructValue<typeof AdbPacketHeader>;
29
29
 
30
30
  type AdbPacketHeaderInit = StructInit<typeof AdbPacketHeader>;
31
31
 
32
- export const AdbPacket = struct(
33
- /* #__PURE__ */ (() => ({
34
- ...AdbPacketHeader.fields,
35
- payload: buffer("payloadLength"),
36
- }))(),
37
- { littleEndian: true },
38
- );
32
+ export const AdbPacket = extend(AdbPacketHeader, {
33
+ payload: buffer("payloadLength"),
34
+ });
39
35
 
40
36
  export type AdbPacket = StructValue<typeof AdbPacket>;
41
37
 
@@ -43,7 +43,7 @@ export class AdbDaemonSocketController
43
43
  readonly localCreated!: boolean;
44
44
  readonly service!: string;
45
45
 
46
- #readable: ReadableStream<Uint8Array>;
46
+ readonly #readable: ReadableStream<Uint8Array>;
47
47
  #readableController!: PushReadableStreamController<Uint8Array>;
48
48
  get readable() {
49
49
  return this.#readable;
@@ -54,12 +54,12 @@ export class AdbDaemonSocketController
54
54
 
55
55
  #closed = false;
56
56
 
57
- #closedPromise = new PromiseResolver<void>();
57
+ readonly #closedPromise = new PromiseResolver<undefined>();
58
58
  get closed() {
59
59
  return this.#closedPromise.promise;
60
60
  }
61
61
 
62
- #socket: AdbDaemonSocket;
62
+ readonly #socket: AdbDaemonSocket;
63
63
  get socket() {
64
64
  return this.#socket;
65
65
  }
@@ -170,7 +170,7 @@ export class AdbDaemonSocketController
170
170
 
171
171
  dispose() {
172
172
  this.#readableController.close();
173
- this.#closedPromise.resolve();
173
+ this.#closedPromise.resolve(undefined);
174
174
  }
175
175
  }
176
176
 
@@ -178,7 +178,7 @@ export class AdbDaemonSocketController
178
178
  * A duplex stream representing a socket to ADB daemon.
179
179
  */
180
180
  export class AdbDaemonSocket implements AdbDaemonSocketInfo, AdbSocket {
181
- #controller: AdbDaemonSocketController;
181
+ readonly #controller: AdbDaemonSocketController;
182
182
 
183
183
  get localId(): number {
184
184
  return this.#controller.localId;
@@ -200,7 +200,7 @@ export class AdbDaemonSocket implements AdbDaemonSocketInfo, AdbSocket {
200
200
  return this.#controller.writable;
201
201
  }
202
202
 
203
- get closed(): Promise<void> {
203
+ get closed(): Promise<undefined> {
204
204
  return this.#controller.closed;
205
205
  }
206
206
 
@@ -2,9 +2,9 @@ import type { MaybePromiseLike } from "@yume-chan/async";
2
2
  import type { Event } from "@yume-chan/event";
3
3
 
4
4
  export interface DeviceObserver<T> {
5
- onDeviceAdd: Event<T[]>;
6
- onDeviceRemove: Event<T[]>;
7
- onListChange: Event<T[]>;
8
- current: T[];
5
+ readonly onDeviceAdd: Event<readonly T[]>;
6
+ readonly onDeviceRemove: Event<readonly T[]>;
7
+ readonly onListChange: Event<readonly T[]>;
8
+ readonly current: readonly T[];
9
9
  stop(): MaybePromiseLike<void>;
10
10
  }
@@ -15,16 +15,27 @@ import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js";
15
15
  import { AdbBanner } from "../banner.js";
16
16
  import type { DeviceObserver as DeviceObserverBase } from "../device-observer.js";
17
17
  import type { AdbFeature } from "../features.js";
18
- import { hexToNumber, sequenceEqual } from "../utils/index.js";
19
-
18
+ import { hexToNumber } from "../utils/index.js";
19
+
20
+ import {
21
+ MDnsCommands,
22
+ WirelessCommands,
23
+ AlreadyConnectedError as _AlreadyConnectedError,
24
+ NetworkError as _NetworkError,
25
+ UnauthorizedError as _UnauthorizedError,
26
+ } from "./commands/index.js";
20
27
  import { AdbServerDeviceObserverOwner } from "./observer.js";
21
- import { AdbServerStream, FAIL } from "./stream.js";
28
+ import { AdbServerStream } from "./stream.js";
22
29
  import { AdbServerTransport } from "./transport.js";
23
30
 
24
31
  /**
25
32
  * Client for the ADB Server.
26
33
  */
27
34
  export class AdbServerClient {
35
+ static NetworkError = _NetworkError;
36
+ static UnauthorizedError = _UnauthorizedError;
37
+ static AlreadyConnectedError = _AlreadyConnectedError;
38
+
28
39
  static parseDeviceList(value: string): AdbServerClient.Device[] {
29
40
  const devices: AdbServerClient.Device[] = [];
30
41
  for (const line of value.split("\n")) {
@@ -99,9 +110,9 @@ export class AdbServerClient {
99
110
 
100
111
  readonly connector: AdbServerClient.ServerConnector;
101
112
 
102
- readonly wireless = new AdbServerClient.WirelessCommands(this);
103
- readonly mDns = new AdbServerClient.MDnsCommands(this);
104
- #observerOwner = new AdbServerDeviceObserverOwner(this);
113
+ readonly wireless = new WirelessCommands(this);
114
+ readonly mDns = new MDnsCommands(this);
115
+ readonly #observerOwner = new AdbServerDeviceObserverOwner(this);
105
116
 
106
117
  constructor(connector: AdbServerClient.ServerConnector) {
107
118
  this.connector = connector;
@@ -447,10 +458,7 @@ export class AdbServerClient {
447
458
  disconnected,
448
459
  );
449
460
 
450
- transport.disconnected.then(
451
- () => waitAbortController.abort(),
452
- () => waitAbortController.abort(),
453
- );
461
+ void transport.disconnected.finally(() => waitAbortController.abort());
454
462
 
455
463
  return transport;
456
464
  }
@@ -496,7 +504,7 @@ export namespace AdbServerClient {
496
504
  export interface ServerConnection
497
505
  extends ReadableWritablePair<Uint8Array, MaybeConsumable<Uint8Array>>,
498
506
  Closeable {
499
- get closed(): Promise<void>;
507
+ get closed(): Promise<undefined>;
500
508
  }
501
509
 
502
510
  export interface ServerConnector {
@@ -537,138 +545,11 @@ export namespace AdbServerClient {
537
545
  transportId: bigint;
538
546
  }
539
547
 
540
- export class NetworkError extends Error {
541
- constructor(message: string) {
542
- super(message);
543
- this.name = "NetworkError";
544
- }
545
- }
546
-
547
- export class UnauthorizedError extends Error {
548
- constructor(message: string) {
549
- super(message);
550
- this.name = "UnauthorizedError";
551
- }
552
- }
553
-
554
- export class AlreadyConnectedError extends Error {
555
- constructor(message: string) {
556
- super(message);
557
- this.name = "AlreadyConnectedError";
558
- }
559
- }
560
-
561
- export class WirelessCommands {
562
- #client: AdbServerClient;
563
-
564
- constructor(client: AdbServerClient) {
565
- this.#client = client;
566
- }
567
-
568
- /**
569
- * `adb pair <password> <address>`
570
- */
571
- async pair(address: string, password: string): Promise<void> {
572
- const connection = await this.#client.createConnection(
573
- `host:pair:${password}:${address}`,
574
- );
575
- try {
576
- const response = await connection.readExactly(4);
577
- // `response` is either `FAIL`, or 4 hex digits for length of the string
578
- if (sequenceEqual(response, FAIL)) {
579
- throw new Error(await connection.readString());
580
- }
581
- const length = hexToNumber(response);
582
- // Ignore the string as it's always `Successful ...`
583
- await connection.readExactly(length);
584
- } finally {
585
- await connection.dispose();
586
- }
587
- }
588
-
589
- /**
590
- * `adb connect <address>`
591
- */
592
- async connect(address: string): Promise<void> {
593
- const connection = await this.#client.createConnection(
594
- `host:connect:${address}`,
595
- );
596
- try {
597
- const response = await connection.readString();
598
- switch (response) {
599
- case `already connected to ${address}`:
600
- throw new AdbServerClient.AlreadyConnectedError(
601
- response,
602
- );
603
- case `failed to connect to ${address}`: // `adb pair` mode not authorized
604
- case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized
605
- throw new AdbServerClient.UnauthorizedError(response);
606
- case `connected to ${address}`:
607
- return;
608
- default:
609
- throw new AdbServerClient.NetworkError(response);
610
- }
611
- } finally {
612
- await connection.dispose();
613
- }
614
- }
615
-
616
- /**
617
- * `adb disconnect <address>`
618
- */
619
- async disconnect(address: string): Promise<void> {
620
- const connection = await this.#client.createConnection(
621
- `host:disconnect:${address}`,
622
- );
623
- try {
624
- await connection.readString();
625
- } finally {
626
- await connection.dispose();
627
- }
628
- }
629
- }
630
-
631
- export class MDnsCommands {
632
- #client: AdbServerClient;
633
-
634
- constructor(client: AdbServerClient) {
635
- this.#client = client;
636
- }
637
-
638
- async check() {
639
- const connection =
640
- await this.#client.createConnection("host:mdns:check");
641
- try {
642
- const response = await connection.readString();
643
- return !response.startsWith("ERROR:");
644
- } finally {
645
- await connection.dispose();
646
- }
647
- }
648
-
649
- async getServices() {
650
- const connection =
651
- await this.#client.createConnection("host:mdns:services");
652
- try {
653
- const response = await connection.readString();
654
- return response
655
- .split("\n")
656
- .filter(Boolean)
657
- .map((line) => {
658
- const parts = line.split("\t");
659
- return {
660
- name: parts[0]!,
661
- service: parts[1]!,
662
- address: parts[2]!,
663
- };
664
- });
665
- } finally {
666
- await connection.dispose();
667
- }
668
- }
669
- }
670
-
671
548
  export interface DeviceObserver extends DeviceObserverBase<Device> {
672
549
  onError: Event<Error>;
673
550
  }
551
+
552
+ export type NetworkError = _NetworkError;
553
+ export type UnauthorizedError = _UnauthorizedError;
554
+ export type AlreadyConnectedError = _AlreadyConnectedError;
674
555
  }
@@ -0,0 +1,2 @@
1
+ export * from "./m-dns.js";
2
+ export * from "./wireless.js";
@@ -0,0 +1,43 @@
1
+ // cspell:ignore mdns
2
+
3
+ import type { AdbServerClient } from "../client.js";
4
+
5
+ export class MDnsCommands {
6
+ readonly #client: AdbServerClient;
7
+
8
+ constructor(client: AdbServerClient) {
9
+ this.#client = client;
10
+ }
11
+
12
+ async check() {
13
+ const connection =
14
+ await this.#client.createConnection("host:mdns:check");
15
+ try {
16
+ const response = await connection.readString();
17
+ return !response.startsWith("ERROR:");
18
+ } finally {
19
+ await connection.dispose();
20
+ }
21
+ }
22
+
23
+ async getServices() {
24
+ const connection =
25
+ await this.#client.createConnection("host:mdns:services");
26
+ try {
27
+ const response = await connection.readString();
28
+ return response
29
+ .split("\n")
30
+ .filter(Boolean)
31
+ .map((line) => {
32
+ const parts = line.split("\t");
33
+ return {
34
+ name: parts[0]!,
35
+ service: parts[1]!,
36
+ address: parts[2]!,
37
+ };
38
+ });
39
+ } finally {
40
+ await connection.dispose();
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,94 @@
1
+ // cspell:ignore tport
2
+
3
+ import { hexToNumber, sequenceEqual } from "../../utils/index.js";
4
+ import type { AdbServerClient } from "../client.js";
5
+ import { FAIL } from "../stream.js";
6
+
7
+ export class NetworkError extends Error {
8
+ constructor(message: string) {
9
+ super(message);
10
+ this.name = "NetworkError";
11
+ }
12
+ }
13
+
14
+ export class UnauthorizedError extends Error {
15
+ constructor(message: string) {
16
+ super(message);
17
+ this.name = "UnauthorizedError";
18
+ }
19
+ }
20
+
21
+ export class AlreadyConnectedError extends Error {
22
+ constructor(message: string) {
23
+ super(message);
24
+ this.name = "AlreadyConnectedError";
25
+ }
26
+ }
27
+
28
+ export class WirelessCommands {
29
+ readonly #client: AdbServerClient;
30
+
31
+ constructor(client: AdbServerClient) {
32
+ this.#client = client;
33
+ }
34
+
35
+ /**
36
+ * `adb pair <password> <address>`
37
+ */
38
+ async pair(address: string, password: string): Promise<void> {
39
+ const connection = await this.#client.createConnection(
40
+ `host:pair:${password}:${address}`,
41
+ );
42
+ try {
43
+ const response = await connection.readExactly(4);
44
+ // `response` is either `FAIL`, or 4 hex digits for length of the string
45
+ if (sequenceEqual(response, FAIL)) {
46
+ throw new Error(await connection.readString());
47
+ }
48
+ const length = hexToNumber(response);
49
+ // Ignore the string as it's always `Successful ...`
50
+ await connection.readExactly(length);
51
+ } finally {
52
+ await connection.dispose();
53
+ }
54
+ }
55
+
56
+ /**
57
+ * `adb connect <address>`
58
+ */
59
+ async connect(address: string): Promise<void> {
60
+ const connection = await this.#client.createConnection(
61
+ `host:connect:${address}`,
62
+ );
63
+ try {
64
+ const response = await connection.readString();
65
+ switch (response) {
66
+ case `already connected to ${address}`:
67
+ throw new AlreadyConnectedError(response);
68
+ case `failed to connect to ${address}`: // `adb pair` mode not authorized
69
+ case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized
70
+ throw new UnauthorizedError(response);
71
+ case `connected to ${address}`:
72
+ return;
73
+ default:
74
+ throw new NetworkError(response);
75
+ }
76
+ } finally {
77
+ await connection.dispose();
78
+ }
79
+ }
80
+
81
+ /**
82
+ * `adb disconnect <address>`
83
+ */
84
+ async disconnect(address: string): Promise<void> {
85
+ const connection = await this.#client.createConnection(
86
+ `host:disconnect:${address}`,
87
+ );
88
+ try {
89
+ await connection.readString();
90
+ } finally {
91
+ await connection.dispose();
92
+ }
93
+ }
94
+ }