@yume-chan/adb 0.0.17 → 0.0.18

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 (127) hide show
  1. package/CHANGELOG.json +6 -0
  2. package/CHANGELOG.md +6 -1
  3. package/LICENSE +1 -1
  4. package/esm/adb.d.ts +6 -6
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +55 -35
  7. package/esm/adb.js.map +1 -1
  8. package/esm/auth.d.ts +4 -4
  9. package/esm/auth.d.ts.map +1 -1
  10. package/esm/auth.js +6 -6
  11. package/esm/auth.js.map +1 -1
  12. package/esm/backend.d.ts +3 -3
  13. package/esm/backend.d.ts.map +1 -1
  14. package/esm/commands/base.d.ts +2 -2
  15. package/esm/commands/base.d.ts.map +1 -1
  16. package/esm/commands/base.js +1 -1
  17. package/esm/commands/framebuffer.d.ts +7 -7
  18. package/esm/commands/framebuffer.d.ts.map +1 -1
  19. package/esm/commands/framebuffer.js +32 -33
  20. package/esm/commands/framebuffer.js.map +1 -1
  21. package/esm/commands/install.d.ts +2 -2
  22. package/esm/commands/install.d.ts.map +1 -1
  23. package/esm/commands/install.js +12 -6
  24. package/esm/commands/install.js.map +1 -1
  25. package/esm/commands/power.d.ts +1 -1
  26. package/esm/commands/power.d.ts.map +1 -1
  27. package/esm/commands/power.js +14 -10
  28. package/esm/commands/power.js.map +1 -1
  29. package/esm/commands/reverse.d.ts +3 -3
  30. package/esm/commands/reverse.d.ts.map +1 -1
  31. package/esm/commands/reverse.js +14 -12
  32. package/esm/commands/reverse.js.map +1 -1
  33. package/esm/commands/subprocess/command.d.ts +2 -2
  34. package/esm/commands/subprocess/command.d.ts.map +1 -1
  35. package/esm/commands/subprocess/command.js +14 -16
  36. package/esm/commands/subprocess/command.js.map +1 -1
  37. package/esm/commands/subprocess/protocols/none.d.ts +4 -4
  38. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  39. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  40. package/esm/commands/subprocess/protocols/shell.d.ts +4 -4
  41. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  42. package/esm/commands/subprocess/protocols/shell.js +23 -15
  43. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  44. package/esm/commands/subprocess/protocols/types.d.ts +4 -4
  45. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  46. package/esm/commands/sync/list.d.ts +6 -6
  47. package/esm/commands/sync/list.d.ts.map +1 -1
  48. package/esm/commands/sync/list.js +23 -11
  49. package/esm/commands/sync/list.js.map +1 -1
  50. package/esm/commands/sync/pull.d.ts +4 -4
  51. package/esm/commands/sync/pull.d.ts.map +1 -1
  52. package/esm/commands/sync/pull.js +12 -11
  53. package/esm/commands/sync/pull.js.map +1 -1
  54. package/esm/commands/sync/push.d.ts +3 -3
  55. package/esm/commands/sync/push.d.ts.map +1 -1
  56. package/esm/commands/sync/push.js +6 -7
  57. package/esm/commands/sync/push.js.map +1 -1
  58. package/esm/commands/sync/request.d.ts +4 -4
  59. package/esm/commands/sync/request.d.ts.map +1 -1
  60. package/esm/commands/sync/request.js +7 -7
  61. package/esm/commands/sync/request.js.map +1 -1
  62. package/esm/commands/sync/response.d.ts +4 -4
  63. package/esm/commands/sync/response.d.ts.map +1 -1
  64. package/esm/commands/sync/response.js +7 -7
  65. package/esm/commands/sync/response.js.map +1 -1
  66. package/esm/commands/sync/stat.d.ts +5 -5
  67. package/esm/commands/sync/stat.d.ts.map +1 -1
  68. package/esm/commands/sync/stat.js +37 -27
  69. package/esm/commands/sync/stat.js.map +1 -1
  70. package/esm/commands/sync/sync.d.ts +6 -6
  71. package/esm/commands/sync/sync.d.ts.map +1 -1
  72. package/esm/commands/sync/sync.js +20 -19
  73. package/esm/commands/sync/sync.js.map +1 -1
  74. package/esm/crypto.d.ts.map +1 -1
  75. package/esm/crypto.js +25 -15
  76. package/esm/crypto.js.map +1 -1
  77. package/esm/index.d.ts +9 -9
  78. package/esm/index.d.ts.map +1 -1
  79. package/esm/index.js +9 -9
  80. package/esm/index.js.map +1 -1
  81. package/esm/packet.d.ts +8 -8
  82. package/esm/packet.d.ts.map +1 -1
  83. package/esm/packet.js +14 -12
  84. package/esm/packet.js.map +1 -1
  85. package/esm/socket/dispatcher.d.ts +6 -6
  86. package/esm/socket/dispatcher.d.ts.map +1 -1
  87. package/esm/socket/dispatcher.js +22 -19
  88. package/esm/socket/dispatcher.js.map +1 -1
  89. package/esm/socket/socket.d.ts +4 -4
  90. package/esm/socket/socket.d.ts.map +1 -1
  91. package/esm/socket/socket.js +37 -17
  92. package/esm/socket/socket.js.map +1 -1
  93. package/esm/utils/auto-reset-event.d.ts +1 -1
  94. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  95. package/esm/utils/auto-reset-event.js +2 -2
  96. package/esm/utils/base64.d.ts.map +1 -1
  97. package/esm/utils/base64.js +30 -29
  98. package/esm/utils/base64.js.map +1 -1
  99. package/package.json +16 -13
  100. package/src/adb.ts +133 -84
  101. package/src/auth.ts +27 -19
  102. package/src/backend.ts +6 -4
  103. package/src/commands/base.ts +2 -2
  104. package/src/commands/framebuffer.ts +37 -41
  105. package/src/commands/install.ts +19 -11
  106. package/src/commands/power.ts +15 -11
  107. package/src/commands/reverse.ts +48 -29
  108. package/src/commands/subprocess/command.ts +24 -21
  109. package/src/commands/subprocess/protocols/none.ts +4 -3
  110. package/src/commands/subprocess/protocols/shell.ts +65 -33
  111. package/src/commands/subprocess/protocols/types.ts +8 -5
  112. package/src/commands/sync/list.ts +51 -24
  113. package/src/commands/sync/pull.ts +51 -34
  114. package/src/commands/sync/push.ts +25 -11
  115. package/src/commands/sync/request.ts +20 -22
  116. package/src/commands/sync/response.ts +31 -25
  117. package/src/commands/sync/stat.ts +78 -55
  118. package/src/commands/sync/sync.ts +47 -26
  119. package/src/crypto.ts +60 -32
  120. package/src/index.ts +9 -10
  121. package/src/packet.ts +40 -30
  122. package/src/socket/dispatcher.ts +115 -78
  123. package/src/socket/socket.ts +68 -27
  124. package/src/utils/auto-reset-event.ts +3 -3
  125. package/src/utils/base64.ts +51 -41
  126. package/tsconfig.build.json +1 -1
  127. package/tsconfig.build.tsbuildinfo +1 -1
