@iyexin/mio-android-tools 0.0.0-stage → 0.1.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/dist/exec.js ADDED
@@ -0,0 +1,67 @@
1
+ import { spawn } from "node:child_process";
2
+ import { MioToolError } from "./errors.js";
3
+ /**
4
+ * Run a child process and capture stdout/stderr.
5
+ *
6
+ * The caller is responsible for interpreting a non-zero exit code. Spawn
7
+ * failures and timeouts are surfaced as MioToolError.
8
+ */
9
+ export async function run(file, args, options = {}) {
10
+ const timeoutMs = options.timeoutMs ?? 120_000;
11
+ return await new Promise((resolve, reject) => {
12
+ let settled = false;
13
+ let timedOut = false;
14
+ let stdout = "";
15
+ let stderr = "";
16
+ const child = spawn(file, args, {
17
+ cwd: options.cwd,
18
+ env: { ...process.env, ...options.env },
19
+ windowsHide: true,
20
+ stdio: ["ignore", "pipe", "pipe"],
21
+ });
22
+ const finish = (result) => {
23
+ if (settled)
24
+ return;
25
+ settled = true;
26
+ clearTimeout(timer);
27
+ resolve(result);
28
+ };
29
+ const fail = (error) => {
30
+ if (settled)
31
+ return;
32
+ settled = true;
33
+ clearTimeout(timer);
34
+ reject(error);
35
+ };
36
+ const timer = setTimeout(() => {
37
+ timedOut = true;
38
+ child.kill();
39
+ }, timeoutMs);
40
+ child.stdout?.setEncoding("utf8");
41
+ child.stderr?.setEncoding("utf8");
42
+ child.stdout?.on("data", (chunk) => {
43
+ stdout += chunk;
44
+ });
45
+ child.stderr?.on("data", (chunk) => {
46
+ stderr += chunk;
47
+ });
48
+ child.on("error", (error) => {
49
+ fail(new MioToolError("SPAWN_FAILED", `Failed to start ${file}: ${error.message}`, {
50
+ cause: error,
51
+ stdout,
52
+ stderr,
53
+ }));
54
+ });
55
+ child.on("close", (code) => {
56
+ if (timedOut) {
57
+ fail(new MioToolError("TIMEOUT", `${file} timed out after ${timeoutMs}ms`, {
58
+ stdout,
59
+ stderr,
60
+ }));
61
+ return;
62
+ }
63
+ finish({ code: code ?? -1, stdout, stderr });
64
+ });
65
+ });
66
+ }
67
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { MioToolError } from "./errors.js";
2
+ export type { MioToolErrorCode, MioToolErrorOptions } from "./errors.js";
3
+ export { discoverAndroidTools, describeAndroidTools, type AndroidTools, type DiscoverOptions, } from "./discover.js";
4
+ export { alignApk, checkAlignment, type AlignOptions, type AlignmentCheck, type PageSize, } from "./zipalign.js";
5
+ export { signApkWithApksigner, verifyApkWithApksigner, buildSignArgs, parseVerifyOutput, type SignApkWithApksignerOptions, type VerifyApkOptions, type VerifyResult, type SignerCertificate, } from "./apksigner.js";
6
+ export { ensureDebugKeystore, type DebugKeystoreOptions } from "./keystore.js";
7
+ export { parseAxml, patchManifestAxml, type AxmlAttribute, type AxmlDocument, type AxmlElement, type ManifestPatch, } from "./axml.js";
8
+ export { injectApk, type InjectApkOptions, type InjectApkResult, } from "./apk.js";
9
+ export { injectWindowsExe, type InjectWindowsExeOptions, type InjectWindowsExeResult, } from "./windows.js";
10
+ export { signApk, verifyApk, type SignApkOptions, type SignResult, } from "./signing.js";
11
+ export { installToolBundle, platformKeyOf, type InstallToolBundleOptions, type InstalledToolBundle, type ToolBundleManifest, type ToolBundlePlatform, } from "./tool-bundle.js";
12
+ export { run, type ExecOptions, type ExecResult } from "./exec.js";
13
+ export { listZipEntries, extractZip, readZipEntry } from "./zip.js";
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ export { MioToolError } from "./errors.js";
2
+ export { discoverAndroidTools, describeAndroidTools, } from "./discover.js";
3
+ export { alignApk, checkAlignment, } from "./zipalign.js";
4
+ export { signApkWithApksigner, verifyApkWithApksigner, buildSignArgs, parseVerifyOutput, } from "./apksigner.js";
5
+ export { ensureDebugKeystore } from "./keystore.js";
6
+ export { parseAxml, patchManifestAxml, } from "./axml.js";
7
+ export { injectApk, } from "./apk.js";
8
+ export { injectWindowsExe, } from "./windows.js";
9
+ export { signApk, verifyApk, } from "./signing.js";
10
+ export { installToolBundle, platformKeyOf, } from "./tool-bundle.js";
11
+ export { run } from "./exec.js";
12
+ export { listZipEntries, extractZip, readZipEntry } from "./zip.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,QAAQ,EACR,cAAc,GAIf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,GAKlB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAA6B,MAAM,eAAe,CAAC;AAE/E,OAAO,EACL,SAAS,EACT,iBAAiB,GAKlB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,SAAS,GAGV,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,gBAAgB,GAGjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,OAAO,EACP,SAAS,GAGV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,iBAAiB,EACjB,aAAa,GAKd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,GAAG,EAAqC,MAAM,WAAW,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { AndroidTools } from "./discover.js";
2
+ export interface DebugKeystoreOptions {
3
+ /** Where to create the keystore. */
4
+ path: string;
5
+ /** Defaults to "android"; only for debug builds. */
6
+ password?: string;
7
+ /** Defaults to "mio-debug". */
8
+ alias?: string;
9
+ /** Defaults to "CN=Mio Debug, O=Mio, C=CN". */
10
+ distinguishedName?: string;
11
+ }
12
+ /**
13
+ * Create a debug keystore if it does not exist yet.
14
+ *
15
+ * Never use this key for release artifacts. Release keys are supplied by the
16
+ * developer and must not be generated or stored by Mio.
17
+ */
18
+ export declare function ensureDebugKeystore(tools: AndroidTools, options: DebugKeystoreOptions): Promise<{
19
+ path: string;
20
+ alias: string;
21
+ password: string;
22
+ }>;
@@ -0,0 +1,65 @@
1
+ import { access, mkdir } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { dirname } from "node:path";
4
+ import { MioToolError } from "./errors.js";
5
+ import { run } from "./exec.js";
6
+ async function exists(path) {
7
+ try {
8
+ await access(path, constants.F_OK);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ /**
16
+ * Create a debug keystore if it does not exist yet.
17
+ *
18
+ * Never use this key for release artifacts. Release keys are supplied by the
19
+ * developer and must not be generated or stored by Mio.
20
+ */
21
+ export async function ensureDebugKeystore(tools, options) {
22
+ const password = options.password ?? "android";
23
+ const alias = options.alias ?? "mio-debug";
24
+ if (await exists(options.path)) {
25
+ return { path: options.path, alias, password };
26
+ }
27
+ if (!tools.keytool) {
28
+ throw new MioToolError("KEYTOOL_NOT_FOUND", "keytool is required to generate a debug keystore but was not found.", {
29
+ details: "Use a JDK/JRE that includes keytool, or provide an existing debug keystore.",
30
+ });
31
+ }
32
+ await mkdir(dirname(options.path), { recursive: true });
33
+ const args = [
34
+ "-genkeypair",
35
+ "-keystore",
36
+ options.path,
37
+ "-storetype",
38
+ "PKCS12",
39
+ "-alias",
40
+ alias,
41
+ "-keyalg",
42
+ "RSA",
43
+ "-keysize",
44
+ "2048",
45
+ "-validity",
46
+ "10000",
47
+ "-storepass",
48
+ password,
49
+ "-keypass",
50
+ password,
51
+ "-dname",
52
+ options.distinguishedName ?? "CN=Mio Debug, O=Mio, C=CN",
53
+ "-noprompt",
54
+ ];
55
+ const result = await run(tools.keytool, args, { timeoutMs: 120_000 });
56
+ if (result.code !== 0) {
57
+ throw new MioToolError("KEYTOOL_FAILED", "keytool failed to create the debug keystore", {
58
+ stdout: result.stdout,
59
+ stderr: result.stderr,
60
+ details: `exit code ${result.code}`,
61
+ });
62
+ }
63
+ return { path: options.path, alias, password };
64
+ }
65
+ //# sourceMappingURL=keystore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keystore.js","sourceRoot":"","sources":["../src/keystore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAchC,KAAK,UAAU,MAAM,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,KAAmB,EACnB,OAA6B;IAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;IAE3C,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,IAAI,YAAY,CACpB,mBAAmB,EACnB,qEAAqE,EACrE;YACE,OAAO,EAAE,6EAA6E;SACvF,CACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,MAAM,IAAI,GAAG;QACX,aAAa;QACb,WAAW;QACX,OAAO,CAAC,IAAI;QACZ,YAAY;QACZ,QAAQ;QACR,QAAQ;QACR,KAAK;QACL,SAAS;QACT,KAAK;QACL,UAAU;QACV,MAAM;QACN,WAAW;QACX,OAAO;QACP,YAAY;QACZ,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,OAAO,CAAC,iBAAiB,IAAI,2BAA2B;QACxD,WAAW;KACZ,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,6CAA6C,EAAE;YACtF,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,aAAa,MAAM,CAAC,IAAI,EAAE;SACpC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type AndroidTools } from "./discover.js";
2
+ import { type SignApkWithApksignerOptions, type VerifyResult } from "./apksigner.js";
3
+ import { type PageSize } from "./zipalign.js";
4
+ export interface SignApkOptions extends Omit<SignApkWithApksignerOptions, "input" | "output"> {
5
+ input: string;
6
+ output: string;
7
+ /** Reuse an already discovered toolchain; otherwise discover it. */
8
+ tools?: AndroidTools;
9
+ /** 16 KiB by default (Android 15+). Use 4 for older build-tools. */
10
+ pageSize?: PageSize;
11
+ }
12
+ export interface SignResult {
13
+ output: string;
14
+ tools: AndroidTools;
15
+ verify: VerifyResult;
16
+ }
17
+ /**
18
+ * Align, sign, and verify an APK.
19
+ *
20
+ * This is the only supported high-level Android signing entry point: alignment
21
+ * must happen before apksigner, and the result must be verified before it is
22
+ * treated as a build artifact.
23
+ */
24
+ export declare function signApk(options: SignApkOptions): Promise<SignResult>;
25
+ export declare function verifyApk(apk: string, options?: {
26
+ tools?: AndroidTools;
27
+ minSdkVersion?: number;
28
+ }): Promise<VerifyResult>;
@@ -0,0 +1,72 @@
1
+ import { access, copyFile, mkdir, mkdtemp, rm } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { discoverAndroidTools } from "./discover.js";
6
+ import { MioToolError } from "./errors.js";
7
+ import { signApkWithApksigner, verifyApkWithApksigner, } from "./apksigner.js";
8
+ import { alignApk } from "./zipalign.js";
9
+ async function exists(path) {
10
+ try {
11
+ await access(path, constants.F_OK);
12
+ return true;
13
+ }
14
+ catch {
15
+ return false;
16
+ }
17
+ }
18
+ /**
19
+ * Align, sign, and verify an APK.
20
+ *
21
+ * This is the only supported high-level Android signing entry point: alignment
22
+ * must happen before apksigner, and the result must be verified before it is
23
+ * treated as a build artifact.
24
+ */
25
+ export async function signApk(options) {
26
+ const tools = options.tools ?? (await discoverAndroidTools());
27
+ const input = resolve(options.input);
28
+ const output = resolve(options.output);
29
+ if (!(await exists(input))) {
30
+ throw new MioToolError("MISSING_FILE", `Input APK does not exist: ${input}`);
31
+ }
32
+ if (input === output) {
33
+ throw new MioToolError("INVALID_ARGUMENT", "Input and output APK must be different files.", { details: "Write the signed artifact to a new path so a failed build cannot destroy the input." });
34
+ }
35
+ await mkdir(dirname(output), { recursive: true });
36
+ const tempDir = await mkdtemp(join(tmpdir(), "mio-sign-"));
37
+ const aligned = join(tempDir, "aligned.apk");
38
+ const signed = join(tempDir, "signed.apk");
39
+ try {
40
+ await alignApk(tools, input, aligned, {
41
+ pageSize: options.pageSize ?? 16,
42
+ verbose: options.verbose,
43
+ });
44
+ await signApkWithApksigner(tools, {
45
+ ...options,
46
+ input: aligned,
47
+ output: signed,
48
+ });
49
+ const verify = await verifyApkWithApksigner(tools, signed, {
50
+ minSdkVersion: options.minSdkVersion,
51
+ });
52
+ if (!verify.verified) {
53
+ throw new MioToolError("APKSIGNER_VERIFY_FAILED", "Signed APK did not verify", {
54
+ stdout: verify.raw,
55
+ details: `exit code ${verify.exitCode}`,
56
+ });
57
+ }
58
+ // Only publish the output after it has passed verification.
59
+ await copyFile(signed, output);
60
+ return { output, tools, verify };
61
+ }
62
+ finally {
63
+ await rm(tempDir, { recursive: true, force: true });
64
+ }
65
+ }
66
+ export async function verifyApk(apk, options = {}) {
67
+ const tools = options.tools ?? (await discoverAndroidTools());
68
+ return await verifyApkWithApksigner(tools, resolve(apk), {
69
+ minSdkVersion: options.minSdkVersion,
70
+ });
71
+ }
72
+ //# sourceMappingURL=signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { type AndroidTools } from "./discover.js";
2
+ export interface ToolBundlePlatform {
3
+ /** Archive URL (http:, https:, or file:). */
4
+ url: string;
5
+ /** SHA-256 of the archive. */
6
+ sha256: string;
7
+ /** Optional expected archive size in bytes. */
8
+ size?: number;
9
+ /** Number of leading path segments to strip during extraction. Default: 1. */
10
+ strip?: number;
11
+ }
12
+ export interface ToolBundleManifest {
13
+ schemaVersion: 1;
14
+ latest: string;
15
+ bundles: Record<string, {
16
+ platforms: Record<string, ToolBundlePlatform>;
17
+ }>;
18
+ }
19
+ export interface InstallToolBundleOptions {
20
+ /** Manifest object, local path, or http(s)/file URL. */
21
+ manifest: ToolBundleManifest | string;
22
+ /** Defaults to manifest.latest. */
23
+ version?: string;
24
+ /** Defaults to `${process.platform}-${process.arch}`. */
25
+ platform?: string;
26
+ /** Defaults to ~/.mio/tools/android. */
27
+ cacheDir?: string;
28
+ /** Defaults to HTTPS_PROXY/HTTP_PROXY/ALL_PROXY. */
29
+ proxy?: string;
30
+ /** Re-download even if a cached bundle exists. */
31
+ force?: boolean;
32
+ }
33
+ export interface InstalledToolBundle {
34
+ tools: AndroidTools;
35
+ dir: string;
36
+ version: string;
37
+ platform: string;
38
+ }
39
+ declare function platformKeyOf(platform: NodeJS.Platform, arch: string): string;
40
+ /**
41
+ * Download, verify, extract, and cache a Mio Android tools bundle.
42
+ *
43
+ * The bundle is a .tar.gz containing apksigner.jar, zipalign[.exe], and
44
+ * optionally jre/. The archive is authenticated by SHA-256 before extraction.
45
+ */
46
+ export declare function installToolBundle(options: InstallToolBundleOptions): Promise<InstalledToolBundle>;
47
+ export { platformKeyOf };
@@ -0,0 +1,204 @@
1
+ import { createHash } from "node:crypto";
2
+ import { access, mkdir, mkdtemp, readFile, rename, rm, writeFile } from "node:fs/promises";
3
+ import { constants } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { dirname, join } from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import * as tar from "tar";
8
+ import { ProxyAgent, fetch as undiciFetch } from "undici";
9
+ import { discoverAndroidTools } from "./discover.js";
10
+ import { MioToolError } from "./errors.js";
11
+ const MANIFEST_FILE = ".mio-tools.json";
12
+ function platformKeyOf(platform, arch) {
13
+ return `${platform}-${arch}`;
14
+ }
15
+ function defaultCacheDir() {
16
+ return join(homedir(), ".mio", "tools", "android");
17
+ }
18
+ function defaultProxy() {
19
+ return (process.env.HTTPS_PROXY ??
20
+ process.env.https_proxy ??
21
+ process.env.HTTP_PROXY ??
22
+ process.env.http_proxy ??
23
+ process.env.ALL_PROXY ??
24
+ process.env.all_proxy);
25
+ }
26
+ async function exists(path) {
27
+ try {
28
+ await access(path, constants.F_OK);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ function sha256(buffer) {
36
+ return createHash("sha256").update(buffer).digest("hex");
37
+ }
38
+ async function fetchBuffer(url, proxy) {
39
+ if (url.startsWith("file:")) {
40
+ return await readFile(fileURLToPath(url));
41
+ }
42
+ const init = {};
43
+ if (proxy) {
44
+ init.dispatcher = new ProxyAgent(proxy);
45
+ }
46
+ let response;
47
+ try {
48
+ response = await undiciFetch(url, init);
49
+ }
50
+ catch (error) {
51
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", `Failed to download ${url}`, {
52
+ cause: error,
53
+ details: proxy ? `proxy: ${proxy}` : undefined,
54
+ });
55
+ }
56
+ if (!response.ok) {
57
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", `Failed to download ${url}: HTTP ${response.status}`);
58
+ }
59
+ return Buffer.from(await response.arrayBuffer());
60
+ }
61
+ async function loadManifest(source, proxy) {
62
+ if (typeof source !== "string")
63
+ return source;
64
+ const buffer = source.startsWith("http:") || source.startsWith("https:") || source.startsWith("file:")
65
+ ? await fetchBuffer(source, proxy)
66
+ : await readFile(source);
67
+ let parsed;
68
+ try {
69
+ parsed = JSON.parse(buffer.toString("utf8"));
70
+ }
71
+ catch (error) {
72
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", "Tool bundle manifest is not valid JSON", {
73
+ cause: error,
74
+ });
75
+ }
76
+ const manifest = parsed;
77
+ if (manifest.schemaVersion !== 1 || typeof manifest.latest !== "string" || !manifest.bundles) {
78
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", "Unsupported tool bundle manifest");
79
+ }
80
+ return manifest;
81
+ }
82
+ function selectBundle(manifest, version, platform) {
83
+ const bundle = manifest.bundles[version];
84
+ if (!bundle) {
85
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", `Unknown tool bundle version: ${version}`);
86
+ }
87
+ const entry = bundle.platforms[platform];
88
+ if (!entry) {
89
+ throw new MioToolError("BUNDLE_DOWNLOAD_FAILED", `Tool bundle ${version} has no build for ${platform}`, { details: `available: ${Object.keys(bundle.platforms).join(", ")}` });
90
+ }
91
+ return entry;
92
+ }
93
+ async function readMarker(path) {
94
+ try {
95
+ const parsed = JSON.parse(await readFile(path, "utf8"));
96
+ if (typeof parsed.version !== "string" ||
97
+ typeof parsed.platform !== "string" ||
98
+ typeof parsed.sha256 !== "string") {
99
+ return undefined;
100
+ }
101
+ return {
102
+ version: parsed.version,
103
+ platform: parsed.platform,
104
+ sha256: parsed.sha256,
105
+ installedAt: parsed.installedAt ?? "",
106
+ };
107
+ }
108
+ catch {
109
+ return undefined;
110
+ }
111
+ }
112
+ async function validateBundleLayout(dir) {
113
+ const apksigner = [join(dir, "apksigner.jar"), join(dir, "lib", "apksigner.jar")];
114
+ const zipalign = process.platform === "win32"
115
+ ? [join(dir, "zipalign.exe"), join(dir, "bin", "zipalign.exe")]
116
+ : [join(dir, "zipalign"), join(dir, "bin", "zipalign")];
117
+ for (const candidate of apksigner) {
118
+ if (await exists(candidate))
119
+ break;
120
+ if (candidate === apksigner[apksigner.length - 1]) {
121
+ throw new MioToolError("BUNDLE_EXTRACT_FAILED", "Tool bundle is missing apksigner.jar");
122
+ }
123
+ }
124
+ for (const candidate of zipalign) {
125
+ if (await exists(candidate))
126
+ break;
127
+ if (candidate === zipalign[zipalign.length - 1]) {
128
+ throw new MioToolError("BUNDLE_EXTRACT_FAILED", "Tool bundle is missing zipalign");
129
+ }
130
+ }
131
+ }
132
+ /**
133
+ * Download, verify, extract, and cache a Mio Android tools bundle.
134
+ *
135
+ * The bundle is a .tar.gz containing apksigner.jar, zipalign[.exe], and
136
+ * optionally jre/. The archive is authenticated by SHA-256 before extraction.
137
+ */
138
+ export async function installToolBundle(options) {
139
+ const proxy = options.proxy ?? defaultProxy();
140
+ const manifest = await loadManifest(options.manifest, proxy);
141
+ const version = options.version ?? manifest.latest;
142
+ const platform = options.platform ?? platformKeyOf(process.platform, process.arch);
143
+ const entry = selectBundle(manifest, version, platform);
144
+ const cacheDir = options.cacheDir ?? defaultCacheDir();
145
+ const dest = join(cacheDir, version, platform);
146
+ const markerPath = join(dest, MANIFEST_FILE);
147
+ await mkdir(cacheDir, { recursive: true });
148
+ if (!options.force) {
149
+ const marker = await readMarker(markerPath);
150
+ if (marker?.sha256 === entry.sha256 && (await exists(dest))) {
151
+ try {
152
+ const tools = await discoverAndroidTools({
153
+ env: { ...process.env, MIO_ANDROID_TOOLS_DIR: dest },
154
+ });
155
+ return { tools, dir: dest, version, platform };
156
+ }
157
+ catch {
158
+ // Cached bundle is incomplete or corrupt; fall through and reinstall.
159
+ await rm(dest, { recursive: true, force: true });
160
+ }
161
+ }
162
+ }
163
+ const tempRoot = await mkdtemp(join(cacheDir, ".download-"));
164
+ const archivePath = join(tempRoot, "tools.tar.gz");
165
+ const extractDir = join(tempRoot, "extracted");
166
+ try {
167
+ await mkdir(extractDir, { recursive: true });
168
+ const archive = await fetchBuffer(entry.url, proxy);
169
+ if (entry.size !== undefined && archive.length !== entry.size) {
170
+ throw new MioToolError("BUNDLE_CHECKSUM_FAILED", `Tool bundle size mismatch: expected ${entry.size}, got ${archive.length}`);
171
+ }
172
+ const digest = sha256(archive);
173
+ if (digest !== entry.sha256.toLowerCase()) {
174
+ throw new MioToolError("BUNDLE_CHECKSUM_FAILED", `Tool bundle SHA-256 mismatch: expected ${entry.sha256}, got ${digest}`);
175
+ }
176
+ await writeFile(archivePath, archive);
177
+ await tar.x({
178
+ file: archivePath,
179
+ cwd: extractDir,
180
+ strip: entry.strip ?? 1,
181
+ strict: true,
182
+ preservePaths: false,
183
+ });
184
+ await validateBundleLayout(extractDir);
185
+ await rm(dest, { recursive: true, force: true });
186
+ await mkdir(dirname(dest), { recursive: true });
187
+ await rename(extractDir, dest);
188
+ await writeFile(markerPath, JSON.stringify({
189
+ version,
190
+ platform,
191
+ sha256: entry.sha256,
192
+ installedAt: new Date().toISOString(),
193
+ }, null, 2));
194
+ const tools = await discoverAndroidTools({
195
+ env: { ...process.env, MIO_ANDROID_TOOLS_DIR: dest },
196
+ });
197
+ return { tools, dir: dest, version, platform };
198
+ }
199
+ finally {
200
+ await rm(tempRoot, { recursive: true, force: true });
201
+ }
202
+ }
203
+ export { platformKeyOf };
204
+ //# sourceMappingURL=tool-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-bundle.js","sourceRoot":"","sources":["../src/tool-bundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface InjectWindowsExeOptions {
2
+ templateExe: string;
3
+ asar: string;
4
+ output: string;
5
+ resourceName?: string;
6
+ language?: number;
7
+ appName?: string;
8
+ version?: string;
9
+ /** Optional PNG used to replace the executable's icon group. */
10
+ icon?: string;
11
+ }
12
+ export interface InjectWindowsExeResult {
13
+ output: string;
14
+ asarBytes: number;
15
+ }
16
+ /**
17
+ * Inject app.asar as an RT_RCDATA resource into a Windows executable.
18
+ *
19
+ * The Flutter shell reads it with FindResourceW/LoadResource. This does not
20
+ * sign the executable; Authenticode must be applied after injection.
21
+ */
22
+ export declare function injectWindowsExe(options: InjectWindowsExeOptions): Promise<InjectWindowsExeResult>;