@leonxin/meetgames 0.1.8 → 0.1.11
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/.agents/skills/meet-sdk-regression/SKILL.md +93 -0
- package/.cursor/mcp.example.json +16 -0
- package/.cursor/mcp.json +11 -0
- package/.cursor/skills/meetgames-mcp/SKILL.md +48 -0
- package/.vite/vitest/results.json +1 -0
- package/README.md +31 -8
- package/dist/aab-converter/aab-entry.d.ts +3 -0
- package/dist/aab-converter/aab-entry.d.ts.map +1 -0
- package/dist/aab-converter/aab-entry.js +49 -0
- package/dist/aab-converter/aab-entry.js.map +1 -0
- package/dist/aab-converter/apksExtractor.d.ts +2 -0
- package/dist/aab-converter/apksExtractor.d.ts.map +1 -0
- package/dist/aab-converter/apksExtractor.js +108 -0
- package/dist/aab-converter/apksExtractor.js.map +1 -0
- package/dist/aab-converter/bundletoolRunner.d.ts +15 -0
- package/dist/aab-converter/bundletoolRunner.d.ts.map +1 -0
- package/dist/aab-converter/bundletoolRunner.js +46 -0
- package/dist/aab-converter/bundletoolRunner.js.map +1 -0
- package/dist/aab-converter/cliArgs.d.ts +27 -0
- package/dist/aab-converter/cliArgs.d.ts.map +1 -0
- package/dist/aab-converter/cliArgs.js +170 -0
- package/dist/aab-converter/cliArgs.js.map +1 -0
- package/dist/aab-converter/convertAabToApk.d.ts +7 -0
- package/dist/aab-converter/convertAabToApk.d.ts.map +1 -0
- package/dist/aab-converter/convertAabToApk.js +69 -0
- package/dist/aab-converter/convertAabToApk.js.map +1 -0
- package/dist/aab-converter/resourcePaths.d.ts +4 -0
- package/dist/aab-converter/resourcePaths.d.ts.map +1 -0
- package/dist/aab-converter/resourcePaths.js +42 -0
- package/dist/aab-converter/resourcePaths.js.map +1 -0
- package/dist/aab-converter/signingOptions.d.ts +9 -0
- package/dist/aab-converter/signingOptions.d.ts.map +1 -0
- package/dist/aab-converter/signingOptions.js +21 -0
- package/dist/aab-converter/signingOptions.js.map +1 -0
- package/dist/aab-converter/types.d.ts +24 -0
- package/dist/aab-converter/types.d.ts.map +1 -0
- package/dist/aab-converter/types.js +2 -0
- package/dist/aab-converter/types.js.map +1 -0
- package/dist/android/adapter.d.ts.map +1 -1
- package/dist/android/adapter.js +2 -2
- package/dist/android/adapter.js.map +1 -1
- package/dist/android/detect.d.ts +2 -2
- package/dist/android/detect.d.ts.map +1 -1
- package/dist/android/detect.js +36 -8
- package/dist/android/detect.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +157 -31
- package/dist/cli.js.map +1 -1
- package/dist/config/meetSdkDefaultConfig.d.ts +19 -2
- package/dist/config/meetSdkDefaultConfig.d.ts.map +1 -1
- package/dist/config/meetSdkDefaultConfig.js +67 -5
- package/dist/config/meetSdkDefaultConfig.js.map +1 -1
- package/dist/config/meetSdkIosConfig.d.ts +21 -0
- package/dist/config/meetSdkIosConfig.d.ts.map +1 -0
- package/dist/config/meetSdkIosConfig.js +66 -0
- package/dist/config/meetSdkIosConfig.js.map +1 -0
- package/dist/config/meetSdkRemoteConfig.d.ts +18 -1
- package/dist/config/meetSdkRemoteConfig.d.ts.map +1 -1
- package/dist/config/meetSdkRemoteConfig.js +61 -25
- package/dist/config/meetSdkRemoteConfig.js.map +1 -1
- package/dist/contracts/types.d.ts +19 -6
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/core/doctor.d.ts +17 -0
- package/dist/core/doctor.d.ts.map +1 -0
- package/dist/core/doctor.js +444 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +0 -15
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/platform.d.ts +12 -0
- package/dist/core/platform.d.ts.map +1 -0
- package/dist/core/platform.js +40 -0
- package/dist/core/platform.js.map +1 -0
- package/dist/core/reporter.js +1 -1
- package/dist/core/reporter.js.map +1 -1
- package/dist/core/workspace.d.ts +2 -2
- package/dist/core/workspace.d.ts.map +1 -1
- package/dist/core/workspace.js +4 -5
- package/dist/core/workspace.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/ios/channelConfig.d.ts +1 -0
- package/dist/ios/channelConfig.d.ts.map +1 -1
- package/dist/ios/channelConfig.js +82 -0
- package/dist/ios/channelConfig.js.map +1 -1
- package/dist/ios/codeUtils.d.ts +1 -0
- package/dist/ios/codeUtils.d.ts.map +1 -1
- package/dist/ios/codeUtils.js +11 -2
- package/dist/ios/codeUtils.js.map +1 -1
- package/dist/ios/detect.d.ts +2 -2
- package/dist/ios/detect.d.ts.map +1 -1
- package/dist/ios/detect.js +49 -10
- package/dist/ios/detect.js.map +1 -1
- package/dist/ios/entitlements.d.ts +4 -0
- package/dist/ios/entitlements.d.ts.map +1 -0
- package/dist/ios/entitlements.js +53 -0
- package/dist/ios/entitlements.js.map +1 -0
- package/dist/ios/fileManager.d.ts.map +1 -1
- package/dist/ios/fileManager.js +3 -2
- package/dist/ios/fileManager.js.map +1 -1
- package/dist/ios/infoPlist.d.ts +1 -1
- package/dist/ios/infoPlist.d.ts.map +1 -1
- package/dist/ios/infoPlist.js.map +1 -1
- package/dist/ios/integrate.d.ts.map +1 -1
- package/dist/ios/integrate.js +211 -36
- package/dist/ios/integrate.js.map +1 -1
- package/dist/ios/pbxprojEditor.d.ts +2 -0
- package/dist/ios/pbxprojEditor.d.ts.map +1 -1
- package/dist/ios/pbxprojEditor.js +179 -1
- package/dist/ios/pbxprojEditor.js.map +1 -1
- package/dist/ios/pluginConfig.d.ts +1 -0
- package/dist/ios/pluginConfig.d.ts.map +1 -1
- package/dist/ios/pluginConfig.js +36 -4
- package/dist/ios/pluginConfig.js.map +1 -1
- package/dist/ios/sdkBundle.d.ts +1 -1
- package/dist/ios/sdkBundle.d.ts.map +1 -1
- package/dist/ios/sdkBundle.js +7 -5
- package/dist/ios/sdkBundle.js.map +1 -1
- package/dist/ios/template.d.ts +1 -0
- package/dist/ios/template.d.ts.map +1 -1
- package/dist/ios/template.js +14 -1
- package/dist/ios/template.js.map +1 -1
- package/dist/ios/types.d.ts +2 -2
- package/dist/ios/types.d.ts.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -13
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/service.d.ts +8 -6
- package/dist/mcp/service.d.ts.map +1 -1
- package/dist/mcp/service.js +34 -14
- package/dist/mcp/service.js.map +1 -1
- package/dist/ops/handlers.d.ts.map +1 -1
- package/dist/ops/handlers.js +10 -4
- package/dist/ops/handlers.js.map +1 -1
- package/dist/remote/sdkHomeDownload.d.ts +65 -0
- package/dist/remote/sdkHomeDownload.d.ts.map +1 -0
- package/dist/remote/sdkHomeDownload.js +208 -0
- package/dist/remote/sdkHomeDownload.js.map +1 -0
- package/dist/remote/topsdkDownloadSdkConfig.d.ts.map +1 -1
- package/dist/remote/topsdkDownloadSdkConfig.js +11 -1
- package/dist/remote/topsdkDownloadSdkConfig.js.map +1 -1
- package/dist/shared/errors.d.ts +7 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +16 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/fileUtils.d.ts +5 -0
- package/dist/shared/fileUtils.d.ts.map +1 -0
- package/dist/shared/fileUtils.js +35 -0
- package/dist/shared/fileUtils.js.map +1 -0
- package/dist/shared/logger.d.ts +10 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/logger.js +37 -0
- package/dist/shared/logger.js.map +1 -0
- package/dist/shared/pathUtils.d.ts +4 -0
- package/dist/shared/pathUtils.d.ts.map +1 -0
- package/dist/shared/pathUtils.js +22 -0
- package/dist/shared/pathUtils.js.map +1 -0
- package/dist/shared/processRunner.d.ts +12 -0
- package/dist/shared/processRunner.d.ts.map +1 -0
- package/dist/shared/processRunner.js +31 -0
- package/dist/shared/processRunner.js.map +1 -0
- package/docs/AAB_CONVERTER_CLI_PLAN.md +392 -0
- package/docs/API.md +246 -32
- package/docs/CLI.md +292 -0
- package/docs/INTEGRATION.md +116 -0
- package/docs/MCP.md +86 -0
- package/docs/README.md +19 -10
- package/docs/{api → archive/api}/downloadSDKConfig.md +8 -6
- package/docs/{api → archive/api}/getChannelConfig-meetgames.md +1 -1
- package/docs/archive/ios-migration.md +2139 -0
- package/docs/{ → archive/product/}/346/212/200/346/234/257/346/226/271/346/241/210/350/260/203/347/240/224.md +7 -7
- package/docs/{ → archive/product/}/351/234/200/346/261/202/346/226/207/346/241/243.md +15 -14
- package/logs/convert-20260622-155037.log +5 -0
- package/logs/convert-20260622-155226.log +6 -0
- package/meetsdk-android.json +2 -1
- package/meetsdk-ios.json +15 -0
- package/package.json +10 -36
- package/scripts/package-aab-cli-win.mjs +193 -0
- package/src/aab-converter/aab-entry.ts +48 -0
- package/src/aab-converter/apksExtractor.ts +119 -0
- package/src/aab-converter/bundletoolRunner.ts +63 -0
- package/src/aab-converter/cliArgs.ts +194 -0
- package/src/aab-converter/convertAabToApk.ts +81 -0
- package/src/aab-converter/resourcePaths.ts +43 -0
- package/src/aab-converter/signingOptions.ts +29 -0
- package/src/aab-converter/types.ts +26 -0
- package/src/android/adapter.ts +9 -0
- package/src/android/assembleIntegrationJson.ts +33 -0
- package/src/android/detect.ts +132 -0
- package/src/android/downloadGoogleServicesJson.ts +56 -0
- package/src/android/gradle.ts +116 -0
- package/src/android/manifest.ts +50 -0
- package/src/android/meetSdkRemoteGradle.ts +837 -0
- package/src/cli.ts +488 -0
- package/src/config/fetchConfigWrite.ts +30 -0
- package/src/config/loadAndroidIntegration.ts +41 -0
- package/src/config/loadManifest.ts +40 -0
- package/src/config/meetSdkDefaultConfig.ts +99 -0
- package/src/config/meetSdkIosConfig.ts +87 -0
- package/src/config/meetSdkRemoteConfig.ts +1211 -0
- package/src/config/topsdkFeatureModules.ts +92 -0
- package/src/contracts/types.ts +121 -0
- package/src/core/doctor.ts +485 -0
- package/src/core/patch.ts +64 -0
- package/src/core/pipeline.ts +107 -0
- package/src/core/platform.ts +47 -0
- package/src/core/previewPatches.ts +23 -0
- package/src/core/reporter.ts +24 -0
- package/src/core/workspace.ts +29 -0
- package/src/entry.ts +7 -0
- package/src/index.ts +133 -0
- package/src/ios/channelConfig.ts +128 -0
- package/src/ios/codeUtils.ts +160 -0
- package/src/ios/detect.ts +105 -0
- package/src/ios/entitlements.ts +61 -0
- package/src/ios/fileManager.ts +48 -0
- package/src/ios/infoPlist.ts +55 -0
- package/src/ios/integrate.ts +516 -0
- package/src/ios/pbxprojEditor.ts +383 -0
- package/src/ios/pluginConfig.ts +97 -0
- package/src/ios/reserved.ts +8 -0
- package/src/ios/sdkBundle.ts +36 -0
- package/src/ios/template.ts +36 -0
- package/src/ios/types.ts +65 -0
- package/src/mcp/server.ts +170 -0
- package/src/mcp/service.ts +222 -0
- package/src/mcp-entry.ts +7 -0
- package/src/ops/fileStore.ts +56 -0
- package/src/ops/handlers.ts +304 -0
- package/src/remote/fetchJson.ts +22 -0
- package/src/remote/sdkHomeDownload.ts +274 -0
- package/src/remote/topsdkDownloadSdkConfig.ts +93 -0
- package/src/remote/topsdkGetSdkConfig.ts +122 -0
- package/src/remote/topsdkSign.ts +10 -0
- package/src/shared/errors.ts +16 -0
- package/src/shared/fileUtils.ts +41 -0
- package/src/shared/logger.ts +49 -0
- package/src/shared/pathUtils.ts +24 -0
- package/src/shared/processRunner.ts +43 -0
- package/test-projects/README.md +51 -0
- package/test-projects/_preview/pipeline.patch +281 -0
- package/tests/aab-converter.test.ts +213 -0
- package/tests/assemble.test.ts +12 -0
- package/tests/doctor.test.ts +89 -0
- package/tests/downloadGoogleServicesJson.test.ts +47 -0
- package/tests/fetch-remote.test.ts +23 -0
- package/tests/fetchConfigOverrides.test.ts +28 -0
- package/tests/fetchConfigWrite.test.ts +54 -0
- package/tests/gradle.test.ts +33 -0
- package/tests/integration-json.test.ts +29 -0
- package/tests/ios.codeUtils.test.ts +23 -0
- package/tests/ios.sdkBundle.test.ts +16 -0
- package/tests/loadManifest.test.ts +15 -0
- package/tests/manifest-xml.test.ts +30 -0
- package/tests/mcp.e2e.ts +217 -0
- package/tests/mcp.service.test.ts +53 -0
- package/tests/meetSdkRemoteConfig.test.ts +456 -0
- package/tests/meetSdkRemoteGradle.test.ts +414 -0
- package/tests/pipeline.android.test.ts +96 -0
- package/tests/pipeline.integration-json.test.ts +58 -0
- package/tests/pipeline.ios.test.ts +385 -0
- package/tests/pipeline.preview.patch.test.ts +85 -0
- package/tests/platformSelection.test.ts +77 -0
- package/tests/sdkHomeDownload.test.ts +124 -0
- package/tests/sdkVersionConfig.test.ts +130 -0
- package/tests/test-projects-hosts.test.ts +78 -0
- package/tests/topsdk.test.ts +53 -0
- package/tests/topsdkDownloadSdkConfig.test.ts +81 -0
- package/tests/topsdkFeatureModules.test.ts +116 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +9 -0
- package/vitest.mcp.config.ts +11 -0
- package/bundled/android/sample.txt +0 -1
- package/docs/ANDROID.md +0 -133
- package/docs/CURSOR-MCP-SETUP.md +0 -72
- package/docs/MCP-SKILL.md +0 -63
- package/fixtures/api-samples/getChannelConfig-meetgames.sample.json +0 -123
- package/fixtures/meetsdk-remote-config.download-shape.json +0 -20
- package/fixtures/meetsdk-remote-config.mock.json +0 -69
- package/fixtures/recipes/android-default.fixture.yaml +0 -15
- package/fixtures/recipes/android-integration.fixture.json +0 -29
- package/fixtures/topsdk-config-reference.json +0 -39
- /package/docs/{api → archive/api}/getSDKConfig.md +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meet-sdk-regression
|
|
3
|
+
description: Run and diagnose meet-sdk-tool SDK integration regression checks, including CLI, MCP stdio, Android, and iOS fixture coverage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Meet SDK Tool Regression
|
|
7
|
+
|
|
8
|
+
Use this skill when the user asks to verify,联调,回归, or diagnose changes in `meet-sdk-tool`.
|
|
9
|
+
|
|
10
|
+
## Scope
|
|
11
|
+
|
|
12
|
+
This skill is for the local `meet-sdk-tool` repository. It validates the SDK integration toolchain across:
|
|
13
|
+
|
|
14
|
+
- TypeScript build output.
|
|
15
|
+
- Vitest unit and fixture integration tests.
|
|
16
|
+
- Android and iOS integration fixtures under `fixtures/`.
|
|
17
|
+
- MCP stdio server startup, tool listing, and tool calls.
|
|
18
|
+
- Fetch/setup flows using local mock HTTP responses where tests provide them.
|
|
19
|
+
|
|
20
|
+
Do not use this skill for publishing to npm, changing production SDK credentials, or running against a real customer project unless the user explicitly asks.
|
|
21
|
+
|
|
22
|
+
## Standard Commands
|
|
23
|
+
|
|
24
|
+
Run from the repository root:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm run build
|
|
28
|
+
npm test
|
|
29
|
+
npm run test:mcp
|
|
30
|
+
npm run test:regression
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use the shortest command that matches the change:
|
|
34
|
+
|
|
35
|
+
- Pure parser/config/utility change: `npm test`
|
|
36
|
+
- MCP server, MCP tool schema, or MCP service change: `npm run test:mcp`
|
|
37
|
+
- Pipeline, Android, iOS, remote config, CLI, or release-sensitive change: `npm run test:regression`
|
|
38
|
+
|
|
39
|
+
## Pass Criteria
|
|
40
|
+
|
|
41
|
+
A regression run passes only when all of these are true:
|
|
42
|
+
|
|
43
|
+
- `npm run build` exits 0.
|
|
44
|
+
- `npm test` exits 0 with no failed tests.
|
|
45
|
+
- Skipped tests are acceptable only for optional fixture variants under `fixtures/` when their required project files or per-project `meetsdk-remote-config.json` are absent.
|
|
46
|
+
- `npm run test:mcp` exits 0.
|
|
47
|
+
- MCP E2E lists exactly these public tools:
|
|
48
|
+
- `meetgames_doctor`
|
|
49
|
+
- `meetgames_fetch_config`
|
|
50
|
+
- `meetgames_integrate_dry_run`
|
|
51
|
+
- `meetgames_integrate_apply`
|
|
52
|
+
- `meetgames_setup`
|
|
53
|
+
- MCP E2E can call `doctor`, `integrate_dry_run`, `integrate_apply`, `fetch_config`, and `setup(dryRun=true)` against temporary fixtures.
|
|
54
|
+
- Dry-run tests do not write integration output into the target project.
|
|
55
|
+
- Apply tests write only into temporary fixture copies.
|
|
56
|
+
- Host project fixtures are read from `fixtures/android-test-project/` and `fixtures/ios-test-project/`; `test-projects/_preview/` is only generated dry-run output.
|
|
57
|
+
- Remote calls used by tests are mocked or redirected to local test servers.
|
|
58
|
+
|
|
59
|
+
## Workflow
|
|
60
|
+
|
|
61
|
+
1. Inspect the change area before running commands.
|
|
62
|
+
2. Run the targeted command first when the change is narrow.
|
|
63
|
+
3. Run `npm run test:regression` before considering the task complete when behavior changed.
|
|
64
|
+
4. If a test fails, read the first failing assertion and the fixture it used before editing code.
|
|
65
|
+
5. Keep fixes scoped to the failing behavior; do not update snapshots or fixture expectations unless the behavior change is intentional.
|
|
66
|
+
6. After a fix, rerun the failed test command, then rerun `npm run test:regression`.
|
|
67
|
+
|
|
68
|
+
## Failure Triage
|
|
69
|
+
|
|
70
|
+
Build failures usually mean exported types, `NodeNext` import paths, or generated `dist/` entry assumptions changed.
|
|
71
|
+
|
|
72
|
+
`npm test` failures usually indicate core behavior regressions in config parsing, platform detection, Gradle edits, Xcode edits, iOS plugin mapping, or dry-run patch generation.
|
|
73
|
+
|
|
74
|
+
`npm run test:mcp` failures usually mean one of these changed:
|
|
75
|
+
|
|
76
|
+
- `dist/mcp-entry.js` was not built.
|
|
77
|
+
- MCP tool names or schemas changed without updating tests/docs.
|
|
78
|
+
- A tool now returns a different `structuredContent` shape.
|
|
79
|
+
- A tool made an unmocked remote request.
|
|
80
|
+
- `dryRun` or `apply` write semantics changed.
|
|
81
|
+
- Temporary fixture setup is missing a required project file.
|
|
82
|
+
|
|
83
|
+
Network-looking failures in tests should be treated as test bugs unless the command was intentionally pointed at a real service. The default automated regression path should not depend on external network availability.
|
|
84
|
+
|
|
85
|
+
## Reporting
|
|
86
|
+
|
|
87
|
+
When reporting results, include:
|
|
88
|
+
|
|
89
|
+
- Commands run.
|
|
90
|
+
- Pass/fail status.
|
|
91
|
+
- Number of test files and tests when available.
|
|
92
|
+
- The first failing file/assertion if anything failed.
|
|
93
|
+
- Whether any real network or real project path was used.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"meetgames-mcp-local-node": {
|
|
4
|
+
"command": "node",
|
|
5
|
+
"args": [
|
|
6
|
+
"/Users/work/Workspace/Projects/meet-sdk-tool/dist/mcp-entry.js"
|
|
7
|
+
],
|
|
8
|
+
"cwd": "/Users/work/Workspace/Projects/meet-sdk-tool"
|
|
9
|
+
},
|
|
10
|
+
"meetgames-mcp-global-bin": {
|
|
11
|
+
"command": "meetgames-mcp",
|
|
12
|
+
"args": [],
|
|
13
|
+
"cwd": "/Users/work/Workspace/Projects/meet-sdk-tool"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
package/.cursor/mcp.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: meetgames-mcp
|
|
3
|
+
description: Use meetgames MCP tools for predictable Android integration workflows. Use when running doctor, fetch-config, dry-run integration, or apply integration for meet-sdk-tool projects.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Meetgames MCP
|
|
8
|
+
|
|
9
|
+
Use this skill when operating the `meetgames` integration workflow through MCP tools.
|
|
10
|
+
|
|
11
|
+
## Goals
|
|
12
|
+
|
|
13
|
+
- Keep operations predictable and repeatable.
|
|
14
|
+
- Minimize accidental writes by preferring dry-run first.
|
|
15
|
+
- Keep project-specific values in `meetsdk-remote-config.json`.
|
|
16
|
+
|
|
17
|
+
## Tool order
|
|
18
|
+
|
|
19
|
+
**Default (one-shot):**
|
|
20
|
+
|
|
21
|
+
1. `meetgames_doctor` (optional)
|
|
22
|
+
2. `meetgames_setup` with `dryRun: true` → review `integrate.patch` / errors
|
|
23
|
+
3. `meetgames_setup` with `dryRun: false` (only after review)
|
|
24
|
+
|
|
25
|
+
**Step-by-step:**
|
|
26
|
+
|
|
27
|
+
1. `meetgames_doctor`
|
|
28
|
+
2. `meetgames_fetch_config` (only when config should be refreshed from backend)
|
|
29
|
+
3. `meetgames_integrate_dry_run`
|
|
30
|
+
4. Review `report.errors`, `report.warnings`, `patch`
|
|
31
|
+
5. `meetgames_integrate_apply` (only after dry-run is accepted)
|
|
32
|
+
|
|
33
|
+
## Operational rules
|
|
34
|
+
|
|
35
|
+
- Always pass `projectRoot` explicitly when it is known.
|
|
36
|
+
- Treat `isError: true` or `report.errors.length > 0` as hard stop.
|
|
37
|
+
- Do not call `meetgames_integrate_apply` before a successful dry-run unless the user explicitly asks to skip preview.
|
|
38
|
+
- Do not edit recipe paths through MCP; integration always uses built-in `recipes/integrate-default.yaml`.
|
|
39
|
+
- Prefer `meetgames_setup` when both remote config and integration are needed; use step-by-step tools when only one phase should run.
|
|
40
|
+
|
|
41
|
+
## Response format
|
|
42
|
+
|
|
43
|
+
After each tool call, report:
|
|
44
|
+
|
|
45
|
+
- What was executed
|
|
46
|
+
- Whether it changed files or only previewed
|
|
47
|
+
- Any warnings/errors
|
|
48
|
+
- Next recommended action
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"2.1.9","results":[[":tests/meetSdkRemoteGradle.test.ts",{"duration":11.436916999999994,"failed":false}],[":tests/meetSdkRemoteConfig.test.ts",{"duration":7.487458000000004,"failed":false}],[":tests/pipeline.ios.test.ts",{"duration":974.107125,"failed":false}],[":tests/topsdkFeatureModules.test.ts",{"duration":2.0586250000000064,"failed":false}],[":tests/topsdkDownloadSdkConfig.test.ts",{"duration":4.965624999999989,"failed":false}],[":tests/pipeline.android.test.ts",{"duration":210.77375000000006,"failed":false}],[":tests/pipeline.preview.patch.test.ts",{"duration":248.23275,"failed":false}],[":tests/topsdk.test.ts",{"duration":3.366041999999993,"failed":false}],[":tests/fetchConfigWrite.test.ts",{"duration":2.470207999999957,"failed":false}],[":tests/downloadGoogleServicesJson.test.ts",{"duration":1.3860410000000059,"failed":false}],[":tests/pipeline.integration-json.test.ts",{"duration":142.87016700000004,"failed":false}],[":tests/manifest-xml.test.ts",{"duration":6.438333,"failed":false}],[":tests/test-projects-hosts.test.ts",{"duration":4.310625000000016,"failed":false}],[":tests/mcp.service.test.ts",{"duration":158.16700000000003,"failed":false}],[":tests/gradle.test.ts",{"duration":2.6391669999999863,"failed":false}],[":tests/ios.codeUtils.test.ts",{"duration":1.1439169999999876,"failed":false}],[":tests/integration-json.test.ts",{"duration":81.065292,"failed":false}],[":tests/fetchConfigOverrides.test.ts",{"duration":2.4532499999999686,"failed":false}],[":tests/ios.sdkBundle.test.ts",{"duration":2.014208999999994,"failed":false}],[":tests/assemble.test.ts",{"duration":1.2230839999999716,"failed":false}],[":tests/fetch-remote.test.ts",{"duration":1.452792000000045,"failed":false}],[":tests/loadManifest.test.ts",{"duration":22.402125000000012,"failed":false}]]}
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Meet SDK 集成 CLI:从 gp-sdk 拉取渠道配置,自动修改 Android Gradle / Manifest 与 iOS Xcode 工程。
|
|
4
4
|
|
|
5
5
|
- **远程配置**(每游戏不同):`meetsdk-remote-config.json` — 由 `fetch-config` 从 `downloadSDKConfig` **原样落盘**
|
|
6
|
-
- **固定 SDK
|
|
6
|
+
- **固定 SDK 配置**(全游戏通用):`meetsdk-android.json` / `meetsdk-ios.json` — 存放和游戏无关的 SDK 版本、仓库、依赖坐标等配置;Android / iOS 版本由 sdk-home `version` 接口获取后写入对应文件
|
|
7
7
|
|
|
8
8
|
要求 **Node.js ≥ 18**。宿主工程需为**纯原生** Android / iOS 项目。
|
|
9
9
|
|
|
@@ -48,6 +48,7 @@ meetgames setup \
|
|
|
48
48
|
| 变量 | 说明 |
|
|
49
49
|
|------|------|
|
|
50
50
|
| `TOPSDK_API_BASE_URL` | 覆盖 API 根地址(本地 gp-sdk console 联调) |
|
|
51
|
+
| `MEETGAMES_SDK_HOME_API_BASE_URL` | 覆盖 sdk-home API 根地址;用于 Android 最新版本查询和 iOS SDK 下载 |
|
|
51
52
|
| `TOPSDK_CHANNEL_TYPE` | 默认渠道类型 |
|
|
52
53
|
| `TOPSDK_APP_ID` | 默认 appId |
|
|
53
54
|
|
|
@@ -60,6 +61,7 @@ TOPSDK_API_BASE_URL=http://localhost:8081/ \
|
|
|
60
61
|
meetgames fetch-config \
|
|
61
62
|
--project-root . \
|
|
62
63
|
--app-id <appId> \
|
|
64
|
+
--app-secret <appSecret> \
|
|
63
65
|
--channel-type GOOGLE
|
|
64
66
|
```
|
|
65
67
|
|
|
@@ -69,11 +71,26 @@ meetgames fetch-config \
|
|
|
69
71
|
|------|------|
|
|
70
72
|
| `doctor` | 检测工程类型与路径 |
|
|
71
73
|
| `fetch-config` | GET `downloadSDKConfig`,原样写入 `meetsdk-remote-config.json` |
|
|
72
|
-
| `integrate` | 按内置 recipe 修改 Gradle / Manifest / iOS
|
|
74
|
+
| `integrate` | 按内置 recipe 修改 Gradle / Manifest / iOS 工程;Android 会从 sdk-home 读取最新 SDK 版本并写入 `meetsdk-android.json` |
|
|
73
75
|
| `setup` | `fetch-config` + `integrate` |
|
|
76
|
+
| `download-ios-sdk` | 从 sdk-home 获取 iOS SDK 下载地址,下载 zip 并解压到 `bundled/ios-sdk`,并写入 `meetsdk-ios.json` |
|
|
74
77
|
|
|
75
78
|
常用参数:`--project-root`、`--dry-run`、`--verbose`、`--patch-file`(integrate 预览 diff)。
|
|
76
79
|
|
|
80
|
+
多 App 入口工程建议显式指定目标:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Android 多 application module
|
|
84
|
+
meetgames integrate \
|
|
85
|
+
--project-root /path/to/android-project \
|
|
86
|
+
--app-target :app
|
|
87
|
+
|
|
88
|
+
# iOS 多 App target
|
|
89
|
+
meetgames integrate \
|
|
90
|
+
--project-root /path/to/ios-project \
|
|
91
|
+
--app-target GameRelease
|
|
92
|
+
```
|
|
93
|
+
|
|
77
94
|
## 从源码开发
|
|
78
95
|
|
|
79
96
|
源码为内部私有仓库,请向团队获取访问权限后 clone,或在本地直接开发:
|
|
@@ -84,7 +101,12 @@ npm install
|
|
|
84
101
|
npm run build
|
|
85
102
|
npm test
|
|
86
103
|
|
|
87
|
-
node dist/entry.js doctor
|
|
104
|
+
node dist/entry.js doctor \
|
|
105
|
+
--app-id <APP_ID> \
|
|
106
|
+
--app-secret '<APP_SECRET>' \
|
|
107
|
+
--channel-type GOOGLE \
|
|
108
|
+
--project-root fixtures/android-test-project/android-latest-project \
|
|
109
|
+
--env test
|
|
88
110
|
```
|
|
89
111
|
|
|
90
112
|
## 发布到 npm
|
|
@@ -101,10 +123,11 @@ npm publish --access public
|
|
|
101
123
|
|
|
102
124
|
| 文档 | 说明 |
|
|
103
125
|
|------|------|
|
|
104
|
-
| [docs/
|
|
105
|
-
| [docs/
|
|
106
|
-
| [docs/
|
|
107
|
-
| [docs/
|
|
126
|
+
| [docs/README.md](docs/README.md) | 文档索引 |
|
|
127
|
+
| [docs/CLI.md](docs/CLI.md) | CLI 子命令、参数、生效范围与环境变量 |
|
|
128
|
+
| [docs/INTEGRATION.md](docs/INTEGRATION.md) | Android / iOS SDK 自动接入说明 |
|
|
129
|
+
| [docs/API.md](docs/API.md) | `downloadSDKConfig` 接口和配置字段说明 |
|
|
130
|
+
| [docs/MCP.md](docs/MCP.md) | MCP 工具与 Cursor 配置 |
|
|
108
131
|
|
|
109
132
|
## npm 包内容说明
|
|
110
133
|
|
|
@@ -113,7 +136,7 @@ npm publish --access public
|
|
|
113
136
|
- `test-projects/`(仅仓库内 Vitest / 联调样例)
|
|
114
137
|
- `bundled/ios-sdk/`(iOS 二进制 SDK 体积大,请从 SDK 下载渠道或源码仓库获取)
|
|
115
138
|
|
|
116
|
-
Android 小型 bundled 资源(`bundled/android
|
|
139
|
+
Android 小型 bundled 资源(`bundled/android/`)、`meetsdk-android.json`、`meetsdk-ios.json` 与 `recipes/` 会随包分发。
|
|
117
140
|
|
|
118
141
|
## License
|
|
119
142
|
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apksExtractor.js","sourceRoot":"","sources":["../../src/aab-converter/apksExtractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|