@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
|
@@ -38,7 +38,7 @@ meetgames fetch-config --app-id 791251136341225472 --app-secret YOUR_APP_SECRET
|
|
|
38
38
|
|
|
39
39
|
- **Content-Type**:`application/json`(附件下载头 `Content-Disposition: meetsdk-remote-config.json`)
|
|
40
40
|
- **Body**:即为 `meetsdk-remote-config.json` 全文(pretty JSON),**不是** `{ code, result }` 包装
|
|
41
|
-
- **落盘**:`fetch-config` / MCP `meetgames_fetch_config` 将响应 **bytes 原样写入**
|
|
41
|
+
- **落盘**:`fetch-config` / MCP `meetgames_fetch_config` 将响应 **bytes 原样写入** `~/.cache/meet-sdk-tool`,不注入 `dependencies`/`repositories`/`topsdk.version` 等字段;这些固定 SDK 配置仅在 `integrate` 时从内置 [`config/meetsdk-android.json`](../../config/meetsdk-android.json) 合并。
|
|
42
42
|
|
|
43
43
|
### 服务端数据来源(gp-sdk MySQL)
|
|
44
44
|
|
|
@@ -56,7 +56,7 @@ meetgames fetch-config --app-id 791251136341225472 --app-secret YOUR_APP_SECRET
|
|
|
56
56
|
|
|
57
57
|
详见 gp-sdk `SdkConfigDownloadServiceImpl`;**不包含** `topsdk.version`(integrate 时用 `meetsdk-android.json` 兜底)。
|
|
58
58
|
|
|
59
|
-
**子模块写入**:只要库表里有对应配置参数即写入子键,value 为对象(或 `{}`);无配置**不写该键**(不出现 `false`)。插件对象内只写有值字段,不写空字符串占位。`channel_auth` 输出字段为 `clientId` / `secret` / `redirect` / `scheme` / `name`;`channel_third_data_platform` 输出字段保持 `devKey` / `appleAppId` / `firebaseUrl` / `firebaseName` / `appCode`
|
|
59
|
+
**子模块写入**:只要库表里有对应配置参数即写入子键,value 为对象(或 `{}`);无配置**不写该键**(不出现 `false`)。插件对象内只写有值字段,不写空字符串占位。`channel_auth` 输出字段为 `clientId` / `secret` / `redirect` / `scheme` / `name`;`channel_third_data_platform` 输出字段保持 `devKey` / `appleAppId` / `firebaseUrl` / `firebaseName` / `appCode` / `eventUrl` 等实体字段名,其中 `eventUrl` 属于 `analytics.adjust`,不属于 `analytics.appsflyer`。**不**再根据 `channel_auth.enable` / `channel_payment.enable` 过滤。`analytics.facebookdata` 等独立开关字段预留,待 meetgames-business 配置后再接。
|
|
60
60
|
|
|
61
61
|
`meet-sdk-tool` 按上述 DTO/entity 原字段名读取配置;旧字段名不再作为兼容输入。
|
|
62
62
|
|
|
@@ -93,7 +93,7 @@ GET https://test-business-api.meetgames.com/customer/topsdk/console/meetgames/ch
|
|
|
93
93
|
| `thirdDataPlatform.firebaseUrl` | Firebase / `firebaseUrl` 字段 |
|
|
94
94
|
| `parameterConfig` | 支付 / Google Play 服务账号等,与 `channel_payment`、parameter 表相关 |
|
|
95
95
|
|
|
96
|
-
完整 Gradle 集成仍依赖工具侧 [`meetsdk-android.json`](../../meetsdk-android.json) 合并版本与依赖。
|
|
96
|
+
完整 Gradle 集成仍依赖工具侧 [`config/meetsdk-android.json`](../../config/meetsdk-android.json) 合并版本与依赖。
|
|
97
97
|
|
|
98
98
|
## 脱敏样例
|
|
99
99
|
|
|
@@ -77,7 +77,7 @@ addManifestPlaceholders([
|
|
|
77
77
|
#### 新方式
|
|
78
78
|
|
|
79
79
|
- 远程 JSON 决定**接入哪些可选模块**(guest、email、facebook、google-iap、appsflyer 等)。
|
|
80
|
-
- 工具内置 [`meetsdk-android.json`](
|
|
80
|
+
- 工具内置 [`config/meetsdk-android.json`](../../config/meetsdk-android.json) 提供**固定** SDK 版本、仓库 URL、`classpath`、Firebase plugin、各模块 `dependencies`。
|
|
81
81
|
- `integrate` 合并后写入根工程与 App Module 的 Gradle(标记块 upsert,避免重复插入)。
|
|
82
82
|
|
|
83
83
|
**示例(由工具生成,非人工维护)**
|
package/package.json
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leonxin/meetgames",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"meetgames": "dist/entry.js",
|
|
8
|
-
"meetgames-mcp": "dist/mcp-entry.js"
|
|
9
|
-
"meetgames-aab": "dist/aab-converter/aab-entry.js"
|
|
8
|
+
"meetgames-mcp": "dist/mcp-entry.js"
|
|
10
9
|
},
|
|
11
10
|
"scripts": {
|
|
12
11
|
"build": "tsc -p tsconfig.json",
|
|
13
|
-
"build:aab": "tsc -p tsconfig.json",
|
|
14
|
-
"package:aab-win-zip": "node scripts/package-aab-cli-win.mjs",
|
|
15
12
|
"test": "vitest run",
|
|
16
13
|
"test:mcp": "npm run build && npm run test:mcp:run",
|
|
17
14
|
"test:mcp:run": "vitest run --config vitest.mcp.config.ts",
|
|
@@ -6,11 +6,6 @@ steps:
|
|
|
6
6
|
- op: files.downloadGoogleServicesJson
|
|
7
7
|
platform: android
|
|
8
8
|
args: {}
|
|
9
|
-
- op: files.copyBundled
|
|
10
|
-
platform: android
|
|
11
|
-
args:
|
|
12
|
-
from: android/sample.txt
|
|
13
|
-
to: vendor/meet-integrate/sample.txt
|
|
14
9
|
- op: ios.integrateTopSdk
|
|
15
10
|
platform: ios
|
|
16
11
|
args: {}
|
package/src/cache.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { MEETSDK_REMOTE_CONFIG_FILENAME } from "./config/meetSdkRemoteConfig.js";
|
|
6
|
+
|
|
7
|
+
export const MEET_SDK_TOOL_CACHE_ROOT = path.join(os.homedir(), ".cache", "meet-sdk-tool");
|
|
8
|
+
|
|
9
|
+
function iosSdkZipFileName(version: string): string {
|
|
10
|
+
return `topSDK-ios--V${version}.zip`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function safeSegment(value: string): string {
|
|
14
|
+
const cleaned = value.trim().replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^_+|_+$/g, "");
|
|
15
|
+
return cleaned || "unknown";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function sha256Hex(value: string, length = 16): string {
|
|
19
|
+
return crypto.createHash("sha256").update(value).digest("hex").slice(0, length);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function writeFileAtomic(absPath: string, content: string | Buffer): void {
|
|
23
|
+
ensureCacheRoot();
|
|
24
|
+
fs.mkdirSync(path.dirname(absPath), { recursive: true });
|
|
25
|
+
const tmp = path.join(path.dirname(absPath), `.${path.basename(absPath)}.${process.pid}.${Date.now()}.tmp`);
|
|
26
|
+
fs.writeFileSync(tmp, content);
|
|
27
|
+
fs.renameSync(tmp, absPath);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function ensureCacheRoot(): string {
|
|
31
|
+
fs.mkdirSync(MEET_SDK_TOOL_CACHE_ROOT, { recursive: true, mode: 0o700 });
|
|
32
|
+
try {
|
|
33
|
+
fs.chmodSync(MEET_SDK_TOOL_CACHE_ROOT, 0o700);
|
|
34
|
+
} catch {
|
|
35
|
+
// Best-effort on filesystems that do not support POSIX modes.
|
|
36
|
+
}
|
|
37
|
+
return MEET_SDK_TOOL_CACHE_ROOT;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveRemoteConfigCachePath(params: {
|
|
41
|
+
env: string;
|
|
42
|
+
appId: string;
|
|
43
|
+
channelType: string;
|
|
44
|
+
}): string {
|
|
45
|
+
return path.join(
|
|
46
|
+
MEET_SDK_TOOL_CACHE_ROOT,
|
|
47
|
+
"configs",
|
|
48
|
+
safeSegment(params.env),
|
|
49
|
+
safeSegment(params.appId),
|
|
50
|
+
safeSegment(params.channelType),
|
|
51
|
+
MEETSDK_REMOTE_CONFIG_FILENAME
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function writeRemoteConfigCache(params: {
|
|
56
|
+
env: string;
|
|
57
|
+
appId: string;
|
|
58
|
+
channelType: string;
|
|
59
|
+
requestUrl: string;
|
|
60
|
+
rawText: string;
|
|
61
|
+
warnings?: readonly string[];
|
|
62
|
+
}): { configPath: string; metadataPath: string } {
|
|
63
|
+
const fetchedAt = new Date().toISOString();
|
|
64
|
+
const metadata = `${JSON.stringify(
|
|
65
|
+
{
|
|
66
|
+
fetchedAt,
|
|
67
|
+
env: params.env,
|
|
68
|
+
appId: params.appId,
|
|
69
|
+
channelType: params.channelType,
|
|
70
|
+
requestUrl: params.requestUrl,
|
|
71
|
+
sha256: crypto.createHash("sha256").update(params.rawText).digest("hex"),
|
|
72
|
+
warnings: params.warnings ?? [],
|
|
73
|
+
},
|
|
74
|
+
null,
|
|
75
|
+
2
|
|
76
|
+
)}\n`;
|
|
77
|
+
const configPath = resolveRemoteConfigCachePath(params);
|
|
78
|
+
const metadataPath = path.join(path.dirname(configPath), "metadata.json");
|
|
79
|
+
|
|
80
|
+
writeFileAtomic(configPath, params.rawText);
|
|
81
|
+
writeFileAtomic(metadataPath, metadata);
|
|
82
|
+
|
|
83
|
+
return { configPath, metadataPath };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function pluginsHash(plugins: readonly string[]): string {
|
|
87
|
+
return sha256Hex(plugins.join(","), 12);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function resolveIosSdkCacheLayout(params: {
|
|
91
|
+
version: string;
|
|
92
|
+
packageType: string;
|
|
93
|
+
plugins: readonly string[];
|
|
94
|
+
}): { baseDir: string; zipPath: string; extractDir: string; metadataPath: string; lockDir: string } {
|
|
95
|
+
const baseDir = path.join(
|
|
96
|
+
MEET_SDK_TOOL_CACHE_ROOT,
|
|
97
|
+
"sdk",
|
|
98
|
+
"ios",
|
|
99
|
+
safeSegment(params.packageType),
|
|
100
|
+
safeSegment(params.version),
|
|
101
|
+
pluginsHash(params.plugins)
|
|
102
|
+
);
|
|
103
|
+
return {
|
|
104
|
+
baseDir,
|
|
105
|
+
zipPath: path.join(baseDir, iosSdkZipFileName(params.version)),
|
|
106
|
+
extractDir: path.join(baseDir, "extracted"),
|
|
107
|
+
metadataPath: path.join(baseDir, "metadata.json"),
|
|
108
|
+
lockDir: path.join(baseDir, ".lock"),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function writeIosSdkCacheMetadata(params: {
|
|
113
|
+
metadataPath: string;
|
|
114
|
+
version: string;
|
|
115
|
+
date?: string;
|
|
116
|
+
packageType: string;
|
|
117
|
+
plugins: readonly string[];
|
|
118
|
+
versionUrl: string;
|
|
119
|
+
downloadApiUrl: string;
|
|
120
|
+
sdkZipUrl: string;
|
|
121
|
+
zipPath: string;
|
|
122
|
+
extractDir: string;
|
|
123
|
+
resolvedSdkRoot: string;
|
|
124
|
+
}): void {
|
|
125
|
+
const zipSha256 = fs.existsSync(params.zipPath)
|
|
126
|
+
? crypto.createHash("sha256").update(fs.readFileSync(params.zipPath)).digest("hex")
|
|
127
|
+
: "";
|
|
128
|
+
writeFileAtomic(
|
|
129
|
+
params.metadataPath,
|
|
130
|
+
`${JSON.stringify(
|
|
131
|
+
{
|
|
132
|
+
fetchedAt: new Date().toISOString(),
|
|
133
|
+
version: params.version,
|
|
134
|
+
date: params.date,
|
|
135
|
+
packageType: params.packageType,
|
|
136
|
+
plugins: params.plugins,
|
|
137
|
+
versionUrl: params.versionUrl,
|
|
138
|
+
downloadApiUrl: params.downloadApiUrl,
|
|
139
|
+
sdkZipUrl: params.sdkZipUrl,
|
|
140
|
+
zipPath: params.zipPath,
|
|
141
|
+
extractDir: params.extractDir,
|
|
142
|
+
resolvedSdkRoot: params.resolvedSdkRoot,
|
|
143
|
+
zipSha256,
|
|
144
|
+
},
|
|
145
|
+
null,
|
|
146
|
+
2
|
|
147
|
+
)}\n`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function withCacheLock<T>(lockDir: string, fn: () => Promise<T>): Promise<T> {
|
|
152
|
+
fs.mkdirSync(path.dirname(lockDir), { recursive: true });
|
|
153
|
+
try {
|
|
154
|
+
fs.mkdirSync(lockDir);
|
|
155
|
+
} catch (e) {
|
|
156
|
+
if ((e as NodeJS.ErrnoException).code === "EEXIST") {
|
|
157
|
+
throw new Error(`cache path is locked by another meet-sdk-tool process: ${lockDir}`);
|
|
158
|
+
}
|
|
159
|
+
throw e;
|
|
160
|
+
}
|
|
161
|
+
return fn().finally(() => {
|
|
162
|
+
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
163
|
+
});
|
|
164
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
import type { Manifest } from "./contracts/types.js";
|
|
21
21
|
import {
|
|
22
22
|
validateDownloadSdkConfigForWrite,
|
|
23
|
-
writeDownloadSdkConfigRaw,
|
|
24
23
|
} from "./config/fetchConfigWrite.js";
|
|
25
24
|
import {
|
|
26
25
|
MEETSDK_REMOTE_CONFIG_FILENAME,
|
|
@@ -28,6 +27,11 @@ import {
|
|
|
28
27
|
tryParseAsMeetSdkRemoteConfig,
|
|
29
28
|
type MeetSdkRemoteConfig,
|
|
30
29
|
} from "./config/meetSdkRemoteConfig.js";
|
|
30
|
+
import {
|
|
31
|
+
MEET_SDK_TOOL_CACHE_ROOT,
|
|
32
|
+
resolveRemoteConfigCachePath,
|
|
33
|
+
writeRemoteConfigCache,
|
|
34
|
+
} from "./cache.js";
|
|
31
35
|
|
|
32
36
|
const EXIT = {
|
|
33
37
|
OK: 0,
|
|
@@ -62,7 +66,6 @@ interface Parsed {
|
|
|
62
66
|
iosSdkVersion: string;
|
|
63
67
|
iosSdkPlugins: string;
|
|
64
68
|
iosSdkPackageType: string;
|
|
65
|
-
iosSdkOutputDir: string;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
function printHelp(): void {
|
|
@@ -70,35 +73,35 @@ function printHelp(): void {
|
|
|
70
73
|
meetgames — Android-first integration CLI (TypeScript)
|
|
71
74
|
|
|
72
75
|
Usage:
|
|
73
|
-
meetgames integrate [--project-root <path>] [--app-target <target>] [--dry-run] [--verbose] [--patch-file <path>]
|
|
76
|
+
meetgames integrate [--project-root <path>] [--app-id ID] [--channel-type TYPE] [--env prod|pre|test] [--app-target <target>] [--dry-run] [--verbose] [--patch-file <path>]
|
|
74
77
|
meetgames fetch-config [--app-id ID] [--app-secret SECRET] [--channel-type TYPE] [--env prod|pre|test] [--project-root <path>] [--verbose]
|
|
75
|
-
meetgames download-ios-sdk [--version VERSION] [--plugins csv] [--package-type native|unity|cocos] [--sdk-api-base-url URL] [--
|
|
78
|
+
meetgames download-ios-sdk [--version VERSION] [--plugins csv] [--package-type native|unity|cocos] [--sdk-api-base-url URL] [--verbose]
|
|
76
79
|
meetgames setup [--app-id ID] [--app-secret SECRET] [--channel-type TYPE] [--env prod|pre|test] [--project-root <path>] [--app-target <target>] [--dry-run] [--verbose] [--patch-file <path>]
|
|
77
80
|
meetgames doctor [--app-id ID] [--app-secret SECRET] [--channel-type TYPE] [--env prod|pre|test] --project-root <path> [--app-target <target>] [--verbose]
|
|
78
81
|
|
|
79
82
|
Notes:
|
|
80
83
|
- Source code is TypeScript only; published bin runs compiled output under dist/.
|
|
81
84
|
- iOS: copies frameworks to topSDK/, edits project.pbxproj & Info.plist, injects AppDelegate (.m/.mm) when present (topsdk-tool-ios parity).
|
|
82
|
-
- fetch-config calls TOPSDK downloadSDKConfig and writes the response body unchanged
|
|
83
|
-
- setup runs fetch-config then
|
|
85
|
+
- fetch-config calls TOPSDK downloadSDKConfig and writes the response body unchanged under ${MEET_SDK_TOOL_CACHE_ROOT}.
|
|
86
|
+
- setup runs fetch-config, then download-ios-sdk for iOS projects, then integrate in one process.
|
|
84
87
|
- doctor / setup / integrate require --project-root and auto-select exactly one platform from that root.
|
|
85
|
-
- doctor first fetches downloadSDKConfig to
|
|
88
|
+
- doctor first fetches downloadSDKConfig to the cache, then validates the detected platform integration.
|
|
86
89
|
- integrate uses recipes/integrate-default.yaml, filtered to the detected platform before execution.
|
|
87
|
-
- iOS SDK is read from
|
|
88
|
-
- Android integrate/doctor reads the latest SDK version from sdk-home and stores it in meetsdk-android.json.
|
|
89
|
-
- download-ios-sdk calls sdk-home getDownLoadUrl, saves the iOS SDK
|
|
90
|
+
- iOS SDK is read from ${MEET_SDK_TOOL_CACHE_ROOT}/sdk/ios/.
|
|
91
|
+
- Android integrate/doctor reads the latest SDK version from sdk-home and stores it in config/meetsdk-android.json.
|
|
92
|
+
- download-ios-sdk calls sdk-home getDownLoadUrl, saves and extracts the iOS SDK under ${MEET_SDK_TOOL_CACHE_ROOT}/sdk/ios/.
|
|
90
93
|
- fetch-config requires --app-secret (or TOPSDK_APP_SECRET) to sign downloadSDKConfig; appSecret is never read from meetsdk-remote-config.json.
|
|
91
94
|
- When analytics.firebase is enabled, Android downloads google-services.json to the detected/selected app module; iOS downloads GoogleService-Info.plist next to Info.plist.
|
|
92
|
-
- fetch-config writes to
|
|
93
|
-
-
|
|
94
|
-
- Recipe op gradle.applyMeetSdkRemoteConfig reads meetsdk-remote-config.json and writes TOPSDK marker blocks to root + app build.gradle (same idea as sdk-integration-agent gradleEditor).
|
|
95
|
+
- fetch-config writes to ${MEET_SDK_TOOL_CACHE_ROOT}/configs/<env>/<appId>/<channelType>/meetsdk-remote-config.json.
|
|
96
|
+
- integrate/doctor read the cache entry selected by --env, --app-id, and --channel-type; without those flags they only read an existing project-root meetsdk-remote-config.json for compatibility.
|
|
97
|
+
- Recipe op gradle.applyMeetSdkRemoteConfig reads cached meetsdk-remote-config.json and writes TOPSDK marker blocks to root + app build.gradle (same idea as sdk-integration-agent gradleEditor).
|
|
95
98
|
|
|
96
99
|
Options (global where noted):
|
|
97
100
|
--project-root Host project directory (default: cwd); for iOS it may point to the project root or directly to a .xcodeproj directory
|
|
98
101
|
--app-target App target to integrate/check: Android application Gradle module (e.g. :app or launcher) or iOS App target name
|
|
99
|
-
--app-id fetch-config
|
|
102
|
+
--app-id fetch-config/integrate/doctor cache selector; default TOPSDK_APP_ID
|
|
100
103
|
--app-secret fetch-config: required appSecret for downloadSDKConfig sign (or env TOPSDK_APP_SECRET)
|
|
101
|
-
--channel-type fetch-config
|
|
104
|
+
--channel-type fetch-config/integrate/doctor cache selector; default TOPSDK_CHANNEL_TYPE
|
|
102
105
|
--env fetch-config: prod(正式服,默认)| pre | test(开发调试)
|
|
103
106
|
TOPSDK_API_BASE_URL fetch-config: 覆盖 API 根地址(如 http://localhost:18080/ 联调本机 console)
|
|
104
107
|
MEETGAMES_SDK_HOME_API_BASE_URL 覆盖 sdk-home API 根地址(默认 https://business-api.meetgames.com);用于 Android 最新版本查询和 iOS SDK 下载
|
|
@@ -106,10 +109,9 @@ Options (global where noted):
|
|
|
106
109
|
--version download-ios-sdk: 指定 iOS SDK 版本;不传时从 /sdk/home/version 读取最新 iOS 版本
|
|
107
110
|
--plugins download-ios-sdk: 逗号分隔插件列表;默认与下载页 iOS 默认选择一致
|
|
108
111
|
--package-type download-ios-sdk: native(默认)| unity | cocos
|
|
109
|
-
--output-dir download-ios-sdk: 解压目标目录;默认 <package-root>/bundled/ios-sdk
|
|
110
112
|
--dry-run integrate: compute changes and patch preview without writing host project files (default is write to disk)
|
|
111
113
|
--report-file Write JSON report to path
|
|
112
|
-
--patch-file integrate: write unified diff to this path (works with --dry-run). If under <pkg>/
|
|
114
|
+
--patch-file integrate: write unified diff to this path (works with --dry-run). If under <pkg>/preview-patches/, all existing files in that dir are removed first so only the latest patch remains.
|
|
113
115
|
--verbose Verbose logs and full patch preview
|
|
114
116
|
|
|
115
117
|
Subcommand notes:
|
|
@@ -139,7 +141,6 @@ function parseArgv(argv: string[]): Parsed {
|
|
|
139
141
|
iosSdkVersion: "",
|
|
140
142
|
iosSdkPlugins: "",
|
|
141
143
|
iosSdkPackageType: "",
|
|
142
|
-
iosSdkOutputDir: "",
|
|
143
144
|
};
|
|
144
145
|
const rest = argv.slice(2);
|
|
145
146
|
if (!rest.length || (rest[0]?.startsWith("-") ?? false)) {
|
|
@@ -201,12 +202,6 @@ function parseArgv(argv: string[]): Parsed {
|
|
|
201
202
|
i += 1;
|
|
202
203
|
continue;
|
|
203
204
|
}
|
|
204
|
-
if (t === "--output-dir") {
|
|
205
|
-
out.iosSdkOutputDir = path.resolve(rest[i + 1] ?? "");
|
|
206
|
-
if (!out.iosSdkOutputDir || rest[i + 1]?.startsWith("-")) fail("--output-dir requires a directory path", EXIT.INVALID_ARGS);
|
|
207
|
-
i += 1;
|
|
208
|
-
continue;
|
|
209
|
-
}
|
|
210
205
|
if (t === "--env") {
|
|
211
206
|
const v = (rest[i + 1] ?? "").toLowerCase();
|
|
212
207
|
i += 1;
|
|
@@ -254,6 +249,13 @@ function resolvedAppTarget(parsed: Parsed): string {
|
|
|
254
249
|
return parsed.appTarget;
|
|
255
250
|
}
|
|
256
251
|
|
|
252
|
+
function cachedRemoteConfigPathFromArgs(parsed: Parsed): string {
|
|
253
|
+
const appId = parsed.topsdkAppId || process.env.TOPSDK_APP_ID || "";
|
|
254
|
+
const channelType = parsed.topsdkChannelType || process.env.TOPSDK_CHANNEL_TYPE || "";
|
|
255
|
+
if (!appId || !channelType) return "";
|
|
256
|
+
return resolveRemoteConfigCachePath({ env: parsed.topsdkEnv, appId, channelType });
|
|
257
|
+
}
|
|
258
|
+
|
|
257
259
|
function selectedPlatformContext(parsed: Parsed): {
|
|
258
260
|
platform: "android" | "ios";
|
|
259
261
|
ctx: ReturnType<typeof buildWorkspaceContext>;
|
|
@@ -262,6 +264,7 @@ function selectedPlatformContext(parsed: Parsed): {
|
|
|
262
264
|
const ctx = buildWorkspaceContext(parsed.projectRoot, resolvePackageRoot(), {
|
|
263
265
|
appTarget: resolvedAppTarget(parsed),
|
|
264
266
|
sdkHomeApiBaseUrl: parsed.sdkHomeApiBaseUrl || undefined,
|
|
267
|
+
remoteConfigPath: cachedRemoteConfigPathFromArgs(parsed) || undefined,
|
|
265
268
|
});
|
|
266
269
|
const detected = detectSinglePlatform(ctx);
|
|
267
270
|
if (!detected.ok) fail(detected.error, EXIT.PROJECT_ERROR);
|
|
@@ -282,13 +285,7 @@ async function cmdDoctor(parsed: Parsed): Promise<void> {
|
|
|
282
285
|
if (!report.ok) process.exit(EXIT.CONFIG_ERROR);
|
|
283
286
|
}
|
|
284
287
|
|
|
285
|
-
|
|
286
|
-
function meetSdkRemoteConfigCachePath(projectRoot: string): string {
|
|
287
|
-
return path.join(projectRoot, MEETSDK_REMOTE_CONFIG_FILENAME);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
function readLocalMeetSdkRemoteConfig(projectRoot: string): MeetSdkRemoteConfig | null {
|
|
291
|
-
const configPath = meetSdkRemoteConfigCachePath(projectRoot);
|
|
288
|
+
function readLocalMeetSdkRemoteConfig(configPath: string): MeetSdkRemoteConfig | null {
|
|
292
289
|
if (!fs.existsSync(configPath)) return null;
|
|
293
290
|
try {
|
|
294
291
|
return tryParseAsMeetSdkRemoteConfig(JSON.parse(fs.readFileSync(configPath, "utf8")) as unknown);
|
|
@@ -298,8 +295,8 @@ function readLocalMeetSdkRemoteConfig(projectRoot: string): MeetSdkRemoteConfig
|
|
|
298
295
|
}
|
|
299
296
|
|
|
300
297
|
async function cmdFetchConfig(parsed: Parsed): Promise<void> {
|
|
301
|
-
const
|
|
302
|
-
const localConfig = readLocalMeetSdkRemoteConfig(
|
|
298
|
+
const selectedConfigPath = cachedRemoteConfigPathFromArgs(parsed);
|
|
299
|
+
const localConfig = selectedConfigPath ? readLocalMeetSdkRemoteConfig(selectedConfigPath) : null;
|
|
303
300
|
|
|
304
301
|
const appId = parsed.topsdkAppId || localConfig?.topsdk.appId || process.env.TOPSDK_APP_ID || "";
|
|
305
302
|
const appSecret = parsed.topsdkAppSecret || process.env.TOPSDK_APP_SECRET || "";
|
|
@@ -347,10 +344,18 @@ async function cmdFetchConfig(parsed: Parsed): Promise<void> {
|
|
|
347
344
|
console.warn(`[meetgames] warning: ${warning}`);
|
|
348
345
|
}
|
|
349
346
|
|
|
350
|
-
|
|
351
|
-
|
|
347
|
+
const written = writeRemoteConfigCache({
|
|
348
|
+
env: parsed.topsdkEnv,
|
|
349
|
+
appId,
|
|
350
|
+
channelType,
|
|
351
|
+
requestUrl,
|
|
352
|
+
rawText,
|
|
353
|
+
warnings: validation.warnings,
|
|
354
|
+
});
|
|
355
|
+
console.log(`[meetgames] wrote ${MEETSDK_REMOTE_CONFIG_FILENAME} (downloadSDKConfig response, unmodified): ${written.configPath}`);
|
|
352
356
|
if (parsed.verbose) {
|
|
353
357
|
console.log(`[meetgames] GET ${requestUrl}`);
|
|
358
|
+
console.log(`[meetgames] metadata: ${written.metadataPath}`);
|
|
354
359
|
}
|
|
355
360
|
}
|
|
356
361
|
|
|
@@ -396,9 +401,13 @@ async function cmdIntegrate(parsed: Parsed): Promise<void> {
|
|
|
396
401
|
}
|
|
397
402
|
|
|
398
403
|
async function cmdSetup(parsed: Parsed): Promise<void> {
|
|
399
|
-
selectedPlatformContext(parsed);
|
|
404
|
+
const { platform } = selectedPlatformContext(parsed);
|
|
400
405
|
console.log("[meetgames] setup: fetching remote config…");
|
|
401
406
|
await cmdFetchConfig(parsed);
|
|
407
|
+
if (platform === "ios") {
|
|
408
|
+
console.log("[meetgames] setup: downloading iOS SDK…");
|
|
409
|
+
await cmdDownloadIosSdk(parsed);
|
|
410
|
+
}
|
|
402
411
|
console.log("[meetgames] setup: integrating project…");
|
|
403
412
|
await cmdIntegrate(parsed);
|
|
404
413
|
}
|
|
@@ -428,7 +437,6 @@ async function cmdDownloadIosSdk(parsed: Parsed): Promise<void> {
|
|
|
428
437
|
version: parsed.iosSdkVersion || undefined,
|
|
429
438
|
plugins,
|
|
430
439
|
packageType,
|
|
431
|
-
outputDir: parsed.iosSdkOutputDir || undefined,
|
|
432
440
|
});
|
|
433
441
|
} catch (e) {
|
|
434
442
|
fail(e instanceof Error ? e.message : String(e), EXIT.NETWORK_ERROR);
|
|
@@ -437,7 +445,7 @@ async function cmdDownloadIosSdk(parsed: Parsed): Promise<void> {
|
|
|
437
445
|
console.log(`[meetgames] downloaded iOS SDK ${result.version} zip: ${result.zipPath}`);
|
|
438
446
|
console.log(`[meetgames] extracted iOS SDK to: ${result.extractDir}`);
|
|
439
447
|
console.log(`[meetgames] resolved iOS SDK root: ${result.resolvedSdkRoot}`);
|
|
440
|
-
console.log(`[meetgames]
|
|
448
|
+
console.log(`[meetgames] wrote iOS SDK metadata: ${result.cacheMetadataPath}`);
|
|
441
449
|
if (parsed.verbose) {
|
|
442
450
|
console.log(`[meetgames] GET ${result.versionUrl}`);
|
|
443
451
|
console.log(`[meetgames] GET ${result.downloadApiUrl}`);
|
|
@@ -6,13 +6,14 @@ import { defaultSdkHomeApiBaseUrl, fetchSdkHomeVersions, type SdkHomePlatformVer
|
|
|
6
6
|
|
|
7
7
|
/** Built-in Android SDK defaults (repos and per-plugin dependencies). */
|
|
8
8
|
export const MEETSDK_ANDROID_DEFAULTS_FILENAME = "meetsdk-android.json";
|
|
9
|
+
const MEETSDK_CONFIG_DIR = "config";
|
|
9
10
|
|
|
10
11
|
const defaultConfigPath = fileURLToPath(
|
|
11
|
-
new URL(`../../${MEETSDK_ANDROID_DEFAULTS_FILENAME}`, import.meta.url)
|
|
12
|
+
new URL(`../../${MEETSDK_CONFIG_DIR}/${MEETSDK_ANDROID_DEFAULTS_FILENAME}`, import.meta.url)
|
|
12
13
|
);
|
|
13
14
|
|
|
14
15
|
export function resolveMeetSdkAndroidConfigPath(packageRoot?: string): string {
|
|
15
|
-
return packageRoot ? path.join(packageRoot, MEETSDK_ANDROID_DEFAULTS_FILENAME) : defaultConfigPath;
|
|
16
|
+
return packageRoot ? path.join(packageRoot, MEETSDK_CONFIG_DIR, MEETSDK_ANDROID_DEFAULTS_FILENAME) : defaultConfigPath;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export function loadBuiltInMeetSdkDefaultConfig(options: { packageRoot?: string } = {}): MeetSdkDefaultConfig {
|
|
@@ -79,7 +80,7 @@ export function syncMeetSdkAndroidVersionToConfig(params: {
|
|
|
79
80
|
|
|
80
81
|
/**
|
|
81
82
|
* Built-in Android SDK defaults with the SDK version resolved at runtime from sdk-home.
|
|
82
|
-
* The version is also persisted to `meetsdk-android.json` so the package config
|
|
83
|
+
* The version is also persisted to `config/meetsdk-android.json` so the package config
|
|
83
84
|
* reflects the latest SDK version discovered from the download center.
|
|
84
85
|
*/
|
|
85
86
|
export async function loadMeetSdkDefaultConfigWithLatestAndroidVersion(options: {
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
4
|
export const MEETSDK_IOS_CONFIG_FILENAME = "meetsdk-ios.json";
|
|
5
|
+
const MEETSDK_CONFIG_DIR = "config";
|
|
5
6
|
|
|
6
7
|
export interface MeetSdkIosConfig {
|
|
7
8
|
topsdk: {
|
|
@@ -27,7 +28,7 @@ function normalizePlugins(value: unknown): string[] | undefined {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
export function resolveMeetSdkIosConfigPath(packageRoot: string): string {
|
|
30
|
-
return path.join(packageRoot, MEETSDK_IOS_CONFIG_FILENAME);
|
|
31
|
+
return path.join(packageRoot, MEETSDK_CONFIG_DIR, MEETSDK_IOS_CONFIG_FILENAME);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
export function tryParseAsMeetSdkIosConfig(raw: unknown): MeetSdkIosConfig | null {
|
|
@@ -57,6 +58,7 @@ export function loadMeetSdkIosConfig(packageRoot: string): MeetSdkIosConfig {
|
|
|
57
58
|
|
|
58
59
|
export function writeMeetSdkIosConfig(packageRoot: string, config: MeetSdkIosConfig): string {
|
|
59
60
|
const configPath = resolveMeetSdkIosConfigPath(packageRoot);
|
|
61
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
60
62
|
fs.writeFileSync(configPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
61
63
|
return configPath;
|
|
62
64
|
}
|
|
@@ -154,6 +154,7 @@ export type MeetSdkAnalyticsFirebaseModule = false | MeetSdkAnalyticsFirebaseCre
|
|
|
154
154
|
export interface MeetSdkAnalyticsAdjustCredentials {
|
|
155
155
|
appId: string;
|
|
156
156
|
clientId?: string;
|
|
157
|
+
eventUrl?: string;
|
|
157
158
|
enableSandbox: boolean;
|
|
158
159
|
dependencies?: MeetSdkGradleDependency[];
|
|
159
160
|
}
|
|
@@ -532,6 +533,7 @@ function parseAnalyticsAdjustModule(v: unknown): MeetSdkAnalyticsAdjustModule |
|
|
|
532
533
|
if (!isRecord(v)) return null;
|
|
533
534
|
return {
|
|
534
535
|
appId: str(v.appCode),
|
|
536
|
+
eventUrl: optionalStr(v.eventUrl),
|
|
535
537
|
enableSandbox: "enableSandbox" in v ? bool(v.enableSandbox) : false,
|
|
536
538
|
dependencies: parseDependencies(v.dependencies),
|
|
537
539
|
};
|
|
@@ -556,7 +558,8 @@ function parseAnalyticsAppsflyerModule(v: unknown): MeetSdkAnalyticsAppsflyerMod
|
|
|
556
558
|
if (!isRecord(v)) return null;
|
|
557
559
|
return {
|
|
558
560
|
devKey: str(v.devKey),
|
|
559
|
-
|
|
561
|
+
clientId: optionalStr(v.clientId),
|
|
562
|
+
appleAppId: optionalStr(v.appleAppId ?? v.appId),
|
|
560
563
|
enableDebugLog: "enableDebugLog" in v ? bool(v.enableDebugLog) : false,
|
|
561
564
|
repositories: Array.isArray(v.repositories) ? v.repositories.map((x) => String(x)) : undefined,
|
|
562
565
|
dependencies: parseDependencies(v.dependencies),
|
|
@@ -810,6 +813,7 @@ export function mapTopSdkGetSdkConfigToMeetSdkRemoteConfig(
|
|
|
810
813
|
out.sdkModules.analytics.adjust = {
|
|
811
814
|
appId: str(item.appId ?? item.appToken ?? item.clientId),
|
|
812
815
|
clientId: optionalStr(item.clientId),
|
|
816
|
+
eventUrl: optionalStr(item.eventUrl ?? item.event_url),
|
|
813
817
|
enableSandbox: bool(item.enableSandbox ?? item.adjustEnableSandbox),
|
|
814
818
|
};
|
|
815
819
|
break;
|
package/src/contracts/types.ts
CHANGED
|
@@ -53,6 +53,10 @@ export interface WorkspaceContext {
|
|
|
53
53
|
packageRoot: string;
|
|
54
54
|
/** sdk-home API root used for latest Android/iOS SDK version discovery. */
|
|
55
55
|
sdkHomeApiBaseUrl?: string;
|
|
56
|
+
/** Cached meetsdk-remote-config.json path for this project. */
|
|
57
|
+
remoteConfigPath?: string;
|
|
58
|
+
/** Cached iOS SDK root used as the source for integration resources. */
|
|
59
|
+
iosSdkRoot?: string;
|
|
56
60
|
android?: AndroidDetectResult;
|
|
57
61
|
/** Reserved: populated via placeholder until iOS tooling ships. */
|
|
58
62
|
ios?: IOSDetectResult;
|
|
@@ -64,6 +68,10 @@ export interface WorkspaceContextOptions {
|
|
|
64
68
|
appTarget?: string;
|
|
65
69
|
/** sdk-home API root; defaults to the production MeetGames business API. */
|
|
66
70
|
sdkHomeApiBaseUrl?: string;
|
|
71
|
+
/** Override the cached remote config path. */
|
|
72
|
+
remoteConfigPath?: string;
|
|
73
|
+
/** Override the iOS SDK source root. */
|
|
74
|
+
iosSdkRoot?: string;
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
export interface ManifestStep {
|
package/src/core/doctor.ts
CHANGED
|
@@ -58,8 +58,8 @@ function addCheck(report: DoctorReport, name: string, ok: boolean, details?: str
|
|
|
58
58
|
if (!ok) report.errors.push(details ? `${name}: ${details}` : name);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
function readJsonConfig(
|
|
62
|
-
const abs =
|
|
61
|
+
function readJsonConfig(configPath: string): MeetSdkRemoteConfig | null {
|
|
62
|
+
const abs = configPath;
|
|
63
63
|
if (!fs.existsSync(abs)) return null;
|
|
64
64
|
try {
|
|
65
65
|
return tryParseAsMeetSdkRemoteConfig(JSON.parse(fs.readFileSync(abs, "utf8")) as unknown);
|
|
@@ -345,7 +345,7 @@ async function checkIos(ctx: WorkspaceContext, report: DoctorReport, config: Mee
|
|
|
345
345
|
addCheck(report, "ios.detect", false, "iOS project not detected");
|
|
346
346
|
return;
|
|
347
347
|
}
|
|
348
|
-
const sdkRoot = resolveIosSdkRoot(ctx.packageRoot);
|
|
348
|
+
const sdkRoot = ctx.iosSdkRoot ?? resolveIosSdkRoot(ctx.packageRoot);
|
|
349
349
|
const channelConfig = buildChannelConfigMap(config);
|
|
350
350
|
const coreConfigs = listSdkCoreConfigs(sdkRoot);
|
|
351
351
|
const pluginConfigs: LoadedPluginConfig[] = [];
|
|
@@ -359,7 +359,7 @@ async function checkIos(ctx: WorkspaceContext, report: DoctorReport, config: Mee
|
|
|
359
359
|
}
|
|
360
360
|
const loadedConfigs = [...coreConfigs, ...pluginConfigs];
|
|
361
361
|
const resourceErrors = loadedConfigs.flatMap(validateLoadedPluginResourcesForDoctor);
|
|
362
|
-
addCheck(report, "ios.
|
|
362
|
+
addCheck(report, "ios.sdkResources", resourceErrors.length === 0, resourceErrors.join(", ") || "SDK resources complete");
|
|
363
363
|
const missingRequired = validateRequiredChannelConfigs(pluginConfigs, channelConfig);
|
|
364
364
|
addCheck(report, "ios.remoteParams", missingRequired.length === 0, missingRequired.join(", ") || "all required plugin params present");
|
|
365
365
|
|
|
@@ -460,7 +460,7 @@ async function checkIos(ctx: WorkspaceContext, report: DoctorReport, config: Mee
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
export async function runDoctor(ctx: WorkspaceContext, platform: "android" | "ios"): Promise<DoctorReport> {
|
|
463
|
-
const configPath = path.join(ctx.projectRoot, MEETSDK_REMOTE_CONFIG_FILENAME);
|
|
463
|
+
const configPath = ctx.remoteConfigPath ?? path.join(ctx.projectRoot, MEETSDK_REMOTE_CONFIG_FILENAME);
|
|
464
464
|
const report: DoctorReport = {
|
|
465
465
|
projectRoot: ctx.projectRoot,
|
|
466
466
|
platform,
|
|
@@ -470,8 +470,8 @@ export async function runDoctor(ctx: WorkspaceContext, platform: "android" | "io
|
|
|
470
470
|
warnings: [],
|
|
471
471
|
errors: [],
|
|
472
472
|
};
|
|
473
|
-
const config = readJsonConfig(
|
|
474
|
-
addCheck(report, "remoteConfig.existsAndParses", Boolean(config),
|
|
473
|
+
const config = readJsonConfig(configPath);
|
|
474
|
+
addCheck(report, "remoteConfig.existsAndParses", Boolean(config), configPath);
|
|
475
475
|
if (!config) {
|
|
476
476
|
report.ok = false;
|
|
477
477
|
return report;
|
|
@@ -3,11 +3,11 @@ import path from "node:path";
|
|
|
3
3
|
|
|
4
4
|
/** Default directory for `pipeline.patch` / `cli-preview.patch` (gitignored). */
|
|
5
5
|
export function resolveDefaultPreviewPatchDir(packageRoot: string): string {
|
|
6
|
-
return path.join(packageRoot, "
|
|
6
|
+
return path.join(packageRoot, "preview-patches");
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Before writing a new patch under `
|
|
10
|
+
* Before writing a new patch under `preview-patches/`, remove all existing files there
|
|
11
11
|
* so only the latest command output remains.
|
|
12
12
|
*/
|
|
13
13
|
export function clearPreviewPatchFilesIfTargetInside(packageRoot: string, patchFileAbs: string): void {
|
package/src/core/workspace.ts
CHANGED
|
@@ -22,6 +22,8 @@ export function buildWorkspaceContext(
|
|
|
22
22
|
projectRoot: root,
|
|
23
23
|
packageRoot: pkg,
|
|
24
24
|
sdkHomeApiBaseUrl: options.sdkHomeApiBaseUrl,
|
|
25
|
+
remoteConfigPath: options.remoteConfigPath,
|
|
26
|
+
iosSdkRoot: options.iosSdkRoot,
|
|
25
27
|
android: detectAndroid(root, { appTarget: options.appTarget }),
|
|
26
28
|
ios: detectIOS(root, { appTarget: options.appTarget }),
|
|
27
29
|
iosReserved: iosToolingReserved,
|
package/src/index.ts
CHANGED
|
@@ -80,6 +80,13 @@ export {
|
|
|
80
80
|
isTopSdkFeatureModuleEnabled,
|
|
81
81
|
} from "./config/topsdkFeatureModules.js";
|
|
82
82
|
export { clearPreviewPatchFilesIfTargetInside, resolveDefaultPreviewPatchDir } from "./core/previewPatches.js";
|
|
83
|
+
export {
|
|
84
|
+
MEET_SDK_TOOL_CACHE_ROOT,
|
|
85
|
+
ensureCacheRoot,
|
|
86
|
+
resolveIosSdkCacheLayout,
|
|
87
|
+
resolveRemoteConfigCachePath,
|
|
88
|
+
writeRemoteConfigCache,
|
|
89
|
+
} from "./cache.js";
|
|
83
90
|
export { buildWorkspaceContext, resolvePackageRoot } from "./core/workspace.js";
|
|
84
91
|
export { runPipeline } from "./core/pipeline.js";
|
|
85
92
|
export { generatePatchForFile } from "./core/patch.js";
|