@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/axml.js ADDED
@@ -0,0 +1,248 @@
1
+ import { Buffer } from "node:buffer";
2
+ const RES_XML_TYPE = 0x0003;
3
+ const RES_STRING_POOL_TYPE = 0x0001;
4
+ const RES_XML_START_ELEMENT_TYPE = 0x0102;
5
+ const NO_INDEX = 0xffffffff;
6
+ const TYPE_STRING = 0x03;
7
+ const TYPE_INT_DEC = 0x10;
8
+ export function parseAxml(buffer) {
9
+ const stringPool = findStringPool(buffer);
10
+ const strings = decodeStringPool(buffer, stringPool);
11
+ const encoding = (buffer.readUInt32LE(stringPool.offset + 16) & 0x100) !== 0 ? "utf8" : "utf16";
12
+ const elements = [];
13
+ let offset = buffer.readUInt16LE(2);
14
+ while (offset + 8 <= buffer.length) {
15
+ const type = buffer.readUInt16LE(offset);
16
+ const headerSize = buffer.readUInt16LE(offset + 2);
17
+ const size = buffer.readUInt32LE(offset + 4);
18
+ if (size < 8 || offset + size > buffer.length)
19
+ break;
20
+ if (type === RES_XML_START_ELEMENT_TYPE) {
21
+ const attrExt = offset + headerSize;
22
+ const nameIndex = buffer.readUInt32LE(attrExt + 4);
23
+ const attributeStart = buffer.readUInt16LE(attrExt + 8);
24
+ const attributeSize = buffer.readUInt16LE(attrExt + 10);
25
+ const attributeCount = buffer.readUInt16LE(attrExt + 12);
26
+ const attributes = [];
27
+ let attributeOffset = attrExt + attributeStart;
28
+ for (let index = 0; index < attributeCount; index += 1) {
29
+ attributes.push({
30
+ chunkOffset: offset,
31
+ attributeOffset,
32
+ namespace: buffer.readUInt32LE(attributeOffset),
33
+ name: buffer.readUInt32LE(attributeOffset + 4),
34
+ rawValue: buffer.readUInt32LE(attributeOffset + 8),
35
+ valueType: buffer[attributeOffset + 15] ?? 0,
36
+ data: buffer.readUInt32LE(attributeOffset + 16),
37
+ });
38
+ attributeOffset += attributeSize;
39
+ }
40
+ elements.push({
41
+ chunkOffset: offset,
42
+ name: strings[nameIndex] ?? "",
43
+ attributes,
44
+ });
45
+ }
46
+ offset += size;
47
+ }
48
+ return { strings, elements, encoding };
49
+ }
50
+ /**
51
+ * Patch a binary AndroidManifest.xml.
52
+ *
53
+ * The template's MainActivity class is intentionally qualified with the
54
+ * template package (dev.mio.mio_shell.MainActivity). The manifest package and
55
+ * package-derived permission/authority strings are rewritten, but that class
56
+ * name must remain untouched so Android can still resolve it.
57
+ */
58
+ export function patchManifestAxml(buffer, patch) {
59
+ if (buffer.readUInt16LE(0) !== RES_XML_TYPE) {
60
+ throw new Error("not an Android binary XML document");
61
+ }
62
+ const document = parseAxml(buffer);
63
+ const manifest = document.elements.find((element) => element.name === "manifest");
64
+ if (!manifest)
65
+ throw new Error("AndroidManifest.xml has no manifest element");
66
+ const application = document.elements.find((element) => element.name === "application");
67
+ const packageAttribute = findAttribute(document, manifest, "package");
68
+ if (!packageAttribute)
69
+ throw new Error("AndroidManifest.xml has no package attribute");
70
+ const oldPackage = attributeString(document.strings, packageAttribute);
71
+ if (!oldPackage)
72
+ throw new Error("AndroidManifest.xml package is empty");
73
+ const versionCodeAttribute = findAttribute(document, manifest, "versionCode");
74
+ const versionNameAttribute = findAttribute(document, manifest, "versionName");
75
+ const labelAttribute = application ? findAttribute(document, application, "label") : undefined;
76
+ const activityClass = `${oldPackage}.MainActivity`;
77
+ const strings = document.strings.map((value) => {
78
+ if (value === activityClass)
79
+ return value;
80
+ if (value === oldPackage || value.startsWith(`${oldPackage}.`)) {
81
+ return value.replace(oldPackage, patch.packageName);
82
+ }
83
+ return value;
84
+ });
85
+ let nextString = strings.length;
86
+ if (patch.versionName !== undefined && versionNameAttribute) {
87
+ const index = nextString++;
88
+ strings.push(patch.versionName);
89
+ setAttributeString(buffer, versionNameAttribute, index);
90
+ }
91
+ if (patch.appName !== undefined && labelAttribute) {
92
+ const index = nextString++;
93
+ strings.push(patch.appName);
94
+ setAttributeString(buffer, labelAttribute, index);
95
+ }
96
+ if (patch.versionCode !== undefined && versionCodeAttribute) {
97
+ buffer.writeUInt32LE(patch.versionCode >>> 0, versionCodeAttribute.attributeOffset + 16);
98
+ buffer[versionCodeAttribute.attributeOffset + 15] = TYPE_INT_DEC;
99
+ }
100
+ return rebuildStringPool(buffer, strings);
101
+ }
102
+ function findAttribute(document, element, name) {
103
+ return element.attributes.find((attribute) => document.strings[attribute.name] === name);
104
+ }
105
+ function attributeString(strings, attribute) {
106
+ if (attribute.rawValue !== NO_INDEX && attribute.rawValue < strings.length) {
107
+ return strings[attribute.rawValue];
108
+ }
109
+ if (attribute.valueType === TYPE_STRING && attribute.data < strings.length) {
110
+ return strings[attribute.data];
111
+ }
112
+ return undefined;
113
+ }
114
+ function setAttributeString(buffer, attribute, index) {
115
+ buffer.writeUInt32LE(index, attribute.attributeOffset + 8);
116
+ const typed = attribute.attributeOffset + 12;
117
+ buffer.writeUInt16LE(8, typed);
118
+ buffer[typed + 2] = 0;
119
+ buffer[typed + 3] = TYPE_STRING;
120
+ buffer.writeUInt32LE(index, typed + 4);
121
+ }
122
+ function findStringPool(buffer) {
123
+ let offset = buffer.readUInt16LE(2);
124
+ while (offset + 8 <= buffer.length) {
125
+ const type = buffer.readUInt16LE(offset);
126
+ const headerSize = buffer.readUInt16LE(offset + 2);
127
+ const size = buffer.readUInt32LE(offset + 4);
128
+ if (type === RES_STRING_POOL_TYPE) {
129
+ const stringCount = buffer.readUInt32LE(offset + 8);
130
+ const styleCount = buffer.readUInt32LE(offset + 12);
131
+ const flags = buffer.readUInt32LE(offset + 16);
132
+ const stringsStart = buffer.readUInt32LE(offset + 20);
133
+ const stylesStart = buffer.readUInt32LE(offset + 24);
134
+ if (styleCount !== 0) {
135
+ throw new Error("AXML string pools with styles are not supported");
136
+ }
137
+ return { offset, headerSize, size, stringCount, styleCount, flags, stringsStart, stylesStart };
138
+ }
139
+ if (size < 8)
140
+ break;
141
+ offset += size;
142
+ }
143
+ throw new Error("AXML string pool not found");
144
+ }
145
+ function decodeStringPool(buffer, pool) {
146
+ const strings = [];
147
+ const utf8 = (pool.flags & 0x100) !== 0;
148
+ const table = pool.offset + pool.headerSize;
149
+ const dataStart = pool.offset + pool.stringsStart;
150
+ for (let index = 0; index < pool.stringCount; index += 1) {
151
+ const relative = buffer.readUInt32LE(table + index * 4);
152
+ let cursor = dataStart + relative;
153
+ if (utf8) {
154
+ const first = buffer.readUInt16LE(cursor);
155
+ cursor += 2;
156
+ if ((first & 0x8000) !== 0) {
157
+ cursor += 2;
158
+ }
159
+ let byteLength = buffer.readUInt16LE(cursor);
160
+ cursor += 2;
161
+ if ((byteLength & 0x8000) !== 0) {
162
+ byteLength = ((byteLength & 0x7fff) << 8) | buffer.readUInt16LE(cursor);
163
+ cursor += 2;
164
+ }
165
+ strings.push(buffer.toString("utf8", cursor, cursor + byteLength));
166
+ }
167
+ else {
168
+ const first = buffer.readUInt16LE(cursor);
169
+ cursor += 2;
170
+ let length = first;
171
+ if ((first & 0x8000) !== 0) {
172
+ length = ((first & 0x7fff) << 16) | buffer.readUInt16LE(cursor);
173
+ cursor += 2;
174
+ }
175
+ strings.push(buffer.toString("utf16le", cursor, cursor + length * 2));
176
+ }
177
+ }
178
+ return strings;
179
+ }
180
+ function rebuildStringPool(original, newStrings) {
181
+ const pool = findStringPool(original);
182
+ const utf8 = (pool.flags & 0x100) !== 0;
183
+ const encoded = [];
184
+ const offsets = [];
185
+ let dataLength = 0;
186
+ for (const value of newStrings) {
187
+ offsets.push(dataLength);
188
+ const item = encodeString(value, utf8);
189
+ encoded.push(item);
190
+ dataLength += item.length;
191
+ const padding = (4 - (dataLength % 4)) % 4;
192
+ if (padding > 0) {
193
+ encoded.push(Buffer.alloc(padding));
194
+ dataLength += padding;
195
+ }
196
+ }
197
+ const tableLength = newStrings.length * 4;
198
+ const chunkSize = 28 + tableLength + dataLength;
199
+ const chunk = Buffer.alloc(chunkSize);
200
+ chunk.writeUInt16LE(RES_STRING_POOL_TYPE, 0);
201
+ chunk.writeUInt16LE(28, 2);
202
+ chunk.writeUInt32LE(chunkSize, 4);
203
+ chunk.writeUInt32LE(newStrings.length, 8);
204
+ chunk.writeUInt32LE(0, 12);
205
+ chunk.writeUInt32LE(pool.flags, 16);
206
+ chunk.writeUInt32LE(28 + tableLength, 20);
207
+ chunk.writeUInt32LE(0, 24);
208
+ for (let index = 0; index < offsets.length; index += 1) {
209
+ chunk.writeUInt32LE(offsets[index] ?? 0, 28 + index * 4);
210
+ }
211
+ let cursor = 28 + tableLength;
212
+ for (const item of encoded) {
213
+ item.copy(chunk, cursor);
214
+ cursor += item.length;
215
+ }
216
+ const before = original.subarray(0, pool.offset);
217
+ const after = original.subarray(pool.offset + pool.size);
218
+ const result = Buffer.concat([before, chunk, after]);
219
+ result.writeUInt32LE(result.length, 4);
220
+ return result;
221
+ }
222
+ function encodeString(value, utf8) {
223
+ if (utf8) {
224
+ const bytes = Buffer.from(value, "utf8");
225
+ const length = value.length;
226
+ const lengthBytes = encodeUtf8Length(length);
227
+ const byteLengthBytes = encodeUtf8Length(bytes.length);
228
+ return Buffer.concat([lengthBytes, byteLengthBytes, bytes, Buffer.from([0])]);
229
+ }
230
+ const bytes = Buffer.from(value, "utf16le");
231
+ const length = value.length;
232
+ const lengthBytes = Buffer.alloc(length > 0x7fff ? 4 : 2);
233
+ if (length > 0x7fff) {
234
+ lengthBytes.writeUInt16LE(((length >> 16) & 0x7fff) | 0x8000, 0);
235
+ lengthBytes.writeUInt16LE(length & 0xffff, 2);
236
+ }
237
+ else {
238
+ lengthBytes.writeUInt16LE(length, 0);
239
+ }
240
+ return Buffer.concat([lengthBytes, bytes, Buffer.from([0, 0])]);
241
+ }
242
+ function encodeUtf8Length(length) {
243
+ if (length > 0x7f) {
244
+ return Buffer.from([((length >> 8) & 0x7f) | 0x80, length & 0xff]);
245
+ }
246
+ return Buffer.from([length]);
247
+ }
248
+ //# sourceMappingURL=axml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"axml.js","sourceRoot":"","sources":["../src/axml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ export interface AndroidTools {
2
+ /** Java executable. Absolute path when known, otherwise "java" from PATH. */
3
+ java: string;
4
+ /** apksigner jar (contains com.android.apksigner.ApkSignerTool). */
5
+ apksignerJar: string;
6
+ /** zipalign executable. */
7
+ zipalign: string;
8
+ /** keytool executable, when available. */
9
+ keytool?: string;
10
+ /** Where the tools came from. */
11
+ source: "env-bundle" | "android-sdk";
12
+ /** build-tools version, when source is android-sdk. */
13
+ buildToolsVersion?: string;
14
+ /** Android SDK root, when source is android-sdk. */
15
+ sdkRoot?: string;
16
+ /** JRE home, when the tools bundle contains one. */
17
+ jreHome?: string;
18
+ }
19
+ export interface DiscoverOptions {
20
+ /** Override for tests; defaults to process.env. */
21
+ env?: NodeJS.ProcessEnv;
22
+ /** Override for tests; defaults to process.platform. */
23
+ platform?: NodeJS.Platform;
24
+ }
25
+ /**
26
+ * Find a usable Android signing toolchain.
27
+ *
28
+ * Priority:
29
+ * 1. MIO_ANDROID_TOOLS_DIR (a downloaded/bundled toolchain)
30
+ * 2. ANDROID_HOME / ANDROID_SDK_ROOT / default SDK locations
31
+ */
32
+ export declare function discoverAndroidTools(options?: DiscoverOptions): Promise<AndroidTools>;
33
+ export declare function describeAndroidTools(tools: AndroidTools): string;
@@ -0,0 +1,239 @@
1
+ import { access, readdir } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+ import { MioToolError } from "./errors.js";
6
+ import { run } from "./exec.js";
7
+ const isWindows = (platform) => platform === "win32";
8
+ const javaName = (platform) => isWindows(platform) ? "java.exe" : "java";
9
+ const keytoolName = (platform) => isWindows(platform) ? "keytool.exe" : "keytool";
10
+ const zipalignName = (platform) => isWindows(platform) ? "zipalign.exe" : "zipalign";
11
+ async function exists(path) {
12
+ try {
13
+ await access(path, constants.F_OK);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ function candidateSdkRoots(env, platform) {
21
+ const roots = [
22
+ env.MIO_ANDROID_SDK,
23
+ env.ANDROID_HOME,
24
+ env.ANDROID_SDK_ROOT,
25
+ ];
26
+ if (platform === "win32") {
27
+ const localAppData = env.LOCALAPPDATA;
28
+ if (localAppData)
29
+ roots.push(join(localAppData, "Android", "Sdk"));
30
+ }
31
+ else if (platform === "darwin") {
32
+ roots.push(join(homedir(), "Library", "Android", "sdk"));
33
+ }
34
+ else {
35
+ roots.push(join(homedir(), "Android", "Sdk"));
36
+ roots.push(join(homedir(), "Android", "sdk"));
37
+ }
38
+ return [...new Set(roots.filter((root) => Boolean(root)))];
39
+ }
40
+ function compareVersions(a, b) {
41
+ const split = (value) => value.split(/[.-]/).map((part) => {
42
+ const parsed = Number.parseInt(part, 10);
43
+ return Number.isFinite(parsed) ? parsed : 0;
44
+ });
45
+ const left = split(a);
46
+ const right = split(b);
47
+ const length = Math.max(left.length, right.length);
48
+ for (let index = 0; index < length; index += 1) {
49
+ const delta = (left[index] ?? 0) - (right[index] ?? 0);
50
+ if (delta !== 0)
51
+ return delta;
52
+ }
53
+ return 0;
54
+ }
55
+ async function findJavaInHome(home, platform) {
56
+ if (!home)
57
+ return undefined;
58
+ const candidate = join(home, "bin", javaName(platform));
59
+ return (await exists(candidate)) ? candidate : undefined;
60
+ }
61
+ async function findJavaFromPath(platform) {
62
+ // Let the OS resolve "java" from PATH. Validate it once so discovery fails
63
+ // early with a useful error instead of at signing time.
64
+ try {
65
+ const result = await run("java", ["-version"], { timeoutMs: 10_000 });
66
+ if (result.code === 0)
67
+ return "java";
68
+ }
69
+ catch {
70
+ // ignore
71
+ }
72
+ return undefined;
73
+ }
74
+ async function resolveJava(env, platform, preferredHome) {
75
+ const fromBundle = await findJavaInHome(preferredHome, platform);
76
+ if (fromBundle) {
77
+ return { java: fromBundle, jreHome: preferredHome };
78
+ }
79
+ const fromMioHome = await findJavaInHome(env.MIO_JAVA_HOME, platform);
80
+ if (fromMioHome) {
81
+ return { java: fromMioHome, jreHome: env.MIO_JAVA_HOME };
82
+ }
83
+ const fromJavaHome = await findJavaInHome(env.JAVA_HOME, platform);
84
+ if (fromJavaHome) {
85
+ return { java: fromJavaHome, jreHome: env.JAVA_HOME };
86
+ }
87
+ const fromPath = await findJavaFromPath(platform);
88
+ if (fromPath) {
89
+ return { java: fromPath };
90
+ }
91
+ throw new MioToolError("JAVA_NOT_FOUND", "Java was not found. Install a JDK/JRE 17+ or place a JRE at <tools>/jre.", {
92
+ details: "Set MIO_JAVA_HOME/JAVA_HOME, put java on PATH, or point MIO_ANDROID_TOOLS_DIR at a tools bundle containing jre/.",
93
+ });
94
+ }
95
+ async function resolveKeytool(java, platform) {
96
+ if (java === "java") {
97
+ try {
98
+ const result = await run("keytool", ["-help"], { timeoutMs: 10_000 });
99
+ if (result.code === 0)
100
+ return "keytool";
101
+ }
102
+ catch {
103
+ return undefined;
104
+ }
105
+ return undefined;
106
+ }
107
+ const candidate = join(dirname(java), keytoolName(platform));
108
+ return (await exists(candidate)) ? candidate : undefined;
109
+ }
110
+ async function fromToolsDir(dir, env, platform) {
111
+ const apksignerCandidates = [
112
+ join(dir, "apksigner.jar"),
113
+ join(dir, "lib", "apksigner.jar"),
114
+ ];
115
+ const zipalignCandidates = [
116
+ join(dir, zipalignName(platform)),
117
+ join(dir, "bin", zipalignName(platform)),
118
+ ];
119
+ const apksignerJar = await firstExisting(apksignerCandidates);
120
+ const zipalign = await firstExisting(zipalignCandidates);
121
+ if (!apksignerJar || !zipalign) {
122
+ throw new MioToolError("INVALID_TOOLS_DIR", `MIO_ANDROID_TOOLS_DIR does not look like an Android tools bundle: ${dir}`, {
123
+ details: "Expected apksigner.jar (or lib/apksigner.jar), zipalign, and optionally jre/.",
124
+ });
125
+ }
126
+ const jreHomeCandidate = join(dir, "jre");
127
+ const jreHome = (await exists(join(jreHomeCandidate, "bin", javaName(platform))))
128
+ ? jreHomeCandidate
129
+ : undefined;
130
+ const { java, jreHome: resolvedJreHome } = await resolveJava(env, platform, jreHome);
131
+ const keytool = await resolveKeytool(java, platform);
132
+ return {
133
+ java,
134
+ apksignerJar,
135
+ zipalign,
136
+ keytool,
137
+ source: "env-bundle",
138
+ jreHome: resolvedJreHome,
139
+ };
140
+ }
141
+ async function firstExisting(candidates) {
142
+ for (const candidate of candidates) {
143
+ if (await exists(candidate))
144
+ return candidate;
145
+ }
146
+ return undefined;
147
+ }
148
+ async function findBuildTools(sdkRoot, platform) {
149
+ const buildToolsRoot = join(sdkRoot, "build-tools");
150
+ let versions;
151
+ try {
152
+ const entries = await readdir(buildToolsRoot, { withFileTypes: true });
153
+ versions = entries
154
+ .filter((entry) => entry.isDirectory())
155
+ .map((entry) => entry.name)
156
+ .sort((a, b) => compareVersions(b, a));
157
+ }
158
+ catch {
159
+ return undefined;
160
+ }
161
+ for (const version of versions) {
162
+ const dir = join(buildToolsRoot, version);
163
+ const apksignerJar = await firstExisting([
164
+ join(dir, "lib", "apksigner.jar"),
165
+ join(dir, "apksigner.jar"),
166
+ ]);
167
+ const zipalign = await firstExisting([
168
+ join(dir, zipalignName(platform)),
169
+ join(dir, "bin", zipalignName(platform)),
170
+ ]);
171
+ if (apksignerJar && zipalign) {
172
+ return { dir, version };
173
+ }
174
+ }
175
+ return undefined;
176
+ }
177
+ async function fromAndroidSdk(env, platform) {
178
+ const roots = candidateSdkRoots(env, platform);
179
+ for (const sdkRoot of roots) {
180
+ if (!(await exists(sdkRoot)))
181
+ continue;
182
+ const match = await findBuildTools(sdkRoot, platform);
183
+ if (!match)
184
+ continue;
185
+ const apksignerJar = await firstExisting([
186
+ join(match.dir, "lib", "apksigner.jar"),
187
+ join(match.dir, "apksigner.jar"),
188
+ ]);
189
+ const zipalign = await firstExisting([
190
+ join(match.dir, zipalignName(platform)),
191
+ join(match.dir, "bin", zipalignName(platform)),
192
+ ]);
193
+ if (!apksignerJar || !zipalign)
194
+ continue;
195
+ const { java, jreHome } = await resolveJava(env, platform);
196
+ const keytool = await resolveKeytool(java, platform);
197
+ return {
198
+ java,
199
+ apksignerJar,
200
+ zipalign,
201
+ keytool,
202
+ source: "android-sdk",
203
+ buildToolsVersion: match.version,
204
+ sdkRoot,
205
+ jreHome,
206
+ };
207
+ }
208
+ throw new MioToolError("ANDROID_TOOLS_NOT_FOUND", "Android build-tools (apksigner + zipalign) were not found.", {
209
+ details: "Set ANDROID_HOME (or MIO_ANDROID_SDK), install Android build-tools 35+, or point MIO_ANDROID_TOOLS_DIR at a Mio tools bundle.",
210
+ });
211
+ }
212
+ /**
213
+ * Find a usable Android signing toolchain.
214
+ *
215
+ * Priority:
216
+ * 1. MIO_ANDROID_TOOLS_DIR (a downloaded/bundled toolchain)
217
+ * 2. ANDROID_HOME / ANDROID_SDK_ROOT / default SDK locations
218
+ */
219
+ export async function discoverAndroidTools(options = {}) {
220
+ const env = options.env ?? process.env;
221
+ const platform = options.platform ?? process.platform;
222
+ if (env.MIO_ANDROID_TOOLS_DIR) {
223
+ return await fromToolsDir(env.MIO_ANDROID_TOOLS_DIR, env, platform);
224
+ }
225
+ return await fromAndroidSdk(env, platform);
226
+ }
227
+ export function describeAndroidTools(tools) {
228
+ const source = tools.source === "android-sdk"
229
+ ? `Android SDK build-tools ${tools.buildToolsVersion ?? "?"}`
230
+ : "Mio tools bundle";
231
+ return [
232
+ `source: ${source}`,
233
+ `java: ${tools.java}`,
234
+ `apksigner: ${tools.apksignerJar}`,
235
+ `zipalign: ${tools.zipalign}`,
236
+ tools.keytool ? `keytool: ${tools.keytool}` : "keytool: not found",
237
+ ].join("\n");
238
+ }
239
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export type MioToolErrorCode = "JAVA_NOT_FOUND" | "ANDROID_TOOLS_NOT_FOUND" | "INVALID_TOOLS_DIR" | "MISSING_FILE" | "INVALID_ARGUMENT" | "SPAWN_FAILED" | "TIMEOUT" | "APKSIGNER_SIGN_FAILED" | "APKSIGNER_VERIFY_FAILED" | "ZIPALIGN_FAILED" | "KEYSTORE_NOT_FOUND" | "KEYTOOL_NOT_FOUND" | "KEYTOOL_FAILED" | "BUNDLE_DOWNLOAD_FAILED" | "BUNDLE_CHECKSUM_FAILED" | "BUNDLE_EXTRACT_FAILED";
2
+ export interface MioToolErrorOptions {
3
+ cause?: unknown;
4
+ stdout?: string;
5
+ stderr?: string;
6
+ details?: string;
7
+ }
8
+ export declare class MioToolError extends Error {
9
+ readonly code: MioToolErrorCode;
10
+ readonly stdout?: string;
11
+ readonly stderr?: string;
12
+ readonly details?: string;
13
+ constructor(code: MioToolErrorCode, message: string, options?: MioToolErrorOptions);
14
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ export class MioToolError extends Error {
2
+ code;
3
+ stdout;
4
+ stderr;
5
+ details;
6
+ constructor(code, message, options = {}) {
7
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
8
+ this.name = "MioToolError";
9
+ this.code = code;
10
+ this.stdout = options.stdout;
11
+ this.stderr = options.stderr;
12
+ this.details = options.details;
13
+ }
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAyBA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAmB;IACvB,MAAM,CAAU;IAChB,MAAM,CAAU;IAChB,OAAO,CAAU;IAE1B,YAAY,IAAsB,EAAE,OAAe,EAAE,UAA+B,EAAE;QACpF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;CACF"}
package/dist/exec.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ export interface ExecResult {
2
+ code: number;
3
+ stdout: string;
4
+ stderr: string;
5
+ }
6
+ export interface ExecOptions {
7
+ cwd?: string;
8
+ env?: NodeJS.ProcessEnv;
9
+ timeoutMs?: number;
10
+ }
11
+ /**
12
+ * Run a child process and capture stdout/stderr.
13
+ *
14
+ * The caller is responsible for interpreting a non-zero exit code. Spawn
15
+ * failures and timeouts are surfaced as MioToolError.
16
+ */
17
+ export declare function run(file: string, args: readonly string[], options?: ExecOptions): Promise<ExecResult>;