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,360 @@
1
+ // 流程:OAuth client_credentials 取 token → get-app-detail 取应用信息 → 更新更新日志
2
+ // →(可选隐私链接)→ 取上传地址 + multipart 上传 APK → update-file-info 绑定 → 提交审核。
3
+ import { readFile } from 'node:fs/promises';
4
+ import { createHash } from 'node:crypto';
5
+ import { postForm, withRetry } from '../../../infra/http.js';
6
+ import { UploadError } from '../../../core/types.js';
7
+ const TOKEN_URL = 'https://iam.developer.hihonor.com/auth/token';
8
+ const BASE = 'https://appmarket-openapi-drcn.cloud.hihonor.com/openapi/v1/publish';
9
+ // 文件类型:图标 1 / APK 100。
10
+ const FILE_TYPE_ICON = 1;
11
+ const FILE_TYPE_APK = 100;
12
+ // 应用介绍截图-纵向 1080×1920(官方文件类型表 fileType=3;横向为 2)。绑定时需带 order 0..N。
13
+ const FILE_TYPE_SCREENSHOT_PORTRAIT = 3;
14
+ const delay = (ms) => new Promise((r) => setTimeout(r, ms));
15
+ function authHeaders(clientId, accessToken) {
16
+ return {
17
+ client_id: clientId,
18
+ Authorization: `Bearer ${accessToken}`,
19
+ 'Content-Type': 'application/json',
20
+ };
21
+ }
22
+ /** 通用 JSON 请求(GET/POST),非 200 抛 UploadError。 */
23
+ /** 发请求返回原始文本(不 JSON.parse)。body 为字符串时按原样发送——用于保 objectId 大整数精度。 */
24
+ async function honorRequestText(method, url, clientId, accessToken, body, timeoutMs) {
25
+ const init = {
26
+ method,
27
+ headers: authHeaders(clientId, accessToken),
28
+ signal: AbortSignal.timeout(timeoutMs),
29
+ };
30
+ if (body !== undefined)
31
+ init.body = typeof body === 'string' ? body : JSON.stringify(body);
32
+ const res = await fetch(url, init);
33
+ const text = await res.text();
34
+ if (!res.ok)
35
+ throw new UploadError(res.status, `http ${res.status}: ${text.slice(0, 300)}`);
36
+ return text;
37
+ }
38
+ async function honorJson(method, url, clientId, accessToken, bodyObj, timeoutMs) {
39
+ const text = await honorRequestText(method, url, clientId, accessToken, bodyObj, timeoutMs);
40
+ try {
41
+ return text ? JSON.parse(text) : {};
42
+ }
43
+ catch {
44
+ throw new UploadError('parse', `非 JSON 响应: ${text.slice(0, 300)}`);
45
+ }
46
+ }
47
+ /**
48
+ * 校验荣耀业务响应:外层 code 须 '0000',内层 data.code(存在时)须 0,否则抛出荣耀的真实原因。
49
+ * 荣耀错误字段用 msg(非 message),空时附完整响应。此前 bindFiles 等不校验业务码,
50
+ * 绑定失败会被静默吞掉、直到 submit 才以「APK file not bound」暴露。
51
+ */
52
+ function assertHonorOk(data, label) {
53
+ // 荣耀各接口成功码不统一:submit-audit 外层用 '0000',绑定/上传等用数字 0 + msg "Success"。两者都认。
54
+ const c = data?.code;
55
+ const outerOk = c === '0000' || c === 0 || c === '0';
56
+ if (!outerOk) {
57
+ const m = data?.msg && String(data.msg).length > 0
58
+ ? String(data.msg)
59
+ : `${label} failed(resp: ${JSON.stringify(data)})`;
60
+ throw new UploadError(String(data?.code ?? label), m);
61
+ }
62
+ const inner = data?.data;
63
+ if (inner && inner.code != null && Number(inner.code) !== 0) {
64
+ const m = inner.msg && String(inner.msg).length > 0
65
+ ? String(inner.msg)
66
+ : `${label} failed(resp: ${JSON.stringify(data)})`;
67
+ throw new UploadError(String(inner.code), m);
68
+ }
69
+ }
70
+ /** OAuth client_credentials 取 access_token(表单编码端点,复用 postForm)。 */
71
+ export async function fetchAccessToken(args) {
72
+ const data = await postForm(TOKEN_URL, {
73
+ grant_type: 'client_credentials',
74
+ client_id: args.clientId,
75
+ client_secret: args.clientSecret,
76
+ }, args.timeoutMs);
77
+ const token = data?.access_token;
78
+ if (!token)
79
+ throw new UploadError('token', `取 token 失败: ${JSON.stringify(data).slice(0, 300)}`);
80
+ return String(token);
81
+ }
82
+ /** 取应用详情(含 basicInfo / languageInfo),供更新日志与隐私链接复用。 */
83
+ async function getAppInfo(args) {
84
+ // get-app-detail 为幂等 GET,瞬时失败自动重试。
85
+ const resp = await withRetry(() => honorJson('GET', `${BASE}/get-app-detail?appId=${args.appId}`, args.clientId, args.accessToken, undefined, args.timeoutMs), { label: 'honor get-app-detail' });
86
+ return resp?.data;
87
+ }
88
+ /**
89
+ * 更新语言文案(update-language-info):在每条 languageInfo 上按需覆写字段。
90
+ * 仅当对应入参有值时才覆写,未传字段沿用商店现有值(PubLanguageInfo 模型字段):
91
+ * - newFeature 更新说明;appName 应用名称;briefIntro 一句话简介(≤80);intro 应用介绍/长描述(≤8000)。
92
+ * 字段均经荣耀官方文档(doc/guides/101359 PubLanguageInfo)确认。
93
+ */
94
+ async function updateLanguageInfo(args) {
95
+ const has = (v) => typeof v === 'string' && v.length > 0;
96
+ // 线上 languageInfo 为空数组/缺失时,直接 map 会得到空 list,导致即便传了 releaseNote 也发空更新。
97
+ // 此时兜底构造一条 { languageId: 'zh-CN' } 作为基底,再按需写入文案字段,确保更新生效。
98
+ const existing = Array.isArray(args.appInfo?.languageInfo) ? args.appInfo.languageInfo : [];
99
+ const baseList = existing.length > 0 ? existing : [{ languageId: 'zh-CN' }];
100
+ const languageInfoList = baseList.map((e) => {
101
+ const next = { ...e };
102
+ if (has(args.newFeature))
103
+ next.newFeature = args.newFeature;
104
+ if (has(args.appName))
105
+ next.appName = args.appName;
106
+ if (has(args.summary))
107
+ next.briefIntro = args.summary;
108
+ if (has(args.description))
109
+ next.intro = args.description;
110
+ return next;
111
+ });
112
+ await honorJson('POST', `${BASE}/update-language-info?appId=${args.appId}`, args.clientId, args.accessToken, { languageInfoList }, args.timeoutMs);
113
+ }
114
+ /** 更新隐私政策链接(在 basicInfo 上改写后整体回传)。 */
115
+ async function updatePrivacy(args) {
116
+ const body = { ...(args.appInfo?.basicInfo ?? {}), privacyPolicyUrl: args.privacyUrl };
117
+ await honorJson('POST', `${BASE}/update-app-info?appId=${args.appId}`, args.clientId, args.accessToken, body, args.timeoutMs);
118
+ }
119
+ /** 取文件上传地址(含 objectId)。 */
120
+ async function getFileUploadInfo(args) {
121
+ // 取上传地址为幂等操作(仅分配上传槽位,失败即未生效),瞬时失败自动重试。
122
+ const raw = await withRetry(() => honorRequestText('POST', `${BASE}/get-file-upload-url?appId=${args.appId}`, args.clientId, args.accessToken, [args.file], args.timeoutMs), { label: 'honor get-file-upload-url' });
123
+ let resp;
124
+ try {
125
+ resp = raw ? JSON.parse(raw) : {};
126
+ }
127
+ catch {
128
+ throw new UploadError('parse', `非 JSON 响应: ${raw.slice(0, 300)}`);
129
+ }
130
+ const info = resp?.data?.[0];
131
+ if (!info?.uploadUrl) {
132
+ throw new UploadError('upload-url', `取上传地址失败: ${raw.slice(0, 300)}`);
133
+ }
134
+ // objectId 保精度:从原始文本抽取数字串。JSON.parse/Number 会把 >2^53 的大整数截断,
135
+ // 导致绑定阶段报 20030「objectId is not exists」(荣耀 objectId 为 64 位整数)。
136
+ const m = raw.match(/"objectId"\s*:\s*"?(\d+)"?/);
137
+ const objectId = m ? m[1] : String(info.objectId ?? '');
138
+ if (!objectId)
139
+ throw new UploadError('upload-url', `未取到 objectId: ${raw.slice(0, 300)}`);
140
+ return { uploadUrl: String(info.uploadUrl), fileName: String(info.fileName), objectId };
141
+ }
142
+ /**
143
+ * 图标与 APK 共用此逻辑,仅 fileName/fileType 不同。
144
+ */
145
+ async function uploadFile(args) {
146
+ const sha256 = createHash('sha256').update(args.bytes).digest('hex');
147
+ const urlInfo = await getFileUploadInfo({
148
+ appId: args.appId,
149
+ clientId: args.clientId,
150
+ accessToken: args.accessToken,
151
+ file: {
152
+ fileName: args.fileName,
153
+ fileSha256: sha256,
154
+ fileSize: args.bytes.length,
155
+ fileType: args.fileType,
156
+ },
157
+ timeoutMs: args.timeoutMs,
158
+ });
159
+ const form = new FormData();
160
+ form.append('file', new Blob([args.bytes]), args.fileName);
161
+ // 不要手动设置 Content-Type,交给 fetch 生成 multipart boundary。
162
+ const res = await fetch(urlInfo.uploadUrl, {
163
+ method: 'POST',
164
+ headers: { client_id: args.clientId, Authorization: `Bearer ${args.accessToken}` },
165
+ body: form,
166
+ signal: AbortSignal.timeout(args.uploadTimeoutMs),
167
+ });
168
+ if (!res.ok) {
169
+ const text = await res.text().catch(() => '');
170
+ throw new UploadError(res.status, `上传文件失败 ${res.status}: ${text.slice(0, 300)}`);
171
+ }
172
+ return urlInfo.objectId;
173
+ }
174
+ /** 上传 APK(fileType=APK),返回 objectId。 */
175
+ async function uploadApk(args) {
176
+ return uploadFile({
177
+ appId: args.appId,
178
+ clientId: args.clientId,
179
+ accessToken: args.accessToken,
180
+ fileName: 'honor.apk',
181
+ bytes: args.apkBytes,
182
+ fileType: FILE_TYPE_APK,
183
+ uploadTimeoutMs: args.uploadTimeoutMs,
184
+ timeoutMs: args.timeoutMs,
185
+ });
186
+ }
187
+ /**
188
+ * 荣耀图标尺寸 512×512(由调用方缩放后传入字节)。
189
+ */
190
+ async function updateIcon(args) {
191
+ return uploadFile({
192
+ appId: args.appId,
193
+ clientId: args.clientId,
194
+ accessToken: args.accessToken,
195
+ fileName: 'honor_icon.png',
196
+ bytes: args.iconBytes,
197
+ fileType: FILE_TYPE_ICON,
198
+ uploadTimeoutMs: args.uploadTimeoutMs,
199
+ timeoutMs: args.timeoutMs,
200
+ });
201
+ }
202
+ /**
203
+ * 绑定已上传文件(zh-CN)。截图需带 fileType + order(同类文件展示顺序)。
204
+ * 截图为全量替换:传入的 screenshots 即视为该语言的完整截图集,会覆盖线上原有截图,
205
+ * 而非追加。这是「设置截图」的正确语义(整组替换否则无法删图)——切勿改成与线上截图合并。
206
+ */
207
+ async function bindFiles(args) {
208
+ // objectId 是 64 位大整数(可能超 JS 安全整数)。用占位符构造后替换回原始数字,
209
+ const placeholders = [];
210
+ let seq = 0;
211
+ const ph = (oid) => {
212
+ const token = `@@OID${seq++}@@`;
213
+ placeholders.push([`"${token}"`, oid]);
214
+ return token;
215
+ };
216
+ const bindingFileList = args.objectIds.map((oid) => ({
217
+ objectId: ph(oid),
218
+ languageId: 'zh-CN',
219
+ }));
220
+ for (const s of args.screenshots ?? []) {
221
+ bindingFileList.push({
222
+ objectId: ph(s.objectId),
223
+ languageId: 'zh-CN',
224
+ fileType: FILE_TYPE_SCREENSHOT_PORTRAIT,
225
+ order: s.order,
226
+ });
227
+ }
228
+ let body = JSON.stringify({ bindingFileList });
229
+ for (const [quoted, digits] of placeholders)
230
+ body = body.replace(quoted, digits);
231
+ const text = await honorRequestText('POST', `${BASE}/update-file-info?appId=${args.appId}`, args.clientId, args.accessToken, body, args.timeoutMs);
232
+ let resp;
233
+ try {
234
+ resp = text ? JSON.parse(text) : {};
235
+ }
236
+ catch {
237
+ throw new UploadError('parse', `非 JSON 响应: ${text.slice(0, 300)}`);
238
+ }
239
+ // 校验绑定业务码——绑定失败必须立刻暴露,否则会以 submit 阶段的「APK file not bound」间接报出。
240
+ assertHonorOk(resp, 'bind');
241
+ }
242
+ /** 提交审核(releaseType=1)。校验外层 code=='0000' 且内层 data.code==0。 */
243
+ async function submit(args) {
244
+ const data = await honorJson('POST', `${BASE}/submit-audit?appId=${args.appId}`, args.clientId, args.accessToken, { releaseType: 1 }, args.timeoutMs);
245
+ assertHonorOk(data, 'submit');
246
+ }
247
+ /** 完整传报:取应用信息 → 更新日志 →(可选隐私)→ 上传 APK → 绑定 → 提交审核。 */
248
+ export async function uploadHonor(args) {
249
+ const uploadTimeoutMs = Math.max(args.timeoutMs, 900000);
250
+ const apkBytes = await readFile(args.apkPath);
251
+ const accessToken = await fetchAccessToken({
252
+ clientId: args.clientId,
253
+ clientSecret: args.clientSecret,
254
+ timeoutMs: args.timeoutMs,
255
+ });
256
+ // 1. 取应用信息(更新日志/隐私链接均需基于现有数据回传)
257
+ const appInfo = await getAppInfo({
258
+ appId: args.appId,
259
+ clientId: args.clientId,
260
+ accessToken,
261
+ timeoutMs: args.timeoutMs,
262
+ });
263
+ // 2. 更新文案(更新说明 + 可选名称/简介/介绍,按需生效;任一有值才请求)
264
+ const hasText = (v) => typeof v === 'string' && v.length > 0;
265
+ if (hasText(args.releaseNote) ||
266
+ hasText(args.appName) ||
267
+ hasText(args.summary) ||
268
+ hasText(args.description)) {
269
+ await updateLanguageInfo({
270
+ appId: args.appId,
271
+ clientId: args.clientId,
272
+ accessToken,
273
+ appInfo,
274
+ newFeature: args.releaseNote,
275
+ appName: args.appName,
276
+ summary: args.summary,
277
+ description: args.description,
278
+ timeoutMs: args.timeoutMs,
279
+ });
280
+ }
281
+ // 3. 更新隐私政策链接(可选)
282
+ if (args.privacyUrl && args.privacyUrl.length > 0) {
283
+ await updatePrivacy({
284
+ appId: args.appId,
285
+ clientId: args.clientId,
286
+ accessToken,
287
+ appInfo,
288
+ privacyUrl: args.privacyUrl,
289
+ timeoutMs: args.timeoutMs,
290
+ });
291
+ }
292
+ // 4. 上传 APK
293
+ const apkObjectId = await uploadApk({
294
+ appId: args.appId,
295
+ clientId: args.clientId,
296
+ accessToken,
297
+ apkBytes,
298
+ uploadTimeoutMs,
299
+ timeoutMs: args.timeoutMs,
300
+ });
301
+ // 5. 上传图标(可选):存在图标字节时上传并加入 objectIds,否则仅绑定 APK(不报错)。
302
+ const objectIds = [apkObjectId];
303
+ if (args.iconBytes && args.iconBytes.length > 0) {
304
+ const iconObjectId = await updateIcon({
305
+ appId: args.appId,
306
+ clientId: args.clientId,
307
+ accessToken,
308
+ iconBytes: args.iconBytes,
309
+ uploadTimeoutMs,
310
+ timeoutMs: args.timeoutMs,
311
+ });
312
+ objectIds.push(iconObjectId);
313
+ }
314
+ // 5b. 上传截图(可选):纵向 fileType=3,逐张上传,按 order 0..N 绑定。
315
+ const screenshotBinds = [];
316
+ if (args.screenshotBytesList && args.screenshotBytesList.length > 0) {
317
+ for (let i = 0; i < args.screenshotBytesList.length; i++) {
318
+ const shotObjectId = await uploadFile({
319
+ appId: args.appId,
320
+ clientId: args.clientId,
321
+ accessToken,
322
+ fileName: `honor_screenshot_${i + 1}.png`,
323
+ bytes: args.screenshotBytesList[i],
324
+ fileType: FILE_TYPE_SCREENSHOT_PORTRAIT,
325
+ uploadTimeoutMs,
326
+ timeoutMs: args.timeoutMs,
327
+ });
328
+ screenshotBinds.push({ objectId: shotObjectId, order: i });
329
+ }
330
+ }
331
+ // 6. 绑定文件(APK,及可选图标 / 截图)
332
+ await bindFiles({
333
+ appId: args.appId,
334
+ clientId: args.clientId,
335
+ accessToken,
336
+ objectIds,
337
+ screenshots: screenshotBinds,
338
+ timeoutMs: args.timeoutMs,
339
+ });
340
+ // 延迟让荣耀异步处理完绑定再提审,规避 "multiple icons"(30026) / "APK file not bound"(30036) 等
341
+ await delay(5000);
342
+ // 7. 提交审核
343
+ await submit({
344
+ appId: args.appId,
345
+ clientId: args.clientId,
346
+ accessToken,
347
+ timeoutMs: args.timeoutMs,
348
+ });
349
+ }
350
+ /** 查询发布状态(get-app-detail),返回原始 JSON 供状态映射。 */
351
+ export async function queryHonorPublishStatus(args) {
352
+ const accessToken = await fetchAccessToken({
353
+ clientId: args.clientId,
354
+ clientSecret: args.clientSecret,
355
+ timeoutMs: args.timeoutMs,
356
+ });
357
+ // get-app-detail 为幂等 GET,瞬时失败自动重试。
358
+ return withRetry(() => honorJson('GET', `${BASE}/get-app-detail?appId=${args.appId}`, args.clientId, accessToken, undefined, args.timeoutMs), { label: 'honor get-app-detail' });
359
+ }
360
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../src/adapters/android/honor/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
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 { queryHonorPublishStatus, uploadHonor } from './api.js';
6
+ // 荣耀 releaseStatus 映射(参考 status/providers/honor_provider.dart 与 online_version.dart):
7
+ // 1 已发布 → published
8
+ // 2 已下架 → offline
9
+ // 0 未发布 / 其它 → pending_review(已提交、待审/待发布)
10
+ function mapReleaseStatus(status) {
11
+ switch (status) {
12
+ case 1:
13
+ return 'published';
14
+ case 2:
15
+ return 'offline';
16
+ case 0:
17
+ default:
18
+ return 'pending_review';
19
+ }
20
+ }
21
+ function asMap(raw) {
22
+ if (!raw)
23
+ return null;
24
+ if (Array.isArray(raw))
25
+ return raw.find((e) => e && typeof e === 'object') ?? null;
26
+ if (typeof raw === 'object')
27
+ return raw;
28
+ return null;
29
+ }
30
+ /** 荣耀应用市场:上传 APK 后直接提交审核,upload 始终为 upload+submit。 */
31
+ export class HonorAdapter {
32
+ channel = 'honor';
33
+ async upload(ctx) {
34
+ const start = Date.now();
35
+ try {
36
+ const spec = getChannelSpec('honor');
37
+ // 默认不更新图标(沿用商店现有),仅 --update-icon 时更新(荣耀 512²、≤200KB 自动压缩);
38
+ // 图标来源:优先 --icon,否则 aapt 从 APK 自动提取。
39
+ const iconBytes = ctx.updateIcon
40
+ ? await resolveIconBytes({
41
+ iconPath: ctx.iconPath,
42
+ apkPath: ctx.pkg,
43
+ size: spec.iconSize,
44
+ maxBytes: spec.iconMaxBytes,
45
+ })
46
+ : undefined;
47
+ // 文案按需更新:写前做长度告警(不阻断,以渠道后台校验为准)。
48
+ warnIfTooLong('honor', 'appName', ctx.appName, spec.appNameMax);
49
+ warnIfTooLong('honor', 'summary', ctx.summary, spec.summaryMax);
50
+ warnIfTooLong('honor', 'description', ctx.description, spec.descriptionMax);
51
+ // 截图按需(--screenshot 为全量替换):传入即视为该语言的完整截图集,会覆盖线上原有截图而非追加
52
+ //(覆盖语义详见 api.ts bindFiles 注释)。纵向 1080×1920、3-5 张、≤5MB(官方 fileType=3),
53
+ // 逐张处理后由 api 层上传+按 order 绑定。
54
+ let screenshotBytesList;
55
+ if (ctx.screenshots && ctx.screenshots.length > 0) {
56
+ screenshotBytesList = [];
57
+ for (const p of ctx.screenshots) {
58
+ screenshotBytesList.push(await prepareScreenshot(p, spec.screenshotFormat, spec.screenshotMaxBytes));
59
+ }
60
+ }
61
+ await uploadHonor({
62
+ appId: ctx.creds.app_id,
63
+ clientId: ctx.creds.client_id,
64
+ clientSecret: ctx.creds.client_secret,
65
+ apkPath: ctx.pkg,
66
+ releaseNote: ctx.releaseNote,
67
+ privacyUrl: ctx.privacyUrl,
68
+ appName: ctx.appName,
69
+ summary: ctx.summary,
70
+ description: ctx.description,
71
+ iconBytes,
72
+ screenshotBytesList,
73
+ timeoutMs: ctx.timeoutMs,
74
+ });
75
+ return {
76
+ channel: this.channel,
77
+ packageName: ctx.packageName,
78
+ versionName: ctx.versionName,
79
+ versionCode: ctx.versionCode,
80
+ action: 'upload+submit',
81
+ status: 'submitted',
82
+ errorCode: null,
83
+ message: '',
84
+ durationMs: Date.now() - start,
85
+ };
86
+ }
87
+ catch (e) {
88
+ return toFailed(this.channel, e, start, 'upload+submit', ctx);
89
+ }
90
+ }
91
+ async queryStatus(ctx) {
92
+ const start = Date.now();
93
+ try {
94
+ const resp = await queryHonorPublishStatus({
95
+ appId: ctx.creds.app_id,
96
+ clientId: ctx.creds.client_id,
97
+ clientSecret: ctx.creds.client_secret,
98
+ timeoutMs: ctx.timeoutMs,
99
+ });
100
+ const data = resp?.data ?? {};
101
+ const publishInfo = asMap(data?.publishInfo);
102
+ const releaseInfo = asMap(data?.releaseInfo);
103
+ const versionSource = releaseInfo ?? publishInfo;
104
+ const rsRaw = publishInfo?.releaseStatus;
105
+ const releaseStatus = rsRaw === undefined || rsRaw === null || rsRaw === '' ? null : Number(rsRaw);
106
+ const marketVersion = versionSource?.versionName?.toString();
107
+ return {
108
+ channel: this.channel,
109
+ packageName: ctx.packageName,
110
+ action: 'status',
111
+ status: mapReleaseStatus(Number.isNaN(releaseStatus) ? null : releaseStatus),
112
+ marketVersion,
113
+ errorCode: null,
114
+ durationMs: Date.now() - start,
115
+ };
116
+ }
117
+ catch (e) {
118
+ return toFailed(this.channel, e, start, 'status');
119
+ }
120
+ }
121
+ }
122
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/adapters/android/honor/index.ts"],"names":[],"mappings":"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"}