From 4370a68dce4d031361a7942e5e00617fabb89166 Mon Sep 17 00:00:00 2001 From: user Date: Mon, 20 Jul 2026 14:14:49 -0300 Subject: [PATCH] feat: extract module paths from code.js via fileFinishedImporting, rename extract output to source paths --- src/update/shared.ts | 1 + src/update/tasks/code.ts | 41 ++++++++++++++++++++++++++++++++--- src/update/tasks/decompile.ts | 18 +++++++++++++-- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/update/shared.ts b/src/update/shared.ts index 6d4c3028c1e..931fdf8b5e7 100644 --- a/src/update/shared.ts +++ b/src/update/shared.ts @@ -7,6 +7,7 @@ export const workFolder = "tmp"; export const apksFolder = join(workFolder, "apks"); export const codePath = join(workFolder, "code.js"); export const modulesPath = join(workFolder, "modules"); +export const modulePathsDest = join("..", "data", "module-paths.json"); export const apkSplits = ["base", "config.hdpi", "config.xxhdpi"] as const; export const oprevFiles = ["source.jsonl"] as const; diff --git a/src/update/tasks/code.ts b/src/update/tasks/code.ts index 8bcc6036fe7..9936c872432 100644 --- a/src/update/tasks/code.ts +++ b/src/update/tasks/code.ts @@ -2,9 +2,20 @@ import { mkdir, rm, readdir, stat } from "node:fs/promises"; import { join as pathJoin } from "node:path"; import { commit } from "../git"; import type { Progress } from "../progress"; -import { commitAnyway, cuteVersion, modulesPath } from "../shared"; +import { commitAnyway, cuteVersion, modulePathsDest, modulesPath } from "../shared"; import { join, sortEntries } from "../utils"; +function extractModuleId(filename: string): number | undefined { + const m1 = filename.match(/^module_(\d+)\.js$/); + if (m1) return Number.parseInt(m1[1], 10); + const m2 = filename.match(/^(\d+)_/); + if (m2) return Number.parseInt(m2[1], 10); +} + +function sanitizePath(p: string): string { + return p.replace(/\\/g, "/").replace(/^\.\.\//, "").replace(/[<>:"|?*]/g, "_"); +} + export default async function code(progress: Progress, _code: string[]) { progress.start("code_getting"); @@ -12,6 +23,15 @@ export default async function code(progress: Progress, _code: string[]) { throw new Error(`Modules directory not found at ${modulesPath}`); } + const modulePaths = new Map(); + try { + const arr: { id: number; path: string }[] = await Bun.file(modulePathsDest).json(); + for (const { id, path } of arr) modulePaths.set(id, path); + console.log(`Loaded ${modulePaths.size} module path mappings`); + } catch { + console.log("No module-paths.json found, using extract names"); + } + async function scanDir(dir: string, basePath: string): Promise> { const files = new Map(); const entries = await readdir(dir, { withFileTypes: true }); @@ -31,9 +51,24 @@ export default async function code(progress: Progress, _code: string[]) { const rawFiles = await scanDir(modulesPath, modulesPath); + function resolveDest(relativePath: string): string { + const id = extractModuleId(relativePath); + if (id !== undefined) { + const sourcePath = modulePaths.get(id); + if (sourcePath) return sanitizePath(sourcePath); + } + return relativePath; + } + + const files = new Map(); + for (const [relativePath, fileSize] of rawFiles) { + const dest = resolveDest(relativePath); + if (!files.has(dest)) files.set(dest, fileSize); + } + await Bun.write( "../data/source.jsonl", - sortEntries([...rawFiles.entries()]) + sortEntries([...files.entries()]) .map(([file, size]) => `{ "file": ${JSON.stringify(file)}, "size": ${size} }`) .join("\n"), ); @@ -48,7 +83,7 @@ export default async function code(progress: Progress, _code: string[]) { await Promise.all( [...rawFiles.entries()].map(async ([relativePath]) => { - const dest = join(filePrefix, relativePath); + const dest = join(filePrefix, resolveDest(relativePath)); await mkdir(pathJoin(dest, ".."), { recursive: true }); await Bun.write(dest, Bun.file(join(modulesPath, relativePath))); }), diff --git a/src/update/tasks/decompile.ts b/src/update/tasks/decompile.ts index c8d4048c0d6..cf2c1d89b40 100644 --- a/src/update/tasks/decompile.ts +++ b/src/update/tasks/decompile.ts @@ -1,7 +1,7 @@ import { exists } from "node:fs/promises"; import { commit } from "../git"; import type { Progress } from "../progress"; -import { codePath, commitAnyway, cuteVersion, modulesPath, workFolder } from "../shared"; +import { codePath, commitAnyway, cuteVersion, modulePathsDest, modulesPath, workFolder } from "../shared"; import { handleShellErr, join } from "../utils"; const gzipWorkerURL = new URL("decompile-gzip.ts", import.meta.url).href; @@ -47,6 +47,20 @@ export default async function decompile(progress: Progress, pathToBundle: string progress.update("decompile_decompiling", true); + progress.start("decompile_paths"); + const codeJs = await Bun.file(codePath).text(); + const modulePaths: { id: number; path: string }[] = []; + const moduleSections = codeJs.split(/\/\/ === Module (\d+): .+ ===\n?/); + for (let i = 1; i < moduleSections.length; i += 2) { + const modId = Number.parseInt(moduleSections[i], 10); + const content = moduleSections[i + 1] || ""; + const m = content.match(/fileFinishedImporting\("([^"]+)"\)/); + if (m) modulePaths.push({ id: modId, path: m[1] }); + } + await Bun.write(modulePathsDest, JSON.stringify(modulePaths)); + console.log(`Extracted ${modulePaths.length} module paths`); + progress.update("decompile_paths", true); + if (process.env.NODE_ENV !== "test" && !commitAnyway) { const gzFile = "code.js.gz"; @@ -54,7 +68,7 @@ export default async function decompile(progress: Progress, pathToBundle: string progress.start("decompile_gzip"); gzipper.addEventListener("message", async ({ data }) => { if (data === true) { - await commit([gzFile], `chore: update decompiled code for ${cuteVersion}`); + await commit([gzFile, "module-paths.json"], `chore: update decompiled code for ${cuteVersion}`); progress.update("decompile_gzip", true); } gzipper.terminate();