import util from "node:util"; import { createBrowser } from "./browser"; import { createDatabase } from "./database"; import { type Book, createLibrary } from "./library"; import { type TPlatform, createPlatform } from "./platform"; import * as pkg from "./package.json"; const options = { db: { type: "string", default: "gadl.db", }, "out-dir": { type: "string", default: "dist", }, "out-authors-limit": { type: "string", default: "3", }, login: { type: "string", async run() { const db = await createDatabase(args.values.db!); const browser = await createBrowser({ db, headless: false }); const platform = createPlatform({ platform: args.values.login as TPlatform, db, browser, }); await platform.login(); await browser.close(); }, }, logout: { type: "string", async run() { const db = await createDatabase(args.values.db!); const browser = await createBrowser({ db }); const platform = createPlatform({ platform: args.values.logout as TPlatform, db, browser, }); await platform.logout(); await browser.close(); }, }, add: { type: "string", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); await library.add(args.values.add!); }, }, delete: { type: "string", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); await library.delete(Number(args.values.delete)); }, }, list: { type: "boolean", short: "l", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); const books = await library.getBooks(); console.dir(books, { depth: null, maxArrayLength: null, maxStringLength: null, }); }, }, view: { type: "string", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); const book = await library.get(Number(args.values.view!)); if (!book) { process.exit(1); } console.dir(book, { depth: null, maxArrayLength: null, maxStringLength: null, }); }, }, pull: { type: "string", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); const browser = await createBrowser({ db }); const platform = createPlatform({ platform: args.values.pull as TPlatform, db, browser, }); for await (const book of platform.pull()) { await library.add(book); } await browser.close(); }, }, download: { type: "string", async run() { const db = await createDatabase(args.values.db!); const library = createLibrary(db); const books: Array = []; if (args.values.download === "all") { books.push(...(await library.getBooks())); } else { if (URL.canParse(args.values.download!)) { await library.add(args.values.download!); } const book = await library.get(Number(args.values.download!)); if (!book) { process.exit(1); } books.push(book); } for (const book of books) { const browser = await createBrowser({ db }); const platform = createPlatform({ platform: book.platform, db, browser, }); const dir = `${args.values["out-dir"]!}/${book.id}`; await platform.download(dir, book); await library.archive(dir, book, { outDir: args.values["out-dir"]!, outAuthorsLimit: Number(args.values["out-authors-limit"]!), }); await browser.close(); } }, }, json: { type: "boolean", }, version: { type: "boolean", short: "v", run() { console.log(pkg.version); }, }, help: { type: "boolean", short: "h", run() { console.log( [ "Available options:", ...Object.entries(options).map((option) => [ ` --${option[0]}`, "short" in option[1] && ` -${option[1].short}`, option[1].type === "string" && "=", ] .filter(Boolean) .join(""), ), ].join("\n"), ); }, }, } as const; const args = util.parseArgs({ options }); if (args.values.json) { console.dir = function dir(arrayOrObject) { for (const obj of [arrayOrObject].flat()) { console.log(JSON.stringify(obj)); } }; } for (const option of Object.keys(options)) { if (args.values[option] && typeof options[option].run === "function") { await options[option].run(); process.exit(); } } options.help.run();