@yume-chan/adb 0.0.9 → 0.0.10

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 (205) hide show
  1. package/CHANGELOG.json +23 -0
  2. package/CHANGELOG.md +16 -0
  3. package/LICENSE +21 -21
  4. package/README.md +227 -257
  5. package/dts/adb.d.ts.map +1 -1
  6. package/dts/auth.d.ts +11 -1
  7. package/dts/auth.d.ts.map +1 -1
  8. package/dts/backend.d.ts +3 -5
  9. package/dts/backend.d.ts.map +1 -1
  10. package/dts/commands/demo-mode.d.ts +3 -3
  11. package/dts/commands/demo-mode.d.ts.map +1 -1
  12. package/dts/commands/reverse.d.ts +2 -2
  13. package/dts/commands/reverse.d.ts.map +1 -1
  14. package/dts/commands/shell/index.d.ts +31 -5
  15. package/dts/commands/shell/index.d.ts.map +1 -1
  16. package/dts/commands/shell/legacy.d.ts +13 -2
  17. package/dts/commands/shell/legacy.d.ts.map +1 -1
  18. package/dts/commands/shell/protocol.d.ts +11 -3
  19. package/dts/commands/shell/protocol.d.ts.map +1 -1
  20. package/dts/commands/shell/types.d.ts +35 -3
  21. package/dts/commands/shell/types.d.ts.map +1 -1
  22. package/dts/commands/sync/request.d.ts +1 -1
  23. package/dts/commands/sync/request.d.ts.map +1 -1
  24. package/dts/commands/sync/response.d.ts +2 -2
  25. package/dts/commands/sync/response.d.ts.map +1 -1
  26. package/dts/commands/sync/sync.d.ts.map +1 -1
  27. package/dts/crypto.d.ts +7 -0
  28. package/dts/crypto.d.ts.map +1 -1
  29. package/dts/packet.d.ts.map +1 -1
  30. package/dts/socket/close-event-emitter.d.ts.map +1 -1
  31. package/dts/socket/controller.d.ts.map +1 -1
  32. package/dts/socket/data-event-emitter.d.ts.map +1 -1
  33. package/dts/socket/dispatcher.d.ts.map +1 -1
  34. package/dts/stream/buffered-stream.d.ts +2 -4
  35. package/dts/stream/buffered-stream.d.ts.map +1 -1
  36. package/dts/utils/encoding.d.ts +3 -0
  37. package/dts/utils/encoding.d.ts.map +1 -0
  38. package/dts/utils/index.d.ts +1 -0
  39. package/dts/utils/index.d.ts.map +1 -1
  40. package/esm/adb.js +3 -2
  41. package/esm/adb.js.map +1 -1
  42. package/esm/auth.js +2 -2
  43. package/esm/auth.js.map +1 -1
  44. package/esm/commands/demo-mode.js +9 -9
  45. package/esm/commands/demo-mode.js.map +1 -1
  46. package/esm/commands/reverse.js +3 -2
  47. package/esm/commands/reverse.js.map +1 -1
  48. package/esm/commands/shell/index.js +28 -18
  49. package/esm/commands/shell/index.js.map +1 -1
  50. package/esm/commands/shell/legacy.js +16 -0
  51. package/esm/commands/shell/legacy.js.map +1 -1
  52. package/esm/commands/shell/protocol.js +36 -9
  53. package/esm/commands/shell/protocol.js.map +1 -1
  54. package/esm/commands/sync/request.js +5 -4
  55. package/esm/commands/sync/request.js.map +1 -1
  56. package/esm/commands/sync/response.js +4 -3
  57. package/esm/commands/sync/response.js.map +1 -1
  58. package/esm/commands/sync/sync.js.map +1 -1
  59. package/esm/crypto.js +7 -2
  60. package/esm/crypto.js.map +1 -1
  61. package/esm/packet.js +12 -14
  62. package/esm/packet.js.map +1 -1
  63. package/esm/socket/close-event-emitter.js.map +1 -1
  64. package/esm/socket/controller.js.map +1 -1
  65. package/esm/socket/data-event-emitter.js.map +1 -1
  66. package/esm/socket/dispatcher.js +7 -7
  67. package/esm/socket/dispatcher.js.map +1 -1
  68. package/esm/stream/buffered-stream.js +0 -6
  69. package/esm/stream/buffered-stream.js.map +1 -1
  70. package/esm/utils/encoding.js +11 -0
  71. package/esm/utils/encoding.js.map +1 -0
  72. package/esm/utils/index.js +1 -0
  73. package/esm/utils/index.js.map +1 -1
  74. package/package.json +44 -51
  75. package/src/adb.ts +243 -242
  76. package/src/auth.ts +166 -156
  77. package/src/backend.ts +20 -24
  78. package/src/commands/base.ts +11 -11
  79. package/src/commands/demo-mode.ts +160 -160
  80. package/src/commands/framebuffer.ts +73 -73
  81. package/src/commands/index.ts +8 -8
  82. package/src/commands/install.ts +21 -21
  83. package/src/commands/reverse.ts +134 -133
  84. package/src/commands/shell/index.ts +87 -68
  85. package/src/commands/shell/legacy.ts +59 -42
  86. package/src/commands/shell/protocol.ts +121 -94
  87. package/src/commands/shell/types.ts +55 -21
  88. package/src/commands/shell/utils.ts +20 -20
  89. package/src/commands/sync/index.ts +7 -7
  90. package/src/commands/sync/list.ts +39 -39
  91. package/src/commands/sync/pull.ts +34 -34
  92. package/src/commands/sync/push.ts +46 -46
  93. package/src/commands/sync/request.ts +49 -48
  94. package/src/commands/sync/response.ts +58 -57
  95. package/src/commands/sync/stat.ts +121 -121
  96. package/src/commands/sync/sync.ts +113 -113
  97. package/src/commands/tcpip.ts +21 -21
  98. package/src/crypto.ts +285 -280
  99. package/src/features.ts +5 -5
  100. package/src/index.ts +10 -10
  101. package/src/packet.ts +84 -89
  102. package/src/socket/close-event-emitter.ts +28 -28
  103. package/src/socket/controller.ts +105 -105
  104. package/src/socket/data-event-emitter.ts +27 -27
  105. package/src/socket/dispatcher.ts +269 -269
  106. package/src/socket/index.ts +6 -6
  107. package/src/socket/logger.ts +12 -12
  108. package/src/socket/socket.ts +28 -28
  109. package/src/stream/buffered-stream.ts +92 -100
  110. package/src/stream/index.ts +2 -2
  111. package/src/stream/stream.ts +50 -50
  112. package/src/utils/auto-reset-event.ts +41 -41
  113. package/src/utils/base64.ts +274 -274
  114. package/src/utils/chunk.ts +70 -70
  115. package/src/utils/encoding.ts +13 -0
  116. package/src/utils/event-queue.ts +145 -145
  117. package/src/utils/index.ts +5 -4
  118. package/cjs/adb.js +0 -205
  119. package/cjs/adb.js.map +0 -1
  120. package/cjs/auth.js +0 -141
  121. package/cjs/auth.js.map +0 -1
  122. package/cjs/backend.js +0 -3
  123. package/cjs/backend.js.map +0 -1
  124. package/cjs/commands/base.js +0 -12
  125. package/cjs/commands/base.js.map +0 -1
  126. package/cjs/commands/demo-mode.js +0 -174
  127. package/cjs/commands/demo-mode.js.map +0 -1
  128. package/cjs/commands/framebuffer.js +0 -66
  129. package/cjs/commands/framebuffer.js.map +0 -1
  130. package/cjs/commands/index.js +0 -12
  131. package/cjs/commands/index.js.map +0 -1
  132. package/cjs/commands/install.js +0 -20
  133. package/cjs/commands/install.js.map +0 -1
  134. package/cjs/commands/reverse.js +0 -105
  135. package/cjs/commands/reverse.js.map +0 -1
  136. package/cjs/commands/shell/index.js +0 -56
  137. package/cjs/commands/shell/index.js.map +0 -1
  138. package/cjs/commands/shell/legacy.js +0 -37
  139. package/cjs/commands/shell/legacy.js.map +0 -1
  140. package/cjs/commands/shell/protocol.js +0 -83
  141. package/cjs/commands/shell/protocol.js.map +0 -1
  142. package/cjs/commands/shell/types.js +0 -3
  143. package/cjs/commands/shell/types.js.map +0 -1
  144. package/cjs/commands/shell/utils.js +0 -23
  145. package/cjs/commands/shell/utils.js.map +0 -1
  146. package/cjs/commands/sync/index.js +0 -11
  147. package/cjs/commands/sync/index.js.map +0 -1
  148. package/cjs/commands/sync/list.js +0 -36
  149. package/cjs/commands/sync/list.js.map +0 -1
  150. package/cjs/commands/sync/pull.js +0 -34
  151. package/cjs/commands/sync/pull.js.map +0 -1
  152. package/cjs/commands/sync/push.js +0 -49
  153. package/cjs/commands/sync/push.js.map +0 -1
  154. package/cjs/commands/sync/request.js +0 -48
  155. package/cjs/commands/sync/request.js.map +0 -1
  156. package/cjs/commands/sync/response.js +0 -53
  157. package/cjs/commands/sync/response.js.map +0 -1
  158. package/cjs/commands/sync/stat.js +0 -109
  159. package/cjs/commands/sync/stat.js.map +0 -1
  160. package/cjs/commands/sync/sync.js +0 -118
  161. package/cjs/commands/sync/sync.js.map +0 -1
  162. package/cjs/commands/tcpip.js +0 -28
  163. package/cjs/commands/tcpip.js.map +0 -1
  164. package/cjs/crypto.js +0 -231
  165. package/cjs/crypto.js.map +0 -1
  166. package/cjs/features.js +0 -10
  167. package/cjs/features.js.map +0 -1
  168. package/cjs/index.js +0 -14
  169. package/cjs/index.js.map +0 -1
  170. package/cjs/packet.js +0 -77
  171. package/cjs/packet.js.map +0 -1
  172. package/cjs/socket/close-event-emitter.js +0 -32
  173. package/cjs/socket/close-event-emitter.js.map +0 -1
  174. package/cjs/socket/controller.js +0 -84
  175. package/cjs/socket/controller.js.map +0 -1
  176. package/cjs/socket/data-event-emitter.js +0 -29
  177. package/cjs/socket/data-event-emitter.js.map +0 -1
  178. package/cjs/socket/dispatcher.js +0 -219
  179. package/cjs/socket/dispatcher.js.map +0 -1
  180. package/cjs/socket/index.js +0 -10
  181. package/cjs/socket/index.js.map +0 -1
  182. package/cjs/socket/logger.js +0 -3
  183. package/cjs/socket/logger.js.map +0 -1
  184. package/cjs/socket/socket.js +0 -24
  185. package/cjs/socket/socket.js.map +0 -1
  186. package/cjs/stream/buffered-stream.js +0 -78
  187. package/cjs/stream/buffered-stream.js.map +0 -1
  188. package/cjs/stream/index.js +0 -6
  189. package/cjs/stream/index.js.map +0 -1
  190. package/cjs/stream/stream.js +0 -45
  191. package/cjs/stream/stream.js.map +0 -1
  192. package/cjs/utils/auto-reset-event.js +0 -37
  193. package/cjs/utils/auto-reset-event.js.map +0 -1
  194. package/cjs/utils/base64.js +0 -210
  195. package/cjs/utils/base64.js.map +0 -1
  196. package/cjs/utils/chunk.js +0 -75
  197. package/cjs/utils/chunk.js.map +0 -1
  198. package/cjs/utils/event-queue.js +0 -108
  199. package/cjs/utils/event-queue.js.map +0 -1
  200. package/cjs/utils/index.js +0 -8
  201. package/cjs/utils/index.js.map +0 -1
  202. package/tsconfig.cjs.json +0 -11
  203. package/tsconfig.esm.json +0 -28
  204. package/tsconfig.esm.tsbuildinfo +0 -1305
  205. package/tsconfig.json +0 -18
