@aepyornis/fastboot.ts 0.0.1

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.
package/src/flasher.ts ADDED
@@ -0,0 +1,174 @@
1
+ import {
2
+ ZipReader,
3
+ BlobReader,
4
+ BlobWriter,
5
+ TextWriter,
6
+ Entry,
7
+ } from "@zip.js/zip.js"
8
+ import type { FastbootClient } from "./client"
9
+
10
+ type CommandName =
11
+ | "update"
12
+ | "flashall"
13
+ | "flash"
14
+ | "flashing"
15
+ | "erase"
16
+ | "format"
17
+ | "getvar"
18
+ | "set_active"
19
+ | "boot"
20
+ | "devices"
21
+ | "continue"
22
+ | "reboot"
23
+ | "reboot-bootloader"
24
+ | "help"
25
+
26
+ type Instruction = {
27
+ command: CommandName
28
+ args: string[]
29
+ options: object
30
+ }
31
+
32
+ function getEntry(entries: Entry[], filename: string): Entry {
33
+ const entry = entries.find(
34
+ (e) => e.filename.split(/[\\/]/).pop() === filename,
35
+ )
36
+ if (entry) {
37
+ return entry
38
+ } else {
39
+ throw new Error(`${filename} not found in zip`)
40
+ }
41
+ }
42
+
43
+ function parseInstruction(text: string): Instruction {
44
+ if (text.slice(0, 8) === "fastboot") {
45
+ text = text.slice(8).trim()
46
+ }
47
+
48
+ let command: CommandName
49
+ const args = []
50
+ const options = {}
51
+
52
+ const words = text.split(" ").map((x) => x.trim())
53
+
54
+ for (const word of words) {
55
+ if (word[0] === "-") {
56
+ if (word === "-w" || word === "--wipe") {
57
+ options.wipe = true
58
+ } else if (word === "--set-active=other") {
59
+ options.setActive = "other"
60
+ } else if (word === '--slot-other') {
61
+ options.slot = 'other'
62
+ } else if (word.slice(0, 6) === "--slot") {
63
+ const slot = word.split("=")[1]
64
+ if (!["current", "other", "a", "b"].includes(slot)) {
65
+ throw new Error(`unknown slot: ${slot}`)
66
+ }
67
+ options.slot = slot
68
+ } else if (word === "--skip-reboot") {
69
+ options.skipReboot = true
70
+ } else if (word === "--apply-vbmeta") {
71
+ options.applyVbmeta = true
72
+ } else {
73
+ console.warn(`Unknown option: ${word}`)
74
+ }
75
+ } else {
76
+ if (command) {
77
+ args.push(word)
78
+ } else {
79
+ command = word
80
+ }
81
+ }
82
+ }
83
+ return { command, args, options }
84
+ }
85
+
86
+ function parseInstructions(text: string): Instruction[] {
87
+ return text
88
+ .split("\n")
89
+ .map((x) => x.trim())
90
+ .filter((x) => x !== "")
91
+ .filter((x) => x[0] !== "#")
92
+ .map(parseInstruction)
93
+ }
94
+
95
+ export class FastbootFlasher {
96
+ client: FastbootClient
97
+ reader: ZipReader
98
+
99
+ constructor(client: FastbootClient, blob: Blob) {
100
+ this.client = client
101
+ this.reader = new ZipReader(new BlobReader(blob))
102
+ }
103
+
104
+ async run(instructions: text) {
105
+ const entries: Entry[] = await this.reader.getEntries() // io with factory.zip
106
+ const commands: Instruction[] = parseInstructions(instructions)
107
+ console.log(commands)
108
+
109
+ for (const command of commands) {
110
+ this.client.logger.log(`‣ ${JSON.stringify(command)}`)
111
+ if (command.command === "flash") {
112
+ const partition = command.args[0]
113
+ const filename = command.args[1]
114
+ const slot = command.options.slot || "current"
115
+ const entry = getEntry(entries, filename)
116
+ const blob = await entry.getData(
117
+ new BlobWriter("application/octet-stream"),
118
+ )
119
+
120
+ await this.client.doFlash(
121
+ partition,
122
+ blob,
123
+ slot,
124
+ Boolean(command.options.applyVbmeta),
125
+ )
126
+ } else if (command.command === "reboot-bootloader") {
127
+ if (command.options.setActive === "other") {
128
+ await this.client.setActiveOtherSlot()
129
+ }
130
+ await this.client.rebootBootloader()
131
+ } else if (command.command === "update") {
132
+ const nestedZipEntry = getEntry(entries, command.args[0])
133
+ const zipBlob = await nestedZipEntry.getData(
134
+ new BlobWriter("application/zip"),
135
+ )
136
+ const zipReader = new ZipReader(new BlobReader(zipBlob))
137
+ const nestedEntries = await zipReader.getEntries()
138
+ const fastbootInfoFile = nestedEntries.find(
139
+ (e) => e.filename === "fastboot-info.txt",
140
+ )
141
+ const fastbootInfoText = await fastbootInfoFile.getData(
142
+ new TextWriter(),
143
+ )
144
+
145
+ this.client.logger.log(`fastboot-info.txt: ${fastbootInfoText}`)
146
+
147
+ // fastboot -w update image-lynx-bp1a.250305.019.zip
148
+ await this.client.fastbootInfo(
149
+ nestedEntries,
150
+ fastbootInfoText,
151
+ Boolean(command.options.wipe),
152
+ )
153
+ } else if (command.command === "flashing") {
154
+ if (command.args[0] === "lock") {
155
+ await this.client.lock()
156
+ } else if (command.args[0] === "unlock") {
157
+ await this.client.unlock()
158
+ } else {
159
+ throw new Error(`Unknown command`)
160
+ }
161
+ } else if (command.command === "getvar") {
162
+ const clientVar = await this.client.getVar(command.args[0])
163
+ this.client.logger(`getVar(${command.args[0]}) => ${clientVar}`)
164
+ } else if (command.command === "erase") {
165
+ await this.client.erase(command.args[0])
166
+ } else if (command.command === "sleep") {
167
+ const ms = command.args[0] ? parseInt(command.args[0]) * 1000 : 5000
168
+ await new Promise((resolve) => setTimeout(resolve, ms))
169
+ } else {
170
+ throw new Error(`Fastboot command ${command.command} not implemented`)
171
+ }
172
+ }
173
+ }
174
+ }
package/src/images.ts ADDED
@@ -0,0 +1,218 @@
1
+ export const IMAGES = [
2
+ {
3
+ nickname: "boot",
4
+ img_name: "boot.img",
5
+ sig_name: "boot.sig",
6
+ part_name: "boot",
7
+ optional: false,
8
+ type: "BootCritical",
9
+ },
10
+ {
11
+ nickname: "bootloader",
12
+ img_name: "bootloader.img",
13
+ sig_name: "",
14
+ part_name: "bootloader",
15
+ optional: true,
16
+ type: "Extra",
17
+ },
18
+ {
19
+ nickname: "init_boot",
20
+ img_name: "init_boot.img",
21
+ sig_name: "init_boot.sig",
22
+ part_name: "init_boot",
23
+ optional: true,
24
+ type: "BootCritical",
25
+ },
26
+ {
27
+ nickname: "",
28
+ img_name: "boot_other.img",
29
+ sig_name: "boot.sig",
30
+ part_name: "boot",
31
+ optional: true,
32
+ type: "Normal",
33
+ },
34
+ {
35
+ nickname: "cache",
36
+ img_name: "cache.img",
37
+ sig_name: "cache.sig",
38
+ part_name: "cache",
39
+ optional: true,
40
+ type: "Extra",
41
+ },
42
+ {
43
+ nickname: "dtbo",
44
+ img_name: "dtbo.img",
45
+ sig_name: "dtbo.sig",
46
+ part_name: "dtbo",
47
+ optional: true,
48
+ type: "BootCritical",
49
+ },
50
+ {
51
+ nickname: "dts",
52
+ img_name: "dt.img",
53
+ sig_name: "dt.sig",
54
+ part_name: "dts",
55
+ optional: true,
56
+ type: "BootCritical",
57
+ },
58
+ {
59
+ nickname: "odm",
60
+ img_name: "odm.img",
61
+ sig_name: "odm.sig",
62
+ part_name: "odm",
63
+ optional: true,
64
+ type: "Normal",
65
+ },
66
+ {
67
+ nickname: "odm_dlkm",
68
+ img_name: "odm_dlkm.img",
69
+ sig_name: "odm_dlkm.sig",
70
+ part_name: "odm_dlkm",
71
+ optional: true,
72
+ type: "Normal",
73
+ },
74
+ {
75
+ nickname: "product",
76
+ img_name: "product.img",
77
+ sig_name: "product.sig",
78
+ part_name: "product",
79
+ optional: true,
80
+ type: "Normal",
81
+ },
82
+ {
83
+ nickname: "pvmfw",
84
+ img_name: "pvmfw.img",
85
+ sig_name: "pvmfw.sig",
86
+ part_name: "pvmfw",
87
+ optional: true,
88
+ type: "BootCritical",
89
+ },
90
+ {
91
+ nickname: "radio",
92
+ img_name: "radio.img",
93
+ sig_name: "",
94
+ part_name: "radio",
95
+ optional: true,
96
+ type: "Extra",
97
+ },
98
+ {
99
+ nickname: "recovery",
100
+ img_name: "recovery.img",
101
+ sig_name: "recovery.sig",
102
+ part_name: "recovery",
103
+ optional: true,
104
+ type: "BootCritical",
105
+ },
106
+ {
107
+ nickname: "super",
108
+ img_name: "super.img",
109
+ sig_name: "super.sig",
110
+ part_name: "super",
111
+ optional: true,
112
+ type: "Extra",
113
+ },
114
+ {
115
+ nickname: "system",
116
+ img_name: "system.img",
117
+ sig_name: "system.sig",
118
+ part_name: "system",
119
+ optional: false,
120
+ type: "Normal",
121
+ },
122
+ {
123
+ nickname: "system_dlkm",
124
+ img_name: "system_dlkm.img",
125
+ sig_name: "system_dlkm.sig",
126
+ part_name: "system_dlkm",
127
+ optional: true,
128
+ type: "Normal",
129
+ },
130
+ {
131
+ nickname: "system_ext",
132
+ img_name: "system_ext.img",
133
+ sig_name: "system_ext.sig",
134
+ part_name: "system_ext",
135
+ optional: true,
136
+ type: "Normal",
137
+ },
138
+ {
139
+ nickname: "",
140
+ img_name: "system_other.img",
141
+ sig_name: "system.sig",
142
+ part_name: "system",
143
+ optional: true,
144
+ type: "Normal",
145
+ },
146
+ {
147
+ nickname: "userdata",
148
+ img_name: "userdata.img",
149
+ sig_name: "userdata.sig",
150
+ part_name: "userdata",
151
+ optional: true,
152
+ type: "Extra",
153
+ },
154
+ {
155
+ nickname: "vbmeta",
156
+ img_name: "vbmeta.img",
157
+ sig_name: "vbmeta.sig",
158
+ part_name: "vbmeta",
159
+ optional: true,
160
+ type: "BootCritical",
161
+ },
162
+ {
163
+ nickname: "vbmeta_system",
164
+ img_name: "vbmeta_system.img",
165
+ sig_name: "vbmeta_system.sig",
166
+ part_name: "vbmeta_system",
167
+ optional: true,
168
+ type: "BootCritical",
169
+ },
170
+ {
171
+ nickname: "vbmeta_vendor",
172
+ img_name: "vbmeta_vendor.img",
173
+ sig_name: "vbmeta_vendor.sig",
174
+ part_name: "vbmeta_vendor",
175
+ optional: true,
176
+ type: "BootCritical",
177
+ },
178
+ {
179
+ nickname: "vendor",
180
+ img_name: "vendor.img",
181
+ sig_name: "vendor.sig",
182
+ part_name: "vendor",
183
+ optional: true,
184
+ type: "Normal",
185
+ },
186
+ {
187
+ nickname: "vendor_boot",
188
+ img_name: "vendor_boot.img",
189
+ sig_name: "vendor_boot.sig",
190
+ part_name: "vendor_boot",
191
+ optional: true,
192
+ type: "BootCritical",
193
+ },
194
+ {
195
+ nickname: "vendor_dlkm",
196
+ img_name: "vendor_dlkm.img",
197
+ sig_name: "vendor_dlkm.sig",
198
+ part_name: "vendor_dlkm",
199
+ optional: true,
200
+ type: "Normal",
201
+ },
202
+ {
203
+ nickname: "vendor_kernel_boot",
204
+ img_name: "vendor_kernel_boot.img",
205
+ sig_name: "vendor_kernel_boot.sig",
206
+ part_name: "vendor_kernel_boot",
207
+ optional: true,
208
+ type: "BootCritical",
209
+ },
210
+ {
211
+ nickname: "",
212
+ img_name: "vendor_other.img",
213
+ sig_name: "vendor.sig",
214
+ part_name: "vendor",
215
+ optional: true,
216
+ type: "Normal",
217
+ },
218
+ ]
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { FastbootDevice } from "./device"
2
+ export { FastbootClient } from "./client"
3
+ export { FastbootFlasher } from "./flasher"