shipup 0.2.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE +14 -0
  3. package/README.md +112 -0
  4. package/README.zh-CN.md +105 -0
  5. package/SECURITY.md +32 -0
  6. package/creds.example.yaml +62 -0
  7. package/dist/adapters/android/honor/api.js +360 -0
  8. package/dist/adapters/android/honor/api.js.map +1 -0
  9. package/dist/adapters/android/honor/index.js +122 -0
  10. package/dist/adapters/android/honor/index.js.map +1 -0
  11. package/dist/adapters/android/huawei/api.js +389 -0
  12. package/dist/adapters/android/huawei/api.js.map +1 -0
  13. package/dist/adapters/android/huawei/index.js +128 -0
  14. package/dist/adapters/android/huawei/index.js.map +1 -0
  15. package/dist/adapters/android/meizu/api.js +367 -0
  16. package/dist/adapters/android/meizu/api.js.map +1 -0
  17. package/dist/adapters/android/meizu/index.js +129 -0
  18. package/dist/adapters/android/meizu/index.js.map +1 -0
  19. package/dist/adapters/android/oppo/api.js +397 -0
  20. package/dist/adapters/android/oppo/api.js.map +1 -0
  21. package/dist/adapters/android/oppo/index.js +135 -0
  22. package/dist/adapters/android/oppo/index.js.map +1 -0
  23. package/dist/adapters/android/qq/api.js +184 -0
  24. package/dist/adapters/android/qq/api.js.map +1 -0
  25. package/dist/adapters/android/qq/index.js +80 -0
  26. package/dist/adapters/android/qq/index.js.map +1 -0
  27. package/dist/adapters/android/samsung/api.js +355 -0
  28. package/dist/adapters/android/samsung/api.js.map +1 -0
  29. package/dist/adapters/android/samsung/index.js +111 -0
  30. package/dist/adapters/android/samsung/index.js.map +1 -0
  31. package/dist/adapters/android/specs.js +106 -0
  32. package/dist/adapters/android/specs.js.map +1 -0
  33. package/dist/adapters/android/stub.js +27 -0
  34. package/dist/adapters/android/stub.js.map +1 -0
  35. package/dist/adapters/android/vivo/api.js +236 -0
  36. package/dist/adapters/android/vivo/api.js.map +1 -0
  37. package/dist/adapters/android/vivo/index.js +121 -0
  38. package/dist/adapters/android/vivo/index.js.map +1 -0
  39. package/dist/adapters/android/xiaomi/api.js +163 -0
  40. package/dist/adapters/android/xiaomi/api.js.map +1 -0
  41. package/dist/adapters/android/xiaomi/index.js +108 -0
  42. package/dist/adapters/android/xiaomi/index.js.map +1 -0
  43. package/dist/adapters/ios/appstore/asc.js +280 -0
  44. package/dist/adapters/ios/appstore/asc.js.map +1 -0
  45. package/dist/adapters/ios/appstore/index.js +323 -0
  46. package/dist/adapters/ios/appstore/index.js.map +1 -0
  47. package/dist/adapters/registry.js +34 -0
  48. package/dist/adapters/registry.js.map +1 -0
  49. package/dist/adapters/util.js +26 -0
  50. package/dist/adapters/util.js.map +1 -0
  51. package/dist/cli/index.js +479 -0
  52. package/dist/cli/index.js.map +1 -0
  53. package/dist/cli/output.js +65 -0
  54. package/dist/cli/output.js.map +1 -0
  55. package/dist/core/exit.js +20 -0
  56. package/dist/core/exit.js.map +1 -0
  57. package/dist/core/orchestrator.js +24 -0
  58. package/dist/core/orchestrator.js.map +1 -0
  59. package/dist/core/types.js +20 -0
  60. package/dist/core/types.js.map +1 -0
  61. package/dist/creds/load.js +68 -0
  62. package/dist/creds/load.js.map +1 -0
  63. package/dist/creds/schema.js +30 -0
  64. package/dist/creds/schema.js.map +1 -0
  65. package/dist/infra/crypto.js +12 -0
  66. package/dist/infra/crypto.js.map +1 -0
  67. package/dist/infra/http.js +87 -0
  68. package/dist/infra/http.js.map +1 -0
  69. package/dist/pkginfo/apk-icon.js +89 -0
  70. package/dist/pkginfo/apk-icon.js.map +1 -0
  71. package/dist/pkginfo/icon.js +83 -0
  72. package/dist/pkginfo/icon.js.map +1 -0
  73. package/dist/pkginfo/index.js +33 -0
  74. package/dist/pkginfo/index.js.map +1 -0
  75. package/docs/android-markets.md +190 -0
  76. package/docs/credentials.md +72 -0
  77. package/docs/providers.md +60 -0
  78. package/lib/common.mjs +265 -0
  79. package/lib/harmony.mjs +190 -0
  80. package/lib/huawei.mjs +153 -0
  81. package/lib/ios.mjs +477 -0
  82. package/package.json +70 -0
  83. package/shipup.mjs +160 -0