@@ -1,48 +1,49 @@
1
- import Struct from '@yume-chan/struct';
2
- import { AdbBufferedStream } from '../../stream';
3
-
4
- export enum AdbSyncRequestId {
5
- List = 'LIST',
6
- Send = 'SEND',
7
- Lstat = 'STAT',
8
- Stat = 'STA2',
9
- Lstat2 = 'LST2',
10
- Data = 'DATA',
11
- Done = 'DONE',
12
- Receive = 'RECV',
13
- }
14
-
15
- export const AdbSyncNumberRequest =
16
- new Struct({ littleEndian: true })
17
- .string('id', { length: 4 })
18
- .uint32('arg');
19
-
20
- export const AdbSyncDataRequest =
21
- new Struct({ littleEndian: true })
22
- .fields(AdbSyncNumberRequest)
23
- .arrayBuffer('data', { lengthField: 'arg' });
24
-
25
- export async function adbSyncWriteRequest(
26
- stream: AdbBufferedStream,
27
- id: AdbSyncRequestId | string,
28
- value: number | string | ArrayBuffer
29
- ): Promise<void> {
30
- let buffer: ArrayBuffer;
31
- if (typeof value === 'number') {
32
- buffer = AdbSyncNumberRequest.serialize({
33
- id,
34
- arg: value,
35
- }, stream);
36
- } else if (typeof value === 'string') {
37
- buffer = AdbSyncDataRequest.serialize({
38
- id,
39
- data: stream.encodeUtf8(value),
40
- }, stream);
41
- } else {
42
- buffer = AdbSyncDataRequest.serialize({
43
- id,
44
- data: value,
45
- }, stream);
46
- }
47
- await stream.write(buffer);
48
- }
1
+ import Struct from '@yume-chan/struct';
2
+ import type { AdbBufferedStream } from '../../stream';
3
+ import { encodeUtf8 } from "../../utils";
4
+
5
+ export enum AdbSyncRequestId {
6
+ List = 'LIST',
7
+ Send = 'SEND',
8
+ Lstat = 'STAT',
9
+ Stat = 'STA2',
10
+ Lstat2 = 'LST2',
11
+ Data = 'DATA',
12
+ Done = 'DONE',
13
+ Receive = 'RECV',
14
+ }
15
+
16
+ export const AdbSyncNumberRequest =
17
+ new Struct({ littleEndian: true })
18
+ .string('id', { length: 4 })
19
+ .uint32('arg');
20
+
21
+ export const AdbSyncDataRequest =
22
+ new Struct({ littleEndian: true })
23
+ .fields(AdbSyncNumberRequest)
24
+ .arrayBuffer('data', { lengthField: 'arg' });
25
+
26
+ export async function adbSyncWriteRequest(
27
+ stream: AdbBufferedStream,
28
+ id: AdbSyncRequestId | string,
29
+ value: number | string | ArrayBuffer
30
+ ): Promise<void> {
31
+ let buffer: ArrayBuffer;
32
+ if (typeof value === 'number') {
33
+ buffer = AdbSyncNumberRequest.serialize({
34
+ id,
35
+ arg: value,
36
+ });
37
+ } else if (typeof value === 'string') {
38
+ buffer = AdbSyncDataRequest.serialize({
39
+ id,
40
+ data: encodeUtf8(value),
41
+ });
42
+ } else {
43
+ buffer = AdbSyncDataRequest.serialize({
44
+ id,
45
+ data: value,
46
+ });
47
+ }
48
+ await stream.write(buffer);
49
+ }
@@ -1,57 +1,58 @@
1
- import Struct, { StructDeserializationContext, StructLike, StructValueType } from '@yume-chan/struct';
2
- import { AdbBufferedStream } from '../../stream';
3
-
4
- export enum AdbSyncResponseId {
5
- Entry = 'DENT',
6
- Lstat = 'STAT',
7
- Stat = 'STA2',
8
- Lstat2 = 'LST2',
9
- Done = 'DONE',
10
- Data = 'DATA',
11
- Ok = 'OKAY',
12
- Fail = 'FAIL',
13
- }
14
-
15
- // DONE responses' size are always same as the request's normal response.
16
- // For example DONE responses for LIST requests are 16 bytes (same as DENT responses),
17
- // but DONE responses for STAT requests are 12 bytes (same as STAT responses)
18
- // So we need to know responses' size in advance.
19
- export class AdbSyncDoneResponse implements StructLike<AdbSyncDoneResponse> {
20
- private length: number;
21
-
22
- public readonly id = AdbSyncResponseId.Done;
23
-
24
- public constructor(length: number) {
25
- this.length = length;
26
- }
27
-
28
- public async deserialize(context: StructDeserializationContext): Promise<this> {
29
- await context.read(this.length);
30
- return this;
31
- }
32
- }
33
-
34
- export const AdbSyncFailResponse =
35
- new Struct({ littleEndian: true })
36
- .uint32('messageLength')
37
- .string('message', { lengthField: 'messageLength' })
38
- .postDeserialize(object => {
39
- throw new Error(object.message);
40
- });
41
-
42
- export async function adbSyncReadResponse<T extends Record<string, StructLike<any>>>(
43
- stream: AdbBufferedStream,
44
- types: T,
45
- ): Promise<StructValueType<T[keyof T]>> {
46
- const id = stream.backend.decodeUtf8(await stream.read(4));
47
-
48
- if (id === AdbSyncResponseId.Fail) {
49
- await AdbSyncFailResponse.deserialize(stream);
50
- }
51
-
52
- if (types[id]) {
53
- return types[id].deserialize(stream);
54
- }
55
-
56
- throw new Error('Unexpected response id');
57
- }
1
+ import Struct, { StructAsyncDeserializeStream, StructLike, StructValueType } from '@yume-chan/struct';
2
+ import { AdbBufferedStream } from '../../stream';
3
+ import { decodeUtf8 } from "../../utils";
4
+
5
+ export enum AdbSyncResponseId {
6
+ Entry = 'DENT',
7
+ Lstat = 'STAT',
8
+ Stat = 'STA2',
9
+ Lstat2 = 'LST2',
10
+ Done = 'DONE',
11
+ Data = 'DATA',
12
+ Ok = 'OKAY',
13
+ Fail = 'FAIL',
14
+ }
15
+
16
+ // DONE responses' size are always same as the request's normal response.
17
+ // For example DONE responses for LIST requests are 16 bytes (same as DENT responses),
18
+ // but DONE responses for STAT requests are 12 bytes (same as STAT responses)
19
+ // So we need to know responses' size in advance.
20
+ export class AdbSyncDoneResponse implements StructLike<AdbSyncDoneResponse> {
21
+ private length: number;
22
+
23
+ public readonly id = AdbSyncResponseId.Done;
24
+
25
+ public constructor(length: number) {
26
+ this.length = length;
27
+ }
28
+
29
+ public async deserialize(stream: StructAsyncDeserializeStream): Promise<this> {
30
+ await stream.read(this.length);
31
+ return this;
32
+ }
33
+ }
34
+
35
+ export const AdbSyncFailResponse =
36
+ new Struct({ littleEndian: true })
37
+ .uint32('messageLength')
38
+ .string('message', { lengthField: 'messageLength' })
39
+ .postDeserialize(object => {
40
+ throw new Error(object.message);
41
+ });
42
+
43
+ export async function adbSyncReadResponse<T extends Record<string, StructLike<any>>>(
44
+ stream: AdbBufferedStream,
45
+ types: T,
46
+ ): Promise<StructValueType<T[keyof T]>> {
47
+ const id = decodeUtf8(await stream.read(4));
48
+
49
+ if (id === AdbSyncResponseId.Fail) {
50
+ await AdbSyncFailResponse.deserialize(stream);
51
+ }
52
+
53
+ if (types[id]) {
54
+ return types[id].deserialize(stream);
55
+ }
56
+
57
+ throw new Error('Unexpected response id');
58
+ }
@@ -1,121 +1,121 @@
1
- import Struct, { placeholder } from '@yume-chan/struct';
2
- import { AdbBufferedStream } from '../../stream';
3
- import { AdbSyncRequestId, adbSyncWriteRequest } from './request';
4
- import { adbSyncReadResponse, AdbSyncResponseId } from './response';
5
-
6
- // https://github.com/python/cpython/blob/4e581d64b8aff3e2eda99b12f080c877bb78dfca/Lib/stat.py#L36
7
- export enum LinuxFileType {
8
- Directory = 0o04,
9
- File = 0o10,
10
- Link = 0o12,
11
- }
12
-
13
- export const AdbSyncLstatResponse =
14
- new Struct({ littleEndian: true })
15
- .int32('mode')
16
- .int32('size')
17
- .int32('mtime')
18
- .extra({
19
- id: AdbSyncResponseId.Lstat as const,
20
- get type() { return this.mode >> 12 as LinuxFileType; },
21
- get permission() { return this.mode & 0b00001111_11111111; },
22
- })
23
- .postDeserialize((object) => {
24
- if (object.mode === 0 &&
25
- object.size === 0 &&
26
- object.mtime === 0
27
- ) {
28
- throw new Error('lstat failed');
29
- }
30
- });
31
-
32
- export type AdbSyncLstatResponse = typeof AdbSyncLstatResponse['TDeserializeResult'];
33
-
34
- export enum AdbSyncStatErrorCode {
35
- EACCES = 13,
36
- EEXIST = 17,
37
- EFAULT = 14,
38
- EFBIG = 27,
39
- EINTR = 4,
40
- EINVAL = 22,
41
- EIO = 5,
42
- EISDIR = 21,
43
- ELOOP = 40,
44
- EMFILE = 24,
45
- ENAMETOOLONG = 36,
46
- ENFILE = 23,
47
- ENOENT = 2,
48
- ENOMEM = 12,
49
- ENOSPC = 28,
50
- ENOTDIR = 20,
51
- EOVERFLOW = 75,
52
- EPERM = 1,
53
- EROFS = 30,
54
- ETXTBSY = 26,
55
- }
56
-
57
- export const AdbSyncStatResponse =
58
- new Struct({ littleEndian: true })
59
- .uint32('error', placeholder<AdbSyncStatErrorCode>())
60
- .uint64('dev')
61
- .uint64('ino')
62
- .uint32('mode')
63
- .uint32('nlink')
64
- .uint32('uid')
65
- .uint32('gid')
66
- .uint64('size')
67
- .uint64('atime')
68
- .uint64('mtime')
69
- .uint64('ctime')
70
- .extra({
71
- id: AdbSyncResponseId.Stat as const,
72
- get type() { return this.mode >> 12 as LinuxFileType; },
73
- get permission() { return this.mode & 0b00001111_11111111; },
74
- })
75
- .postDeserialize((object) => {
76
- if (object.error) {
77
- throw new Error(AdbSyncStatErrorCode[object.error]);
78
- }
79
- });
80
-
81
- export type AdbSyncStatResponse = typeof AdbSyncStatResponse['TDeserializeResult'];
82
-
83
- const StatResponseType = {
84
- [AdbSyncResponseId.Stat]: AdbSyncStatResponse,
85
- };
86
-
87
- const LstatResponseType = {
88
- [AdbSyncResponseId.Lstat]: AdbSyncLstatResponse,
89
- };
90
-
91
- const Lstat2ResponseType = {
92
- [AdbSyncResponseId.Lstat2]: AdbSyncStatResponse,
93
- };
94
-
95
- export async function adbSyncLstat(
96
- stream: AdbBufferedStream,
97
- path: string,
98
- v2: boolean,
99
- ): Promise<AdbSyncLstatResponse | AdbSyncStatResponse> {
100
- let requestId: AdbSyncRequestId.Lstat | AdbSyncRequestId.Lstat2;
101
- let responseType: typeof LstatResponseType | typeof Lstat2ResponseType;
102
-
103
- if (v2) {
104
- requestId = AdbSyncRequestId.Lstat2;
105
- responseType = Lstat2ResponseType;
106
- } else {
107
- requestId = AdbSyncRequestId.Lstat;
108
- responseType = LstatResponseType;
109
- }
110
-
111
- await adbSyncWriteRequest(stream, requestId, path);
112
- return adbSyncReadResponse(stream, responseType);
113
- }
114
-
115
- export async function adbSyncStat(
116
- stream: AdbBufferedStream,
117
- path: string,
118
- ): Promise<AdbSyncStatResponse> {
119
- await adbSyncWriteRequest(stream, AdbSyncRequestId.Stat, path);
120
- return adbSyncReadResponse(stream, StatResponseType);
121
- }
1
+ import Struct, { placeholder } from '@yume-chan/struct';
2
+ import { AdbBufferedStream } from '../../stream';
3
+ import { AdbSyncRequestId, adbSyncWriteRequest } from './request';
4
+ import { adbSyncReadResponse, AdbSyncResponseId } from './response';
5
+
6
+ // https://github.com/python/cpython/blob/4e581d64b8aff3e2eda99b12f080c877bb78dfca/Lib/stat.py#L36
7
+ export enum LinuxFileType {
8
+ Directory = 0o04,
9
+ File = 0o10,
10
+ Link = 0o12,
11
+ }
12
+
13
+ export const AdbSyncLstatResponse =
14
+ new Struct({ littleEndian: true })
15
+ .int32('mode')
16
+ .int32('size')
17
+ .int32('mtime')
18
+ .extra({
19
+ id: AdbSyncResponseId.Lstat as const,
20
+ get type() { return this.mode >> 12 as LinuxFileType; },
21
+ get permission() { return this.mode & 0b00001111_11111111; },
22
+ })
23
+ .postDeserialize((object) => {
24
+ if (object.mode === 0 &&
25
+ object.size === 0 &&
26
+ object.mtime === 0
27
+ ) {
28
+ throw new Error('lstat failed');
29
+ }
30
+ });
31
+
32
+ export type AdbSyncLstatResponse = typeof AdbSyncLstatResponse['TDeserializeResult'];
33
+
34
+ export enum AdbSyncStatErrorCode {
35
+ EACCES = 13,
36
+ EEXIST = 17,
37
+ EFAULT = 14,
38
+ EFBIG = 27,
39
+ EINTR = 4,
40
+ EINVAL = 22,
41
+ EIO = 5,
42
+ EISDIR = 21,
43
+ ELOOP = 40,
44
+ EMFILE = 24,
45
+ ENAMETOOLONG = 36,
46
+ ENFILE = 23,
47
+ ENOENT = 2,
48
+ ENOMEM = 12,
49
+ ENOSPC = 28,
50
+ ENOTDIR = 20,
51
+ EOVERFLOW = 75,
52
+ EPERM = 1,
53
+ EROFS = 30,
54
+ ETXTBSY = 26,
55
+ }
56
+
57
+ export const AdbSyncStatResponse =
58
+ new Struct({ littleEndian: true })
59
+ .uint32('error', placeholder<AdbSyncStatErrorCode>())
60
+ .uint64('dev')
61
+ .uint64('ino')
62
+ .uint32('mode')
63
+ .uint32('nlink')
64
+ .uint32('uid')
65
+ .uint32('gid')
66
+ .uint64('size')
67
+ .uint64('atime')
68
+ .uint64('mtime')
69
+ .uint64('ctime')
70
+ .extra({
71
+ id: AdbSyncResponseId.Stat as const,
72
+ get type() { return this.mode >> 12 as LinuxFileType; },
73
+ get permission() { return this.mode & 0b00001111_11111111; },
74
+ })
75
+ .postDeserialize((object) => {
76
+ if (object.error) {
77
+ throw new Error(AdbSyncStatErrorCode[object.error]);
78
+ }
79
+ });
80
+
81
+ export type AdbSyncStatResponse = typeof AdbSyncStatResponse['TDeserializeResult'];
82
+
83
+ const StatResponseType = {
84
+ [AdbSyncResponseId.Stat]: AdbSyncStatResponse,
85
+ };
86
+
87
+ const LstatResponseType = {
88
+ [AdbSyncResponseId.Lstat]: AdbSyncLstatResponse,
89
+ };
90
+
91
+ const Lstat2ResponseType = {
92
+ [AdbSyncResponseId.Lstat2]: AdbSyncStatResponse,
93
+ };
94
+
95
+ export async function adbSyncLstat(
96
+ stream: AdbBufferedStream,
97
+ path: string,
98
+ v2: boolean,
99
+ ): Promise<AdbSyncLstatResponse | AdbSyncStatResponse> {
100
+ let requestId: AdbSyncRequestId.Lstat | AdbSyncRequestId.Lstat2;
101
+ let responseType: typeof LstatResponseType | typeof Lstat2ResponseType;
102
+
103
+ if (v2) {
104
+ requestId = AdbSyncRequestId.Lstat2;
105
+ responseType = Lstat2ResponseType;
106
+ } else {
107
+ requestId = AdbSyncRequestId.Lstat;
108
+ responseType = LstatResponseType;
109
+ }
110
+
111
+ await adbSyncWriteRequest(stream, requestId, path);
112
+ return adbSyncReadResponse(stream, responseType);
113
+ }
114
+
115
+ export async function adbSyncStat(
116
+ stream: AdbBufferedStream,
117
+ path: string,
118
+ ): Promise<AdbSyncStatResponse> {
119
+ await adbSyncWriteRequest(stream, AdbSyncRequestId.Stat, path);
120
+ return adbSyncReadResponse(stream, StatResponseType);
121
+ }