diff --git a/src/cli/commands/extract.ts b/src/cli/commands/extract.ts new file mode 100644 index 0000000..dfe434b --- /dev/null +++ b/src/cli/commands/extract.ts @@ -0,0 +1,29 @@ +import { Asar, BaseEntry } from "../.."; + +import { readFile, writeFile, mkdir } from "fs/promises"; + +import { join as joinPaths, dirname } from "path"; + +export default async function extract(...args: string[]) { + const [archive, output] = args; + + const asarBytes = await readFile(archive); + + const asar = new Asar(asarBytes); + + for (const [, filePathChunks, fileEntry] of asar.walkFiles(true)) { + if (BaseEntry.isDirectory(fileEntry)) { + const fileDirPath = joinPaths(output, ...filePathChunks); + + await mkdir(fileDirPath, { + recursive: true, + }); + } else { + const filePath = joinPaths(output, ...filePathChunks); + + const fileData = asar.readFile(fileEntry); + + await writeFile(filePath, fileData); + } + } +} diff --git a/src/cli/index.ts b/src/cli/index.ts index e1ce8ea..66d4d5f 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -3,6 +3,8 @@ import { help } from "./help"; import { colors, error } from "../log"; +import extract from "./commands/extract"; + const command = process.argv[2]; if (!command) { @@ -10,9 +12,17 @@ if (!command) { help(2); } -const commands = ["extract", "pack", "list", "help"]; +const commands = { + extract: extract, + pack: console.log, // TODO + list: console.log, // TODO + help: console.log, // TODO +}; +type Command = keyof typeof commands; -if (!commands.includes(command)) { +if (!(command in commands)) { error(`Unknown command ${colors.bold(`"${command}"`)}\n`); help(2); } + +commands[command as Command](...process.argv.slice(3));