@huoye/app-ship 0.1.0
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 +503 -0
- package/dist/cli.js +4298 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +4167 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1304 -0
- package/dist/index.d.ts +1304 -0
- package/dist/index.js +4118 -0
- package/dist/index.js.map +1 -0
- package/package.json +89 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,1304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 上传配置接口
|
|
3
|
+
*/
|
|
4
|
+
interface UploadConfig {
|
|
5
|
+
/** 应用 ID */
|
|
6
|
+
appId?: string;
|
|
7
|
+
/** 版本号 */
|
|
8
|
+
version?: string;
|
|
9
|
+
/** 构建相关配置 */
|
|
10
|
+
build?: {
|
|
11
|
+
/** Android 构建配置 */
|
|
12
|
+
android?: {
|
|
13
|
+
/** 构建产物类型:apk 或 appbundle */
|
|
14
|
+
type?: 'apk' | 'appbundle';
|
|
15
|
+
/** 构建风味(Flavor) */
|
|
16
|
+
flavor?: string;
|
|
17
|
+
/** 构建目标 */
|
|
18
|
+
target?: string;
|
|
19
|
+
/** 构建名称 */
|
|
20
|
+
buildName?: string;
|
|
21
|
+
/** 构建号 */
|
|
22
|
+
buildNumber?: string;
|
|
23
|
+
};
|
|
24
|
+
/** iOS 构建配置 */
|
|
25
|
+
ios?: {
|
|
26
|
+
/** 工程 Scheme */
|
|
27
|
+
scheme?: string;
|
|
28
|
+
/** 导出方式:app-store | development | ad-hoc | enterprise */
|
|
29
|
+
exportMethod?: 'app-store' | 'development' | 'ad-hoc' | 'enterprise';
|
|
30
|
+
/** Apple 团队 ID */
|
|
31
|
+
teamId?: string;
|
|
32
|
+
/** 构建配置:Debug 或 Release */
|
|
33
|
+
configuration?: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/** 所有上传操作的重试配置 */
|
|
37
|
+
retry?: {
|
|
38
|
+
/** 最大重试次数(默认:3) */
|
|
39
|
+
maxRetries?: number;
|
|
40
|
+
/** 初始延迟毫秒数(默认:1000) */
|
|
41
|
+
initialDelayMs?: number;
|
|
42
|
+
/** 指数退避乘数(默认:2) */
|
|
43
|
+
backoffMultiplier?: number;
|
|
44
|
+
/** 最大延迟毫秒数(默认:30000) */
|
|
45
|
+
maxDelayMs?: number;
|
|
46
|
+
};
|
|
47
|
+
/** 发布平台配置 */
|
|
48
|
+
publish?: {
|
|
49
|
+
/** 蒲公英平台配置 */
|
|
50
|
+
pgyer?: {
|
|
51
|
+
/** 是否启用 */
|
|
52
|
+
enable: boolean;
|
|
53
|
+
/** API 密钥 */
|
|
54
|
+
apiKey: string;
|
|
55
|
+
/** 版本描述 */
|
|
56
|
+
description?: string;
|
|
57
|
+
};
|
|
58
|
+
/** 华为应用市场配置 */
|
|
59
|
+
huawei?: {
|
|
60
|
+
/** 是否启用 */
|
|
61
|
+
enable: boolean;
|
|
62
|
+
/** 认证信息 */
|
|
63
|
+
auth: {
|
|
64
|
+
/** 客户端 ID */
|
|
65
|
+
clientId: string;
|
|
66
|
+
/** 客户端密钥 */
|
|
67
|
+
clientSecret: string;
|
|
68
|
+
};
|
|
69
|
+
/** 应用 ID */
|
|
70
|
+
appId: string;
|
|
71
|
+
/** 发布类型:草稿或提交审核 */
|
|
72
|
+
releaseType?: 'draft' | 'submit';
|
|
73
|
+
/**
|
|
74
|
+
* API 基础地址(可选)
|
|
75
|
+
* 默认为中国区:https://connect-api.cloud.huawei.com
|
|
76
|
+
* 欧洲区:https://connect-api-dre.cloud.huawei.com
|
|
77
|
+
* 亚太区:https://connect-api-dra.cloud.huawei.com
|
|
78
|
+
* 俄罗斯区:https://connect-api-dru.cloud.huawei.com
|
|
79
|
+
*/
|
|
80
|
+
apiBaseUrl?: string;
|
|
81
|
+
/** 商店素材配置 */
|
|
82
|
+
assets?: {
|
|
83
|
+
/** 应用图标路径(png/jpg,216x216 推荐) */
|
|
84
|
+
icon?: string;
|
|
85
|
+
/** 商店截图路径列表(png/jpg/bmp,3-8张) */
|
|
86
|
+
screenshots?: string[];
|
|
87
|
+
/** 预览视频路径(mp4/mov,可选) */
|
|
88
|
+
video?: string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/** 小米应用商店配置 */
|
|
92
|
+
xiaomi?: {
|
|
93
|
+
/** 是否启用 */
|
|
94
|
+
enable: boolean;
|
|
95
|
+
/** 认证信息 */
|
|
96
|
+
auth: {
|
|
97
|
+
/** 开发者账号邮箱 */
|
|
98
|
+
userName: string;
|
|
99
|
+
/** API 访问密码 (非登录密码) */
|
|
100
|
+
privateKey: string;
|
|
101
|
+
/** 小米分配的 RSA 公钥文件路径 */
|
|
102
|
+
publicKeyPath?: string;
|
|
103
|
+
};
|
|
104
|
+
/** 应用包名 (可选, 不填则从 APK 推断) */
|
|
105
|
+
packageName?: string;
|
|
106
|
+
/** 应用名称 (可选, 不填则从包名推断, 小米 API 必需) */
|
|
107
|
+
appName?: string;
|
|
108
|
+
/** 版本描述 */
|
|
109
|
+
description?: string;
|
|
110
|
+
/**
|
|
111
|
+
* 上传类型 (可选)
|
|
112
|
+
* - 'auto': 自动查询应用是否存在 (默认)
|
|
113
|
+
* - 'new': 强制新增应用 (synchroType=0)
|
|
114
|
+
* - 'update': 强制更新应用 (synchroType=1)
|
|
115
|
+
*/
|
|
116
|
+
uploadType?: 'auto' | 'new' | 'update';
|
|
117
|
+
/** 应用分类 ID (新增应用必填, 通过 /dev/category 接口获取) */
|
|
118
|
+
category?: number;
|
|
119
|
+
/** 搜索关键字, 空格分隔 (新增应用必填) */
|
|
120
|
+
keyWords?: string;
|
|
121
|
+
/** 应用介绍 (新增应用必填) */
|
|
122
|
+
desc?: string;
|
|
123
|
+
/** 一句话简介 (新增应用必填) */
|
|
124
|
+
brief?: string;
|
|
125
|
+
/** 隐私政策链接 (新增应用必填) */
|
|
126
|
+
privacyUrl?: string;
|
|
127
|
+
/** 商店素材配置 (新增应用需要 icon 和截图) */
|
|
128
|
+
assets?: {
|
|
129
|
+
/** 应用图标路径 */
|
|
130
|
+
icon?: string;
|
|
131
|
+
/** 手机截图路径列表 (新增应用至少 3 张) */
|
|
132
|
+
screenshots?: string[];
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/** 鸿蒙应用市场配置 */
|
|
136
|
+
harmony?: {
|
|
137
|
+
/** 是否启用 */
|
|
138
|
+
enable: boolean;
|
|
139
|
+
/** 认证信息 */
|
|
140
|
+
auth: {
|
|
141
|
+
/** 客户端 ID */
|
|
142
|
+
clientId: string;
|
|
143
|
+
/** 客户端密钥 */
|
|
144
|
+
clientSecret: string;
|
|
145
|
+
};
|
|
146
|
+
/** 应用 ID */
|
|
147
|
+
appId: string;
|
|
148
|
+
/** 发布类型:草稿或提交审核 */
|
|
149
|
+
releaseType?: 'draft' | 'submit';
|
|
150
|
+
};
|
|
151
|
+
/** App Store 配置 */
|
|
152
|
+
app_store?: {
|
|
153
|
+
/** 是否启用 */
|
|
154
|
+
enable: boolean;
|
|
155
|
+
/** 发布模式:app_store | testflight | adhoc */
|
|
156
|
+
mode?: 'app_store' | 'testflight' | 'adhoc';
|
|
157
|
+
/**
|
|
158
|
+
* App Store Connect 中的应用 ID(数字)
|
|
159
|
+
* 用于 API 自动更新发行说明,可在 App Store Connect 应用详情页 URL 中找到
|
|
160
|
+
* 例如: https://appstoreconnect.apple.com/apps/123456789 中的 123456789
|
|
161
|
+
*/
|
|
162
|
+
appId?: string;
|
|
163
|
+
/** 认证信息(至少配置一种认证方式) */
|
|
164
|
+
auth: {
|
|
165
|
+
/**
|
|
166
|
+
* CLI 上传凭据(Apple ID + App-specific Password)
|
|
167
|
+
* 用于 Transporter / altool 上传 IPA
|
|
168
|
+
* App-specific Password 需在 appleid.apple.com 生成
|
|
169
|
+
*/
|
|
170
|
+
/** Apple ID (邮箱) */
|
|
171
|
+
appleId?: string;
|
|
172
|
+
/** App-specific Password */
|
|
173
|
+
appPassword?: string;
|
|
174
|
+
/**
|
|
175
|
+
* API Key 凭据(用于 App Store Connect API)
|
|
176
|
+
* 用于自动更新发行说明(What's New)
|
|
177
|
+
* 在 App Store Connect > 用户和访问 > 密钥 中生成
|
|
178
|
+
*/
|
|
179
|
+
/** API 密钥 ID */
|
|
180
|
+
apiKeyId?: string;
|
|
181
|
+
/** API 签发者 ID */
|
|
182
|
+
apiIssuerId?: string;
|
|
183
|
+
/** 私钥文件路径 (.p8) */
|
|
184
|
+
privateKeyPath?: string;
|
|
185
|
+
/** 私钥内容 (PEM 格式) */
|
|
186
|
+
privateKeyContent?: string;
|
|
187
|
+
};
|
|
188
|
+
/** TestFlight 配置 */
|
|
189
|
+
testflight?: {
|
|
190
|
+
/** 测试员邮箱列表 */
|
|
191
|
+
betaTesters?: string[];
|
|
192
|
+
/** 多语言测试信息 */
|
|
193
|
+
betaBuildLocalization?: {
|
|
194
|
+
/** 语言代码,如 'en-US', 'zh-Hans' */
|
|
195
|
+
locale: string;
|
|
196
|
+
/** 描述文本 */
|
|
197
|
+
description: string;
|
|
198
|
+
/** 关键词列表 */
|
|
199
|
+
keywords?: string[];
|
|
200
|
+
}[];
|
|
201
|
+
/** 自动通知测试员(默认:true) */
|
|
202
|
+
autoNotify?: boolean;
|
|
203
|
+
};
|
|
204
|
+
/** Ad Hoc 配置 */
|
|
205
|
+
adhoc?: {
|
|
206
|
+
/** Apple 团队 ID */
|
|
207
|
+
teamId?: string;
|
|
208
|
+
/** Provisioning Profile 名称 */
|
|
209
|
+
provisioningProfileSpecifier?: string;
|
|
210
|
+
/** 签名证书名称 */
|
|
211
|
+
signingIdentity?: string;
|
|
212
|
+
/** 导出选项 */
|
|
213
|
+
exportOptions?: {
|
|
214
|
+
/** 导出方法:ad-hoc */
|
|
215
|
+
method: 'ad-hoc';
|
|
216
|
+
/** 签名风格:自动或手动 */
|
|
217
|
+
signingStyle?: 'automatic' | 'manual';
|
|
218
|
+
/** 是否裁剪 Swift 符号 */
|
|
219
|
+
stripSwiftSymbols?: boolean;
|
|
220
|
+
/** 瘦身配置 */
|
|
221
|
+
thinning?: string;
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
/** OPPO 应用商店配置 */
|
|
226
|
+
oppo?: {
|
|
227
|
+
/** 是否启用 */
|
|
228
|
+
enable: boolean;
|
|
229
|
+
/** 认证信息 */
|
|
230
|
+
auth: {
|
|
231
|
+
/** 客户端 ID (OPPO 开放平台分配) */
|
|
232
|
+
clientId: string;
|
|
233
|
+
/** 客户端密钥 */
|
|
234
|
+
clientSecret: string;
|
|
235
|
+
};
|
|
236
|
+
/** 应用包名 (可选, 不填则从 APK 推断) */
|
|
237
|
+
packageName?: string;
|
|
238
|
+
/**
|
|
239
|
+
* 发布类型 (可选)
|
|
240
|
+
* 1: 审核通过后立即发布 (默认)
|
|
241
|
+
* 2: 定时发布
|
|
242
|
+
*/
|
|
243
|
+
onlineType?: '1' | '2';
|
|
244
|
+
};
|
|
245
|
+
/** vivo 应用商店配置 */
|
|
246
|
+
vivo?: {
|
|
247
|
+
/** 是否启用 */
|
|
248
|
+
enable: boolean;
|
|
249
|
+
/** 认证信息 */
|
|
250
|
+
auth: {
|
|
251
|
+
/** Access Key (vivo 开放平台分配) */
|
|
252
|
+
accessKey: string;
|
|
253
|
+
/** Access Secret */
|
|
254
|
+
accessSecret: string;
|
|
255
|
+
};
|
|
256
|
+
/** 应用包名 (可选, 不填则从 APK 推断) */
|
|
257
|
+
packageName?: string;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* 腾讯应用宝配置 (腾讯开放平台)
|
|
261
|
+
* 使用 HMAC-SHA256 签名, 通用 API 路由: https://api.open.qq.com/router/rest
|
|
262
|
+
*/
|
|
263
|
+
tencent?: {
|
|
264
|
+
/** 是否启用 */
|
|
265
|
+
enable: boolean;
|
|
266
|
+
/** 认证信息 */
|
|
267
|
+
auth: {
|
|
268
|
+
/** 开发者用户 ID (分配给开发者的数字 ID) */
|
|
269
|
+
userId: string;
|
|
270
|
+
/** 应用 ID (应用宝分配的应用标识) */
|
|
271
|
+
appId: string;
|
|
272
|
+
/** Access Secret (接入密钥) */
|
|
273
|
+
accessSecret: string;
|
|
274
|
+
};
|
|
275
|
+
/** 应用包名 (可选, 不填则从 APK 推断) */
|
|
276
|
+
packageName?: string;
|
|
277
|
+
};
|
|
278
|
+
/** Google Play 配置 */
|
|
279
|
+
google_play?: {
|
|
280
|
+
/** 是否启用 */
|
|
281
|
+
enable: boolean;
|
|
282
|
+
/** 认证信息 */
|
|
283
|
+
auth: {
|
|
284
|
+
/** 服务账号 JSON 文件路径 */
|
|
285
|
+
serviceAccountJsonPath?: string;
|
|
286
|
+
/** 服务账号 JSON 内容 */
|
|
287
|
+
serviceAccountJsonContent?: string;
|
|
288
|
+
};
|
|
289
|
+
/** 包名 */
|
|
290
|
+
packageName?: string;
|
|
291
|
+
/** 发布轨道:internal | alpha | beta | production */
|
|
292
|
+
track?: 'internal' | 'alpha' | 'beta' | 'production';
|
|
293
|
+
};
|
|
294
|
+
/** 未来扩展的其他平台 */
|
|
295
|
+
[key: string]: any;
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* 应用元数据接口
|
|
300
|
+
*/
|
|
301
|
+
interface AppMetadata {
|
|
302
|
+
/** 版本号 */
|
|
303
|
+
version: string;
|
|
304
|
+
/** 应用名称 */
|
|
305
|
+
appName?: string;
|
|
306
|
+
/** 构建号 */
|
|
307
|
+
buildNumber: string;
|
|
308
|
+
/** 更新日志 */
|
|
309
|
+
changelog: string;
|
|
310
|
+
/** 本次要上传到的平台列表 */
|
|
311
|
+
platform?: string[];
|
|
312
|
+
/** 构建产物路径(apk/ipa) */
|
|
313
|
+
artifactPath?: string;
|
|
314
|
+
/** 全局工具链设置 */
|
|
315
|
+
globalSettings?: {
|
|
316
|
+
/** Android SDK 路径 */
|
|
317
|
+
androidSdkPath?: string;
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* 上传结果接口
|
|
322
|
+
*/
|
|
323
|
+
interface UploadResult {
|
|
324
|
+
/** 平台名称 */
|
|
325
|
+
platform: string;
|
|
326
|
+
/** 是否成功 */
|
|
327
|
+
success: boolean;
|
|
328
|
+
/**
|
|
329
|
+
* 提示信息 (必填)
|
|
330
|
+
* - 成功时:简短的成功提示
|
|
331
|
+
* - 失败时:必须是可读的错误描述,供 UI 直接展示
|
|
332
|
+
*/
|
|
333
|
+
message: string;
|
|
334
|
+
/** 下载地址 */
|
|
335
|
+
url?: string;
|
|
336
|
+
/** 链接地址 */
|
|
337
|
+
link?: string;
|
|
338
|
+
/** 二维码地址 */
|
|
339
|
+
qrCode?: string;
|
|
340
|
+
/**
|
|
341
|
+
* 原始错误对象 (可选)
|
|
342
|
+
* 仅用于调试,UI 不应直接展示此字段
|
|
343
|
+
*/
|
|
344
|
+
error?: Error | any;
|
|
345
|
+
/** 平台特有的响应数据 */
|
|
346
|
+
data?: any;
|
|
347
|
+
/** 商店后台管理链接(上传成功后用于快速跳转) */
|
|
348
|
+
consoleUrl?: string;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* 上传器接口
|
|
352
|
+
*/
|
|
353
|
+
interface IUploader {
|
|
354
|
+
/** 上传器名称 */
|
|
355
|
+
name: string;
|
|
356
|
+
/**
|
|
357
|
+
* 验证平台相关配置
|
|
358
|
+
*/
|
|
359
|
+
validateConfig(config: any): boolean;
|
|
360
|
+
/**
|
|
361
|
+
* 上传产物
|
|
362
|
+
*/
|
|
363
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
364
|
+
/**
|
|
365
|
+
* 判断该上传器是否能处理指定文件
|
|
366
|
+
* 用于多文件混合上传的智能分发
|
|
367
|
+
* @param filePath 文件路径
|
|
368
|
+
* @returns 是否支持该文件类型
|
|
369
|
+
*/
|
|
370
|
+
canHandle(filePath: string): boolean;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* 构建结果接口
|
|
374
|
+
*/
|
|
375
|
+
interface BuildResult {
|
|
376
|
+
/** 是否成功 */
|
|
377
|
+
success: boolean;
|
|
378
|
+
/** 构建产物路径 */
|
|
379
|
+
artifactPath: string;
|
|
380
|
+
/** 构建耗时(毫秒) */
|
|
381
|
+
buildTime: number;
|
|
382
|
+
/** 平台:android | ios */
|
|
383
|
+
platform: 'android' | 'ios';
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
declare class EnvValidator {
|
|
387
|
+
/**
|
|
388
|
+
* 验证环境变量
|
|
389
|
+
* @param requiredVars 必需的环境变量列表
|
|
390
|
+
*/
|
|
391
|
+
static validate(requiredVars: string[]): boolean;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
declare class ConfigValidator {
|
|
395
|
+
/**
|
|
396
|
+
* 加载并验证配置文件
|
|
397
|
+
* @param filePath 配置文件路径
|
|
398
|
+
*/
|
|
399
|
+
static loadAndValidate(filePath: string): UploadConfig | null;
|
|
400
|
+
/**
|
|
401
|
+
* 验证配置 Schema
|
|
402
|
+
* @param config 配置对象
|
|
403
|
+
*/
|
|
404
|
+
private static validateSchema;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
declare class PgyerUploader implements IUploader {
|
|
408
|
+
name: string;
|
|
409
|
+
private static UPLOAD_API;
|
|
410
|
+
/**
|
|
411
|
+
* 验证配置
|
|
412
|
+
* @param config 配置对象
|
|
413
|
+
*/
|
|
414
|
+
validateConfig(config: any): boolean;
|
|
415
|
+
/**
|
|
416
|
+
* 判断是否支持该文件
|
|
417
|
+
* @param filePath 文件路径
|
|
418
|
+
*/
|
|
419
|
+
canHandle(filePath: string): boolean;
|
|
420
|
+
/**
|
|
421
|
+
* 上传文件到蒲公英
|
|
422
|
+
* @param filePath 文件路径
|
|
423
|
+
* @param config 配置
|
|
424
|
+
* @param metadata 元数据
|
|
425
|
+
*/
|
|
426
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
427
|
+
/**
|
|
428
|
+
* 执行实际上传操作
|
|
429
|
+
* @param filePath 文件路径
|
|
430
|
+
* @param apiKey API Key
|
|
431
|
+
* @param desc 描述
|
|
432
|
+
*/
|
|
433
|
+
private performUpload;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
declare class HuaweiUploader implements IUploader {
|
|
437
|
+
name: string;
|
|
438
|
+
private static DEFAULT_API_BASE;
|
|
439
|
+
private static TOKEN_PATH;
|
|
440
|
+
private static PUBLISH_API_PATH;
|
|
441
|
+
/** 获取 API 基础地址 */
|
|
442
|
+
private getApiBase;
|
|
443
|
+
/** 获取 Token URL */
|
|
444
|
+
private getTokenUrl;
|
|
445
|
+
/** 获取 Publish API 根路径 */
|
|
446
|
+
private getApiRoot;
|
|
447
|
+
/** 创建 API 请求头(消除 7 处重复) */
|
|
448
|
+
private headers;
|
|
449
|
+
/** 检查 API 响应(消除 6 处重复) */
|
|
450
|
+
private checkResponse;
|
|
451
|
+
/**
|
|
452
|
+
* 验证配置
|
|
453
|
+
* @param config 配置对象
|
|
454
|
+
* @returns 是否有效
|
|
455
|
+
*/
|
|
456
|
+
validateConfig(config: any): boolean;
|
|
457
|
+
/**
|
|
458
|
+
* 判断是否支持该文件
|
|
459
|
+
* @param filePath 文件路径
|
|
460
|
+
* @returns 是否支持
|
|
461
|
+
*/
|
|
462
|
+
canHandle(filePath: string): boolean;
|
|
463
|
+
/**
|
|
464
|
+
* 执行上传
|
|
465
|
+
* @param filePath 文件路径
|
|
466
|
+
* @param config 配置
|
|
467
|
+
* @param metadata 元数据
|
|
468
|
+
*/
|
|
469
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
470
|
+
/**
|
|
471
|
+
* 查询审核状态
|
|
472
|
+
* @param clientId 客户端 ID
|
|
473
|
+
* @param clientSecret 客户端密钥
|
|
474
|
+
* @param appId 应用 ID
|
|
475
|
+
* @param apiBaseUrl API 基础地址(可选)
|
|
476
|
+
*/
|
|
477
|
+
queryReviewStatus(clientId: string, clientSecret: string, appId: string, apiBaseUrl?: string): Promise<any>;
|
|
478
|
+
/**
|
|
479
|
+
* 获取 Access Token
|
|
480
|
+
* @param tokenUrl Token URL
|
|
481
|
+
* @param clientId 客户端 ID
|
|
482
|
+
* @param clientSecret 客户端密钥
|
|
483
|
+
*/
|
|
484
|
+
private getAccessToken;
|
|
485
|
+
/** 获取上传 URL */
|
|
486
|
+
private getUploadUrl;
|
|
487
|
+
/** 通用文件上传(FormData 方式,无需 API 认证头) */
|
|
488
|
+
private executeUploadRequest;
|
|
489
|
+
/** 上传文件 (APK/AAB) */
|
|
490
|
+
private uploadFile;
|
|
491
|
+
/** 更新应用文件信息 */
|
|
492
|
+
private updateAppFileInfo;
|
|
493
|
+
/** 更新发布说明(支持多语言) */
|
|
494
|
+
private updateReleaseNotes;
|
|
495
|
+
/** 提交审核 */
|
|
496
|
+
private submitForReview;
|
|
497
|
+
/** 获取应用信息 */
|
|
498
|
+
private getAppInfo;
|
|
499
|
+
/** 上传商店素材(图标、截图、视频) */
|
|
500
|
+
private uploadStoreAssets;
|
|
501
|
+
/** 批量上传素材文件 */
|
|
502
|
+
private uploadAssetFiles;
|
|
503
|
+
/** 更新素材文件信息(关联到应用) */
|
|
504
|
+
private updateAssetFileInfo;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* 小米应用商店上传器
|
|
509
|
+
*
|
|
510
|
+
* 基于小米官方「应用自动发布接口」实现
|
|
511
|
+
* 文档: https://dev.mi.com/xiaomihyperos/documentation/detail?pId=1134
|
|
512
|
+
*
|
|
513
|
+
* 上传流程:
|
|
514
|
+
* 1. 构建 RequestData JSON (userName, appInfo, synchroType)
|
|
515
|
+
* 2. 计算所有参数的 MD5 (RequestData 字符串 + APK 文件)
|
|
516
|
+
* 3. 拼接 SIG JSON, 用 RSA 公钥加密
|
|
517
|
+
* 4. POST multipart/form-data 到 /dev/push
|
|
518
|
+
*/
|
|
519
|
+
declare class XiaomiUploader implements IUploader {
|
|
520
|
+
name: string;
|
|
521
|
+
private static readonly API_BASE;
|
|
522
|
+
private static readonly PUSH_API;
|
|
523
|
+
private static readonly QUERY_API;
|
|
524
|
+
private static readonly CATEGORY_API;
|
|
525
|
+
/**
|
|
526
|
+
* RSA 公钥分段加密 (PKCS1Padding)
|
|
527
|
+
*
|
|
528
|
+
* 小米要求: 使用平台分配的 RSA 公钥加密 SIG JSON,
|
|
529
|
+
* 输出小写十六进制字符串。RSA 1024-bit 密钥单次最多加密 117 字节,
|
|
530
|
+
* 超出需分段加密后拼接。
|
|
531
|
+
*/
|
|
532
|
+
private rsaEncryptWithPublicKey;
|
|
533
|
+
/**
|
|
534
|
+
* 从 X.509 证书或 PEM 公钥中提取可用于加密的公钥
|
|
535
|
+
* 优先使用 crypto.X509Certificate,因为它能同时处理 DER 和 PEM 格式的证书
|
|
536
|
+
*/
|
|
537
|
+
private extractPublicKey;
|
|
538
|
+
/**
|
|
539
|
+
* 计算文件 MD5 (小写十六进制)
|
|
540
|
+
*/
|
|
541
|
+
private calculateFileMD5;
|
|
542
|
+
/**
|
|
543
|
+
* 计算字符串 MD5 (小写十六进制)
|
|
544
|
+
*/
|
|
545
|
+
private calculateStringMD5;
|
|
546
|
+
/**
|
|
547
|
+
* 构建 RequestData JSON
|
|
548
|
+
*/
|
|
549
|
+
private buildRequestData;
|
|
550
|
+
/**
|
|
551
|
+
* 生成只包含 RequestData 的 SIG(用于查询接口)
|
|
552
|
+
*/
|
|
553
|
+
private generateQuerySIG;
|
|
554
|
+
/**
|
|
555
|
+
* 生成包含 RequestData + apk 的加密 SIG 字符串(用于上传接口)
|
|
556
|
+
*/
|
|
557
|
+
private generateUploadSIG;
|
|
558
|
+
/**
|
|
559
|
+
* 将用户输入的公钥字符串规范化为 PEM 格式
|
|
560
|
+
*/
|
|
561
|
+
private normalizePEM;
|
|
562
|
+
validateConfig(config: any): boolean;
|
|
563
|
+
canHandle(filePath: string): boolean;
|
|
564
|
+
/**
|
|
565
|
+
* 查询应用状态
|
|
566
|
+
* 使用 POST /dev/query 接口,需要 SIG 签名认证
|
|
567
|
+
*
|
|
568
|
+
* 返回值说明:
|
|
569
|
+
* - create: true → 需要通过新增方式上传 (synchroType=0)
|
|
570
|
+
* - updateVersion: true → 可以更新包 (synchroType=1)
|
|
571
|
+
* - updateInfo: true → 可以仅更新信息 (synchroType=2)
|
|
572
|
+
*/
|
|
573
|
+
private queryAppStatus;
|
|
574
|
+
/**
|
|
575
|
+
* 查询小米应用商店分类列表
|
|
576
|
+
* POST /dev/category, 无需参数
|
|
577
|
+
*/
|
|
578
|
+
queryCategories(): Promise<{
|
|
579
|
+
categoryId: number;
|
|
580
|
+
categoryName: string;
|
|
581
|
+
}[] | null>;
|
|
582
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
583
|
+
/**
|
|
584
|
+
* 执行实际的上传操作
|
|
585
|
+
*/
|
|
586
|
+
private performUpload;
|
|
587
|
+
/**
|
|
588
|
+
* 解析公钥: 优先使用内容字段, 其次从文件路径读取
|
|
589
|
+
*/
|
|
590
|
+
private resolvePublicKey;
|
|
591
|
+
/**
|
|
592
|
+
* 尝试从文件名推断包名
|
|
593
|
+
* 例如: com.example.app-release.apk → com.example.app
|
|
594
|
+
*/
|
|
595
|
+
private inferPackageName;
|
|
596
|
+
/**
|
|
597
|
+
* 从包名推断应用名称
|
|
598
|
+
* 例如: com.example.app → app 或 com.app → app
|
|
599
|
+
*/
|
|
600
|
+
private inferAppName;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* 工具命令信息
|
|
605
|
+
*/
|
|
606
|
+
/**
|
|
607
|
+
* App Store 上传器
|
|
608
|
+
*
|
|
609
|
+
* 上传方式:使用官方 CLI 工具上传 IPA
|
|
610
|
+
* - 优先: Transporter CLI(官方推荐)
|
|
611
|
+
* - 备选: xcrun altool(Xcode 自带,已弃用但可用)
|
|
612
|
+
*
|
|
613
|
+
* 可选功能:通过 App Store Connect API 自动更新发行说明
|
|
614
|
+
* - 需要额外配置 API Key 凭据(apiKeyId + apiIssuerId + privateKey)
|
|
615
|
+
* - 不配置 API Key 时仅上传 IPA,发行说明需手动更新
|
|
616
|
+
*/
|
|
617
|
+
declare class AppleStoreUploader implements IUploader {
|
|
618
|
+
name: string;
|
|
619
|
+
/**
|
|
620
|
+
* 验证配置是否有效
|
|
621
|
+
* 至少需要一种认证方式:
|
|
622
|
+
* - appleId + appPassword(CLI 上传)
|
|
623
|
+
* - apiKeyId + apiIssuerId + privateKey(API 调用,也可用于 CLI 上传)
|
|
624
|
+
*/
|
|
625
|
+
validateConfig(config: any): boolean;
|
|
626
|
+
/**
|
|
627
|
+
* 判断是否支持处理该文件
|
|
628
|
+
*/
|
|
629
|
+
canHandle(filePath: string): boolean;
|
|
630
|
+
/**
|
|
631
|
+
* 执行上传流程
|
|
632
|
+
*/
|
|
633
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
634
|
+
/**
|
|
635
|
+
* 使用可用的工具上传
|
|
636
|
+
* 策略: 优先 Transporter → 降级 altool → 都失败
|
|
637
|
+
*/
|
|
638
|
+
private uploadWithAvailableTool;
|
|
639
|
+
/**
|
|
640
|
+
* 解析工具路径结果
|
|
641
|
+
*/
|
|
642
|
+
private resolveToolPath;
|
|
643
|
+
/**
|
|
644
|
+
* 通过 Transporter CLI 上传
|
|
645
|
+
*/
|
|
646
|
+
private uploadViaTransporter;
|
|
647
|
+
/**
|
|
648
|
+
* 通过 altool 上传
|
|
649
|
+
*/
|
|
650
|
+
private uploadViaAltool;
|
|
651
|
+
/**
|
|
652
|
+
* 解析 altool/Transporter 错误信息,翻译为用户友好的语言
|
|
653
|
+
*/
|
|
654
|
+
private parseAltoolError;
|
|
655
|
+
/**
|
|
656
|
+
* 检查是否配置了 API Key 凭据
|
|
657
|
+
*/
|
|
658
|
+
private hasApiCredentials;
|
|
659
|
+
/**
|
|
660
|
+
* 创建 JWT 生成器
|
|
661
|
+
*/
|
|
662
|
+
private createJWTGenerator;
|
|
663
|
+
/**
|
|
664
|
+
* 获取 API 请求头
|
|
665
|
+
*/
|
|
666
|
+
private apiHeaders;
|
|
667
|
+
/**
|
|
668
|
+
* 尝试更新发行说明(失败不影响上传结果)
|
|
669
|
+
*/
|
|
670
|
+
private tryUpdateReleaseNotes;
|
|
671
|
+
/**
|
|
672
|
+
* 获取处于"准备提交"状态的版本
|
|
673
|
+
* 只有此状态下的版本才能修改发行说明
|
|
674
|
+
*/
|
|
675
|
+
private getPrepareForSubmissionVersion;
|
|
676
|
+
/**
|
|
677
|
+
* 获取版本的本地化信息列表
|
|
678
|
+
*/
|
|
679
|
+
private getVersionLocalizations;
|
|
680
|
+
/**
|
|
681
|
+
* 更新本地化版本的 What's New 内容
|
|
682
|
+
*/
|
|
683
|
+
private updateLocalizationWhatsNew;
|
|
684
|
+
/**
|
|
685
|
+
* 获取工具安装指引
|
|
686
|
+
*/
|
|
687
|
+
private getToolInstallationGuide;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* TestFlight 上传器
|
|
692
|
+
*
|
|
693
|
+
* 用于上传应用到 TestFlight 进行 Beta 测试
|
|
694
|
+
* 参考: https://developer.apple.com/documentation/appstoreconnectapi/build-beta-versions
|
|
695
|
+
*/
|
|
696
|
+
declare class TestFlightUploader implements IUploader {
|
|
697
|
+
name: string;
|
|
698
|
+
private static readonly API_ROOT;
|
|
699
|
+
private static readonly API_TIMEOUT;
|
|
700
|
+
private static readonly BUILD_PROCESSING_TIMEOUT;
|
|
701
|
+
private static readonly BUILD_POLLING_INTERVAL;
|
|
702
|
+
/**
|
|
703
|
+
* 验证配置
|
|
704
|
+
* @param config 配置对象
|
|
705
|
+
*/
|
|
706
|
+
validateConfig(config: any): boolean;
|
|
707
|
+
/**
|
|
708
|
+
* 判断是否支持该文件
|
|
709
|
+
* @param filePath 文件路径
|
|
710
|
+
*/
|
|
711
|
+
canHandle(filePath: string): boolean;
|
|
712
|
+
/**
|
|
713
|
+
* 执行上传到 TestFlight
|
|
714
|
+
* @param filePath 文件路径
|
|
715
|
+
* @param config 配置
|
|
716
|
+
* @param metadata 元数据
|
|
717
|
+
*/
|
|
718
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
719
|
+
/**
|
|
720
|
+
* 加载 JWT 生成器
|
|
721
|
+
* @param auth 认证信息
|
|
722
|
+
*/
|
|
723
|
+
private loadJWTGenerator;
|
|
724
|
+
/**
|
|
725
|
+
* 提取 Bundle ID
|
|
726
|
+
* @param ipaPath IPA 路径
|
|
727
|
+
*/
|
|
728
|
+
private extractBundleId;
|
|
729
|
+
/**
|
|
730
|
+
* 创建构建记录
|
|
731
|
+
* @param jwt JWT
|
|
732
|
+
* @param bundleId Bundle ID
|
|
733
|
+
* @param version 版本号
|
|
734
|
+
*/
|
|
735
|
+
private createBuild;
|
|
736
|
+
/**
|
|
737
|
+
* 上传 IPA 文件
|
|
738
|
+
* @param jwt JWT
|
|
739
|
+
* @param buildId 构建 ID
|
|
740
|
+
* @param filePath 文件路径
|
|
741
|
+
*/
|
|
742
|
+
private uploadIPAFile;
|
|
743
|
+
/**
|
|
744
|
+
* 等待构建处理
|
|
745
|
+
* @param jwt JWT
|
|
746
|
+
* @param buildId 构建 ID
|
|
747
|
+
* @param timeoutMs 超时时间
|
|
748
|
+
*/
|
|
749
|
+
private waitForBuildProcessing;
|
|
750
|
+
/**
|
|
751
|
+
* 创建 Beta 版本(使其可测试)
|
|
752
|
+
* @param jwt JWT
|
|
753
|
+
* @param buildId 构建 ID
|
|
754
|
+
*/
|
|
755
|
+
private createBetaBuildVersion;
|
|
756
|
+
/**
|
|
757
|
+
* Add beta testers to the build
|
|
758
|
+
*/
|
|
759
|
+
private addBetaTesters;
|
|
760
|
+
/**
|
|
761
|
+
* 添加单个测试员到组
|
|
762
|
+
* @param jwt JWT
|
|
763
|
+
* @param testerEmail 测试员邮箱
|
|
764
|
+
* @param buildId 构建 ID
|
|
765
|
+
*/
|
|
766
|
+
private addBetaTesterToGroup;
|
|
767
|
+
/**
|
|
768
|
+
* Add localization for beta build
|
|
769
|
+
*/
|
|
770
|
+
private addBetaBuildLocalization;
|
|
771
|
+
/**
|
|
772
|
+
* Add single localization
|
|
773
|
+
*/
|
|
774
|
+
private addLocalizationToBuilder;
|
|
775
|
+
/**
|
|
776
|
+
* 通知测试员
|
|
777
|
+
* @param jwt JWT
|
|
778
|
+
* @param buildId 构建 ID
|
|
779
|
+
* @param message 消息
|
|
780
|
+
*/
|
|
781
|
+
private notifyBetaTesters;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Ad Hoc 上传器
|
|
786
|
+
*
|
|
787
|
+
* 用于创建 Ad Hoc 分发包,供特定设备安装
|
|
788
|
+
* Ad Hoc 允许在最多 100 个特定的 iOS 设备上安装应用
|
|
789
|
+
*
|
|
790
|
+
* 流程:
|
|
791
|
+
* 1. 使用 Xcode 生成 Ad Hoc IPA(使用指定的 Provisioning Profile)
|
|
792
|
+
* 2. 生成设备安装链接/二维码
|
|
793
|
+
* 3. 支持通过蒲公英或其他分发平台
|
|
794
|
+
*/
|
|
795
|
+
declare class AdHocUploader implements IUploader {
|
|
796
|
+
name: string;
|
|
797
|
+
/**
|
|
798
|
+
* 验证配置
|
|
799
|
+
* @param config 配置对象
|
|
800
|
+
* @returns 是否有效
|
|
801
|
+
*/
|
|
802
|
+
validateConfig(config: any): boolean;
|
|
803
|
+
/**
|
|
804
|
+
* 判断是否支持该文件
|
|
805
|
+
* @param filePath 文件路径
|
|
806
|
+
* @returns 是否支持
|
|
807
|
+
*/
|
|
808
|
+
canHandle(filePath: string): boolean;
|
|
809
|
+
/**
|
|
810
|
+
* 执行上传(生成 Ad Hoc 分发包)
|
|
811
|
+
* @param filePath 文件路径
|
|
812
|
+
* @param config 配置
|
|
813
|
+
* @param metadata 元数据
|
|
814
|
+
*/
|
|
815
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
816
|
+
/**
|
|
817
|
+
* 从 IPA 提取 Bundle ID
|
|
818
|
+
* @param ipaPath IPA 路径
|
|
819
|
+
*/
|
|
820
|
+
private extractBundleId;
|
|
821
|
+
/**
|
|
822
|
+
* 验证 Provisioning Profile
|
|
823
|
+
* @param profileSpecifier Profile 名称
|
|
824
|
+
* @param teamId 团队 ID
|
|
825
|
+
*/
|
|
826
|
+
private verifyProvisioningProfile;
|
|
827
|
+
/**
|
|
828
|
+
* 创建 manifest.plist 文件
|
|
829
|
+
* @param ipaPath IPA 路径
|
|
830
|
+
* @param version 版本号
|
|
831
|
+
* @param bundleId Bundle ID
|
|
832
|
+
* @param changelog 更新日志
|
|
833
|
+
*/
|
|
834
|
+
private createManifest;
|
|
835
|
+
/**
|
|
836
|
+
* 设置分发目录结构
|
|
837
|
+
* @param ipaPath IPA 路径
|
|
838
|
+
* @param manifestPath Manifest 路径
|
|
839
|
+
*/
|
|
840
|
+
private setupDistributionDirectory;
|
|
841
|
+
/**
|
|
842
|
+
* 生成安装链接 (itms-services)
|
|
843
|
+
* @param distributionPath 分发目录
|
|
844
|
+
* @param bundleId Bundle ID
|
|
845
|
+
*/
|
|
846
|
+
private generateInstallUrl;
|
|
847
|
+
/**
|
|
848
|
+
* 生成二维码
|
|
849
|
+
* @param url 安装链接
|
|
850
|
+
* @param distributionPath 分发目录
|
|
851
|
+
*/
|
|
852
|
+
private generateQRCode;
|
|
853
|
+
/**
|
|
854
|
+
* 输出分发信息
|
|
855
|
+
* @param installUrl 安装链接
|
|
856
|
+
* @param qrCodePath 二维码路径
|
|
857
|
+
* @param distributionPath 分发目录
|
|
858
|
+
* @param profileInfo Profile 信息
|
|
859
|
+
*/
|
|
860
|
+
private outputDistributionInfo;
|
|
861
|
+
/**
|
|
862
|
+
* 检查是否安装了 Xcode
|
|
863
|
+
* @returns 是否安装
|
|
864
|
+
*/
|
|
865
|
+
private checkXcodeInstalled;
|
|
866
|
+
/**
|
|
867
|
+
* 生成 Ad Hoc 导出选项 (ExportOptions.plist)
|
|
868
|
+
* @param teamId 团队 ID
|
|
869
|
+
* @param signingIdentity 签名证书
|
|
870
|
+
* @param provisioningProfile Profile 名称
|
|
871
|
+
*/
|
|
872
|
+
private generateExportOptions;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* 鸿蒙应用市场上传器
|
|
877
|
+
* 复用华为 AppGallery Connect API,但针对鸿蒙包优化
|
|
878
|
+
*/
|
|
879
|
+
declare class HarmonyUploader implements IUploader {
|
|
880
|
+
name: string;
|
|
881
|
+
private static TOKEN_URL;
|
|
882
|
+
private static PUBLISH_API_ROOT;
|
|
883
|
+
validateConfig(config: any): boolean;
|
|
884
|
+
/**
|
|
885
|
+
* 判断是否支持该文件
|
|
886
|
+
* @param filePath 文件路径
|
|
887
|
+
*/
|
|
888
|
+
canHandle(filePath: string): boolean;
|
|
889
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
890
|
+
/**
|
|
891
|
+
* 获取 Access Token
|
|
892
|
+
* @param clientId 客户端 ID
|
|
893
|
+
* @param clientSecret 客户端密钥
|
|
894
|
+
*/
|
|
895
|
+
private getAccessToken;
|
|
896
|
+
/**
|
|
897
|
+
* 获取上传 URL
|
|
898
|
+
* @param token Token
|
|
899
|
+
* @param appId 应用 ID
|
|
900
|
+
* @param suffix 后缀
|
|
901
|
+
*/
|
|
902
|
+
private getUploadUrl;
|
|
903
|
+
private uploadFile;
|
|
904
|
+
/**
|
|
905
|
+
* 更新应用文件信息
|
|
906
|
+
* @param token Token
|
|
907
|
+
* @param appId 应用 ID
|
|
908
|
+
* @param authCode 授权码
|
|
909
|
+
* @param filePath 文件路径
|
|
910
|
+
*/
|
|
911
|
+
private updateAppFileInfo;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* OPPO 应用商店上传器
|
|
916
|
+
*
|
|
917
|
+
* 基于 OPPO 开放平台「应用发布 API」实现
|
|
918
|
+
* 文档: https://open.oppomobile.com/new/developmentDoc/info?id=11280
|
|
919
|
+
*
|
|
920
|
+
* 上传流程:
|
|
921
|
+
* 1. 使用 client_id + client_secret 获取 access_token
|
|
922
|
+
* 2. 获取上传 URL
|
|
923
|
+
* 3. 上传 APK 文件
|
|
924
|
+
* 4. 提交版本信息(更新日志等)
|
|
925
|
+
*/
|
|
926
|
+
declare class OppoUploader implements IUploader {
|
|
927
|
+
name: string;
|
|
928
|
+
/** OPPO 开放 API 基础地址 */
|
|
929
|
+
private static readonly API_BASE;
|
|
930
|
+
/** 获取 token 接口 */
|
|
931
|
+
private static readonly TOKEN_API;
|
|
932
|
+
/** 获取上传 URL 接口 */
|
|
933
|
+
private static readonly UPLOAD_URL_API;
|
|
934
|
+
/** 上传完成后提交版本 */
|
|
935
|
+
private static readonly SUBMIT_API;
|
|
936
|
+
/** 查询应详情接口 */
|
|
937
|
+
private static readonly APP_INFO_API;
|
|
938
|
+
/**
|
|
939
|
+
* OPPO API 签名生成
|
|
940
|
+
* OPPO 使用 HMAC-SHA256 签名机制
|
|
941
|
+
*/
|
|
942
|
+
private generateSign;
|
|
943
|
+
validateConfig(config: any): boolean;
|
|
944
|
+
canHandle(filePath: string): boolean;
|
|
945
|
+
/**
|
|
946
|
+
* 尝试从文件名推断包名
|
|
947
|
+
*/
|
|
948
|
+
private inferPackageName;
|
|
949
|
+
/**
|
|
950
|
+
* 从包名推断应用名称
|
|
951
|
+
*/
|
|
952
|
+
private inferAppName;
|
|
953
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
954
|
+
/**
|
|
955
|
+
* 获取 access_token
|
|
956
|
+
* 官方文档: https://open.oppomobile.com/documentation/page/info?id=10998
|
|
957
|
+
*/
|
|
958
|
+
private getAccessToken;
|
|
959
|
+
/**
|
|
960
|
+
* 获取应用详情
|
|
961
|
+
*/
|
|
962
|
+
private getAppInfo;
|
|
963
|
+
/**
|
|
964
|
+
* 获取上传地址
|
|
965
|
+
*/
|
|
966
|
+
private getUploadUrl;
|
|
967
|
+
/**
|
|
968
|
+
* 上传 APK 文件
|
|
969
|
+
*/
|
|
970
|
+
private uploadFile;
|
|
971
|
+
/**
|
|
972
|
+
* 提交版本信息
|
|
973
|
+
*/
|
|
974
|
+
private submitVersion;
|
|
975
|
+
/**
|
|
976
|
+
* 格式化错误信息
|
|
977
|
+
*/
|
|
978
|
+
private formatError;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* vivo 应用商店上传器
|
|
983
|
+
*
|
|
984
|
+
* 基于 vivo 开放平台「应用分发 API」实现 (协议与腾讯开放平台 Open-QQ 规范一致)
|
|
985
|
+
* 文档: https://dev.vivo.com.cn/documentCenter/doc/326
|
|
986
|
+
*
|
|
987
|
+
* 上传流程:
|
|
988
|
+
* 1. 使用 access_key + access_secret 生成签名
|
|
989
|
+
* 2. 获取上传地址 (分段上传或直传)
|
|
990
|
+
* 3. 上传 APK 文件
|
|
991
|
+
* 4. 提交版本更新信息
|
|
992
|
+
*
|
|
993
|
+
* 签名方式: HMAC-SHA256(params_sorted, access_secret) → 16进制字符串
|
|
994
|
+
*/
|
|
995
|
+
declare class VivoUploader implements IUploader {
|
|
996
|
+
name: string;
|
|
997
|
+
/** vivo 开放 API 基础地址 */
|
|
998
|
+
private static readonly API_BASE;
|
|
999
|
+
/**
|
|
1000
|
+
* vivo API 签名生成
|
|
1001
|
+
* 规则: 所有参数按 ASCII 码排序后拼接为 key=val&... 字符串,
|
|
1002
|
+
* 以 accessSecret 为密钥进行 HMAC-SHA256 加密,结果转为小写 16 进制字符串
|
|
1003
|
+
*/
|
|
1004
|
+
private generateSign;
|
|
1005
|
+
validateConfig(config: any): boolean;
|
|
1006
|
+
canHandle(filePath: string): boolean;
|
|
1007
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
1008
|
+
/**
|
|
1009
|
+
* 计算文件 MD5
|
|
1010
|
+
*/
|
|
1011
|
+
private calculateFileMD5;
|
|
1012
|
+
/**
|
|
1013
|
+
* 上传 APK 文件并获取流水号
|
|
1014
|
+
* 将公共参数与业务参数放入一个 multipart 请求中直接上传至 API_BASE
|
|
1015
|
+
*/
|
|
1016
|
+
private uploadApk;
|
|
1017
|
+
/**
|
|
1018
|
+
* 提交版本更新信息
|
|
1019
|
+
*/
|
|
1020
|
+
private submitVersion;
|
|
1021
|
+
/**
|
|
1022
|
+
* 格式化错误信息
|
|
1023
|
+
*/
|
|
1024
|
+
private formatError;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* 腾讯应用宝上传器
|
|
1029
|
+
*
|
|
1030
|
+
* 基于腾讯开放平台「应用管理 API」实现
|
|
1031
|
+
* 文档: https://wiki.open.qq.com/wiki/应用上传
|
|
1032
|
+
*
|
|
1033
|
+
* 上传流程:
|
|
1034
|
+
* 1. 使用 appId + accessSecret 生成签名
|
|
1035
|
+
* 2. 上传 APK 文件
|
|
1036
|
+
* 3. 提交版本信息(更新说明等)
|
|
1037
|
+
*
|
|
1038
|
+
* 签名方式: HMAC-SHA256
|
|
1039
|
+
*/
|
|
1040
|
+
declare class TencentUploader implements IUploader {
|
|
1041
|
+
name: string;
|
|
1042
|
+
/** 腾讯开放平台 API 基础地址 */
|
|
1043
|
+
private static readonly API_BASE;
|
|
1044
|
+
/**
|
|
1045
|
+
* 接口签名生成 (HmacSHA256)
|
|
1046
|
+
* 规则: 所有参数按字典序排序拼接为 k1=v1&k2=v2... (不要进行 URL 编码)
|
|
1047
|
+
* 使用 accessSecret 计算 HmacSHA256,转小写 16 进制
|
|
1048
|
+
*/
|
|
1049
|
+
private generateSign;
|
|
1050
|
+
validateConfig(config: any): boolean;
|
|
1051
|
+
canHandle(filePath: string): boolean;
|
|
1052
|
+
upload(filePath: string, config: any, metadata: AppMetadata): Promise<UploadResult>;
|
|
1053
|
+
/**
|
|
1054
|
+
* 阶段 1: 获取文件上传信息
|
|
1055
|
+
*/
|
|
1056
|
+
private getFileUploadInfo;
|
|
1057
|
+
/**
|
|
1058
|
+
* 获取应用详情
|
|
1059
|
+
*/
|
|
1060
|
+
private queryAppDetail;
|
|
1061
|
+
/**
|
|
1062
|
+
* 阶段 2: 直接上传到 COS (PUT)
|
|
1063
|
+
*/
|
|
1064
|
+
private uploadToCos;
|
|
1065
|
+
/**
|
|
1066
|
+
* 阶段 3: 提交流水号信息
|
|
1067
|
+
*/
|
|
1068
|
+
private submitModifyAppInfo;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
interface RetryConfig {
|
|
1072
|
+
maxRetries?: number;
|
|
1073
|
+
initialDelayMs?: number;
|
|
1074
|
+
backoffMultiplier?: number;
|
|
1075
|
+
maxDelayMs?: number;
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* 重试结果
|
|
1079
|
+
*/
|
|
1080
|
+
interface RetryResult<T> {
|
|
1081
|
+
success: boolean;
|
|
1082
|
+
data?: T;
|
|
1083
|
+
error?: Error;
|
|
1084
|
+
totalAttempts: number;
|
|
1085
|
+
lastError?: string;
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* 错误分类
|
|
1089
|
+
*/
|
|
1090
|
+
declare enum ErrorCategory {
|
|
1091
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
1092
|
+
TEMPORARY_ERROR = "TEMPORARY_ERROR",
|
|
1093
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
1094
|
+
AUTH_ERROR = "AUTH_ERROR",
|
|
1095
|
+
CLIENT_ERROR = "CLIENT_ERROR",
|
|
1096
|
+
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* 重试策略管理器
|
|
1100
|
+
*/
|
|
1101
|
+
declare class RetryStrategy {
|
|
1102
|
+
private config;
|
|
1103
|
+
constructor(config?: RetryConfig);
|
|
1104
|
+
/**
|
|
1105
|
+
* 根据错误类型判断是否应该重试
|
|
1106
|
+
*/
|
|
1107
|
+
shouldRetry(error: Error, retryCount: number): boolean;
|
|
1108
|
+
/**
|
|
1109
|
+
* 对错误进行分类
|
|
1110
|
+
*/
|
|
1111
|
+
classifyError(error: Error): ErrorCategory;
|
|
1112
|
+
/**
|
|
1113
|
+
* 判断错误类别是否可重试
|
|
1114
|
+
*/
|
|
1115
|
+
private isRetryableCategory;
|
|
1116
|
+
/**
|
|
1117
|
+
* 计算延迟时间(使用指数退避策略)
|
|
1118
|
+
*/
|
|
1119
|
+
calculateDelay(retryCount: number): number;
|
|
1120
|
+
/**
|
|
1121
|
+
* 等待指定时间
|
|
1122
|
+
*/
|
|
1123
|
+
private sleep;
|
|
1124
|
+
/**
|
|
1125
|
+
* 执行带重试的异步函数
|
|
1126
|
+
*/
|
|
1127
|
+
execute<T>(fn: () => Promise<T>, operationName?: string): Promise<RetryResult<T>>;
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* 默认重试配置
|
|
1131
|
+
*/
|
|
1132
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
1133
|
+
/**
|
|
1134
|
+
* 为上传操作创建重试策略
|
|
1135
|
+
*/
|
|
1136
|
+
declare function createUploadRetryStrategy(config?: RetryConfig): RetryStrategy;
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* 上传管理器配置
|
|
1140
|
+
*/
|
|
1141
|
+
interface UploadManagerConfig {
|
|
1142
|
+
maxConcurrent?: number;
|
|
1143
|
+
continueOnError?: boolean;
|
|
1144
|
+
verbose?: boolean;
|
|
1145
|
+
cancellationToken?: {
|
|
1146
|
+
isCancelled: boolean;
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* 聚合的上传结果报告
|
|
1151
|
+
*/
|
|
1152
|
+
interface UploadReport {
|
|
1153
|
+
totalUploads: number;
|
|
1154
|
+
successCount: number;
|
|
1155
|
+
failureCount: number;
|
|
1156
|
+
successPlatforms: string[];
|
|
1157
|
+
failurePlatforms: string[];
|
|
1158
|
+
results: UploadResult[];
|
|
1159
|
+
totalDurationMs: number;
|
|
1160
|
+
summary: string;
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* 上传管理器 - 处理多平台并行上传
|
|
1164
|
+
*/
|
|
1165
|
+
declare class UploadManager {
|
|
1166
|
+
private uploaders;
|
|
1167
|
+
private config;
|
|
1168
|
+
constructor(config?: UploadManagerConfig);
|
|
1169
|
+
/**
|
|
1170
|
+
* 注册上传器
|
|
1171
|
+
*/
|
|
1172
|
+
registerUploader(platform: string, uploader: IUploader): void;
|
|
1173
|
+
/**
|
|
1174
|
+
* 获取启用的平台列表(根据配置)
|
|
1175
|
+
*/
|
|
1176
|
+
getEnabledPlatforms(config: any): string[];
|
|
1177
|
+
/**
|
|
1178
|
+
* 获取可用的平台列表
|
|
1179
|
+
*/
|
|
1180
|
+
getAvailablePlatforms(): string[];
|
|
1181
|
+
/**
|
|
1182
|
+
* 执行并行上传(支持多文件智能分发)
|
|
1183
|
+
*/
|
|
1184
|
+
uploadToMultiplePlatforms(filePaths: string | string[], // 支持单文件或文件数组
|
|
1185
|
+
config: any, metadata: AppMetadata, targetPlatforms?: string[]): Promise<UploadReport>;
|
|
1186
|
+
/**
|
|
1187
|
+
* 上传到单个平台
|
|
1188
|
+
*/
|
|
1189
|
+
private uploadToPlatform;
|
|
1190
|
+
/**
|
|
1191
|
+
* 聚合上传结果
|
|
1192
|
+
*/
|
|
1193
|
+
private aggregateResults;
|
|
1194
|
+
/**
|
|
1195
|
+
* 输出上传报告
|
|
1196
|
+
*/
|
|
1197
|
+
private printReport;
|
|
1198
|
+
/**
|
|
1199
|
+
* 格式化持续时间
|
|
1200
|
+
*/
|
|
1201
|
+
private formatDuration;
|
|
1202
|
+
/**
|
|
1203
|
+
* 获取可重试的失败平台
|
|
1204
|
+
*/
|
|
1205
|
+
getRetryablePlatforms(report: UploadReport): string[];
|
|
1206
|
+
/**
|
|
1207
|
+
* 重试失败的平台
|
|
1208
|
+
*/
|
|
1209
|
+
retryFailedPlatforms(failedPlatforms: string[], filePath: string, config: any, metadata: AppMetadata): Promise<UploadReport>;
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* 创建上传管理器实例
|
|
1213
|
+
*/
|
|
1214
|
+
declare function createUploadManager(config?: UploadManagerConfig): UploadManager;
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Apple App Store Connect API JWT 生成器
|
|
1218
|
+
*
|
|
1219
|
+
* 使用 ES256 (ECDSA with SHA-256) 算法生成签名 JWT
|
|
1220
|
+
* 有效期: 最多 20 分钟
|
|
1221
|
+
*
|
|
1222
|
+
* 参考: https://developer.apple.com/documentation/appstoreconnectapi/generating-tokens-for-api-requests
|
|
1223
|
+
*/
|
|
1224
|
+
declare class AppleJWTGenerator {
|
|
1225
|
+
private issuerId;
|
|
1226
|
+
private keyId;
|
|
1227
|
+
private privateKey;
|
|
1228
|
+
constructor(issuerId: string, keyId: string, privateKey: string);
|
|
1229
|
+
/**
|
|
1230
|
+
* 从文件路径加载私钥内容
|
|
1231
|
+
*/
|
|
1232
|
+
static fromFile(issuerId: string, keyId: string, privateKeyPath: string): Promise<AppleJWTGenerator>;
|
|
1233
|
+
/**
|
|
1234
|
+
* 从内容字符串创建生成器
|
|
1235
|
+
*/
|
|
1236
|
+
static fromContent(issuerId: string, keyId: string, privateKeyContent: string): AppleJWTGenerator;
|
|
1237
|
+
/**
|
|
1238
|
+
* 生成 JWT 令牌
|
|
1239
|
+
* @returns Base64URL 编码的 JWT 字符串
|
|
1240
|
+
*/
|
|
1241
|
+
generate(): string;
|
|
1242
|
+
/**
|
|
1243
|
+
* 创建 JWT Header
|
|
1244
|
+
*/
|
|
1245
|
+
private createHeader;
|
|
1246
|
+
/**
|
|
1247
|
+
* 创建 JWT Payload
|
|
1248
|
+
* 有效期: 20 分钟(1200 秒)
|
|
1249
|
+
*/
|
|
1250
|
+
private createPayload;
|
|
1251
|
+
/**
|
|
1252
|
+
* 使用 ES256 算法签名
|
|
1253
|
+
* ES256 = ECDSA with SHA-256
|
|
1254
|
+
*/
|
|
1255
|
+
private sign;
|
|
1256
|
+
/**
|
|
1257
|
+
* 解析 DER 格式的签名并提取 r 和 s
|
|
1258
|
+
*/
|
|
1259
|
+
private parseDERSignature;
|
|
1260
|
+
/**
|
|
1261
|
+
* 将 Buffer 填充或截断到指定长度
|
|
1262
|
+
*/
|
|
1263
|
+
private padBuffer;
|
|
1264
|
+
/**
|
|
1265
|
+
* Base64URL 编码 (RFC 4648)
|
|
1266
|
+
*/
|
|
1267
|
+
private base64urlEncode;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* 安装包版本信息
|
|
1272
|
+
*/
|
|
1273
|
+
interface PackageInfo {
|
|
1274
|
+
/** 版本名称,如 "1.2.3" */
|
|
1275
|
+
versionName?: string;
|
|
1276
|
+
/** 版本号(构建号),如 "42" */
|
|
1277
|
+
versionCode?: string;
|
|
1278
|
+
/** 包名/Bundle ID,如 "com.example.app" */
|
|
1279
|
+
packageName?: string;
|
|
1280
|
+
/** CPU 架构列表 (Android),如 ["arm64-v8a", "armeabi-v7a"] */
|
|
1281
|
+
nativeCode?: string[];
|
|
1282
|
+
/** 文件 MD5 校验值 */
|
|
1283
|
+
md5?: string;
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* 解析选项
|
|
1287
|
+
*/
|
|
1288
|
+
interface ParseOptions {
|
|
1289
|
+
/** Android SDK 路径 */
|
|
1290
|
+
androidSdkPath?: string;
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* 从安装包文件中解析版本信息
|
|
1294
|
+
*
|
|
1295
|
+
* 支持三种格式:
|
|
1296
|
+
* - APK: 使用 aapt2/aapt(Android SDK 自带)
|
|
1297
|
+
* - IPA: 使用 unzip + plutil(macOS 原生)
|
|
1298
|
+
* - HAP: 使用 unzip(系统自带)
|
|
1299
|
+
*
|
|
1300
|
+
* 解析失败时返回 null,不会抛出异常
|
|
1301
|
+
*/
|
|
1302
|
+
declare function parsePackageInfo(filePath: string, options?: ParseOptions): Promise<PackageInfo | null>;
|
|
1303
|
+
|
|
1304
|
+
export { AdHocUploader, type AppMetadata, AppleJWTGenerator, AppleStoreUploader, type BuildResult, ConfigValidator, DEFAULT_RETRY_CONFIG, EnvValidator, ErrorCategory, HarmonyUploader, HuaweiUploader, type IUploader, OppoUploader, type PackageInfo, type ParseOptions, PgyerUploader, type RetryConfig, type RetryResult, RetryStrategy, TencentUploader, TestFlightUploader, type UploadConfig, UploadManager, type UploadManagerConfig, type UploadReport, type UploadResult, VivoUploader, XiaomiUploader, createUploadManager, createUploadRetryStrategy, parsePackageInfo };
|