package/src/auth.ts CHANGED
@@ -1,10 +1,14 @@
1
- import { PromiseResolver } from '@yume-chan/async';
2
- import type { Disposable } from '@yume-chan/event';
3
- import type { ValueOrPromise } from '@yume-chan/struct';
4
-
5
- import { calculatePublicKey, calculatePublicKeyLength, sign } from './crypto.js';
6
- import { AdbCommand, type AdbPacketData } from './packet.js';
7
- import { calculateBase64EncodedLength, encodeBase64 } from './utils/index.js';
1
+ import { PromiseResolver } from "@yume-chan/async";
2
+ import { type Disposable } from "@yume-chan/event";
3
+ import { type ValueOrPromise } from "@yume-chan/struct";
4
+
5
+ import {
6
+ calculatePublicKey,
7
+ calculatePublicKeyLength,
8
+ sign,
9
+ } from "./crypto.js";
10
+ import { AdbCommand, type AdbPacketData } from "./packet.js";
11
+ import { calculateBase64EncodedLength, encodeBase64 } from "./utils/index.js";
8
12
 
9
13
  export type AdbKeyIterable = Iterable<Uint8Array> | AsyncIterable<Uint8Array>;
10
14
 
@@ -50,7 +54,7 @@ export interface AdbAuthenticator {
50
54
 
51
55
  export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
52
56
  credentialStore: AdbCredentialStore,
53
- getNextRequest: () => Promise<AdbPacketData>,
57
+ getNextRequest: () => Promise<AdbPacketData>
54
58
  ): AsyncIterable<AdbPacketData> {
55
59
  for await (const key of credentialStore.iterateKeys()) {
56
60
  const packet = await getNextRequest();
@@ -71,7 +75,7 @@ export const AdbSignatureAuthenticator: AdbAuthenticator = async function* (
71
75
 
72
76
  export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
73
77
  credentialStore: AdbCredentialStore,
74
- getNextRequest: () => Promise<AdbPacketData>,
78
+ getNextRequest: () => Promise<AdbPacketData>
75
79
  ): AsyncIterable<AdbPacketData> {
76
80
  const packet = await getNextRequest();
77
81
 
@@ -85,23 +89,20 @@ export const AdbPublicKeyAuthenticator: AdbAuthenticator = async function* (
85
89
  break;
86
90
  }
87
91
 
88
-
89
92
  if (!privateKey) {
90
93
  privateKey = await credentialStore.generateKey();
91
94
  }
92
95
 
93
96
  const publicKeyLength = calculatePublicKeyLength();
94
- const [publicKeyBase64Length] = calculateBase64EncodedLength(publicKeyLength);
97
+ const [publicKeyBase64Length] =
98
+ calculateBase64EncodedLength(publicKeyLength);
95
99
 
96
100
  // The public key is null terminated,
97
101
  // So we allocate the buffer with one extra byte.
98
102
  const publicKeyBuffer = new Uint8Array(publicKeyBase64Length + 1);
99
103
 
100
104
  calculatePublicKey(privateKey, publicKeyBuffer);
101
- encodeBase64(
102
- publicKeyBuffer.subarray(0, publicKeyLength),
103
- publicKeyBuffer
104
- );
105
+ encodeBase64(publicKeyBuffer.subarray(0, publicKeyLength), publicKeyBuffer);
105
106
 
106
107
  yield {
107
108
  command: AdbCommand.Auth,
@@ -137,9 +138,16 @@ export class AdbAuthenticationProcessor implements Disposable {
137
138
  return this.pendingRequest.promise;
138
139
  };
139
140
 
140
- private async* invokeAuthenticator(): AsyncGenerator<AdbPacketData, void, void> {
141
+ private async *invokeAuthenticator(): AsyncGenerator<
142
+ AdbPacketData,
143
+ void,
144
+ void
145
+ > {
141
146
  for (const authenticator of this.authenticators) {
142
- for await (const packet of authenticator(this.credentialStore, this.getNextRequest)) {
147
+ for await (const packet of authenticator(
148
+ this.credentialStore,
149
+ this.getNextRequest
150
+ )) {
143
151
  // If the authenticator yielded a response
144
152
  // Prepare `nextRequest` for next authentication request
145
153
  this.pendingRequest = new PromiseResolver();
@@ -162,13 +170,13 @@ export class AdbAuthenticationProcessor implements Disposable {
162
170
 
163
171
  const result = await this.iterator.next();
164
172
  if (result.done) {
165
- throw new Error('No authenticator can handle the request');
173
+ throw new Error("No authenticator can handle the request");
166
174
  }
167
175
 
168
176
  return result.value;
169
177
  }
170
178
 
171
179
  public dispose() {
172
- this.iterator?.return?.();
180
+ void this.iterator?.return?.();
173
181
  }
174
182
  }
package/src/backend.ts CHANGED
@@ -1,12 +1,14 @@
1
- import type { ReadableWritablePair } from '@yume-chan/stream-extra';
2
- import type { ValueOrPromise } from '@yume-chan/struct';
1
+ import { type ReadableWritablePair } from "@yume-chan/stream-extra";
2
+ import { type ValueOrPromise } from "@yume-chan/struct";
3
3
 
4
- import type { AdbPacketData, AdbPacketInit } from './packet.js';
4
+ import { type AdbPacketData, type AdbPacketInit } from "./packet.js";
5
5
 
6
6
  export interface AdbBackend {
7
7
  readonly serial: string;
8
8
 
9
9
  readonly name: string | undefined;
10
10
 
11
- connect(): ValueOrPromise<ReadableWritablePair<AdbPacketData, AdbPacketInit>>;
11
+ connect(): ValueOrPromise<
12
+ ReadableWritablePair<AdbPacketData, AdbPacketInit>
13
+ >;
12
14
  }
@@ -1,6 +1,6 @@
1
- import { AutoDisposable } from '@yume-chan/event';
1
+ import { AutoDisposable } from "@yume-chan/event";
2
2
 
3
- import type { Adb } from '../adb.js';
3
+ import { type Adb } from "../adb.js";
4
4
 
5
5
  export class AdbCommandBase extends AutoDisposable {
6
6
  protected adb: Adb;
@@ -1,48 +1,44 @@
1
- import { BufferedReadableStream } from '@yume-chan/stream-extra';
2
- import Struct from '@yume-chan/struct';
1
+ import { BufferedReadableStream } from "@yume-chan/stream-extra";
2
+ import Struct from "@yume-chan/struct";
3
3
 
4
- import type { Adb } from '../adb.js';
4
+ import { type Adb } from "../adb.js";
5
5
 
6
- const Version =
7
- new Struct({ littleEndian: true })
8
- .uint32('version');
6
+ const Version = new Struct({ littleEndian: true }).uint32("version");
9
7
 
10
- export const AdbFrameBufferV1 =
11
- new Struct({ littleEndian: true })
12
- .uint32('bpp')
13
- .uint32('size')
14
- .uint32('width')
15
- .uint32('height')
16
- .uint32('red_offset')
17
- .uint32('red_length')
18
- .uint32('blue_offset')
19
- .uint32('blue_length')
20
- .uint32('green_offset')
21
- .uint32('green_length')
22
- .uint32('alpha_offset')
23
- .uint32('alpha_length')
24
- .uint8Array('data', { lengthField: 'size' });
8
+ export const AdbFrameBufferV1 = new Struct({ littleEndian: true })
9
+ .uint32("bpp")
10
+ .uint32("size")
11
+ .uint32("width")
12
+ .uint32("height")
13
+ .uint32("red_offset")
14
+ .uint32("red_length")
15
+ .uint32("blue_offset")
16
+ .uint32("blue_length")
17
+ .uint32("green_offset")
18
+ .uint32("green_length")
19
+ .uint32("alpha_offset")
20
+ .uint32("alpha_length")
21
+ .uint8Array("data", { lengthField: "size" });
25
22
 
26
- export type AdbFrameBufferV1 = typeof AdbFrameBufferV1['TDeserializeResult'];
23
+ export type AdbFrameBufferV1 = typeof AdbFrameBufferV1["TDeserializeResult"];
27
24
 
28
- export const AdbFrameBufferV2 =
29
- new Struct({ littleEndian: true })
30
- .uint32('bpp')
31
- .uint32('colorSpace')
32
- .uint32('size')
33
- .uint32('width')
34
- .uint32('height')
35
- .uint32('red_offset')
36
- .uint32('red_length')
37
- .uint32('blue_offset')
38
- .uint32('blue_length')
39
- .uint32('green_offset')
40
- .uint32('green_length')
41
- .uint32('alpha_offset')
42
- .uint32('alpha_length')
43
- .uint8Array('data', { lengthField: 'size' });
25
+ export const AdbFrameBufferV2 = new Struct({ littleEndian: true })
26
+ .uint32("bpp")
27
+ .uint32("colorSpace")
28
+ .uint32("size")
29
+ .uint32("width")
30
+ .uint32("height")
31
+ .uint32("red_offset")
32
+ .uint32("red_length")
33
+ .uint32("blue_offset")
34
+ .uint32("blue_length")
35
+ .uint32("green_offset")
36
+ .uint32("green_length")
37
+ .uint32("alpha_offset")
38
+ .uint32("alpha_length")
39
+ .uint8Array("data", { lengthField: "size" });
44
40
 
45
- export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
41
+ export type AdbFrameBufferV2 = typeof AdbFrameBufferV2["TDeserializeResult"];
46
42
 
47
43
  /**
48
44
  * ADB uses 8 int32 fields to describe bit depths
@@ -63,7 +59,7 @@ export type AdbFrameBufferV2 = typeof AdbFrameBufferV2['TDeserializeResult'];
63
59
  export type AdbFrameBuffer = AdbFrameBufferV1 | AdbFrameBufferV2;
64
60
 
65
61
  export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
66
- const socket = await adb.createSocket('framebuffer:');
62
+ const socket = await adb.createSocket("framebuffer:");
67
63
  const stream = new BufferedReadableStream(socket.readable);
68
64
  const { version } = await Version.deserialize(stream);
69
65
  switch (version) {
@@ -73,6 +69,6 @@ export async function framebuffer(adb: Adb): Promise<AdbFrameBuffer> {
73
69
  case 2:
74
70
  return AdbFrameBufferV2.deserialize(stream);
75
71
  default:
76
- throw new Error('Unknown FrameBuffer version');
72
+ throw new Error("Unknown FrameBuffer version");
77
73
  }
78
74
  }
@@ -1,13 +1,17 @@
1
- import { WrapWritableStream, WritableStream } from '@yume-chan/stream-extra';
1
+ import {
2
+ WrapWritableStream,
3
+ type WritableStream,
4
+ } from "@yume-chan/stream-extra";
2
5
 
3
- import type { Adb } from '../adb.js';
4
- import { escapeArg } from './subprocess/index.js';
5
- import type { AdbSync } from './sync/index.js';
6
+ import { type Adb } from "../adb.js";
6
7
 
7
- export function install(
8
- adb: Adb,
9
- ): WritableStream<Uint8Array> {
10
- const filename = `/data/local/tmp/${Math.random().toString().substring(2)}.apk`;
8
+ import { escapeArg } from "./subprocess/index.js";
9
+ import { type AdbSync } from "./sync/index.js";
10
+
11
+ export function install(adb: Adb): WritableStream<Uint8Array> {
12
+ const filename = `/data/local/tmp/${Math.random()
13
+ .toString()
14
+ .substring(2)}.apk`;
11
15
 
12
16
  let sync!: AdbSync;
13
17
  return new WrapWritableStream<Uint8Array>({
@@ -20,13 +24,17 @@ export function install(
20
24
  return sync.write(filename, undefined, undefined);
21
25
  },
22
26
  async close() {
23
- sync.dispose();
27
+ await sync.dispose();
24
28
 
25
29
  // Invoke `pm install` to install it
26
- await adb.subprocess.spawnAndWaitLegacy(['pm', 'install', escapeArg(filename)]);
30
+ await adb.subprocess.spawnAndWaitLegacy([
31
+ "pm",
32
+ "install",
33
+ escapeArg(filename),
34
+ ]);
27
35
 
28
36
  // Remove the temp file
29
37
  await adb.rm(filename);
30
- }
38
+ },
31
39
  });
32
40
  }
@@ -3,27 +3,27 @@
3
3
  // cspell: ignore keyevent
4
4
  // cspell: ignore longpress
5
5
 
6
- import { AdbCommandBase } from './base.js';
6
+ import { AdbCommandBase } from "./base.js";
7
7
 
8
8
  export class AdbPower extends AdbCommandBase {
9
- public reboot(name: string = '') {
9
+ public reboot(name = "") {
10
10
  return this.adb.createSocketAndWait(`reboot:${name}`);
11
11
  }
12
12
 
13
13
  public bootloader() {
14
- return this.reboot('bootloader');
14
+ return this.reboot("bootloader");
15
15
  }
16
16
 
17
17
  public fastboot() {
18
- return this.reboot('fastboot');
18
+ return this.reboot("fastboot");
19
19
  }
20
20
 
21
21
  public recovery() {
22
- return this.reboot('recovery');
22
+ return this.reboot("recovery");
23
23
  }
24
24
 
25
25
  public sideload() {
26
- return this.reboot('sideload');
26
+ return this.reboot("sideload");
27
27
  }
28
28
 
29
29
  /**
@@ -32,15 +32,19 @@ export class AdbPower extends AdbCommandBase {
32
32
  * Only works on some Qualcomm devices.
33
33
  */
34
34
  public qualcommEdlMode() {
35
- return this.reboot('edl');
35
+ return this.reboot("edl");
36
36
  }
37
37
 
38
38
  public powerOff() {
39
- return this.adb.subprocess.spawnAndWaitLegacy(['reboot', '-p']);
39
+ return this.adb.subprocess.spawnAndWaitLegacy(["reboot", "-p"]);
40
40
  }
41
41
 
42
- public powerButton(longPress: boolean = false) {
43
- return this.adb.subprocess.spawnAndWaitLegacy(['input', 'keyevent', longPress ? '--longpress POWER' : 'POWER']);
42
+ public powerButton(longPress = false) {
43
+ return this.adb.subprocess.spawnAndWaitLegacy([
44
+ "input",
45
+ "keyevent",
46
+ longPress ? "--longpress POWER" : "POWER",
47
+ ]);
44
48
  }
45
49
 
46
50
  /**
@@ -49,6 +53,6 @@ export class AdbPower extends AdbCommandBase {
49
53
  * Only works on Samsung devices.
50
54
  */
51
55
  public samsungOdin() {
52
- return this.reboot('download');
56
+ return this.reboot("download");
53
57
  }
54
58
  }
@@ -1,12 +1,18 @@
1
1
  // cspell: ignore killforward
2
2
 
3
- import { AutoDisposable } from '@yume-chan/event';
4
- import { BufferedReadableStream, BufferedReadableStreamEndedError } from '@yume-chan/stream-extra';
5
- import Struct from '@yume-chan/struct';
6
-
7
- import type { Adb } from '../adb.js';
8
- import type { AdbIncomingSocketHandler, AdbSocket } from '../socket/index.js';
9
- import { decodeUtf8 } from '../utils/index.js';
3
+ import { AutoDisposable } from "@yume-chan/event";
4
+ import {
5
+ BufferedReadableStream,
6
+ BufferedReadableStreamEndedError,
7
+ } from "@yume-chan/stream-extra";
8
+ import Struct from "@yume-chan/struct";
9
+
10
+ import { type Adb } from "../adb.js";
11
+ import {
12
+ type AdbIncomingSocketHandler,
13
+ type AdbSocket,
14
+ } from "../socket/index.js";
15
+ import { decodeUtf8 } from "../utils/index.js";
10
16
 
11
17
  export interface AdbForwardListener {
12
18
  deviceSerial: string;
@@ -16,20 +22,21 @@ export interface AdbForwardListener {
16
22
  remoteName: string;
17
23
  }
18
24
 
19
- const AdbReverseStringResponse =
20
- new Struct()
21
- .string('length', { length: 4 })
22
- .string('content', { lengthField: 'length', lengthFieldRadix: 16 });
25
+ const AdbReverseStringResponse = new Struct()
26
+ .string("length", { length: 4 })
27
+ .string("content", { lengthField: "length", lengthFieldRadix: 16 });
23
28
 
24
- const AdbReverseErrorResponse =
25
- new Struct()
26
- .fields(AdbReverseStringResponse)
27
- .postDeserialize((value) => {
28
- throw new Error(value.content);
29
- });
29
+ const AdbReverseErrorResponse = new Struct()
30
+ .fields(AdbReverseStringResponse)
31
+ .postDeserialize((value) => {
32
+ throw new Error(value.content);
33
+ });
30
34
 
31
35
  export class AdbReverseCommand extends AutoDisposable {
32
- protected localAddressToHandler = new Map<string, AdbIncomingSocketHandler>();
36
+ protected localAddressToHandler = new Map<
37
+ string,
38
+ AdbIncomingSocketHandler
39
+ >();
33
40
 
34
41
  protected deviceAddressToLocalAddress = new Map<string, string>();
35
42
 
@@ -41,13 +48,15 @@ export class AdbReverseCommand extends AutoDisposable {
41
48
  super();
42
49
 
43
50
  this.adb = adb;
44
- this.addDisposable(this.adb.onIncomingSocket(this.handleIncomingSocket));
51
+ this.addDisposable(
52
+ this.adb.onIncomingSocket(this.handleIncomingSocket)
53
+ );
45
54
  }
46
55
 
47
56
  protected handleIncomingSocket = async (socket: AdbSocket) => {
48
57
  let address = socket.serviceString;
49
58
  // ADB daemon appends `\0` to the service string
50
- address = address.replace(/\0/g, '');
59
+ address = address.replace(/\0/g, "");
51
60
  return !!(await this.localAddressToHandler.get(address)?.(socket));
52
61
  };
53
62
 
@@ -58,7 +67,7 @@ export class AdbReverseCommand extends AutoDisposable {
58
67
 
59
68
  private async sendRequest(service: string) {
60
69
  const stream = await this.createBufferedStream(service);
61
- const success = decodeUtf8(await stream.read(4)) === 'OKAY';
70
+ const success = decodeUtf8(await stream.read(4)) === "OKAY";
62
71
  if (!success) {
63
72
  await AdbReverseErrorResponse.deserialize(stream);
64
73
  }
@@ -66,11 +75,15 @@ export class AdbReverseCommand extends AutoDisposable {
66
75
  }
67
76
 
68
77
  public async list(): Promise<AdbForwardListener[]> {
69
- const stream = await this.createBufferedStream('reverse:list-forward');
78
+ const stream = await this.createBufferedStream("reverse:list-forward");
70
79
 
71
80
  const response = await AdbReverseStringResponse.deserialize(stream);
72
- return response.content!.split('\n').map(line => {
73
- const [deviceSerial, localName, remoteName] = line.split(' ') as [string, string, string];
81
+ return response.content!.split("\n").map((line) => {
82
+ const [deviceSerial, localName, remoteName] = line.split(" ") as [
83
+ string,
84
+ string,
85
+ string
86
+ ];
74
87
  return { deviceSerial, localName, remoteName };
75
88
  });
76
89
 
@@ -86,13 +99,17 @@ export class AdbReverseCommand extends AutoDisposable {
86
99
  public async add(
87
100
  deviceAddress: string,
88
101
  localAddress: string,
89
- handler: AdbIncomingSocketHandler,
102
+ handler: AdbIncomingSocketHandler
90
103
  ): Promise<string> {
91
- const stream = await this.sendRequest(`reverse:forward:${deviceAddress};${localAddress}`);
104
+ // TODO(reverse): handle ADB bug
105
+ // https://issuetracker.google.com/issues/37066218
106
+ const stream = await this.sendRequest(
107
+ `reverse:forward:${deviceAddress};${localAddress}`
108
+ );
92
109
 
93
110
  // `tcp:0` tells the device to pick an available port.
94
111
  // On Android >=8, device will respond with the selected port for all `tcp:` requests.
95
- if (deviceAddress.startsWith('tcp:')) {
112
+ if (deviceAddress.startsWith("tcp:")) {
96
113
  let length: number | undefined;
97
114
  try {
98
115
  length = Number.parseInt(decodeUtf8(await stream.read(4)), 16);
@@ -107,7 +124,7 @@ export class AdbReverseCommand extends AutoDisposable {
107
124
  }
108
125
 
109
126
  if (length !== undefined) {
110
- const port = decodeUtf8(await stream.read(length!));
127
+ const port = decodeUtf8(await stream.read(length));
111
128
  deviceAddress = `tcp:${Number.parseInt(port, 10)}`;
112
129
  }
113
130
  }
@@ -123,7 +140,9 @@ export class AdbReverseCommand extends AutoDisposable {
123
140
  await this.sendRequest(`reverse:killforward:${deviceAddress}`);
124
141
 
125
142
  if (this.deviceAddressToLocalAddress.has(deviceAddress)) {
126
- this.localAddressToHandler.delete(this.deviceAddressToLocalAddress.get(deviceAddress)!);
143
+ this.localAddressToHandler.delete(
144
+ this.deviceAddressToLocalAddress.get(deviceAddress)!
145
+ );
127
146
  this.deviceAddressToLocalAddress.delete(deviceAddress);
128
147
  }
129
148
 
@@ -1,7 +1,13 @@
1
- import { GatherStringStream, DecodeUtf8Stream } from '@yume-chan/stream-extra';
1
+ import { DecodeUtf8Stream, GatherStringStream } from "@yume-chan/stream-extra";
2
2
 
3
- import { AdbCommandBase } from '../base.js';
4
- import { AdbSubprocessNoneProtocol, AdbSubprocessProtocol, AdbSubprocessProtocolConstructor, AdbSubprocessShellProtocol } from './protocols/index.js';
3
+ import { AdbCommandBase } from "../base.js";
4
+
5
+ import {
6
+ AdbSubprocessNoneProtocol,
7
+ AdbSubprocessShellProtocol,
8
+ type AdbSubprocessProtocol,
9
+ type AdbSubprocessProtocolConstructor,
10
+ } from "./protocols/index.js";
5
11
 
6
12
  export interface AdbSubprocessOptions {
7
13
  /**
@@ -30,7 +36,7 @@ export interface AdbSubprocessWaitResult {
30
36
 
31
37
  export class AdbSubprocess extends AdbCommandBase {
32
38
  private async createProtocol(
33
- mode: 'pty' | 'raw',
39
+ mode: "pty" | "raw",
34
40
  command?: string | string[],
35
41
  options?: Partial<AdbSubprocessOptions>
36
42
  ): Promise<AdbSubprocessProtocol> {
@@ -46,14 +52,14 @@ export class AdbSubprocess extends AdbCommandBase {
46
52
  }
47
53
 
48
54
  if (!Constructor) {
49
- throw new Error('No specified protocol is supported by the device');
55
+ throw new Error("No specified protocol is supported by the device");
50
56
  }
51
57
 
52
58
  if (Array.isArray(command)) {
53
- command = command.join(' ');
59
+ command = command.join(" ");
54
60
  } else if (command === undefined) {
55
61
  // spawn the default shell
56
- command = '';
62
+ command = "";
57
63
  }
58
64
  return await Constructor[mode](this.adb, command);
59
65
  }
@@ -68,7 +74,7 @@ export class AdbSubprocess extends AdbCommandBase {
68
74
  command?: string | string[],
69
75
  options?: Partial<AdbSubprocessOptions>
70
76
  ): Promise<AdbSubprocessProtocol> {
71
- return this.createProtocol('pty', command, options);
77
+ return this.createProtocol("pty", command, options);
72
78
  }
73
79
 
74
80
  /**
@@ -81,7 +87,7 @@ export class AdbSubprocess extends AdbCommandBase {
81
87
  command: string | string[],
82
88
  options?: Partial<AdbSubprocessOptions>
83
89
  ): Promise<AdbSubprocessProtocol> {
84
- return this.createProtocol('raw', command, options);
90
+ return this.createProtocol("raw", command, options);
85
91
  }
86
92
 
87
93
  /**
@@ -100,13 +106,9 @@ export class AdbSubprocess extends AdbCommandBase {
100
106
  const stderr = new GatherStringStream();
101
107
 
102
108
  const [, , exitCode] = await Promise.all([
103
- shell.stdout
104
- .pipeThrough(new DecodeUtf8Stream())
105
- .pipeTo(stdout),
106
- shell.stderr
107
- .pipeThrough(new DecodeUtf8Stream())
108
- .pipeTo(stderr),
109
- shell.exit
109
+ shell.stdout.pipeThrough(new DecodeUtf8Stream()).pipeTo(stdout),
110
+ shell.stderr.pipeThrough(new DecodeUtf8Stream()).pipeTo(stderr),
111
+ shell.exit,
110
112
  ]);
111
113
 
112
114
  return {
@@ -121,11 +123,12 @@ export class AdbSubprocess extends AdbCommandBase {
121
123
  * @param command The command to run
122
124
  * @returns The entire output of the command
123
125
  */
124
- public async spawnAndWaitLegacy(command: string | string[]): Promise<string> {
125
- const { stdout } = await this.spawnAndWait(
126
- command,
127
- { protocols: [AdbSubprocessNoneProtocol] }
128
- );
126
+ public async spawnAndWaitLegacy(
127
+ command: string | string[]
128
+ ): Promise<string> {
129
+ const { stdout } = await this.spawnAndWait(command, {
130
+ protocols: [AdbSubprocessNoneProtocol],
131
+ });
129
132
  return stdout;
130
133
  }
131
134
  }
@@ -1,8 +1,9 @@
1
1
  import { DuplexStreamFactory, ReadableStream } from '@yume-chan/stream-extra';
2
2
 
3
- import type { Adb } from '../../../adb.js';
4
- import type { AdbSocket } from '../../../socket/index.js';
5
- import type { AdbSubprocessProtocol } from './types.js';
3
+ import { type Adb } from "../../../adb.js";
4
+ import { type AdbSocket } from "../../../socket/index.js";
5
+
6
+ import { type AdbSubprocessProtocol } from "./types.js";
6
7
 
7
8
  /**
8
9
  * The legacy shell