@leonxin/meetgames 0.1.11 → 0.1.12
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/README.md +9 -9
- package/dist/cache.d.ts +44 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +101 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +43 -37
- package/dist/cli.js.map +1 -1
- package/dist/config/meetSdkDefaultConfig.d.ts +1 -1
- package/dist/config/meetSdkDefaultConfig.d.ts.map +1 -1
- package/dist/config/meetSdkDefaultConfig.js +4 -3
- package/dist/config/meetSdkDefaultConfig.js.map +1 -1
- package/dist/config/meetSdkIosConfig.d.ts.map +1 -1
- package/dist/config/meetSdkIosConfig.js +3 -1
- package/dist/config/meetSdkIosConfig.js.map +1 -1
- package/dist/config/meetSdkRemoteConfig.d.ts +1 -0
- package/dist/config/meetSdkRemoteConfig.d.ts.map +1 -1
- package/dist/config/meetSdkRemoteConfig.js +4 -1
- package/dist/config/meetSdkRemoteConfig.js.map +1 -1
- package/dist/contracts/types.d.ts +8 -0
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/core/doctor.js +7 -7
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/previewPatches.d.ts +1 -1
- package/dist/core/previewPatches.js +2 -2
- package/dist/core/previewPatches.js.map +1 -1
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +2 -0
- package/dist/core/workspace.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ios/integrate.d.ts.map +1 -1
- package/dist/ios/integrate.js +3 -3
- package/dist/ios/integrate.js.map +1 -1
- package/dist/ios/pbxprojEditor.d.ts.map +1 -1
- package/dist/ios/pbxprojEditor.js +71 -5
- package/dist/ios/pbxprojEditor.js.map +1 -1
- package/dist/ios/sdkBundle.d.ts +1 -6
- package/dist/ios/sdkBundle.d.ts.map +1 -1
- package/dist/ios/sdkBundle.js +44 -16
- package/dist/ios/sdkBundle.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +12 -6
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/service.d.ts +3 -0
- package/dist/mcp/service.d.ts.map +1 -1
- package/dist/mcp/service.js +31 -8
- package/dist/mcp/service.js.map +1 -1
- package/dist/ops/handlers.d.ts.map +1 -1
- package/dist/ops/handlers.js +24 -19
- package/dist/ops/handlers.js.map +1 -1
- package/dist/remote/sdkHomeDownload.d.ts +1 -1
- package/dist/remote/sdkHomeDownload.d.ts.map +1 -1
- package/dist/remote/sdkHomeDownload.js +27 -6
- package/dist/remote/sdkHomeDownload.js.map +1 -1
- package/docs/API.md +16 -16
- package/docs/CLI.md +21 -22
- package/docs/INTEGRATION.md +11 -11
- package/docs/MCP.md +1 -1
- package/docs/README.md +0 -1
- package/docs/archive/api/downloadSDKConfig.md +2 -2
- package/docs/archive/api/getChannelConfig-meetgames.md +1 -1
- package/docs/archive/product//351/234/200/346/261/202/346/226/207/346/241/243.md +1 -1
- package/package.json +2 -5
- package/recipes/android-default.yaml +0 -5
- package/recipes/integrate-default.yaml +0 -5
- package/src/cache.ts +164 -0
- package/src/cli.ts +46 -38
- package/src/config/meetSdkDefaultConfig.ts +4 -3
- package/src/config/meetSdkIosConfig.ts +3 -1
- package/src/config/meetSdkRemoteConfig.ts +5 -1
- package/src/contracts/types.ts +8 -0
- package/src/core/doctor.ts +7 -7
- package/src/core/previewPatches.ts +2 -2
- package/src/core/workspace.ts +2 -0
- package/src/index.ts +7 -0
- package/src/ios/integrate.ts +4 -3
- package/src/ios/pbxprojEditor.ts +70 -3
- package/src/ios/sdkBundle.ts +41 -18
- package/src/mcp/server.ts +12 -6
- package/src/mcp/service.ts +39 -8
- package/src/ops/handlers.ts +23 -19
- package/src/remote/sdkHomeDownload.ts +28 -7
- package/tests/doctor.test.ts +4 -2
- package/tests/{test-projects-hosts.test.ts → fixtures-hosts.test.ts} +2 -2
- package/tests/ios.sdkBundle.test.ts +10 -5
- package/tests/mcp.e2e.ts +2 -5
- package/tests/meetSdkRemoteConfig.test.ts +25 -0
- package/tests/pipeline.android.test.ts +1 -2
- package/tests/pipeline.ios.test.ts +26 -19
- package/tests/pipeline.preview.patch.test.ts +2 -2
- package/tests/sdkVersionConfig.test.ts +3 -2
- package/dist/aab-converter/aab-entry.d.ts +0 -3
- package/dist/aab-converter/aab-entry.d.ts.map +0 -1
- package/dist/aab-converter/aab-entry.js +0 -49
- package/dist/aab-converter/aab-entry.js.map +0 -1
- package/dist/aab-converter/apksExtractor.d.ts +0 -2
- package/dist/aab-converter/apksExtractor.d.ts.map +0 -1
- package/dist/aab-converter/apksExtractor.js +0 -108
- package/dist/aab-converter/apksExtractor.js.map +0 -1
- package/dist/aab-converter/bundletoolRunner.d.ts +0 -15
- package/dist/aab-converter/bundletoolRunner.d.ts.map +0 -1
- package/dist/aab-converter/bundletoolRunner.js +0 -46
- package/dist/aab-converter/bundletoolRunner.js.map +0 -1
- package/dist/aab-converter/cliArgs.d.ts +0 -27
- package/dist/aab-converter/cliArgs.d.ts.map +0 -1
- package/dist/aab-converter/cliArgs.js +0 -170
- package/dist/aab-converter/cliArgs.js.map +0 -1
- package/dist/aab-converter/convertAabToApk.d.ts +0 -7
- package/dist/aab-converter/convertAabToApk.d.ts.map +0 -1
- package/dist/aab-converter/convertAabToApk.js +0 -69
- package/dist/aab-converter/convertAabToApk.js.map +0 -1
- package/dist/aab-converter/resourcePaths.d.ts +0 -4
- package/dist/aab-converter/resourcePaths.d.ts.map +0 -1
- package/dist/aab-converter/resourcePaths.js +0 -42
- package/dist/aab-converter/resourcePaths.js.map +0 -1
- package/dist/aab-converter/signingOptions.d.ts +0 -9
- package/dist/aab-converter/signingOptions.d.ts.map +0 -1
- package/dist/aab-converter/signingOptions.js +0 -21
- package/dist/aab-converter/signingOptions.js.map +0 -1
- package/dist/aab-converter/types.d.ts +0 -24
- package/dist/aab-converter/types.d.ts.map +0 -1
- package/dist/aab-converter/types.js +0 -2
- package/dist/aab-converter/types.js.map +0 -1
- package/dist/shared/fileUtils.d.ts +0 -5
- package/dist/shared/fileUtils.d.ts.map +0 -1
- package/dist/shared/fileUtils.js +0 -35
- package/dist/shared/fileUtils.js.map +0 -1
- package/dist/shared/logger.d.ts +0 -10
- package/dist/shared/logger.d.ts.map +0 -1
- package/dist/shared/logger.js +0 -37
- package/dist/shared/logger.js.map +0 -1
- package/dist/shared/pathUtils.d.ts +0 -4
- package/dist/shared/pathUtils.d.ts.map +0 -1
- package/dist/shared/pathUtils.js +0 -22
- package/dist/shared/pathUtils.js.map +0 -1
- package/dist/shared/processRunner.d.ts +0 -12
- package/dist/shared/processRunner.d.ts.map +0 -1
- package/dist/shared/processRunner.js +0 -31
- package/dist/shared/processRunner.js.map +0 -1
- package/docs/AAB_CONVERTER_CLI_PLAN.md +0 -392
- package/logs/convert-20260622-155037.log +0 -5
- package/logs/convert-20260622-155226.log +0 -6
- package/scripts/package-aab-cli-win.mjs +0 -193
- package/src/aab-converter/aab-entry.ts +0 -48
- package/src/aab-converter/apksExtractor.ts +0 -119
- package/src/aab-converter/bundletoolRunner.ts +0 -63
- package/src/aab-converter/cliArgs.ts +0 -194
- package/src/aab-converter/convertAabToApk.ts +0 -81
- package/src/aab-converter/resourcePaths.ts +0 -43
- package/src/aab-converter/signingOptions.ts +0 -29
- package/src/aab-converter/types.ts +0 -26
- package/src/shared/fileUtils.ts +0 -41
- package/src/shared/logger.ts +0 -49
- package/src/shared/pathUtils.ts +0 -24
- package/src/shared/processRunner.ts +0 -43
- package/test-projects/README.md +0 -51
- package/test-projects/_preview/pipeline.patch +0 -281
- package/tests/aab-converter.test.ts +0 -213
- /package/{meetsdk-android.json → config/meetsdk-android.json} +0 -0
- /package/{meetsdk-ios.json → config/meetsdk-ios.json} +0 -0
|
@@ -52,8 +52,7 @@ async function runAndroidPipelineDryRun(projectRoot: string, opts?: { requirePac
|
|
|
52
52
|
const { report, patch, binaryCopies } = await runPipeline(ctx, manifest, { dryRun: true });
|
|
53
53
|
expect(report.errors).toEqual([]);
|
|
54
54
|
expect(patch.length).toBeGreaterThan(0);
|
|
55
|
-
expect(binaryCopies
|
|
56
|
-
expect(binaryCopies[0].relTo).toBe("vendor/meet-integrate/sample.txt");
|
|
55
|
+
expect(binaryCopies).toEqual([]);
|
|
57
56
|
expect(patch).toContain("TOPSDK REPO AUTO");
|
|
58
57
|
expect(patch).toContain("TOPSDK AUTO");
|
|
59
58
|
if (opts?.requirePackageNameInPatch !== false) {
|
|
@@ -7,7 +7,7 @@ import { loadManifestFile } from "../src/config/loadManifest.js";
|
|
|
7
7
|
import { buildWorkspaceContext } from "../src/core/workspace.js";
|
|
8
8
|
import { runPipeline } from "../src/core/pipeline.js";
|
|
9
9
|
import { detectIOS } from "../src/ios/detect.js";
|
|
10
|
-
import {
|
|
10
|
+
import { resolveIosSdkRootFromDirectory } from "../src/remote/sdkHomeDownload.js";
|
|
11
11
|
|
|
12
12
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
13
13
|
const pkgRoot = path.resolve(here, "..");
|
|
@@ -15,6 +15,7 @@ const iosRoot = path.join(pkgRoot, "fixtures", "ios-test-project", "tooltest");
|
|
|
15
15
|
const iosRemoteConfigFixture = path.join(pkgRoot, "fixtures", "meetsdk-remote-config.ios-tooltest.json");
|
|
16
16
|
const hasIosProjectFixture = fs.existsSync(iosRoot);
|
|
17
17
|
const manifest = () => loadManifestFile(path.join(pkgRoot, "recipes", "ios-default.yaml"));
|
|
18
|
+
const fixtureIosSdkRoot = resolveIosSdkRootFromDirectory(path.join(pkgRoot, "fixtures", "ios-sdk", "topSDK-ios--V1.6.0.5"));
|
|
18
19
|
|
|
19
20
|
function writeOfflineRemoteConfig(projectRoot: string): void {
|
|
20
21
|
fs.copyFileSync(iosRemoteConfigFixture, path.join(projectRoot, "meetsdk-remote-config.json"));
|
|
@@ -47,11 +48,14 @@ function plannedIosAsset(patch: string, binaryCopies: Array<{ relTo: string }>,
|
|
|
47
48
|
return patch.includes(name) || binaryCopies.some((c) => c.relTo.includes(name));
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
function testIosContext(projectRoot: string) {
|
|
52
|
+
return buildWorkspaceContext(projectRoot, pkgRoot, { iosSdkRoot: fixtureIosSdkRoot });
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
describe("pipeline ios fixture SDK", () => {
|
|
56
|
+
it("resolves TopSDK iOS fixture package", () => {
|
|
57
|
+
expect(fs.existsSync(path.join(fixtureIosSdkRoot, "sdk", "topsdkConfig.t.json"))).toBe(true);
|
|
58
|
+
expect(fs.existsSync(path.join(fixtureIosSdkRoot, "plugins", "GuestSignin", "config.t.json"))).toBe(true);
|
|
55
59
|
});
|
|
56
60
|
});
|
|
57
61
|
|
|
@@ -76,7 +80,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
76
80
|
});
|
|
77
81
|
|
|
78
82
|
it("builds workspace context when project root is the xcodeproj directory", () => {
|
|
79
|
-
const ctx =
|
|
83
|
+
const ctx = testIosContext(path.join(iosRoot, "tooltest.xcodeproj"));
|
|
80
84
|
expect(ctx.ios?.ok).toBe(true);
|
|
81
85
|
expect(ctx.ios?.ok && ctx.ios.xcodeprojPath).toBe(path.join(iosRoot, "tooltest.xcodeproj"));
|
|
82
86
|
});
|
|
@@ -84,7 +88,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
84
88
|
it("dry-run: plans TOPCore + GuestSignin frameworks and pbxproj edits", async () => {
|
|
85
89
|
const tmp = copyProjectToTemp();
|
|
86
90
|
try {
|
|
87
|
-
const ctx =
|
|
91
|
+
const ctx = testIosContext(tmp);
|
|
88
92
|
expect(ctx.ios?.ok).toBe(true);
|
|
89
93
|
const { report, patch, binaryCopies } = await runPipeline(ctx, manifest(), { dryRun: true });
|
|
90
94
|
expect(report.errors).toEqual([]);
|
|
@@ -101,7 +105,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
101
105
|
it("apply: copies SDK, updates pbxproj, injects AppDelegate", async () => {
|
|
102
106
|
const tmp = copyProjectToTemp();
|
|
103
107
|
try {
|
|
104
|
-
const ctx =
|
|
108
|
+
const ctx = testIosContext(tmp);
|
|
105
109
|
const { report } = await runPipeline(ctx, manifest(), { dryRun: false });
|
|
106
110
|
expect(report.errors).toEqual([]);
|
|
107
111
|
|
|
@@ -113,8 +117,12 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
113
117
|
const pbx = fs.readFileSync(path.join(tmp, "tooltest.xcodeproj", "project.pbxproj"), "utf8");
|
|
114
118
|
expect(pbx).toContain("TOPCore.framework");
|
|
115
119
|
expect(pbx).toContain("TOPGuestSigninPlugin.framework");
|
|
116
|
-
expect(pbx).toContain("-ObjC");
|
|
120
|
+
expect(pbx).toContain('"-ObjC"');
|
|
121
|
+
expect(pbx).toContain('"-lc++"');
|
|
122
|
+
expect(pbx).not.toMatch(/\n\s+-ObjC,/);
|
|
123
|
+
expect(pbx).not.toMatch(/\n\s+-lc\+\+,/);
|
|
117
124
|
expect(pbxBuildFileRefErrors(pbx)).toEqual([]);
|
|
125
|
+
expect(pbx).not.toMatch(/\bundefined;/);
|
|
118
126
|
|
|
119
127
|
const delegate = fs.readFileSync(path.join(tmp, "tooltest", "AppDelegate.m"), "utf8");
|
|
120
128
|
expect(delegate).toContain("#import <TOPSDK/TopSDK.h>");
|
|
@@ -143,7 +151,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
143
151
|
};
|
|
144
152
|
fs.writeFileSync(configPath, JSON.stringify(remote, null, 2), "utf8");
|
|
145
153
|
|
|
146
|
-
const ctx =
|
|
154
|
+
const ctx = testIosContext(tmp);
|
|
147
155
|
const { report } = await runPipeline(ctx, manifest(), { dryRun: false });
|
|
148
156
|
expect(report.errors).toEqual([]);
|
|
149
157
|
|
|
@@ -235,7 +243,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
235
243
|
};
|
|
236
244
|
fs.writeFileSync(configPath, JSON.stringify(remote, null, 2), "utf8");
|
|
237
245
|
|
|
238
|
-
const ctx =
|
|
246
|
+
const ctx = testIosContext(tmp);
|
|
239
247
|
const { report, patch, binaryCopies } = await runPipeline(ctx, manifest(), { dryRun: true });
|
|
240
248
|
expect(report.errors).toEqual([]);
|
|
241
249
|
expect(report.warnings.join("\n")).not.toContain("Discord");
|
|
@@ -284,13 +292,12 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
284
292
|
};
|
|
285
293
|
fs.writeFileSync(configPath, JSON.stringify(remote, null, 2), "utf8");
|
|
286
294
|
|
|
287
|
-
const ctx =
|
|
288
|
-
const { report, patch } = await runPipeline(ctx, manifest(), { dryRun: true });
|
|
295
|
+
const ctx = testIosContext(tmp);
|
|
296
|
+
const { report, patch, binaryCopies } = await runPipeline(ctx, manifest(), { dryRun: true });
|
|
289
297
|
|
|
290
298
|
expect(report.errors).toEqual([]);
|
|
291
299
|
expect(report.warnings.join("\n")).toContain("would download GoogleService-Info.plist to tooltest/GoogleService-Info.plist");
|
|
292
|
-
expect(patch
|
|
293
|
-
expect(patch).toContain("GoogleService-Info.plist");
|
|
300
|
+
expect(plannedIosAsset(patch, binaryCopies, "TOPDataFirebasePlugin.framework")).toBe(true);
|
|
294
301
|
} finally {
|
|
295
302
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
296
303
|
}
|
|
@@ -324,7 +331,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
324
331
|
"utf8"
|
|
325
332
|
);
|
|
326
333
|
|
|
327
|
-
const ctx =
|
|
334
|
+
const ctx = testIosContext(tmp);
|
|
328
335
|
const { report } = await runPipeline(ctx, manifest(), { dryRun: false });
|
|
329
336
|
expect(report.errors).toEqual([]);
|
|
330
337
|
|
|
@@ -351,7 +358,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
351
358
|
try {
|
|
352
359
|
fs.rmSync(path.join(tmp, "tooltest", "Info.plist"));
|
|
353
360
|
|
|
354
|
-
const ctx =
|
|
361
|
+
const ctx = testIosContext(tmp);
|
|
355
362
|
const { report } = await runPipeline(ctx, manifest(), { dryRun: true });
|
|
356
363
|
|
|
357
364
|
expect(report.errors.join("\n")).toContain("Info.plist not found for iOS target tooltest");
|
|
@@ -372,7 +379,7 @@ describe.skipIf(!hasIosProjectFixture)("pipeline ios fixture", () => {
|
|
|
372
379
|
};
|
|
373
380
|
fs.writeFileSync(configPath, JSON.stringify(remote, null, 2), "utf8");
|
|
374
381
|
|
|
375
|
-
const ctx =
|
|
382
|
+
const ctx = testIosContext(tmp);
|
|
376
383
|
const { report } = await runPipeline(ctx, manifest(), { dryRun: false });
|
|
377
384
|
expect(report.errors.join("\n")).toContain("iOS remote config missing required channel params");
|
|
378
385
|
expect(report.errors.join("\n")).toContain("GoogleSignin: GOOGLE.scheme");
|
|
@@ -13,7 +13,7 @@ const here = path.dirname(fileURLToPath(import.meta.url));
|
|
|
13
13
|
const pkgRoot = path.resolve(here, "..");
|
|
14
14
|
const fixtureRoot = path.join(pkgRoot, "fixtures", "android-test-project", "android-latest-project");
|
|
15
15
|
const recipeFixtureRoot = path.join(pkgRoot, "fixtures", "recipes");
|
|
16
|
-
const previewPatchPath = path.join(pkgRoot, "
|
|
16
|
+
const previewPatchPath = path.join(pkgRoot, "preview-patches", "pipeline.patch");
|
|
17
17
|
|
|
18
18
|
function stubSdkHomeVersion(): void {
|
|
19
19
|
vi.stubGlobal(
|
|
@@ -54,7 +54,7 @@ describe("pipeline preview patch", () => {
|
|
|
54
54
|
vi.unstubAllGlobals();
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
it("writes
|
|
57
|
+
it("writes preview-patches/pipeline.patch (yaml + integration-json)", async () => {
|
|
58
58
|
const ctx = buildWorkspaceContext(fixtureRoot, pkgRoot);
|
|
59
59
|
expect(ctx.android?.ok).toBe(true);
|
|
60
60
|
|
|
@@ -14,8 +14,9 @@ function makeTempPackageRoot(): string {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function writeAndroidDefaults(packageRoot: string): void {
|
|
17
|
+
fs.mkdirSync(path.join(packageRoot, "config"), { recursive: true });
|
|
17
18
|
fs.writeFileSync(
|
|
18
|
-
path.join(packageRoot, "meetsdk-android.json"),
|
|
19
|
+
path.join(packageRoot, "config", "meetsdk-android.json"),
|
|
19
20
|
JSON.stringify(
|
|
20
21
|
{
|
|
21
22
|
topsdk: {
|
|
@@ -68,7 +69,7 @@ describe("SDK version package configs", () => {
|
|
|
68
69
|
packageRoot,
|
|
69
70
|
});
|
|
70
71
|
|
|
71
|
-
const stored = JSON.parse(fs.readFileSync(path.join(packageRoot, "meetsdk-android.json"), "utf8")) as {
|
|
72
|
+
const stored = JSON.parse(fs.readFileSync(path.join(packageRoot, "config", "meetsdk-android.json"), "utf8")) as {
|
|
72
73
|
topsdk: { version: string; date: string };
|
|
73
74
|
};
|
|
74
75
|
expect(defaults.topsdk.version).toBe("9.8.7");
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aab-entry.d.ts","sourceRoot":"","sources":["../../src/aab-converter/aab-entry.ts"],"names":[],"mappings":";AAcA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB1C"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { UserFacingError, errorMessage } from "../shared/errors.js";
|
|
4
|
-
import { createFileLogger } from "../shared/logger.js";
|
|
5
|
-
import { convertAabToApk } from "./convertAabToApk.js";
|
|
6
|
-
import { parseAabCliArgv, printAabHelp, validateConvertArgs } from "./cliArgs.js";
|
|
7
|
-
import { resolveBundletoolPath, resolveJavaPath, resolveToolRoot } from "./resourcePaths.js";
|
|
8
|
-
const EXIT = {
|
|
9
|
-
OK: 0,
|
|
10
|
-
INVALID_ARGS: 2,
|
|
11
|
-
CONVERT_FAILED: 3,
|
|
12
|
-
};
|
|
13
|
-
export async function main() {
|
|
14
|
-
const parsed = parseAabCliArgv(process.argv);
|
|
15
|
-
if (parsed.help) {
|
|
16
|
-
printAabHelp();
|
|
17
|
-
process.exit(EXIT.OK);
|
|
18
|
-
}
|
|
19
|
-
const toolRoot = resolveToolRoot(import.meta.url);
|
|
20
|
-
const convertArgs = validateConvertArgs(parsed);
|
|
21
|
-
const logger = createFileLogger(path.join(toolRoot, "logs"));
|
|
22
|
-
try {
|
|
23
|
-
const result = await convertAabToApk({
|
|
24
|
-
...convertArgs,
|
|
25
|
-
javaPath: resolveJavaPath(toolRoot),
|
|
26
|
-
bundletoolPath: resolveBundletoolPath(toolRoot),
|
|
27
|
-
logger,
|
|
28
|
-
});
|
|
29
|
-
console.log(`[aab2apk] APK: ${result.apkPath}`);
|
|
30
|
-
if (result.apksPath)
|
|
31
|
-
console.log(`[aab2apk] APKS: ${result.apksPath}`);
|
|
32
|
-
if (result.logPath)
|
|
33
|
-
console.log(`[aab2apk] Log: ${result.logPath}`);
|
|
34
|
-
}
|
|
35
|
-
finally {
|
|
36
|
-
logger.close();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
main().catch((err) => {
|
|
40
|
-
if (err instanceof UserFacingError) {
|
|
41
|
-
console.error(`[aab2apk] ERROR (${err.code}): ${err.message}`);
|
|
42
|
-
if (err.details)
|
|
43
|
-
console.error(err.details);
|
|
44
|
-
process.exit(err.code === "INVALID_ARGS" || err.code === "INVALID_COMMAND" ? EXIT.INVALID_ARGS : EXIT.CONVERT_FAILED);
|
|
45
|
-
}
|
|
46
|
-
console.error(`[aab2apk] ERROR: ${errorMessage(err)}`);
|
|
47
|
-
process.exit(EXIT.CONVERT_FAILED);
|
|
48
|
-
});
|
|
49
|
-
//# sourceMappingURL=aab-entry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"aab-entry.js","sourceRoot":"","sources":["../../src/aab-converter/aab-entry.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,IAAI,GAAG;IACX,EAAE,EAAE,CAAC;IACL,YAAY,EAAE,CAAC;IACf,cAAc,EAAE,CAAC;CACT,CAAC;AAEX,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,GAAG,WAAW;YACd,QAAQ,EAAE,eAAe,CAAC,QAAQ,CAAC;YACnC,cAAc,EAAE,qBAAqB,CAAC,QAAQ,CAAC;YAC/C,MAAM;SACP,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,QAAQ;YAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,IAAI,GAAG,CAAC,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,cAAc,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,oBAAoB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apksExtractor.d.ts","sourceRoot":"","sources":["../../src/aab-converter/apksExtractor.ts"],"names":[],"mappings":"AA6GA,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CASpH"}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import zlib from "node:zlib";
|
|
4
|
-
import { UserFacingError } from "../shared/errors.js";
|
|
5
|
-
import { assertCanWriteFile } from "../shared/fileUtils.js";
|
|
6
|
-
function readAt(fd, position, length) {
|
|
7
|
-
const buf = Buffer.alloc(length);
|
|
8
|
-
const bytesRead = fs.readSync(fd, buf, 0, length, position);
|
|
9
|
-
return bytesRead === length ? buf : buf.subarray(0, bytesRead);
|
|
10
|
-
}
|
|
11
|
-
function findEndOfCentralDirectory(buf) {
|
|
12
|
-
const signature = 0x06054b50;
|
|
13
|
-
for (let i = buf.length - 22; i >= 0; i -= 1) {
|
|
14
|
-
if (buf.readUInt32LE(i) === signature)
|
|
15
|
-
return i;
|
|
16
|
-
}
|
|
17
|
-
throw new UserFacingError("APKS_INVALID", "Invalid .apks file: end of central directory not found");
|
|
18
|
-
}
|
|
19
|
-
function readZipEntries(apksPath) {
|
|
20
|
-
const fd = fs.openSync(apksPath, "r");
|
|
21
|
-
try {
|
|
22
|
-
const fileSize = fs.fstatSync(fd).size;
|
|
23
|
-
const tailSize = Math.min(fileSize, 0xffff + 22);
|
|
24
|
-
const tailStart = fileSize - tailSize;
|
|
25
|
-
const tail = readAt(fd, tailStart, tailSize);
|
|
26
|
-
const eocd = findEndOfCentralDirectory(tail);
|
|
27
|
-
const totalEntries = tail.readUInt16LE(eocd + 10);
|
|
28
|
-
const centralDirSize = tail.readUInt32LE(eocd + 12);
|
|
29
|
-
const centralDirOffset = tail.readUInt32LE(eocd + 16);
|
|
30
|
-
if (centralDirSize === 0xffffffff || centralDirOffset === 0xffffffff || totalEntries === 0xffff) {
|
|
31
|
-
throw new UserFacingError("APKS_ZIP64_UNSUPPORTED", "ZIP64 .apks files are not supported yet");
|
|
32
|
-
}
|
|
33
|
-
const buf = readAt(fd, centralDirOffset, centralDirSize);
|
|
34
|
-
return parseCentralDirectory(buf, totalEntries);
|
|
35
|
-
}
|
|
36
|
-
finally {
|
|
37
|
-
fs.closeSync(fd);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function parseCentralDirectory(buf, totalEntries) {
|
|
41
|
-
const entries = [];
|
|
42
|
-
let pos = 0;
|
|
43
|
-
for (let i = 0; i < totalEntries; i += 1) {
|
|
44
|
-
if (buf.readUInt32LE(pos) !== 0x02014b50) {
|
|
45
|
-
throw new UserFacingError("APKS_INVALID", "Invalid .apks file: central directory is corrupt");
|
|
46
|
-
}
|
|
47
|
-
const method = buf.readUInt16LE(pos + 10);
|
|
48
|
-
const compressedSize = buf.readUInt32LE(pos + 20);
|
|
49
|
-
const nameLength = buf.readUInt16LE(pos + 28);
|
|
50
|
-
const extraLength = buf.readUInt16LE(pos + 30);
|
|
51
|
-
const commentLength = buf.readUInt16LE(pos + 32);
|
|
52
|
-
const localHeaderOffset = buf.readUInt32LE(pos + 42);
|
|
53
|
-
const name = buf.subarray(pos + 46, pos + 46 + nameLength).toString("utf8");
|
|
54
|
-
entries.push({ name, method, compressedSize, localHeaderOffset });
|
|
55
|
-
pos += 46 + nameLength + extraLength + commentLength;
|
|
56
|
-
}
|
|
57
|
-
return entries;
|
|
58
|
-
}
|
|
59
|
-
async function extractEntryToFile(apksPath, entry, outputApkPath) {
|
|
60
|
-
const fd = fs.openSync(apksPath, "r");
|
|
61
|
-
let dataStart;
|
|
62
|
-
try {
|
|
63
|
-
const localHeader = readAt(fd, entry.localHeaderOffset, 30);
|
|
64
|
-
if (localHeader.readUInt32LE(0) !== 0x04034b50) {
|
|
65
|
-
throw new UserFacingError("APKS_INVALID", `Invalid .apks file: local header not found for ${entry.name}`);
|
|
66
|
-
}
|
|
67
|
-
const nameLength = localHeader.readUInt16LE(26);
|
|
68
|
-
const extraLength = localHeader.readUInt16LE(28);
|
|
69
|
-
dataStart = entry.localHeaderOffset + 30 + nameLength + extraLength;
|
|
70
|
-
}
|
|
71
|
-
finally {
|
|
72
|
-
fs.closeSync(fd);
|
|
73
|
-
}
|
|
74
|
-
await new Promise((resolve, reject) => {
|
|
75
|
-
const input = fs.createReadStream(apksPath, {
|
|
76
|
-
start: dataStart,
|
|
77
|
-
end: dataStart + entry.compressedSize - 1,
|
|
78
|
-
});
|
|
79
|
-
const output = fs.createWriteStream(outputApkPath);
|
|
80
|
-
const source = entry.method === 0
|
|
81
|
-
? input
|
|
82
|
-
: entry.method === 8
|
|
83
|
-
? input.pipe(zlib.createInflateRaw())
|
|
84
|
-
: null;
|
|
85
|
-
if (!source) {
|
|
86
|
-
input.destroy();
|
|
87
|
-
output.destroy();
|
|
88
|
-
reject(new UserFacingError("APKS_UNSUPPORTED_ZIP_METHOD", `Unsupported zip compression method ${entry.method}`));
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
input.on("error", reject);
|
|
92
|
-
source.on("error", reject);
|
|
93
|
-
output.on("error", reject);
|
|
94
|
-
output.on("finish", resolve);
|
|
95
|
-
source.pipe(output);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
export async function extractUniversalApk(apksPath, outputApkPath, overwrite) {
|
|
99
|
-
assertCanWriteFile(outputApkPath, overwrite, "Output APK");
|
|
100
|
-
const entries = readZipEntries(apksPath);
|
|
101
|
-
const universal = entries.find((entry) => entry.name === "universal.apk" || entry.name.endsWith("/universal.apk"));
|
|
102
|
-
if (!universal) {
|
|
103
|
-
throw new UserFacingError("UNIVERSAL_APK_NOT_FOUND", "universal.apk not found in .apks output");
|
|
104
|
-
}
|
|
105
|
-
fs.mkdirSync(path.dirname(outputApkPath), { recursive: true });
|
|
106
|
-
await extractEntryToFile(apksPath, universal, outputApkPath);
|
|
107
|
-
}
|
|
108
|
-
//# sourceMappingURL=apksExtractor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apksExtractor.js","sourceRoot":"","sources":["../../src/aab-converter/apksExtractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Logger } from "../shared/logger.js";
|
|
2
|
-
import type { SigningOptions } from "./types.js";
|
|
3
|
-
export interface BuildApksOptions {
|
|
4
|
-
javaPath: string;
|
|
5
|
-
bundletoolPath: string;
|
|
6
|
-
aabPath: string;
|
|
7
|
-
apksPath: string;
|
|
8
|
-
signing: SigningOptions;
|
|
9
|
-
overwrite: boolean;
|
|
10
|
-
logger?: Logger;
|
|
11
|
-
}
|
|
12
|
-
export declare function buildBundletoolArgs(options: Omit<BuildApksOptions, "javaPath" | "logger">): string[];
|
|
13
|
-
export declare function redactedBundletoolCommand(javaPath: string, args: string[]): string;
|
|
14
|
-
export declare function buildUniversalApks(options: BuildApksOptions): Promise<void>;
|
|
15
|
-
//# sourceMappingURL=bundletoolRunner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bundletoolRunner.d.ts","sourceRoot":"","sources":["../../src/aab-converter/bundletoolRunner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,QAAQ,CAAC,GAAG,MAAM,EAAE,CAmBpG;AAQD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAElF;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAejF"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { UserFacingError } from "../shared/errors.js";
|
|
3
|
-
import { runProcess } from "../shared/processRunner.js";
|
|
4
|
-
export function buildBundletoolArgs(options) {
|
|
5
|
-
const args = [
|
|
6
|
-
"-jar",
|
|
7
|
-
options.bundletoolPath,
|
|
8
|
-
"build-apks",
|
|
9
|
-
`--bundle=${options.aabPath}`,
|
|
10
|
-
`--output=${options.apksPath}`,
|
|
11
|
-
"--mode=universal",
|
|
12
|
-
`--ks=${options.signing.keyStorePath}`,
|
|
13
|
-
`--ks-key-alias=${options.signing.keyAlias}`,
|
|
14
|
-
`--ks-pass=pass:${options.signing.keyStorePassword}`,
|
|
15
|
-
];
|
|
16
|
-
if (options.signing.keyPassword) {
|
|
17
|
-
args.push(`--key-pass=pass:${options.signing.keyPassword}`);
|
|
18
|
-
}
|
|
19
|
-
if (options.overwrite) {
|
|
20
|
-
args.push("--overwrite");
|
|
21
|
-
}
|
|
22
|
-
return args;
|
|
23
|
-
}
|
|
24
|
-
function redactArg(arg) {
|
|
25
|
-
if (arg.startsWith("--ks-pass=pass:"))
|
|
26
|
-
return "--ks-pass=pass:******";
|
|
27
|
-
if (arg.startsWith("--key-pass=pass:"))
|
|
28
|
-
return "--key-pass=pass:******";
|
|
29
|
-
return arg;
|
|
30
|
-
}
|
|
31
|
-
export function redactedBundletoolCommand(javaPath, args) {
|
|
32
|
-
return [javaPath, ...args.map(redactArg)].map((part) => (part.includes(" ") ? `"${part}"` : part)).join(" ");
|
|
33
|
-
}
|
|
34
|
-
export async function buildUniversalApks(options) {
|
|
35
|
-
const args = buildBundletoolArgs(options);
|
|
36
|
-
options.logger?.info(`Running bundletool: ${redactedBundletoolCommand(options.javaPath, args)}`);
|
|
37
|
-
const result = await runProcess(options.javaPath, args, {
|
|
38
|
-
cwd: path.dirname(options.apksPath),
|
|
39
|
-
onStdout: (chunk) => options.logger?.info(chunk.trimEnd()),
|
|
40
|
-
onStderr: (chunk) => options.logger?.warn(chunk.trimEnd()),
|
|
41
|
-
});
|
|
42
|
-
if (result.exitCode !== 0) {
|
|
43
|
-
throw new UserFacingError("BUNDLETOOL_FAILED", "bundletool failed to build APK set", (result.stderr || result.stdout).trim());
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=bundletoolRunner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bundletoolRunner.js","sourceRoot":"","sources":["../../src/aab-converter/bundletoolRunner.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAcxD,MAAM,UAAU,mBAAmB,CAAC,OAAsD;IACxF,MAAM,IAAI,GAAG;QACX,MAAM;QACN,OAAO,CAAC,cAAc;QACtB,YAAY;QACZ,YAAY,OAAO,CAAC,OAAO,EAAE;QAC7B,YAAY,OAAO,CAAC,QAAQ,EAAE;QAC9B,kBAAkB;QAClB,QAAQ,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE;QACtC,kBAAkB,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC5C,kBAAkB,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE;KACrD,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,mBAAmB,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,uBAAuB,CAAC;IACtE,IAAI,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAAC;QAAE,OAAO,wBAAwB,CAAC;IACxE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB,EAAE,IAAc;IACxE,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/G,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAyB;IAChE,MAAM,IAAI,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,uBAAuB,yBAAyB,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACjG,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE;QACtD,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC1D,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;KAC3D,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,eAAe,CACvB,mBAAmB,EACnB,oCAAoC,EACpC,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CACxC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { SigningOptions } from "./types.js";
|
|
2
|
-
export interface ParsedAabCli {
|
|
3
|
-
help: boolean;
|
|
4
|
-
command: string;
|
|
5
|
-
aabPath: string;
|
|
6
|
-
outDir: string;
|
|
7
|
-
keyStorePath: string;
|
|
8
|
-
keyAlias: string;
|
|
9
|
-
keyStorePassword?: string;
|
|
10
|
-
keyPassword?: string;
|
|
11
|
-
apkName?: string;
|
|
12
|
-
keepApks: boolean;
|
|
13
|
-
overwrite: boolean;
|
|
14
|
-
verbose: boolean;
|
|
15
|
-
}
|
|
16
|
-
export declare function printAabHelp(): void;
|
|
17
|
-
export declare function parseAabCliArgv(argv: string[]): ParsedAabCli;
|
|
18
|
-
export declare function validateConvertArgs(parsed: ParsedAabCli): {
|
|
19
|
-
aabPath: string;
|
|
20
|
-
outDir: string;
|
|
21
|
-
signing: SigningOptions;
|
|
22
|
-
apkName?: string;
|
|
23
|
-
keepApks: boolean;
|
|
24
|
-
overwrite: boolean;
|
|
25
|
-
verbose: boolean;
|
|
26
|
-
};
|
|
27
|
-
//# sourceMappingURL=cliArgs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cliArgs.d.ts","sourceRoot":"","sources":["../../src/aab-converter/cliArgs.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAkBD,wBAAgB,YAAY,IAAI,IAAI,CA0BnC;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAmG5D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB,CAmBA"}
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { UserFacingError } from "../shared/errors.js";
|
|
3
|
-
import { toAbsolutePath } from "../shared/pathUtils.js";
|
|
4
|
-
import { resolveSigningOptions } from "./signingOptions.js";
|
|
5
|
-
function valueAfter(args, index, flag) {
|
|
6
|
-
const value = args[index + 1] ?? "";
|
|
7
|
-
if (!value || value.startsWith("--")) {
|
|
8
|
-
throw new UserFacingError("INVALID_ARGS", `${flag} requires a value`);
|
|
9
|
-
}
|
|
10
|
-
return value;
|
|
11
|
-
}
|
|
12
|
-
function passwordFromEnv(envName, flag) {
|
|
13
|
-
const value = process.env[envName];
|
|
14
|
-
if (!value) {
|
|
15
|
-
throw new UserFacingError("ENV_PASSWORD_MISSING", `${flag} points to an empty or missing environment variable: ${envName}`);
|
|
16
|
-
}
|
|
17
|
-
return value;
|
|
18
|
-
}
|
|
19
|
-
export function printAabHelp() {
|
|
20
|
-
console.log(`
|
|
21
|
-
aab2apk — Convert Android App Bundle (.aab) to signed universal APK
|
|
22
|
-
|
|
23
|
-
Usage:
|
|
24
|
-
aab2apk.cmd convert --aab <file.aab> --out-dir <dir> --ks <file.jks> --ks-key-alias <alias> [password options]
|
|
25
|
-
|
|
26
|
-
Required:
|
|
27
|
-
--aab AAB file path
|
|
28
|
-
--out-dir Output directory
|
|
29
|
-
--ks Keystore/JKS file path
|
|
30
|
-
--ks-key-alias Key alias in keystore
|
|
31
|
-
|
|
32
|
-
Password options:
|
|
33
|
-
--ks-pass-env Read keystore password from environment variable (recommended)
|
|
34
|
-
--key-pass-env Read key password from environment variable (recommended)
|
|
35
|
-
--ks-pass Keystore password as command argument (not recommended)
|
|
36
|
-
--key-pass Key password as command argument (not recommended)
|
|
37
|
-
|
|
38
|
-
Other options:
|
|
39
|
-
--apk-name Output APK file name
|
|
40
|
-
--keep-apks Keep intermediate .apks file
|
|
41
|
-
--no-overwrite Fail if output already exists (default is overwrite)
|
|
42
|
-
--verbose Print detailed logs
|
|
43
|
-
--help, -h Show help
|
|
44
|
-
`);
|
|
45
|
-
}
|
|
46
|
-
export function parseAabCliArgv(argv) {
|
|
47
|
-
const rest = argv.slice(2);
|
|
48
|
-
if (!rest.length || rest[0] === "--help" || rest[0] === "-h") {
|
|
49
|
-
return {
|
|
50
|
-
help: true,
|
|
51
|
-
command: "",
|
|
52
|
-
aabPath: "",
|
|
53
|
-
outDir: "",
|
|
54
|
-
keyStorePath: "",
|
|
55
|
-
keyAlias: "",
|
|
56
|
-
keepApks: false,
|
|
57
|
-
overwrite: true,
|
|
58
|
-
verbose: false,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
const parsed = {
|
|
62
|
-
help: false,
|
|
63
|
-
command: rest[0] ?? "",
|
|
64
|
-
aabPath: "",
|
|
65
|
-
outDir: "",
|
|
66
|
-
keyStorePath: "",
|
|
67
|
-
keyAlias: "",
|
|
68
|
-
keepApks: false,
|
|
69
|
-
overwrite: true,
|
|
70
|
-
verbose: false,
|
|
71
|
-
};
|
|
72
|
-
if (parsed.command !== "convert") {
|
|
73
|
-
throw new UserFacingError("INVALID_COMMAND", `Unknown command: ${parsed.command}`);
|
|
74
|
-
}
|
|
75
|
-
for (let i = 1; i < rest.length; i += 1) {
|
|
76
|
-
const flag = rest[i];
|
|
77
|
-
if (flag === "--help" || flag === "-h") {
|
|
78
|
-
parsed.help = true;
|
|
79
|
-
return parsed;
|
|
80
|
-
}
|
|
81
|
-
if (flag === "--keep-apks") {
|
|
82
|
-
parsed.keepApks = true;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (flag === "--verbose") {
|
|
86
|
-
parsed.verbose = true;
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
if (flag === "--no-overwrite") {
|
|
90
|
-
parsed.overwrite = false;
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
if (flag === "--overwrite") {
|
|
94
|
-
parsed.overwrite = true;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
if (flag === "--aab") {
|
|
98
|
-
parsed.aabPath = valueAfter(rest, i, flag);
|
|
99
|
-
i += 1;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (flag === "--out-dir") {
|
|
103
|
-
parsed.outDir = valueAfter(rest, i, flag);
|
|
104
|
-
i += 1;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
if (flag === "--ks") {
|
|
108
|
-
parsed.keyStorePath = valueAfter(rest, i, flag);
|
|
109
|
-
i += 1;
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (flag === "--ks-key-alias") {
|
|
113
|
-
parsed.keyAlias = valueAfter(rest, i, flag);
|
|
114
|
-
i += 1;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (flag === "--ks-pass-env") {
|
|
118
|
-
parsed.keyStorePassword = passwordFromEnv(valueAfter(rest, i, flag), flag);
|
|
119
|
-
i += 1;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (flag === "--key-pass-env") {
|
|
123
|
-
parsed.keyPassword = passwordFromEnv(valueAfter(rest, i, flag), flag);
|
|
124
|
-
i += 1;
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (flag === "--ks-pass") {
|
|
128
|
-
parsed.keyStorePassword = valueAfter(rest, i, flag);
|
|
129
|
-
i += 1;
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
if (flag === "--key-pass") {
|
|
133
|
-
parsed.keyPassword = valueAfter(rest, i, flag);
|
|
134
|
-
i += 1;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (flag === "--apk-name") {
|
|
138
|
-
parsed.apkName = valueAfter(rest, i, flag);
|
|
139
|
-
i += 1;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
throw new UserFacingError("INVALID_ARGS", `Unsupported argument: ${flag}`);
|
|
143
|
-
}
|
|
144
|
-
return parsed;
|
|
145
|
-
}
|
|
146
|
-
export function validateConvertArgs(parsed) {
|
|
147
|
-
if (!parsed.aabPath)
|
|
148
|
-
throw new UserFacingError("INVALID_ARGS", "Missing --aab");
|
|
149
|
-
if (!parsed.outDir)
|
|
150
|
-
throw new UserFacingError("INVALID_ARGS", "Missing --out-dir");
|
|
151
|
-
if (!parsed.keyStorePath)
|
|
152
|
-
throw new UserFacingError("INVALID_ARGS", "Missing --ks");
|
|
153
|
-
if (!parsed.keyAlias)
|
|
154
|
-
throw new UserFacingError("INVALID_ARGS", "Missing --ks-key-alias");
|
|
155
|
-
return {
|
|
156
|
-
aabPath: toAbsolutePath(parsed.aabPath),
|
|
157
|
-
outDir: path.resolve(parsed.outDir),
|
|
158
|
-
signing: resolveSigningOptions({
|
|
159
|
-
keyStorePath: parsed.keyStorePath,
|
|
160
|
-
keyAlias: parsed.keyAlias,
|
|
161
|
-
keyStorePassword: parsed.keyStorePassword,
|
|
162
|
-
keyPassword: parsed.keyPassword,
|
|
163
|
-
}),
|
|
164
|
-
apkName: parsed.apkName,
|
|
165
|
-
keepApks: parsed.keepApks,
|
|
166
|
-
overwrite: parsed.overwrite,
|
|
167
|
-
verbose: parsed.verbose,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
//# sourceMappingURL=cliArgs.js.map
|