@@ -0,0 +1,389 @@
1
+ // 文档:https://developer.huawei.com/consumer/cn/doc/AppGallery-connect-References
2
+ // 流程:OAuth client_credentials 取 token → 取上传地址 → 上传 APK(multipart)
3
+ // → app-file-info 绑定 → 更新 app-language-info(更新说明/名称/简介/描述,按需)
4
+ // →(可选图标)→(可选截图,整组替换)→(可选绿标文件)→(可选隐私链接)→ 提交审核。
5
+ import { readFile } from 'node:fs/promises';
6
+ import { basename, extname } from 'node:path';
7
+ import { UploadError } from '../../../core/types.js';
8
+ import { withRetry } from '../../../infra/http.js';
9
+ const TOKEN_URL = 'https://connect-api.cloud.huawei.com/api/oauth2/v1/token';
10
+ const BASE = 'https://connect-api.cloud.huawei.com/api/publish/v2';
11
+ const delay = (ms) => new Promise((r) => setTimeout(r, ms));
12
+ function authHeaders(clientId, accessToken) {
13
+ return {
14
+ client_id: clientId,
15
+ Authorization: `Bearer ${accessToken}`,
16
+ 'Content-Type': 'application/json',
17
+ };
18
+ }
19
+ /** 通用 JSON 请求(GET/PUT/POST),非 200 抛 UploadError。 */
20
+ async function hwJson(method, url, clientId, accessToken, bodyObj, timeoutMs) {
21
+ const init = {
22
+ method,
23
+ headers: authHeaders(clientId, accessToken),
24
+ signal: AbortSignal.timeout(timeoutMs),
25
+ };
26
+ if (bodyObj !== undefined)
27
+ init.body = JSON.stringify(bodyObj);
28
+ const res = await fetch(url, init);
29
+ const text = await res.text();
30
+ if (!res.ok)
31
+ throw new UploadError(res.status, `http ${res.status}: ${text.slice(0, 300)}`);
32
+ try {
33
+ return text ? JSON.parse(text) : {};
34
+ }
35
+ catch {
36
+ throw new UploadError('parse', `非 JSON 响应: ${text.slice(0, 300)}`);
37
+ }
38
+ }
39
+ /** OAuth client_credentials 取 access_token。幂等,瞬时失败自动重试。 */
40
+ export async function fetchAccessToken(args) {
41
+ return withRetry(async () => {
42
+ const res = await fetch(TOKEN_URL, {
43
+ method: 'POST',
44
+ headers: { 'Content-Type': 'application/json' },
45
+ body: JSON.stringify({
46
+ grant_type: 'client_credentials',
47
+ client_id: args.clientId,
48
+ client_secret: args.clientSecret,
49
+ }),
50
+ signal: AbortSignal.timeout(args.timeoutMs),
51
+ });
52
+ const text = await res.text();
53
+ if (!res.ok)
54
+ throw new UploadError(res.status, `token http ${res.status}: ${text.slice(0, 300)}`);
55
+ let data;
56
+ try {
57
+ data = JSON.parse(text);
58
+ }
59
+ catch {
60
+ throw new UploadError('parse', `token 非 JSON 响应: ${text.slice(0, 300)}`);
61
+ }
62
+ const token = data?.access_token;
63
+ if (!token)
64
+ throw new UploadError(String(data?.ret ?? 'token'), `取 token 失败: ${text.slice(0, 300)}`);
65
+ return String(token);
66
+ }, { label: 'huawei token' });
67
+ }
68
+ /** 取上传地址(含 authCode)。 */
69
+ async function getUploadUrl(args) {
70
+ // 取上传地址为幂等 GET,瞬时失败自动重试。
71
+ const data = await withRetry(() => hwJson('GET', `${BASE}/upload-url?appId=${args.appId}&suffix=${args.suffix}`, args.clientId, args.accessToken, undefined, args.timeoutMs), { label: 'huawei get-upload-url' });
72
+ return { uploadUrl: String(data.uploadUrl), authCode: String(data.authCode) };
73
+ }
74
+ /** 取上传地址后 multipart 直传文件,返回 result.UploadFileRsp(含 fileInfoList)。 */
75
+ async function uploadFileToHuawei(args) {
76
+ const suffix = extname(args.fileName).replace('.', '');
77
+ const urlInfo = await getUploadUrl({
78
+ appId: args.appId,
79
+ suffix,
80
+ clientId: args.clientId,
81
+ accessToken: args.accessToken,
82
+ timeoutMs: args.timeoutMs,
83
+ });
84
+ const form = new FormData();
85
+ form.append('authCode', urlInfo.authCode);
86
+ form.append('fileCount', '1');
87
+ form.append('parseType', args.isImg ? '1' : '0');
88
+ form.append('file', new Blob([args.bytes]), args.fileName);
89
+ // 注意:不要手动设置 Content-Type,交给 fetch 生成 multipart boundary。
90
+ const res = await fetch(urlInfo.uploadUrl, {
91
+ method: 'POST',
92
+ headers: { client_id: args.clientId, Authorization: `Bearer ${args.accessToken}` },
93
+ body: form,
94
+ signal: AbortSignal.timeout(args.uploadTimeoutMs),
95
+ });
96
+ const text = await res.text();
97
+ if (!res.ok)
98
+ throw new UploadError(res.status, `上传文件失败 ${res.status}: ${text.slice(0, 300)}`);
99
+ let data;
100
+ try {
101
+ data = JSON.parse(text);
102
+ }
103
+ catch {
104
+ throw new UploadError('parse', `上传文件非 JSON 响应: ${text.slice(0, 300)}`);
105
+ }
106
+ return data?.result?.UploadFileRsp;
107
+ }
108
+ /** 上传 APK 并通过 app-file-info 绑定(fileType=5)。 */
109
+ async function uploadApk(args) {
110
+ const rsp = await uploadFileToHuawei({
111
+ appId: args.appId,
112
+ clientId: args.clientId,
113
+ accessToken: args.accessToken,
114
+ bytes: args.apkBytes,
115
+ fileName: args.apkName,
116
+ isImg: false,
117
+ uploadTimeoutMs: args.uploadTimeoutMs,
118
+ timeoutMs: args.timeoutMs,
119
+ });
120
+ // rsp(UploadFileRsp) 或 fileInfoList 缺失时,直接抛带响应片段的 UploadError,
121
+ // 避免后续 rsp.fileInfoList 触发 TypeError 并吞掉真正的渠道错误。
122
+ if (!rsp || !Array.isArray(rsp.fileInfoList) || rsp.fileInfoList.length === 0) {
123
+ throw new UploadError('upload', `上传 APK 响应缺少 fileInfoList: ${JSON.stringify(rsp ?? null).slice(0, 300)}`);
124
+ }
125
+ rsp.fileInfoList[0].fileName = args.apkName;
126
+ const body = { fileType: 5, files: rsp.fileInfoList, lang: 'zh-CN' };
127
+ // 华为接口此处字段为 fileDestUrl,而取地址返回的是拼写错误的 fileDestUlr,需修正。
128
+ const serialized = JSON.stringify(body).replace(/fileDestUlr/g, 'fileDestUrl');
129
+ const res = await fetch(`${BASE}/app-file-info?appId=${args.appId}`, {
130
+ method: 'PUT',
131
+ headers: authHeaders(args.clientId, args.accessToken),
132
+ body: serialized,
133
+ signal: AbortSignal.timeout(args.timeoutMs),
134
+ });
135
+ if (!res.ok) {
136
+ const text = await res.text().catch(() => '');
137
+ throw new UploadError(res.status, `app-file-info 失败 ${res.status}: ${text.slice(0, 300)}`);
138
+ }
139
+ }
140
+ /** 上传图标并通过 app-file-info 绑定(fileType=0,isImg)。 */
141
+ async function updateIcon(args) {
142
+ const rsp = await uploadFileToHuawei({
143
+ appId: args.appId,
144
+ clientId: args.clientId,
145
+ accessToken: args.accessToken,
146
+ bytes: args.iconBytes,
147
+ fileName: args.iconName,
148
+ isImg: true,
149
+ uploadTimeoutMs: args.uploadTimeoutMs,
150
+ timeoutMs: args.timeoutMs,
151
+ });
152
+ // 同 uploadApk:rsp / fileInfoList 缺失时抛带响应片段的 UploadError,避免 TypeError 吞错。
153
+ if (!rsp || !Array.isArray(rsp.fileInfoList) || rsp.fileInfoList.length === 0) {
154
+ throw new UploadError('upload', `上传图标响应缺少 fileInfoList: ${JSON.stringify(rsp ?? null).slice(0, 300)}`);
155
+ }
156
+ const body = { fileType: 0, files: rsp.fileInfoList, lang: 'zh-CN' };
157
+ // 同 app-file-info:取地址返回的拼写错误字段 fileDestUlr 需修正为 fileDestUrl。
158
+ const serialized = JSON.stringify(body).replace(/fileDestUlr/g, 'fileDestUrl');
159
+ const res = await fetch(`${BASE}/app-file-info?appId=${args.appId}`, {
160
+ method: 'PUT',
161
+ headers: authHeaders(args.clientId, args.accessToken),
162
+ body: serialized,
163
+ signal: AbortSignal.timeout(args.timeoutMs),
164
+ });
165
+ if (!res.ok) {
166
+ const text = await res.text().catch(() => '');
167
+ throw new UploadError(res.status, `app-file-info(icon) 失败 ${res.status}: ${text.slice(0, 300)}`);
168
+ }
169
+ }
170
+ /**
171
+ * 更新 app-language-info(zh-CN):更新说明(newFeatures) + 应用名称(appName)
172
+ * + 一句话简介(briefInfo) + 应用描述(appDesc),四者均「按需」——仅对传入的非空字段更新,
173
+ * 其余沿用线上。无任何可更新字段时直接跳过,不发请求。
174
+ */
175
+ async function updateLanguageInfo(args) {
176
+ const body = { lang: 'zh-CN' };
177
+ if (args.newFeatures && args.newFeatures.length > 0)
178
+ body.newFeatures = args.newFeatures;
179
+ if (args.appName && args.appName.length > 0)
180
+ body.appName = args.appName;
181
+ if (args.briefInfo && args.briefInfo.length > 0)
182
+ body.briefInfo = args.briefInfo;
183
+ if (args.appDesc && args.appDesc.length > 0)
184
+ body.appDesc = args.appDesc;
185
+ // 只剩 lang、无任何可更新字段:跳过(保持现有行为,绝不空更新)。
186
+ if (Object.keys(body).length <= 1)
187
+ return;
188
+ await hwJson('PUT', `${BASE}/app-language-info?appId=${args.appId}`, args.clientId, args.accessToken, body, args.timeoutMs);
189
+ }
190
+ /**
191
+ * 更新应用截图(app-file-info,fileType=2,竖屏 imgShowType=0,lang=zh-CN)。
192
+ * 逐张走 upload-url+upload-file 直传得 fileInfoList,再一次性绑定。
193
+ * --screenshot 为全量替换:传入即视为该语言的完整截图集,会覆盖线上原有截图。
194
+ * 这是「设置截图」的正确语义(整组替换而非追加),否则将无法删除线上多余截图——
195
+ * 切勿改成「与线上截图合并后再提交」的追加语义。
196
+ */
197
+ async function updateScreenshots(args) {
198
+ const fileInfoList = [];
199
+ for (let i = 0; i < args.images.length; i++) {
200
+ const fileName = `screenshot-${i + 1}.png`;
201
+ const rsp = await uploadFileToHuawei({
202
+ appId: args.appId,
203
+ clientId: args.clientId,
204
+ accessToken: args.accessToken,
205
+ bytes: args.images[i],
206
+ fileName,
207
+ isImg: true,
208
+ uploadTimeoutMs: args.uploadTimeoutMs,
209
+ timeoutMs: args.timeoutMs,
210
+ });
211
+ const info = rsp?.fileInfoList?.[0];
212
+ if (info) {
213
+ info.fileName = fileName;
214
+ fileInfoList.push(info);
215
+ }
216
+ }
217
+ if (fileInfoList.length === 0)
218
+ return;
219
+ const body = { fileType: 2, lang: 'zh-CN', imgShowType: 0, files: fileInfoList };
220
+ // 同 app-file-info:取地址返回的拼写错误字段 fileDestUlr 需修正为 fileDestUrl。
221
+ const serialized = JSON.stringify(body).replace(/fileDestUlr/g, 'fileDestUrl');
222
+ const res = await fetch(`${BASE}/app-file-info?appId=${args.appId}`, {
223
+ method: 'PUT',
224
+ headers: authHeaders(args.clientId, args.accessToken),
225
+ body: serialized,
226
+ signal: AbortSignal.timeout(args.timeoutMs),
227
+ });
228
+ if (!res.ok) {
229
+ const text = await res.text().catch(() => '');
230
+ throw new UploadError(res.status, `app-file-info(screenshot) 失败 ${res.status}: ${text.slice(0, 300)}`);
231
+ }
232
+ }
233
+ /** 更新隐私政策链接。 */
234
+ async function updatePrivacy(args) {
235
+ await hwJson('PUT', `${BASE}/app-info?appId=${args.appId}`, args.clientId, args.accessToken, { privacyPolicy: args.privacyUrl }, args.timeoutMs);
236
+ }
237
+ /** 下载绿标检测文件并上传到华为,返回其 fileDestUlr。 */
238
+ async function uploadGreenVerifyFile(args) {
239
+ const dl = await fetch(args.greenFileUrl, { signal: AbortSignal.timeout(args.uploadTimeoutMs) });
240
+ if (!dl.ok)
241
+ throw new UploadError(dl.status, `下载绿标文件失败 ${dl.status}`);
242
+ const bytes = Buffer.from(await dl.arrayBuffer());
243
+ const rsp = await uploadFileToHuawei({
244
+ appId: args.appId,
245
+ clientId: args.clientId,
246
+ accessToken: args.accessToken,
247
+ bytes,
248
+ fileName: 'green_verify.zip',
249
+ isImg: false,
250
+ uploadTimeoutMs: args.uploadTimeoutMs,
251
+ timeoutMs: args.timeoutMs,
252
+ });
253
+ return String(rsp?.fileInfoList?.[0]?.fileDestUlr ?? '');
254
+ }
255
+ /** 提交审核。ret.code==0 成功;204144727 表示处理中,延迟重试(≤30 次)。 */
256
+ async function submit(args) {
257
+ for (let attempt = 0; attempt < 30; attempt++) {
258
+ const res = await fetch(`${BASE}/app-submit?appId=${args.appId}`, {
259
+ method: 'POST',
260
+ headers: authHeaders(args.clientId, args.accessToken),
261
+ body: JSON.stringify(args.body),
262
+ signal: AbortSignal.timeout(args.timeoutMs),
263
+ });
264
+ const text = await res.text();
265
+ if (!res.ok)
266
+ throw new UploadError(res.status, `submit http ${res.status}: ${text.slice(0, 300)}`);
267
+ let data;
268
+ try {
269
+ data = JSON.parse(text);
270
+ }
271
+ catch {
272
+ throw new UploadError('parse', `submit 非 JSON 响应: ${text.slice(0, 300)}`);
273
+ }
274
+ const code = Number(data?.ret?.code ?? -1);
275
+ if (code === 0)
276
+ return;
277
+ if (code === 204144727) {
278
+ await delay(2000);
279
+ continue;
280
+ }
281
+ throw new UploadError(code, String(data?.ret?.msg ?? 'submit failed'));
282
+ }
283
+ throw new UploadError(204144727, 'submit failed, retry count > 30');
284
+ }
285
+ /** 完整传报:取上传地址 → 上传 APK → 更新日志 →(可选绿标)→(可选隐私)→ 提交审核。 */
286
+ export async function uploadHuawei(args) {
287
+ const uploadTimeoutMs = Math.max(args.timeoutMs, 900000);
288
+ const apkBytes = await readFile(args.apkPath);
289
+ const apkName = basename(args.apkPath);
290
+ const accessToken = await fetchAccessToken({
291
+ clientId: args.clientId,
292
+ clientSecret: args.clientSecret,
293
+ timeoutMs: args.timeoutMs,
294
+ });
295
+ // 1. 上传 APK
296
+ await uploadApk({
297
+ appId: args.appId,
298
+ clientId: args.clientId,
299
+ accessToken,
300
+ apkBytes,
301
+ apkName,
302
+ uploadTimeoutMs,
303
+ timeoutMs: args.timeoutMs,
304
+ });
305
+ // 2. 更新 app-language-info:更新说明 + 名称/简介/描述(均按需,函数内部无字段则跳过)
306
+ await updateLanguageInfo({
307
+ appId: args.appId,
308
+ clientId: args.clientId,
309
+ accessToken,
310
+ newFeatures: args.releaseNote,
311
+ appName: args.appName,
312
+ briefInfo: args.summary,
313
+ appDesc: args.description,
314
+ timeoutMs: args.timeoutMs,
315
+ });
316
+ // 3. 更新图标(可选):上传调用方传入的图标 PNG(华为要求 216×216)。
317
+ // 无图标字节时跳过,不报错。
318
+ if (args.iconBytes && args.iconBytes.length > 0) {
319
+ await updateIcon({
320
+ appId: args.appId,
321
+ clientId: args.clientId,
322
+ accessToken,
323
+ iconBytes: args.iconBytes,
324
+ iconName: 'icon.png',
325
+ uploadTimeoutMs,
326
+ timeoutMs: args.timeoutMs,
327
+ });
328
+ }
329
+ // 3b. 更新截图(可选):传入截图非空时整组替换线上截图(覆盖语义见 updateScreenshots 注释)。
330
+ if (args.screenshots && args.screenshots.length > 0) {
331
+ await updateScreenshots({
332
+ appId: args.appId,
333
+ clientId: args.clientId,
334
+ accessToken,
335
+ images: args.screenshots,
336
+ uploadTimeoutMs,
337
+ timeoutMs: args.timeoutMs,
338
+ });
339
+ }
340
+ // 4. 提交体(回调地址可选,由调用方注入)
341
+ const submitBody = {
342
+ requestId: args.packageName,
343
+ };
344
+ if (args.callbackAddr)
345
+ submitBody.callbackAddr = args.callbackAddr;
346
+ // 5. 绿标检测材料(可选)
347
+ if (args.greenVerifyFileUrl && args.greenVerifyFileUrl.length > 0) {
348
+ const greenFileHWUrl = await uploadGreenVerifyFile({
349
+ appId: args.appId,
350
+ clientId: args.clientId,
351
+ accessToken,
352
+ greenFileUrl: args.greenVerifyFileUrl,
353
+ uploadTimeoutMs,
354
+ timeoutMs: args.timeoutMs,
355
+ });
356
+ submitBody.isPureDetection = '1';
357
+ submitBody.sensitivePermissionIconUrl = greenFileHWUrl;
358
+ submitBody.isCommitSensitivePermissionTips = 'true';
359
+ }
360
+ // 6. 隐私政策链接(可选)
361
+ if (args.privacyUrl && args.privacyUrl.length > 0) {
362
+ await updatePrivacy({
363
+ appId: args.appId,
364
+ clientId: args.clientId,
365
+ accessToken,
366
+ privacyUrl: args.privacyUrl,
367
+ timeoutMs: args.timeoutMs,
368
+ });
369
+ }
370
+ // 7. 提交审核
371
+ await submit({
372
+ appId: args.appId,
373
+ clientId: args.clientId,
374
+ accessToken,
375
+ body: submitBody,
376
+ timeoutMs: args.timeoutMs,
377
+ });
378
+ }
379
+ /** 查询应用信息(app-info),返回原始 JSON 供状态映射。 */
380
+ export async function queryHuaweiAppInfo(args) {
381
+ const accessToken = await fetchAccessToken({
382
+ clientId: args.clientId,
383
+ clientSecret: args.clientSecret,
384
+ timeoutMs: args.timeoutMs,
385
+ });
386
+ // 查询应用信息为幂等 GET,瞬时失败自动重试。
387
+ return withRetry(() => hwJson('GET', `${BASE}/app-info?appId=${args.appId}`, args.clientId, accessToken, undefined, args.timeoutMs), { label: 'huawei queryAppInfo' });
388
+ }
389
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/adapters/android/huawei/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ import { toFailed } from '../../util.js';
2
+ import { prepareScreenshot } from '../../../pkginfo/icon.js';
3
+ import { resolveIconBytes } from '../../../pkginfo/apk-icon.js';
4
+ import { getChannelSpec, warnIfTooLong } from '../specs.js';
5
+ import { queryHuaweiAppInfo, uploadHuawei } from './api.js';
6
+ // 华为 releaseState 映射(参考 status/providers/huawei_provider.dart 的官方语义):
7
+ // 0 已上架 → published
8
+ // 1/8/9/13 审核不通过 → rejected
9
+ // 3/4/5/12 审核/预审中 → pending_review
10
+ // 2/6/10/11 下架/撤销 → offline
11
+ // 7 草稿 → uploaded
12
+ // 其它/缺失 → submitted(刚提交,暂无更细状态)
13
+ function mapReleaseState(state) {
14
+ switch (state) {
15
+ case 0:
16
+ return 'published';
17
+ case 1:
18
+ case 8:
19
+ case 9:
20
+ case 13:
21
+ return 'rejected';
22
+ case 3:
23
+ case 4:
24
+ case 5:
25
+ case 12:
26
+ return 'pending_review';
27
+ case 2:
28
+ case 6:
29
+ case 10:
30
+ case 11:
31
+ return 'offline';
32
+ case 7:
33
+ return 'uploaded';
34
+ default:
35
+ return 'submitted';
36
+ }
37
+ }
38
+ /** 华为应用市场:上传 APK 后直接提交审核,upload 始终为 upload+submit。 */
39
+ export class HuaweiAdapter {
40
+ channel = 'huawei';
41
+ async upload(ctx) {
42
+ const start = Date.now();
43
+ try {
44
+ const spec = getChannelSpec(this.channel);
45
+ // 图标按需更新:--update-icon 时取图标——优先 --icon,否则 aapt 从 APK 自动提取(最高密度 PNG);
46
+ // 不更新则 undefined,uploadHuawei 跳过图标步骤沿用线上。
47
+ const iconBytes = ctx.updateIcon
48
+ ? await resolveIconBytes({
49
+ iconPath: ctx.iconPath,
50
+ apkPath: ctx.pkg,
51
+ size: spec.iconSize,
52
+ maxBytes: spec.iconMaxBytes,
53
+ })
54
+ : undefined;
55
+ // 截图按需(--screenshot 为全量替换):传入即视为该语言的完整截图集,会覆盖线上原有截图,
56
+ // 而非在原有截图上追加(覆盖语义详见 api.ts updateScreenshots 注释)。
57
+ // 每张先按渠道格式(华为 png)+ 大小上限编码。
58
+ const screenshots = ctx.screenshots && ctx.screenshots.length > 0
59
+ ? await Promise.all(ctx.screenshots.map((p) => prepareScreenshot(p, 'png', spec.screenshotMaxBytes)))
60
+ : undefined;
61
+ // 文案写前长度告警(仅提示,不阻断;huawei spec 无 appNameMax 时 warnIfTooLong 自动跳过)。
62
+ warnIfTooLong(this.channel, 'appName', ctx.appName, spec.appNameMax);
63
+ warnIfTooLong(this.channel, 'summary', ctx.summary, spec.summaryMax);
64
+ warnIfTooLong(this.channel, 'description', ctx.description, spec.descriptionMax);
65
+ await uploadHuawei({
66
+ appId: ctx.creds.app_id,
67
+ clientId: ctx.creds.client_id,
68
+ clientSecret: ctx.creds.client_secret,
69
+ apkPath: ctx.pkg,
70
+ packageName: ctx.packageName,
71
+ iconBytes,
72
+ releaseNote: ctx.releaseNote,
73
+ appName: ctx.appName,
74
+ summary: ctx.summary,
75
+ description: ctx.description,
76
+ screenshots,
77
+ privacyUrl: ctx.privacyUrl,
78
+ greenVerifyFileUrl: ctx.creds.green_verify_file_url,
79
+ callbackAddr: ctx.creds.callback_addr,
80
+ timeoutMs: ctx.timeoutMs,
81
+ });
82
+ return {
83
+ channel: this.channel,
84
+ packageName: ctx.packageName,
85
+ versionName: ctx.versionName,
86
+ versionCode: ctx.versionCode,
87
+ action: 'upload+submit',
88
+ status: 'submitted',
89
+ errorCode: null,
90
+ message: '',
91
+ durationMs: Date.now() - start,
92
+ };
93
+ }
94
+ catch (e) {
95
+ return toFailed(this.channel, e, start, 'upload+submit', ctx);
96
+ }
97
+ }
98
+ async queryStatus(ctx) {
99
+ const start = Date.now();
100
+ try {
101
+ const data = await queryHuaweiAppInfo({
102
+ appId: ctx.creds.app_id,
103
+ clientId: ctx.creds.client_id,
104
+ clientSecret: ctx.creds.client_secret,
105
+ timeoutMs: ctx.timeoutMs,
106
+ });
107
+ const appInfo = data?.appInfo ?? data ?? {};
108
+ const stateRaw = appInfo?.releaseState;
109
+ const state = stateRaw === undefined || stateRaw === null || stateRaw === ''
110
+ ? null
111
+ : Number(stateRaw);
112
+ const marketVersion = appInfo?.onShelfVersionNumber?.toString() ?? appInfo?.versionNumber?.toString();
113
+ return {
114
+ channel: this.channel,
115
+ packageName: ctx.packageName,
116
+ action: 'status',
117
+ status: mapReleaseState(Number.isNaN(state) ? null : state),
118
+ marketVersion,
119
+ errorCode: null,
120
+ durationMs: Date.now() - start,
121
+ };
122
+ }
123
+ catch (e) {
124
+ return toFailed(this.channel, e, start, 'status');
125
+ }
126
+ }
127
+ }
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/android/huawei/index.ts"],"names":[],"mappings":"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"}