@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,274 +1,274 @@
1
- // Prepare maps for O(1) searching
2
- const charToIndex: Record<string, number> = {};
3
- const indexToChar: number[] = [];
4
- const paddingChar = '='.charCodeAt(0);
5
-
6
- function addRange(start: string, end: string) {
7
- const charCodeStart = start.charCodeAt(0);
8
- const charCodeEnd = end.charCodeAt(0);
9
- const length = charCodeEnd - charCodeStart + 1;
10
-
11
- for (let charCode = charCodeStart; charCode <= charCodeEnd; charCode += 1) {
12
- charToIndex[String.fromCharCode(charCode)] = indexToChar.length;
13
- indexToChar.push(charCode);
14
- }
15
- }
16
-
17
- addRange('A', 'Z');
18
- addRange('a', 'z');
19
- addRange('0', '9');
20
- addRange('+', '+');
21
- addRange('/', '/');
22
-
23
- export function calculateBase64EncodedLength(inputLength: number): [outputLength: number, paddingLength: number] {
24
- const remainder = inputLength % 3;
25
- const paddingLength = remainder !== 0 ? 3 - remainder : 0;
26
- return [(inputLength + paddingLength) / 3 * 4, paddingLength];
27
- }
28
-
29
- export function encodeBase64(
30
- input: ArrayBuffer | Uint8Array,
31
- inputOffset?: number,
32
- inputLength?: number,
33
- ): ArrayBuffer; // overload 1
34
- export function encodeBase64(
35
- input: ArrayBuffer | Uint8Array,
36
- output: ArrayBuffer | Uint8Array,
37
- outputOffset?: number
38
- ): number; // overload 2
39
- export function encodeBase64(
40
- input: ArrayBuffer | Uint8Array,
41
- inputOffset: number,
42
- output: ArrayBuffer | Uint8Array,
43
- outputOffset?: number
44
- ): number; // overload 3
45
- export function encodeBase64(
46
- input: ArrayBuffer | Uint8Array,
47
- inputOffset: number,
48
- inputLength: number,
49
- output: ArrayBuffer | Uint8Array,
50
- outputOffset?: number
51
- ): number; // overload 4
52
- export function encodeBase64(
53
- input: ArrayBuffer | Uint8Array,
54
- arg1?: number | ArrayBuffer | Uint8Array,
55
- arg2?: number | ArrayBuffer | Uint8Array,
56
- _arg3?: number | ArrayBuffer | Uint8Array,
57
- _arg4?: number,
58
- ): ArrayBuffer | number {
59
- if (input instanceof ArrayBuffer) {
60
- input = new Uint8Array(input);
61
- }
62
-
63
- // Because `Uint8Array` is type compatible with `ArrayBuffer`,
64
- // TypeScript doesn't correctly narrow `input` to `Uint8Array` when assigning.
65
- // Manually eliminate `ArrayBuffer` from `input` with a type guard.
66
- if (input instanceof ArrayBuffer) {
67
- return input;
68
- }
69
-
70
- let inputOffset: number;
71
- let inputLength: number;
72
- let output: Uint8Array;
73
- let outputOffset: number;
74
-
75
- let outputArgumentIndex: number;
76
- if (typeof arg1 === 'number') {
77
- // overload 1, 3, 4
78
- inputOffset = arg1;
79
-
80
- if (typeof arg2 === 'number') {
81
- // overload 1, 4
82
- inputLength = arg2;
83
- outputArgumentIndex = 3;
84
- } else {
85
- // overload 3
86
- inputLength = input.byteLength - inputOffset;
87
- outputArgumentIndex = 2;
88
- }
89
- } else {
90
- // overload 2
91
- inputOffset = 0;
92
- inputLength = input.byteLength;
93
- outputArgumentIndex = 1;
94
- }
95
-
96
- const [outputLength, paddingLength] = calculateBase64EncodedLength(inputLength);
97
-
98
- let maybeOutput: ArrayBuffer | Uint8Array | undefined = arguments[outputArgumentIndex];
99
- let outputType: 'ArrayBuffer' | 'number';
100
- if (maybeOutput) {
101
- outputOffset = arguments[outputArgumentIndex + 1] ?? 0;
102
-
103
- if (maybeOutput.byteLength - outputOffset < outputLength) {
104
- throw new Error('output buffer is too small');
105
- }
106
-
107
- if (maybeOutput instanceof ArrayBuffer) {
108
- output = new Uint8Array(maybeOutput);
109
- } else {
110
- output = maybeOutput;
111
- }
112
-
113
- outputType = 'number';
114
- } else {
115
- const buffer = new ArrayBuffer(outputLength);
116
- output = new Uint8Array(buffer);
117
- outputOffset = 0;
118
- outputType = 'ArrayBuffer';
119
- }
120
-
121
- // Because `Uint8Array` is type compatible with `ArrayBuffer`,
122
- // TypeScript doesn't correctly narrow `output` to `Uint8Array` when assigning.
123
- // Manually eliminate `ArrayBuffer` from `output` with a type guard.
124
- if (output instanceof ArrayBuffer) {
125
- return output;
126
- }
127
-
128
- if (input.buffer === output.buffer) {
129
- const bufferInputStart = input.byteOffset + inputOffset;
130
- const bufferOutputStart = output.byteOffset + outputOffset;
131
- if (bufferOutputStart < bufferInputStart - 1) {
132
- const bufferOutputEnd = bufferOutputStart + outputLength;
133
- if (bufferOutputEnd >= bufferInputStart) {
134
- throw new Error('input and output buffer can not be overlapping');
135
- }
136
- }
137
- }
138
-
139
- // Run backward to do in-place overwrite
140
- let inputIndex = inputOffset + inputLength - 1;
141
- let outputIndex = outputOffset + outputLength - 1;
142
-
143
- if (paddingLength === 2) {
144
- // aaaaaabb
145
- const x = input[inputIndex];
146
- inputIndex -= 1;
147
-
148
- output[outputIndex] = paddingChar;
149
- outputIndex -= 1;
150
-
151
- output[outputIndex] = paddingChar;
152
- outputIndex -= 1;
153
-
154
- output[outputIndex] = indexToChar[((x & 0b11) << 4)];
155
- outputIndex -= 1;
156
-
157
- output[outputIndex] = indexToChar[x >> 2];
158
- outputIndex -= 1;
159
- } else if (paddingLength === 1) {
160
- // bbbbcccc
161
- const y = input[inputIndex];
162
- inputIndex -= 1;
163
-
164
- // aaaaaabb
165
- const x = input[inputIndex];
166
- inputIndex -= 1;
167
-
168
- output[outputIndex] = paddingChar;
169
- outputIndex -= 1;
170
-
171
- output[outputIndex] = indexToChar[((y & 0b1111) << 2)];
172
- outputIndex -= 1;
173
-
174
- output[outputIndex] = indexToChar[((x & 0b11) << 4) | (y >> 4)];
175
- outputIndex -= 1;
176
-
177
- output[outputIndex] = indexToChar[x >> 2];
178
- outputIndex -= 1;
179
- }
180
-
181
- while (inputIndex >= inputOffset) {
182
- // ccdddddd
183
- const z = input[inputIndex];
184
- inputIndex -= 1;
185
-
186
- // bbbbcccc
187
- const y = input[inputIndex];
188
- inputIndex -= 1;
189
-
190
- // aaaaaabb
191
- const x = input[inputIndex];
192
- inputIndex -= 1;
193
-
194
- output[outputIndex] = indexToChar[z & 0b111111];
195
- outputIndex -= 1;
196
-
197
- output[outputIndex] = indexToChar[((y & 0b1111) << 2) | (z >> 6)];
198
- outputIndex -= 1;
199
-
200
- output[outputIndex] = indexToChar[((x & 0b11) << 4) | (y >> 4)];
201
- outputIndex -= 1;
202
-
203
- output[outputIndex] = indexToChar[x >> 2];
204
- outputIndex -= 1;
205
- }
206
-
207
- if (outputType === 'ArrayBuffer') {
208
- return output.buffer;
209
- } else {
210
- return outputLength;
211
- }
212
- }
213
-
214
- export function decodeBase64(input: string): ArrayBuffer {
215
- let padding: number;
216
- if (input[input.length - 2] === '=') {
217
- padding = 2;
218
- } else if (input[input.length - 1] === '=') {
219
- padding = 1;
220
- } else {
221
- padding = 0;
222
- }
223
-
224
- const result = new Uint8Array(input.length / 4 * 3 - padding);
225
- let sIndex = 0;
226
- let dIndex = 0;
227
-
228
- while (sIndex < input.length - (padding !== 0 ? 4 : 0)) {
229
- const a = charToIndex[input[sIndex]];
230
- sIndex += 1;
231
-
232
- const b = charToIndex[input[sIndex]];
233
- sIndex += 1;
234
-
235
- const c = charToIndex[input[sIndex]];
236
- sIndex += 1;
237
-
238
- const d = charToIndex[input[sIndex]];
239
- sIndex += 1;
240
-
241
- result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
242
- dIndex += 1;
243
-
244
- result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
245
- dIndex += 1;
246
-
247
- result[dIndex] = ((c & 0b11) << 6) | d;
248
- dIndex += 1;
249
- }
250
-
251
- if (padding === 1) {
252
- const a = charToIndex[input[sIndex]];
253
- sIndex += 1;
254
-
255
- const b = charToIndex[input[sIndex]];
256
- sIndex += 1;
257
-
258
- const c = charToIndex[input[sIndex]];
259
-
260
- result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
261
- dIndex += 1;
262
-
263
- result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
264
- } else if (padding === 2) {
265
- const a = charToIndex[input[sIndex]];
266
- sIndex += 1;
267
-
268
- const b = charToIndex[input[sIndex]];
269
-
270
- result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
271
- }
272
-
273
- return result.buffer;
274
- }
1
+ // Prepare maps for O(1) searching
2
+ const charToIndex: Record<string, number> = {};
3
+ const indexToChar: number[] = [];
4
+ const paddingChar = '='.charCodeAt(0);
5
+
6
+ function addRange(start: string, end: string) {
7
+ const charCodeStart = start.charCodeAt(0);
8
+ const charCodeEnd = end.charCodeAt(0);
9
+ const length = charCodeEnd - charCodeStart + 1;
10
+
11
+ for (let charCode = charCodeStart; charCode <= charCodeEnd; charCode += 1) {
12
+ charToIndex[String.fromCharCode(charCode)] = indexToChar.length;
13
+ indexToChar.push(charCode);
14
+ }
15
+ }
16
+
17
+ addRange('A', 'Z');
18
+ addRange('a', 'z');
19
+ addRange('0', '9');
20
+ addRange('+', '+');
21
+ addRange('/', '/');
22
+
23
+ export function calculateBase64EncodedLength(inputLength: number): [outputLength: number, paddingLength: number] {
24
+ const remainder = inputLength % 3;
25
+ const paddingLength = remainder !== 0 ? 3 - remainder : 0;
26
+ return [(inputLength + paddingLength) / 3 * 4, paddingLength];
27
+ }
28
+
29
+ export function encodeBase64(
30
+ input: ArrayBuffer | Uint8Array,
31
+ inputOffset?: number,
32
+ inputLength?: number,
33
+ ): ArrayBuffer; // overload 1
34
+ export function encodeBase64(
35
+ input: ArrayBuffer | Uint8Array,
36
+ output: ArrayBuffer | Uint8Array,
37
+ outputOffset?: number
38
+ ): number; // overload 2
39
+ export function encodeBase64(
40
+ input: ArrayBuffer | Uint8Array,
41
+ inputOffset: number,
42
+ output: ArrayBuffer | Uint8Array,
43
+ outputOffset?: number
44
+ ): number; // overload 3
45
+ export function encodeBase64(
46
+ input: ArrayBuffer | Uint8Array,
47
+ inputOffset: number,
48
+ inputLength: number,
49
+ output: ArrayBuffer | Uint8Array,
50
+ outputOffset?: number
51
+ ): number; // overload 4
52
+ export function encodeBase64(
53
+ input: ArrayBuffer | Uint8Array,
54
+ arg1?: number | ArrayBuffer | Uint8Array,
55
+ arg2?: number | ArrayBuffer | Uint8Array,
56
+ _arg3?: number | ArrayBuffer | Uint8Array,
57
+ _arg4?: number,
58
+ ): ArrayBuffer | number {
59
+ if (input instanceof ArrayBuffer) {
60
+ input = new Uint8Array(input);
61
+ }
62
+
63
+ // Because `Uint8Array` is type compatible with `ArrayBuffer`,
64
+ // TypeScript doesn't correctly narrow `input` to `Uint8Array` when assigning.
65
+ // Manually eliminate `ArrayBuffer` from `input` with a type guard.
66
+ if (input instanceof ArrayBuffer) {
67
+ return input;
68
+ }
69
+
70
+ let inputOffset: number;
71
+ let inputLength: number;
72
+ let output: Uint8Array;
73
+ let outputOffset: number;
74
+
75
+ let outputArgumentIndex: number;
76
+ if (typeof arg1 === 'number') {
77
+ // overload 1, 3, 4
78
+ inputOffset = arg1;
79
+
80
+ if (typeof arg2 === 'number') {
81
+ // overload 1, 4
82
+ inputLength = arg2;
83
+ outputArgumentIndex = 3;
84
+ } else {
85
+ // overload 3
86
+ inputLength = input.byteLength - inputOffset;
87
+ outputArgumentIndex = 2;
88
+ }
89
+ } else {
90
+ // overload 2
91
+ inputOffset = 0;
92
+ inputLength = input.byteLength;
93
+ outputArgumentIndex = 1;
94
+ }
95
+
96
+ const [outputLength, paddingLength] = calculateBase64EncodedLength(inputLength);
97
+
98
+ let maybeOutput: ArrayBuffer | Uint8Array | undefined = arguments[outputArgumentIndex];
99
+ let outputType: 'ArrayBuffer' | 'number';
100
+ if (maybeOutput) {
101
+ outputOffset = arguments[outputArgumentIndex + 1] ?? 0;
102
+
103
+ if (maybeOutput.byteLength - outputOffset < outputLength) {
104
+ throw new Error('output buffer is too small');
105
+ }
106
+
107
+ if (maybeOutput instanceof ArrayBuffer) {
108
+ output = new Uint8Array(maybeOutput);
109
+ } else {
110
+ output = maybeOutput;
111
+ }
112
+
113
+ outputType = 'number';
114
+ } else {
115
+ const buffer = new ArrayBuffer(outputLength);
116
+ output = new Uint8Array(buffer);
117
+ outputOffset = 0;
118
+ outputType = 'ArrayBuffer';
119
+ }
120
+
121
+ // Because `Uint8Array` is type compatible with `ArrayBuffer`,
122
+ // TypeScript doesn't correctly narrow `output` to `Uint8Array` when assigning.
123
+ // Manually eliminate `ArrayBuffer` from `output` with a type guard.
124
+ if (output instanceof ArrayBuffer) {
125
+ return output;
126
+ }
127
+
128
+ if (input.buffer === output.buffer) {
129
+ const bufferInputStart = input.byteOffset + inputOffset;
130
+ const bufferOutputStart = output.byteOffset + outputOffset;
131
+ if (bufferOutputStart < bufferInputStart - 1) {
132
+ const bufferOutputEnd = bufferOutputStart + outputLength;
133
+ if (bufferOutputEnd >= bufferInputStart) {
134
+ throw new Error('input and output buffer can not be overlapping');
135
+ }
136
+ }
137
+ }
138
+
139
+ // Run backward to do in-place overwrite
140
+ let inputIndex = inputOffset + inputLength - 1;
141
+ let outputIndex = outputOffset + outputLength - 1;
142
+
143
+ if (paddingLength === 2) {
144
+ // aaaaaabb
145
+ const x = input[inputIndex];
146
+ inputIndex -= 1;
147
+
148
+ output[outputIndex] = paddingChar;
149
+ outputIndex -= 1;
150
+
151
+ output[outputIndex] = paddingChar;
152
+ outputIndex -= 1;
153
+
154
+ output[outputIndex] = indexToChar[((x & 0b11) << 4)];
155
+ outputIndex -= 1;
156
+
157
+ output[outputIndex] = indexToChar[x >> 2];
158
+ outputIndex -= 1;
159
+ } else if (paddingLength === 1) {
160
+ // bbbbcccc
161
+ const y = input[inputIndex];
162
+ inputIndex -= 1;
163
+
164
+ // aaaaaabb
165
+ const x = input[inputIndex];
166
+ inputIndex -= 1;
167
+
168
+ output[outputIndex] = paddingChar;
169
+ outputIndex -= 1;
170
+
171
+ output[outputIndex] = indexToChar[((y & 0b1111) << 2)];
172
+ outputIndex -= 1;
173
+
174
+ output[outputIndex] = indexToChar[((x & 0b11) << 4) | (y >> 4)];
175
+ outputIndex -= 1;
176
+
177
+ output[outputIndex] = indexToChar[x >> 2];
178
+ outputIndex -= 1;
179
+ }
180
+
181
+ while (inputIndex >= inputOffset) {
182
+ // ccdddddd
183
+ const z = input[inputIndex];
184
+ inputIndex -= 1;
185
+
186
+ // bbbbcccc
187
+ const y = input[inputIndex];
188
+ inputIndex -= 1;
189
+
190
+ // aaaaaabb
191
+ const x = input[inputIndex];
192
+ inputIndex -= 1;
193
+
194
+ output[outputIndex] = indexToChar[z & 0b111111];
195
+ outputIndex -= 1;
196
+
197
+ output[outputIndex] = indexToChar[((y & 0b1111) << 2) | (z >> 6)];
198
+ outputIndex -= 1;
199
+
200
+ output[outputIndex] = indexToChar[((x & 0b11) << 4) | (y >> 4)];
201
+ outputIndex -= 1;
202
+
203
+ output[outputIndex] = indexToChar[x >> 2];
204
+ outputIndex -= 1;
205
+ }
206
+
207
+ if (outputType === 'ArrayBuffer') {
208
+ return output.buffer;
209
+ } else {
210
+ return outputLength;
211
+ }
212
+ }
213
+
214
+ export function decodeBase64(input: string): ArrayBuffer {
215
+ let padding: number;
216
+ if (input[input.length - 2] === '=') {
217
+ padding = 2;
218
+ } else if (input[input.length - 1] === '=') {
219
+ padding = 1;
220
+ } else {
221
+ padding = 0;
222
+ }
223
+
224
+ const result = new Uint8Array(input.length / 4 * 3 - padding);
225
+ let sIndex = 0;
226
+ let dIndex = 0;
227
+
228
+ while (sIndex < input.length - (padding !== 0 ? 4 : 0)) {
229
+ const a = charToIndex[input[sIndex]];
230
+ sIndex += 1;
231
+
232
+ const b = charToIndex[input[sIndex]];
233
+ sIndex += 1;
234
+
235
+ const c = charToIndex[input[sIndex]];
236
+ sIndex += 1;
237
+
238
+ const d = charToIndex[input[sIndex]];
239
+ sIndex += 1;
240
+
241
+ result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
242
+ dIndex += 1;
243
+
244
+ result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
245
+ dIndex += 1;
246
+
247
+ result[dIndex] = ((c & 0b11) << 6) | d;
248
+ dIndex += 1;
249
+ }
250
+
251
+ if (padding === 1) {
252
+ const a = charToIndex[input[sIndex]];
253
+ sIndex += 1;
254
+
255
+ const b = charToIndex[input[sIndex]];
256
+ sIndex += 1;
257
+
258
+ const c = charToIndex[input[sIndex]];
259
+
260
+ result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
261
+ dIndex += 1;
262
+
263
+ result[dIndex] = ((b & 0b1111) << 4) | ((c & 0b11_1100) >> 2);
264
+ } else if (padding === 2) {
265
+ const a = charToIndex[input[sIndex]];
266
+ sIndex += 1;
267
+
268
+ const b = charToIndex[input[sIndex]];
269
+
270
+ result[dIndex] = (a << 2) | ((b & 0b11_0000) >> 4);
271
+ }
272
+
273
+ return result.buffer;
274
+ }