@huoye/app-ship 0.1.0 → 0.1.2
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/LICENSE +57 -0
- package/README.md +315 -299
- package/dist/cli.js +931 -519
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +927 -515
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +141 -41
- package/dist/index.d.ts +141 -41
- package/dist/index.js +927 -515
- package/dist/index.js.map +1 -1
- package/package.json +37 -9
package/dist/index.cjs
CHANGED
|
@@ -53,23 +53,517 @@ __export(index_exports, {
|
|
|
53
53
|
});
|
|
54
54
|
module.exports = __toCommonJS(index_exports);
|
|
55
55
|
|
|
56
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
57
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
58
|
+
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
59
|
+
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
60
|
+
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
61
|
+
var styles = {
|
|
62
|
+
modifier: {
|
|
63
|
+
reset: [0, 0],
|
|
64
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
65
|
+
bold: [1, 22],
|
|
66
|
+
dim: [2, 22],
|
|
67
|
+
italic: [3, 23],
|
|
68
|
+
underline: [4, 24],
|
|
69
|
+
overline: [53, 55],
|
|
70
|
+
inverse: [7, 27],
|
|
71
|
+
hidden: [8, 28],
|
|
72
|
+
strikethrough: [9, 29]
|
|
73
|
+
},
|
|
74
|
+
color: {
|
|
75
|
+
black: [30, 39],
|
|
76
|
+
red: [31, 39],
|
|
77
|
+
green: [32, 39],
|
|
78
|
+
yellow: [33, 39],
|
|
79
|
+
blue: [34, 39],
|
|
80
|
+
magenta: [35, 39],
|
|
81
|
+
cyan: [36, 39],
|
|
82
|
+
white: [37, 39],
|
|
83
|
+
// Bright color
|
|
84
|
+
blackBright: [90, 39],
|
|
85
|
+
gray: [90, 39],
|
|
86
|
+
// Alias of `blackBright`
|
|
87
|
+
grey: [90, 39],
|
|
88
|
+
// Alias of `blackBright`
|
|
89
|
+
redBright: [91, 39],
|
|
90
|
+
greenBright: [92, 39],
|
|
91
|
+
yellowBright: [93, 39],
|
|
92
|
+
blueBright: [94, 39],
|
|
93
|
+
magentaBright: [95, 39],
|
|
94
|
+
cyanBright: [96, 39],
|
|
95
|
+
whiteBright: [97, 39]
|
|
96
|
+
},
|
|
97
|
+
bgColor: {
|
|
98
|
+
bgBlack: [40, 49],
|
|
99
|
+
bgRed: [41, 49],
|
|
100
|
+
bgGreen: [42, 49],
|
|
101
|
+
bgYellow: [43, 49],
|
|
102
|
+
bgBlue: [44, 49],
|
|
103
|
+
bgMagenta: [45, 49],
|
|
104
|
+
bgCyan: [46, 49],
|
|
105
|
+
bgWhite: [47, 49],
|
|
106
|
+
// Bright color
|
|
107
|
+
bgBlackBright: [100, 49],
|
|
108
|
+
bgGray: [100, 49],
|
|
109
|
+
// Alias of `bgBlackBright`
|
|
110
|
+
bgGrey: [100, 49],
|
|
111
|
+
// Alias of `bgBlackBright`
|
|
112
|
+
bgRedBright: [101, 49],
|
|
113
|
+
bgGreenBright: [102, 49],
|
|
114
|
+
bgYellowBright: [103, 49],
|
|
115
|
+
bgBlueBright: [104, 49],
|
|
116
|
+
bgMagentaBright: [105, 49],
|
|
117
|
+
bgCyanBright: [106, 49],
|
|
118
|
+
bgWhiteBright: [107, 49]
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var modifierNames = Object.keys(styles.modifier);
|
|
122
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
123
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
124
|
+
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
125
|
+
function assembleStyles() {
|
|
126
|
+
const codes = /* @__PURE__ */ new Map();
|
|
127
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
128
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
129
|
+
styles[styleName] = {
|
|
130
|
+
open: `\x1B[${style[0]}m`,
|
|
131
|
+
close: `\x1B[${style[1]}m`
|
|
132
|
+
};
|
|
133
|
+
group[styleName] = styles[styleName];
|
|
134
|
+
codes.set(style[0], style[1]);
|
|
135
|
+
}
|
|
136
|
+
Object.defineProperty(styles, groupName, {
|
|
137
|
+
value: group,
|
|
138
|
+
enumerable: false
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
Object.defineProperty(styles, "codes", {
|
|
142
|
+
value: codes,
|
|
143
|
+
enumerable: false
|
|
144
|
+
});
|
|
145
|
+
styles.color.close = "\x1B[39m";
|
|
146
|
+
styles.bgColor.close = "\x1B[49m";
|
|
147
|
+
styles.color.ansi = wrapAnsi16();
|
|
148
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
149
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
150
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
151
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
152
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
153
|
+
Object.defineProperties(styles, {
|
|
154
|
+
rgbToAnsi256: {
|
|
155
|
+
value(red, green, blue) {
|
|
156
|
+
if (red === green && green === blue) {
|
|
157
|
+
if (red < 8) {
|
|
158
|
+
return 16;
|
|
159
|
+
}
|
|
160
|
+
if (red > 248) {
|
|
161
|
+
return 231;
|
|
162
|
+
}
|
|
163
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
164
|
+
}
|
|
165
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
166
|
+
},
|
|
167
|
+
enumerable: false
|
|
168
|
+
},
|
|
169
|
+
hexToRgb: {
|
|
170
|
+
value(hex) {
|
|
171
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
172
|
+
if (!matches) {
|
|
173
|
+
return [0, 0, 0];
|
|
174
|
+
}
|
|
175
|
+
let [colorString] = matches;
|
|
176
|
+
if (colorString.length === 3) {
|
|
177
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
178
|
+
}
|
|
179
|
+
const integer = Number.parseInt(colorString, 16);
|
|
180
|
+
return [
|
|
181
|
+
/* eslint-disable no-bitwise */
|
|
182
|
+
integer >> 16 & 255,
|
|
183
|
+
integer >> 8 & 255,
|
|
184
|
+
integer & 255
|
|
185
|
+
/* eslint-enable no-bitwise */
|
|
186
|
+
];
|
|
187
|
+
},
|
|
188
|
+
enumerable: false
|
|
189
|
+
},
|
|
190
|
+
hexToAnsi256: {
|
|
191
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
192
|
+
enumerable: false
|
|
193
|
+
},
|
|
194
|
+
ansi256ToAnsi: {
|
|
195
|
+
value(code) {
|
|
196
|
+
if (code < 8) {
|
|
197
|
+
return 30 + code;
|
|
198
|
+
}
|
|
199
|
+
if (code < 16) {
|
|
200
|
+
return 90 + (code - 8);
|
|
201
|
+
}
|
|
202
|
+
let red;
|
|
203
|
+
let green;
|
|
204
|
+
let blue;
|
|
205
|
+
if (code >= 232) {
|
|
206
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
207
|
+
green = red;
|
|
208
|
+
blue = red;
|
|
209
|
+
} else {
|
|
210
|
+
code -= 16;
|
|
211
|
+
const remainder = code % 36;
|
|
212
|
+
red = Math.floor(code / 36) / 5;
|
|
213
|
+
green = Math.floor(remainder / 6) / 5;
|
|
214
|
+
blue = remainder % 6 / 5;
|
|
215
|
+
}
|
|
216
|
+
const value = Math.max(red, green, blue) * 2;
|
|
217
|
+
if (value === 0) {
|
|
218
|
+
return 30;
|
|
219
|
+
}
|
|
220
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
221
|
+
if (value === 2) {
|
|
222
|
+
result += 60;
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
},
|
|
226
|
+
enumerable: false
|
|
227
|
+
},
|
|
228
|
+
rgbToAnsi: {
|
|
229
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
230
|
+
enumerable: false
|
|
231
|
+
},
|
|
232
|
+
hexToAnsi: {
|
|
233
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
234
|
+
enumerable: false
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return styles;
|
|
238
|
+
}
|
|
239
|
+
var ansiStyles = assembleStyles();
|
|
240
|
+
var ansi_styles_default = ansiStyles;
|
|
241
|
+
|
|
242
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
243
|
+
var import_node_process = __toESM(require("process"), 1);
|
|
244
|
+
var import_node_os = __toESM(require("os"), 1);
|
|
245
|
+
var import_node_tty = __toESM(require("tty"), 1);
|
|
246
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
|
|
247
|
+
const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
248
|
+
const position = argv.indexOf(prefix + flag);
|
|
249
|
+
const terminatorPosition = argv.indexOf("--");
|
|
250
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
251
|
+
}
|
|
252
|
+
var { env } = import_node_process.default;
|
|
253
|
+
var flagForceColor;
|
|
254
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
255
|
+
flagForceColor = 0;
|
|
256
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
257
|
+
flagForceColor = 1;
|
|
258
|
+
}
|
|
259
|
+
function envForceColor() {
|
|
260
|
+
if ("FORCE_COLOR" in env) {
|
|
261
|
+
if (env.FORCE_COLOR === "true") {
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
if (env.FORCE_COLOR === "false") {
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function translateLevel(level) {
|
|
271
|
+
if (level === 0) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
level,
|
|
276
|
+
hasBasic: true,
|
|
277
|
+
has256: level >= 2,
|
|
278
|
+
has16m: level >= 3
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
282
|
+
const noFlagForceColor = envForceColor();
|
|
283
|
+
if (noFlagForceColor !== void 0) {
|
|
284
|
+
flagForceColor = noFlagForceColor;
|
|
285
|
+
}
|
|
286
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
287
|
+
if (forceColor === 0) {
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
if (sniffFlags) {
|
|
291
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
292
|
+
return 3;
|
|
293
|
+
}
|
|
294
|
+
if (hasFlag("color=256")) {
|
|
295
|
+
return 2;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
299
|
+
return 1;
|
|
300
|
+
}
|
|
301
|
+
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
302
|
+
return 0;
|
|
303
|
+
}
|
|
304
|
+
const min = forceColor || 0;
|
|
305
|
+
if (env.TERM === "dumb") {
|
|
306
|
+
return min;
|
|
307
|
+
}
|
|
308
|
+
if (import_node_process.default.platform === "win32") {
|
|
309
|
+
const osRelease = import_node_os.default.release().split(".");
|
|
310
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
311
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
312
|
+
}
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
if ("CI" in env) {
|
|
316
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
|
|
317
|
+
return 3;
|
|
318
|
+
}
|
|
319
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
320
|
+
return 1;
|
|
321
|
+
}
|
|
322
|
+
return min;
|
|
323
|
+
}
|
|
324
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
325
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
326
|
+
}
|
|
327
|
+
if (env.COLORTERM === "truecolor") {
|
|
328
|
+
return 3;
|
|
329
|
+
}
|
|
330
|
+
if (env.TERM === "xterm-kitty") {
|
|
331
|
+
return 3;
|
|
332
|
+
}
|
|
333
|
+
if (env.TERM === "xterm-ghostty") {
|
|
334
|
+
return 3;
|
|
335
|
+
}
|
|
336
|
+
if (env.TERM === "wezterm") {
|
|
337
|
+
return 3;
|
|
338
|
+
}
|
|
339
|
+
if ("TERM_PROGRAM" in env) {
|
|
340
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
341
|
+
switch (env.TERM_PROGRAM) {
|
|
342
|
+
case "iTerm.app": {
|
|
343
|
+
return version >= 3 ? 3 : 2;
|
|
344
|
+
}
|
|
345
|
+
case "Apple_Terminal": {
|
|
346
|
+
return 2;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
351
|
+
return 2;
|
|
352
|
+
}
|
|
353
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
354
|
+
return 1;
|
|
355
|
+
}
|
|
356
|
+
if ("COLORTERM" in env) {
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
return min;
|
|
360
|
+
}
|
|
361
|
+
function createSupportsColor(stream, options = {}) {
|
|
362
|
+
const level = _supportsColor(stream, {
|
|
363
|
+
streamIsTTY: stream && stream.isTTY,
|
|
364
|
+
...options
|
|
365
|
+
});
|
|
366
|
+
return translateLevel(level);
|
|
367
|
+
}
|
|
368
|
+
var supportsColor = {
|
|
369
|
+
stdout: createSupportsColor({ isTTY: import_node_tty.default.isatty(1) }),
|
|
370
|
+
stderr: createSupportsColor({ isTTY: import_node_tty.default.isatty(2) })
|
|
371
|
+
};
|
|
372
|
+
var supports_color_default = supportsColor;
|
|
373
|
+
|
|
374
|
+
// node_modules/chalk/source/utilities.js
|
|
375
|
+
function stringReplaceAll(string, substring, replacer) {
|
|
376
|
+
let index = string.indexOf(substring);
|
|
377
|
+
if (index === -1) {
|
|
378
|
+
return string;
|
|
379
|
+
}
|
|
380
|
+
const substringLength = substring.length;
|
|
381
|
+
let endIndex = 0;
|
|
382
|
+
let returnValue = "";
|
|
383
|
+
do {
|
|
384
|
+
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
385
|
+
endIndex = index + substringLength;
|
|
386
|
+
index = string.indexOf(substring, endIndex);
|
|
387
|
+
} while (index !== -1);
|
|
388
|
+
returnValue += string.slice(endIndex);
|
|
389
|
+
return returnValue;
|
|
390
|
+
}
|
|
391
|
+
function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
392
|
+
let endIndex = 0;
|
|
393
|
+
let returnValue = "";
|
|
394
|
+
do {
|
|
395
|
+
const gotCR = string[index - 1] === "\r";
|
|
396
|
+
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
397
|
+
endIndex = index + 1;
|
|
398
|
+
index = string.indexOf("\n", endIndex);
|
|
399
|
+
} while (index !== -1);
|
|
400
|
+
returnValue += string.slice(endIndex);
|
|
401
|
+
return returnValue;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// node_modules/chalk/source/index.js
|
|
405
|
+
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
406
|
+
var GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
|
|
407
|
+
var STYLER = /* @__PURE__ */ Symbol("STYLER");
|
|
408
|
+
var IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
|
|
409
|
+
var levelMapping = [
|
|
410
|
+
"ansi",
|
|
411
|
+
"ansi",
|
|
412
|
+
"ansi256",
|
|
413
|
+
"ansi16m"
|
|
414
|
+
];
|
|
415
|
+
var styles2 = /* @__PURE__ */ Object.create(null);
|
|
416
|
+
var applyOptions = (object, options = {}) => {
|
|
417
|
+
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
418
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
419
|
+
}
|
|
420
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
421
|
+
object.level = options.level === void 0 ? colorLevel : options.level;
|
|
422
|
+
};
|
|
423
|
+
var chalkFactory = (options) => {
|
|
424
|
+
const chalk2 = (...strings) => strings.join(" ");
|
|
425
|
+
applyOptions(chalk2, options);
|
|
426
|
+
Object.setPrototypeOf(chalk2, createChalk.prototype);
|
|
427
|
+
return chalk2;
|
|
428
|
+
};
|
|
429
|
+
function createChalk(options) {
|
|
430
|
+
return chalkFactory(options);
|
|
431
|
+
}
|
|
432
|
+
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
433
|
+
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
434
|
+
styles2[styleName] = {
|
|
435
|
+
get() {
|
|
436
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
437
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
438
|
+
return builder;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
styles2.visible = {
|
|
443
|
+
get() {
|
|
444
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
445
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
446
|
+
return builder;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var getModelAnsi = (model, level, type, ...arguments_) => {
|
|
450
|
+
if (model === "rgb") {
|
|
451
|
+
if (level === "ansi16m") {
|
|
452
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
453
|
+
}
|
|
454
|
+
if (level === "ansi256") {
|
|
455
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
456
|
+
}
|
|
457
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
458
|
+
}
|
|
459
|
+
if (model === "hex") {
|
|
460
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
461
|
+
}
|
|
462
|
+
return ansi_styles_default[type][model](...arguments_);
|
|
463
|
+
};
|
|
464
|
+
var usedModels = ["rgb", "hex", "ansi256"];
|
|
465
|
+
for (const model of usedModels) {
|
|
466
|
+
styles2[model] = {
|
|
467
|
+
get() {
|
|
468
|
+
const { level } = this;
|
|
469
|
+
return function(...arguments_) {
|
|
470
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
471
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
476
|
+
styles2[bgModel] = {
|
|
477
|
+
get() {
|
|
478
|
+
const { level } = this;
|
|
479
|
+
return function(...arguments_) {
|
|
480
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
|
|
481
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
var proto = Object.defineProperties(() => {
|
|
487
|
+
}, {
|
|
488
|
+
...styles2,
|
|
489
|
+
level: {
|
|
490
|
+
enumerable: true,
|
|
491
|
+
get() {
|
|
492
|
+
return this[GENERATOR].level;
|
|
493
|
+
},
|
|
494
|
+
set(level) {
|
|
495
|
+
this[GENERATOR].level = level;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
var createStyler = (open, close, parent) => {
|
|
500
|
+
let openAll;
|
|
501
|
+
let closeAll;
|
|
502
|
+
if (parent === void 0) {
|
|
503
|
+
openAll = open;
|
|
504
|
+
closeAll = close;
|
|
505
|
+
} else {
|
|
506
|
+
openAll = parent.openAll + open;
|
|
507
|
+
closeAll = close + parent.closeAll;
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
open,
|
|
511
|
+
close,
|
|
512
|
+
openAll,
|
|
513
|
+
closeAll,
|
|
514
|
+
parent
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
518
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
519
|
+
Object.setPrototypeOf(builder, proto);
|
|
520
|
+
builder[GENERATOR] = self;
|
|
521
|
+
builder[STYLER] = _styler;
|
|
522
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
523
|
+
return builder;
|
|
524
|
+
};
|
|
525
|
+
var applyStyle = (self, string) => {
|
|
526
|
+
if (self.level <= 0 || !string) {
|
|
527
|
+
return self[IS_EMPTY] ? "" : string;
|
|
528
|
+
}
|
|
529
|
+
let styler = self[STYLER];
|
|
530
|
+
if (styler === void 0) {
|
|
531
|
+
return string;
|
|
532
|
+
}
|
|
533
|
+
const { openAll, closeAll } = styler;
|
|
534
|
+
if (string.includes("\x1B")) {
|
|
535
|
+
while (styler !== void 0) {
|
|
536
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
537
|
+
styler = styler.parent;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
const lfIndex = string.indexOf("\n");
|
|
541
|
+
if (lfIndex !== -1) {
|
|
542
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
543
|
+
}
|
|
544
|
+
return openAll + string + closeAll;
|
|
545
|
+
};
|
|
546
|
+
Object.defineProperties(createChalk.prototype, styles2);
|
|
547
|
+
var chalk = createChalk();
|
|
548
|
+
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
549
|
+
var source_default = chalk;
|
|
550
|
+
|
|
56
551
|
// src/utils/logger.ts
|
|
57
|
-
var import_chalk = __toESM(require("chalk"), 1);
|
|
58
552
|
var ConsoleLogger = class {
|
|
59
553
|
info(message) {
|
|
60
|
-
console.log(
|
|
554
|
+
console.log(source_default.blue("\u2139\uFE0F " + message));
|
|
61
555
|
}
|
|
62
556
|
success(message) {
|
|
63
|
-
console.log(
|
|
557
|
+
console.log(source_default.green("\u2705 " + message));
|
|
64
558
|
}
|
|
65
559
|
warn(message) {
|
|
66
|
-
console.log(
|
|
560
|
+
console.log(source_default.yellow("\u26A0\uFE0F " + message));
|
|
67
561
|
}
|
|
68
562
|
error(message) {
|
|
69
|
-
console.log(
|
|
563
|
+
console.log(source_default.red("\u274C " + message));
|
|
70
564
|
}
|
|
71
565
|
title(message) {
|
|
72
|
-
console.log(
|
|
566
|
+
console.log(source_default.bold.cyan("\n" + message + "\n"));
|
|
73
567
|
}
|
|
74
568
|
newLine() {
|
|
75
569
|
console.log("");
|
|
@@ -293,12 +787,7 @@ var RetryStrategy = class {
|
|
|
293
787
|
logger.warn(`${operationName} failed (Attempt ${attempt}): ${errorMessage} [${category}]`);
|
|
294
788
|
if (!this.shouldRetry(error, attempt)) {
|
|
295
789
|
logger.error(`${operationName} failed with non-retryable error: ${errorMessage}`);
|
|
296
|
-
|
|
297
|
-
success: false,
|
|
298
|
-
error,
|
|
299
|
-
totalAttempts: attempt,
|
|
300
|
-
lastError: errorMessage
|
|
301
|
-
};
|
|
790
|
+
throw error;
|
|
302
791
|
}
|
|
303
792
|
if (attempt <= this.config.maxRetries) {
|
|
304
793
|
const delayMs = this.calculateDelay(attempt - 1);
|
|
@@ -309,12 +798,7 @@ var RetryStrategy = class {
|
|
|
309
798
|
}
|
|
310
799
|
}
|
|
311
800
|
}
|
|
312
|
-
|
|
313
|
-
success: false,
|
|
314
|
-
error: lastError || new Error(`${operationName} failed after all retries`),
|
|
315
|
-
totalAttempts: attempt,
|
|
316
|
-
lastError: lastError?.message
|
|
317
|
-
};
|
|
801
|
+
throw lastError || new Error(`${operationName} failed after all retries`);
|
|
318
802
|
}
|
|
319
803
|
};
|
|
320
804
|
var DEFAULT_RETRY_CONFIG = {
|
|
@@ -508,6 +992,7 @@ async function parseHap(filePath) {
|
|
|
508
992
|
}
|
|
509
993
|
|
|
510
994
|
// src/utils/upload-manager.ts
|
|
995
|
+
var GROUPED_ARTIFACT_PLATFORMS = /* @__PURE__ */ new Set(["huawei", "xiaomi", "oppo", "vivo", "tencent"]);
|
|
511
996
|
var UploadManager = class {
|
|
512
997
|
uploaders;
|
|
513
998
|
config;
|
|
@@ -607,30 +1092,64 @@ var UploadManager = class {
|
|
|
607
1092
|
};
|
|
608
1093
|
}
|
|
609
1094
|
const files = Array.isArray(filePaths) ? filePaths : [filePaths];
|
|
610
|
-
|
|
611
|
-
|
|
1095
|
+
const tasks = [];
|
|
1096
|
+
validPlatforms.forEach((platform) => {
|
|
612
1097
|
const uploader = this.uploaders.get(platform);
|
|
613
|
-
const
|
|
614
|
-
if (
|
|
1098
|
+
const matchedFiles = files.filter((f) => uploader.canHandle(f));
|
|
1099
|
+
if (matchedFiles.length === 0) {
|
|
615
1100
|
logger.warn(`[${platform}] No compatible file found in provided files`);
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
1101
|
+
} else {
|
|
1102
|
+
if (this.shouldGroupArtifacts(platform)) {
|
|
1103
|
+
const artifactSelection = this.resolveArtifactSelection(platform, matchedFiles, metadata);
|
|
1104
|
+
if (!artifactSelection) {
|
|
1105
|
+
logger.warn(`[${platform}] Failed to build grouped artifact selection`);
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
tasks.push({
|
|
1109
|
+
platform,
|
|
1110
|
+
file: this.getRepresentativeFilePath(artifactSelection),
|
|
1111
|
+
artifactSelection
|
|
1112
|
+
});
|
|
1113
|
+
} else {
|
|
1114
|
+
matchedFiles.forEach((file) => {
|
|
1115
|
+
tasks.push({ platform, file, artifactSelection: file });
|
|
1116
|
+
});
|
|
1117
|
+
}
|
|
621
1118
|
}
|
|
622
|
-
|
|
623
|
-
|
|
1119
|
+
});
|
|
1120
|
+
if (tasks.length === 0) {
|
|
1121
|
+
logger.error("No valid platform-file matches found");
|
|
1122
|
+
return {
|
|
1123
|
+
totalUploads: validPlatforms.length,
|
|
1124
|
+
successCount: 0,
|
|
1125
|
+
failureCount: validPlatforms.length,
|
|
1126
|
+
successPlatforms: [],
|
|
1127
|
+
failurePlatforms: validPlatforms,
|
|
1128
|
+
results: [],
|
|
1129
|
+
totalDurationMs: Date.now() - startTime,
|
|
1130
|
+
summary: "No compatible files found for any of the selected platforms"
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
logger.info(`Scheduled ${tasks.length} upload task(s) for ${validPlatforms.length} platform(s)`);
|
|
1134
|
+
const uploadPromises = tasks.map((task) => {
|
|
1135
|
+
logger.info(`[${task.platform}] Matched file: ${import_path2.default.basename(task.file)}`);
|
|
1136
|
+
return this.uploadToPlatform(
|
|
1137
|
+
task.platform,
|
|
1138
|
+
task.file,
|
|
1139
|
+
config,
|
|
1140
|
+
metadata,
|
|
1141
|
+
task.artifactSelection
|
|
1142
|
+
);
|
|
624
1143
|
});
|
|
625
1144
|
const results = await Promise.all(uploadPromises);
|
|
626
|
-
const report = this.aggregateResults(results,
|
|
1145
|
+
const report = this.aggregateResults(results, tasks.length, startTime);
|
|
627
1146
|
this.printReport(report);
|
|
628
1147
|
return report;
|
|
629
1148
|
}
|
|
630
1149
|
/**
|
|
631
1150
|
* 上传到单个平台
|
|
632
1151
|
*/
|
|
633
|
-
async uploadToPlatform(platform, filePath, config, metadata) {
|
|
1152
|
+
async uploadToPlatform(platform, filePath, config, metadata, artifactSelection = filePath) {
|
|
634
1153
|
if (this.config.cancellationToken?.isCancelled) {
|
|
635
1154
|
logger.warn(`[${platform.toUpperCase()}] Upload skipped due to cancellation`);
|
|
636
1155
|
return {
|
|
@@ -651,25 +1170,30 @@ var UploadManager = class {
|
|
|
651
1170
|
if (this.config.verbose) {
|
|
652
1171
|
logger.info(`[${platform.toUpperCase()}] Starting upload...`);
|
|
653
1172
|
}
|
|
1173
|
+
const effectiveMetadata = {
|
|
1174
|
+
...metadata,
|
|
1175
|
+
artifactPath: artifactSelection
|
|
1176
|
+
};
|
|
1177
|
+
await this.validateArtifactSelection(platform, artifactSelection, effectiveMetadata);
|
|
654
1178
|
const pkgInfo = await parsePackageInfo(filePath, {
|
|
655
|
-
androidSdkPath:
|
|
1179
|
+
androidSdkPath: effectiveMetadata.globalSettings?.androidSdkPath
|
|
656
1180
|
});
|
|
657
1181
|
if (pkgInfo) {
|
|
658
1182
|
if (pkgInfo.versionName) {
|
|
659
|
-
|
|
1183
|
+
effectiveMetadata.version = pkgInfo.versionName;
|
|
660
1184
|
}
|
|
661
1185
|
if (pkgInfo.versionCode) {
|
|
662
|
-
|
|
1186
|
+
effectiveMetadata.buildNumber = pkgInfo.versionCode;
|
|
663
1187
|
}
|
|
664
1188
|
if (pkgInfo.packageName) {
|
|
665
1189
|
;
|
|
666
|
-
|
|
1190
|
+
effectiveMetadata.packageName = pkgInfo.packageName;
|
|
667
1191
|
}
|
|
668
1192
|
logger.info(
|
|
669
|
-
`[${platform.toUpperCase()}] \u5DF2\u6821\u51C6\u7248\u672C\u4FE1\u606F: v${
|
|
1193
|
+
`[${platform.toUpperCase()}] \u5DF2\u6821\u51C6\u7248\u672C\u4FE1\u606F: v${effectiveMetadata.version}+${effectiveMetadata.buildNumber}`
|
|
670
1194
|
);
|
|
671
1195
|
}
|
|
672
|
-
const result = await uploader.upload(filePath, config,
|
|
1196
|
+
const result = await uploader.upload(filePath, config, effectiveMetadata);
|
|
673
1197
|
return result;
|
|
674
1198
|
} catch (error) {
|
|
675
1199
|
const errorMessage = error.message || String(error);
|
|
@@ -682,6 +1206,85 @@ var UploadManager = class {
|
|
|
682
1206
|
};
|
|
683
1207
|
}
|
|
684
1208
|
}
|
|
1209
|
+
shouldGroupArtifacts(platform) {
|
|
1210
|
+
return GROUPED_ARTIFACT_PLATFORMS.has(platform);
|
|
1211
|
+
}
|
|
1212
|
+
resolveArtifactSelection(platform, matchedFiles, metadata) {
|
|
1213
|
+
const explicitArtifacts = metadata.platformArtifacts?.[platform];
|
|
1214
|
+
if (explicitArtifacts) {
|
|
1215
|
+
if (typeof explicitArtifacts === "string") {
|
|
1216
|
+
return explicitArtifacts;
|
|
1217
|
+
}
|
|
1218
|
+
if (Object.keys(explicitArtifacts).length > 0) {
|
|
1219
|
+
return explicitArtifacts;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (matchedFiles.length === 0) {
|
|
1223
|
+
return null;
|
|
1224
|
+
}
|
|
1225
|
+
if (matchedFiles.length === 1) {
|
|
1226
|
+
return matchedFiles[0];
|
|
1227
|
+
}
|
|
1228
|
+
return this.buildArtifactMapFromFiles(matchedFiles);
|
|
1229
|
+
}
|
|
1230
|
+
buildArtifactMapFromFiles(files) {
|
|
1231
|
+
return files.reduce(
|
|
1232
|
+
(acc, filePath, index) => {
|
|
1233
|
+
acc[this.inferArtifactKey(filePath, index)] = filePath;
|
|
1234
|
+
return acc;
|
|
1235
|
+
},
|
|
1236
|
+
{}
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
inferArtifactKey(filePath, index) {
|
|
1240
|
+
const fileName = import_path2.default.basename(filePath).toLowerCase();
|
|
1241
|
+
if (fileName.includes("arm64-v8a")) return "arm64-v8a";
|
|
1242
|
+
if (fileName.includes("armeabi-v7a")) return "armeabi-v7a";
|
|
1243
|
+
if (fileName.includes("x86_64")) return "x86_64";
|
|
1244
|
+
if (fileName.includes("universal")) return "universal";
|
|
1245
|
+
return `artifact_${index + 1}`;
|
|
1246
|
+
}
|
|
1247
|
+
getRepresentativeFilePath(artifactSelection) {
|
|
1248
|
+
if (typeof artifactSelection === "string") {
|
|
1249
|
+
return artifactSelection;
|
|
1250
|
+
}
|
|
1251
|
+
return Object.values(artifactSelection)[0];
|
|
1252
|
+
}
|
|
1253
|
+
async validateArtifactSelection(platform, artifactSelection, metadata) {
|
|
1254
|
+
if (typeof artifactSelection === "string") {
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
const artifactPaths = Object.values(artifactSelection).filter(Boolean);
|
|
1258
|
+
if (artifactPaths.length < 2) {
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const parsedInfos = await Promise.all(
|
|
1262
|
+
artifactPaths.map(
|
|
1263
|
+
(artifactPath) => parsePackageInfo(artifactPath, {
|
|
1264
|
+
androidSdkPath: metadata.globalSettings?.androidSdkPath
|
|
1265
|
+
})
|
|
1266
|
+
)
|
|
1267
|
+
);
|
|
1268
|
+
const availableInfos = parsedInfos.filter((info) => !!info);
|
|
1269
|
+
if (availableInfos.length < 2) {
|
|
1270
|
+
logger.warn(
|
|
1271
|
+
`[${platform.toUpperCase()}] Unable to fully validate multi-artifact package info; continuing with upload.`
|
|
1272
|
+
);
|
|
1273
|
+
return;
|
|
1274
|
+
}
|
|
1275
|
+
const [baseInfo, ...restInfos] = availableInfos;
|
|
1276
|
+
for (const info of restInfos) {
|
|
1277
|
+
if (baseInfo?.packageName && info?.packageName && baseInfo.packageName !== info.packageName) {
|
|
1278
|
+
throw new Error("\u53CC\u5305\u4E0A\u4F20\u5931\u8D25\uFF1A\u6240\u9009\u5B89\u88C5\u5305\u7684 packageName \u4E0D\u4E00\u81F4");
|
|
1279
|
+
}
|
|
1280
|
+
if (baseInfo?.versionName && info?.versionName && baseInfo.versionName !== info.versionName) {
|
|
1281
|
+
throw new Error("\u53CC\u5305\u4E0A\u4F20\u5931\u8D25\uFF1A\u6240\u9009\u5B89\u88C5\u5305\u7684 versionName \u4E0D\u4E00\u81F4");
|
|
1282
|
+
}
|
|
1283
|
+
if (baseInfo?.versionCode && info?.versionCode && baseInfo.versionCode !== info.versionCode) {
|
|
1284
|
+
throw new Error("\u53CC\u5305\u4E0A\u4F20\u5931\u8D25\uFF1A\u6240\u9009\u5B89\u88C5\u5305\u7684 versionCode \u4E0D\u4E00\u81F4");
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
685
1288
|
/**
|
|
686
1289
|
* 聚合上传结果
|
|
687
1290
|
*/
|
|
@@ -1147,27 +1750,39 @@ var HuaweiUploader = class _HuaweiUploader {
|
|
|
1147
1750
|
clientId,
|
|
1148
1751
|
appId
|
|
1149
1752
|
};
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1753
|
+
const artifacts = typeof metadata.artifactPath === "object" ? metadata.artifactPath : { universal: filePath || metadata.artifactPath || "" };
|
|
1754
|
+
logger.info(`[Huawei] \u5904\u7406\u4EA7\u7269\u6570\u91CF: ${Object.keys(artifacts).length}`);
|
|
1755
|
+
const uploadResults = [];
|
|
1756
|
+
const uploadPromises = Object.entries(artifacts).map(async ([abi, p]) => {
|
|
1757
|
+
if (!p || !import_fs_extra4.default.existsSync(p)) return;
|
|
1758
|
+
const currentSuffix = import_path3.default.extname(p).substring(1);
|
|
1759
|
+
logger.info(`[Huawei] \u6B63\u5728\u4E0A\u4F20 ${abi} \u5305: ${import_path3.default.basename(p)}`);
|
|
1760
|
+
const uploadInfo = await retryStrategy.execute(
|
|
1761
|
+
() => this.getUploadUrl(ctx, currentSuffix),
|
|
1762
|
+
`Huawei get upload URL for ${abi}`
|
|
1763
|
+
);
|
|
1764
|
+
if (!uploadInfo.success || !uploadInfo.data) {
|
|
1765
|
+
throw uploadInfo.error || new Error(`Failed to get upload URL for ${abi}`);
|
|
1766
|
+
}
|
|
1767
|
+
const uploadFileRes = await retryStrategy.execute(
|
|
1768
|
+
() => this.executeUploadRequest(uploadInfo.data.uploadUrl, uploadInfo.data.authCode, p),
|
|
1769
|
+
`Huawei upload file for ${abi}`
|
|
1770
|
+
);
|
|
1771
|
+
if (!uploadFileRes.success || !uploadFileRes.data || uploadFileRes.data.length === 0) {
|
|
1772
|
+
throw uploadFileRes.error || new Error(`File upload failed for ${abi}`);
|
|
1773
|
+
}
|
|
1774
|
+
uploadResults.push({
|
|
1775
|
+
fileName: import_path3.default.basename(p),
|
|
1776
|
+
fileDestUrl: uploadFileRes.data[0].fileDestUrl
|
|
1777
|
+
});
|
|
1778
|
+
});
|
|
1779
|
+
await Promise.all(uploadPromises);
|
|
1780
|
+
if (uploadResults.length === 0) {
|
|
1781
|
+
throw new Error("No files were successfully uploaded");
|
|
1166
1782
|
}
|
|
1167
|
-
|
|
1168
|
-
logger.info("Linking file to app...");
|
|
1783
|
+
logger.info(`[Huawei] \u6B63\u5728\u5173\u8054 ${uploadResults.length} \u4E2A\u6587\u4EF6\u5230\u5E94\u7528...`);
|
|
1169
1784
|
const updateInfoResult = await retryStrategy.execute(
|
|
1170
|
-
() => this.updateAppFileInfo(ctx,
|
|
1785
|
+
() => this.updateAppFileInfo(ctx, uploadResults, filePath),
|
|
1171
1786
|
"Huawei update file info"
|
|
1172
1787
|
);
|
|
1173
1788
|
if (!updateInfoResult.success) {
|
|
@@ -1371,14 +1986,17 @@ var HuaweiUploader = class _HuaweiUploader {
|
|
|
1371
1986
|
throw new Error("Upload succeeded but fileDestUrl not found in response");
|
|
1372
1987
|
}
|
|
1373
1988
|
/** 更新应用文件信息 */
|
|
1374
|
-
async updateAppFileInfo(ctx,
|
|
1375
|
-
const
|
|
1376
|
-
const fileType =
|
|
1989
|
+
async updateAppFileInfo(ctx, files, anyFilePath) {
|
|
1990
|
+
const hasAab = files.some((f) => f.fileName.toLowerCase().endsWith(".aab"));
|
|
1991
|
+
const fileType = hasAab ? 7 /* AAB */ : 5 /* APP_PACKAGE */;
|
|
1377
1992
|
const res = await import_axios2.default.put(
|
|
1378
1993
|
`${ctx.apiRoot}/app-file-info`,
|
|
1379
1994
|
{
|
|
1380
1995
|
fileType,
|
|
1381
|
-
files:
|
|
1996
|
+
files: files.map((f) => ({
|
|
1997
|
+
fileName: f.fileName,
|
|
1998
|
+
fileDestUrl: f.fileDestUrl
|
|
1999
|
+
}))
|
|
1382
2000
|
},
|
|
1383
2001
|
{
|
|
1384
2002
|
params: { appId: ctx.appId },
|
|
@@ -1548,6 +2166,7 @@ var HuaweiUploader = class _HuaweiUploader {
|
|
|
1548
2166
|
|
|
1549
2167
|
// src/adapters/xiaomi_uploader.ts
|
|
1550
2168
|
var import_fs_extra5 = __toESM(require("fs-extra"), 1);
|
|
2169
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
1551
2170
|
var import_axios3 = __toESM(require("axios"), 1);
|
|
1552
2171
|
var import_form_data3 = __toESM(require("form-data"), 1);
|
|
1553
2172
|
var import_crypto3 = __toESM(require("crypto"), 1);
|
|
@@ -1798,80 +2417,39 @@ ${lines.join("\n")}
|
|
|
1798
2417
|
const xiaomiConfig = config.publish?.xiaomi;
|
|
1799
2418
|
const { userName, privateKey, publicKeyPath } = xiaomiConfig.auth;
|
|
1800
2419
|
const updateDesc = metadata.changelog || xiaomiConfig?.description || "App Update";
|
|
1801
|
-
const
|
|
1802
|
-
if (!import_fs_extra5.default.existsSync(filePath)) {
|
|
1803
|
-
return {
|
|
1804
|
-
platform: "xiaomi",
|
|
1805
|
-
success: false,
|
|
1806
|
-
message: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`
|
|
1807
|
-
};
|
|
1808
|
-
}
|
|
2420
|
+
const artifacts = typeof metadata.artifactPath === "object" ? metadata.artifactPath : { universal: filePath || (typeof metadata.artifactPath === "string" ? metadata.artifactPath : "") };
|
|
1809
2421
|
const resolvedPublicKey = await this.resolvePublicKey(publicKeyPath);
|
|
1810
2422
|
if (!resolvedPublicKey) {
|
|
1811
|
-
|
|
1812
|
-
platform: "xiaomi",
|
|
1813
|
-
success: false,
|
|
1814
|
-
message: "\u65E0\u6CD5\u83B7\u53D6 RSA \u516C\u94A5: publicKeyPath \u672A\u63D0\u4F9B\u6216\u6587\u4EF6\u4E0D\u5B58\u5728"
|
|
1815
|
-
};
|
|
1816
|
-
}
|
|
1817
|
-
const packageName = xiaomiConfig.packageName || this.inferPackageName(filePath);
|
|
1818
|
-
if (!packageName) {
|
|
1819
|
-
return {
|
|
1820
|
-
platform: "xiaomi",
|
|
1821
|
-
success: false,
|
|
1822
|
-
message: "\u7F3A\u5C11 packageName \u914D\u7F6E, \u4E14\u65E0\u6CD5\u4ECE\u6587\u4EF6\u540D\u63A8\u65AD\u5E94\u7528\u5305\u540D"
|
|
1823
|
-
};
|
|
1824
|
-
}
|
|
1825
|
-
const appName = xiaomiConfig.appName || this.inferAppName(packageName);
|
|
1826
|
-
if (!appName) {
|
|
1827
|
-
return {
|
|
1828
|
-
platform: "xiaomi",
|
|
1829
|
-
success: false,
|
|
1830
|
-
message: "\u7F3A\u5C11 appName \u914D\u7F6E, \u4E14\u65E0\u6CD5\u4ECE\u5305\u540D\u63A8\u65AD\u5E94\u7528\u540D\u79F0"
|
|
1831
|
-
};
|
|
2423
|
+
throw new Error("\u65E0\u6CD5\u83B7\u53D6 RSA \u516C\u94A5");
|
|
1832
2424
|
}
|
|
1833
|
-
logger.info("\u5F00\u59CB\u4E0A\u4F20\u5230\u5C0F\u7C73\u5E94\u7528\u5546\u5E97...");
|
|
1834
|
-
logger.info(`\u6587\u4EF6: ${filePath}`);
|
|
1835
|
-
logger.info(`\u5305\u540D: ${packageName}`);
|
|
1836
|
-
logger.info(`\u5E94\u7528\u540D: ${appName}`);
|
|
1837
2425
|
const publicKeyObj = this.extractPublicKey(resolvedPublicKey);
|
|
1838
|
-
const
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
logger.info("\u6B63\u5728\u67E5\u8BE2\u5E94\u7528\u4FE1\u606F...");
|
|
1843
|
-
const status = await this.queryAppStatus(userName, packageName, privateKey, publicKeyObj);
|
|
1844
|
-
uploadType = status.type;
|
|
1845
|
-
existingAppInfo = status.appInfo;
|
|
1846
|
-
} else {
|
|
1847
|
-
uploadType = configUploadType;
|
|
1848
|
-
}
|
|
1849
|
-
const uploadTypeDesc = uploadType === "update" ? "\u5E94\u7528\u66F4\u65B0 (synchroType=1)" : "\u65B0\u589E\u5E94\u7528 (synchroType=0)";
|
|
1850
|
-
logger.info(`\u4E0A\u4F20\u7C7B\u578B: ${uploadTypeDesc}`);
|
|
1851
|
-
if (uploadType === "new" && xiaomiConfig.uploadType === "new") {
|
|
1852
|
-
const missing = [];
|
|
1853
|
-
if (xiaomiConfig.category == null) missing.push("category (\u5206\u7C7BID)");
|
|
1854
|
-
if (!xiaomiConfig.desc) missing.push("desc (\u5E94\u7528\u4ECB\u7ECD)");
|
|
1855
|
-
if (missing.length > 0) {
|
|
1856
|
-
return {
|
|
1857
|
-
platform: "xiaomi",
|
|
1858
|
-
success: false,
|
|
1859
|
-
message: `\u9996\u6B21\u63D0\u5BA1\u6A21\u5F0F\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5: ${missing.join(", ")}\u3002\u8BF7\u5728\u540E\u53F0\u8865\u5168\u6216\u5728\u914D\u7F6E\u4E2D\u6DFB\u52A0\u3002`
|
|
1860
|
-
};
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
2426
|
+
const anyPath = Object.values(artifacts)[0];
|
|
2427
|
+
const packageName = xiaomiConfig.packageName || this.inferPackageName(anyPath);
|
|
2428
|
+
if (!packageName) throw new Error("\u7F3A\u5C11 packageName");
|
|
2429
|
+
const appName = xiaomiConfig.appName || this.inferAppName(packageName);
|
|
1863
2430
|
try {
|
|
1864
|
-
|
|
2431
|
+
logger.info(`\u5F00\u59CB\u4E0A\u4F20\u5230\u5C0F\u7C73\u5E94\u7528\u5546\u5E97 (\u5305\u542B ${Object.keys(artifacts).length} \u4E2A\u5305)...`);
|
|
2432
|
+
let uploadType = xiaomiConfig.uploadType || "auto";
|
|
2433
|
+
let finalUploadType;
|
|
2434
|
+
let existingAppInfo = null;
|
|
2435
|
+
if (uploadType === "auto") {
|
|
2436
|
+
const status = await this.queryAppStatus(userName, packageName, privateKey, publicKeyObj);
|
|
2437
|
+
finalUploadType = status.type;
|
|
2438
|
+
existingAppInfo = status.appInfo;
|
|
2439
|
+
} else {
|
|
2440
|
+
finalUploadType = uploadType;
|
|
2441
|
+
}
|
|
2442
|
+
const retryStrategy = createUploadRetryStrategy(config.retry);
|
|
1865
2443
|
const result = await retryStrategy.execute(
|
|
1866
2444
|
() => this.performUpload({
|
|
1867
|
-
|
|
2445
|
+
artifacts,
|
|
1868
2446
|
userName,
|
|
1869
2447
|
privateKey,
|
|
1870
2448
|
publicKey: resolvedPublicKey,
|
|
2449
|
+
uploadType: finalUploadType,
|
|
1871
2450
|
packageName,
|
|
1872
|
-
appName,
|
|
2451
|
+
appName: appName || "",
|
|
1873
2452
|
updateDesc,
|
|
1874
|
-
uploadType,
|
|
1875
2453
|
category: xiaomiConfig.category || existingAppInfo?.category,
|
|
1876
2454
|
keyWords: xiaomiConfig.keyWords || existingAppInfo?.keyWords,
|
|
1877
2455
|
desc: xiaomiConfig.desc || existingAppInfo?.desc,
|
|
@@ -1881,50 +2459,19 @@ ${lines.join("\n")}
|
|
|
1881
2459
|
}),
|
|
1882
2460
|
"Xiaomi push upload"
|
|
1883
2461
|
);
|
|
1884
|
-
if (!result.success) {
|
|
1885
|
-
throw result.error || new Error("Upload failed");
|
|
1886
|
-
}
|
|
1887
|
-
logger.success("\u4E0A\u4F20\u5230\u5C0F\u7C73\u5E94\u7528\u5546\u5E97\u6210\u529F!");
|
|
1888
2462
|
return {
|
|
1889
2463
|
platform: "xiaomi",
|
|
1890
2464
|
success: true,
|
|
1891
|
-
message: "\u4E0A\u4F20\u6210\u529F
|
|
1892
|
-
data: result.data,
|
|
2465
|
+
message: "\u4E0A\u4F20\u6210\u529F",
|
|
1893
2466
|
consoleUrl: "https://dev.mi.com/distribute/app/details"
|
|
1894
2467
|
};
|
|
1895
2468
|
} catch (error) {
|
|
1896
|
-
logger.error(`\u4E0A\u4F20\
|
|
1897
|
-
|
|
1898
|
-
logger.info(`\u9519\u8BEF\u8BE6\u60C5: ${JSON.stringify(error.response.data)}`);
|
|
1899
|
-
}
|
|
1900
|
-
return {
|
|
1901
|
-
platform: "xiaomi",
|
|
1902
|
-
success: false,
|
|
1903
|
-
message: error.message,
|
|
1904
|
-
error
|
|
1905
|
-
};
|
|
2469
|
+
logger.error(`\u5C0F\u7C73\u4E0A\u4F20\u5931\u8D25: ${error.message}`);
|
|
2470
|
+
return { platform: "xiaomi", success: false, message: error.message, error };
|
|
1906
2471
|
}
|
|
1907
2472
|
}
|
|
1908
|
-
/**
|
|
1909
|
-
* 执行实际的上传操作
|
|
1910
|
-
*/
|
|
1911
2473
|
async performUpload(params) {
|
|
1912
|
-
const {
|
|
1913
|
-
filePath,
|
|
1914
|
-
userName,
|
|
1915
|
-
privateKey,
|
|
1916
|
-
publicKey,
|
|
1917
|
-
packageName,
|
|
1918
|
-
appName,
|
|
1919
|
-
updateDesc,
|
|
1920
|
-
uploadType,
|
|
1921
|
-
category,
|
|
1922
|
-
keyWords,
|
|
1923
|
-
desc,
|
|
1924
|
-
brief,
|
|
1925
|
-
privacyUrl,
|
|
1926
|
-
assets
|
|
1927
|
-
} = params;
|
|
2474
|
+
const { artifacts, userName, privateKey, publicKey, packageName, appName, updateDesc, uploadType, category, keyWords, desc, brief, privacyUrl, assets } = params;
|
|
1928
2475
|
const publicKeyObj = this.extractPublicKey(publicKey);
|
|
1929
2476
|
const requestData = this.buildRequestData({
|
|
1930
2477
|
userName,
|
|
@@ -1938,67 +2485,55 @@ ${lines.join("\n")}
|
|
|
1938
2485
|
brief,
|
|
1939
2486
|
privacyUrl
|
|
1940
2487
|
});
|
|
1941
|
-
logger.info("RequestData \u5DF2\u6784\u5EFA");
|
|
1942
|
-
logger.info(`RequestData: ${requestData}`);
|
|
1943
2488
|
const requestDataMD5 = this.calculateStringMD5(requestData);
|
|
1944
|
-
|
|
1945
|
-
|
|
2489
|
+
let mainPath;
|
|
2490
|
+
let secondPath = void 0;
|
|
2491
|
+
const artifactEntries = Object.entries(artifacts);
|
|
2492
|
+
const arm64 = artifactEntries.find(([abi]) => abi === "arm64-v8a");
|
|
2493
|
+
const arm32 = artifactEntries.find(([abi]) => abi === "armeabi-v7a");
|
|
2494
|
+
if (arm64 && arm32) {
|
|
2495
|
+
mainPath = arm64[1];
|
|
2496
|
+
secondPath = arm32[1];
|
|
2497
|
+
logger.info(`[Xiaomi] \u8BC6\u522B\u5230\u591A\u67B6\u6784\u5206\u5305: \u4E3B\u5305(64\u4F4D)=${import_path4.default.basename(mainPath)}, \u6B21\u5305(32\u4F4D)=${import_path4.default.basename(secondPath)}`);
|
|
2498
|
+
} else {
|
|
2499
|
+
mainPath = artifactEntries[0][1];
|
|
2500
|
+
if (artifactEntries.length > 1) {
|
|
2501
|
+
secondPath = artifactEntries[1][1];
|
|
2502
|
+
logger.info(`[Xiaomi] \u8BC6\u522B\u5230\u591A\u4E2A\u5305\uFF08\u975E\u6807\u51C6\u540D\uFF09\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u987A\u5E8F: \u4E3B\u5305=${import_path4.default.basename(mainPath)}, \u6B21\u5305=${import_path4.default.basename(secondPath)}`);
|
|
2503
|
+
} else {
|
|
2504
|
+
logger.info(`[Xiaomi] \u4F7F\u7528\u5355\u5305\u6A21\u5F0F: ${import_path4.default.basename(mainPath)}`);
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
const mainMD5 = await this.calculateFileMD5(mainPath);
|
|
1946
2508
|
const extraSigItems = [];
|
|
1947
|
-
|
|
2509
|
+
if (secondPath) {
|
|
2510
|
+
const secondMD5 = await this.calculateFileMD5(secondPath);
|
|
2511
|
+
extraSigItems.push({ name: "secondApk", hash: secondMD5 });
|
|
2512
|
+
}
|
|
1948
2513
|
if (assets?.icon && import_fs_extra5.default.existsSync(assets.icon)) {
|
|
1949
|
-
|
|
1950
|
-
const iconMD5 = await this.calculateFileMD5(iconPath);
|
|
1951
|
-
extraSigItems.push({ name: "icon", hash: iconMD5 });
|
|
1952
|
-
}
|
|
1953
|
-
const screenshotPaths = [];
|
|
1954
|
-
if (assets?.screenshots) {
|
|
1955
|
-
for (let i = 0; i < assets.screenshots.length && i < 4; i++) {
|
|
1956
|
-
const ssPath = assets.screenshots[i];
|
|
1957
|
-
if (import_fs_extra5.default.existsSync(ssPath)) {
|
|
1958
|
-
screenshotPaths.push(ssPath);
|
|
1959
|
-
const ssMD5 = await this.calculateFileMD5(ssPath);
|
|
1960
|
-
extraSigItems.push({ name: `screenshot_${i + 1}`, hash: ssMD5 });
|
|
1961
|
-
}
|
|
1962
|
-
}
|
|
2514
|
+
extraSigItems.push({ name: "icon", hash: await this.calculateFileMD5(assets.icon) });
|
|
1963
2515
|
}
|
|
1964
|
-
const sig = this.generateUploadSIG(
|
|
1965
|
-
requestDataMD5,
|
|
1966
|
-
apkFileMD5,
|
|
1967
|
-
privateKey,
|
|
1968
|
-
publicKeyObj,
|
|
1969
|
-
extraSigItems.length > 0 ? extraSigItems : void 0
|
|
1970
|
-
);
|
|
1971
|
-
logger.info("SIG \u7B7E\u540D\u5DF2\u751F\u6210");
|
|
2516
|
+
const sig = this.generateUploadSIG(requestDataMD5, mainMD5, privateKey, publicKeyObj, extraSigItems);
|
|
1972
2517
|
const form = new import_form_data3.default();
|
|
1973
2518
|
form.append("RequestData", requestData);
|
|
1974
2519
|
form.append("SIG", sig);
|
|
1975
|
-
form.append("apk", import_fs_extra5.default.createReadStream(
|
|
1976
|
-
if (
|
|
1977
|
-
form.append("
|
|
1978
|
-
logger.info(`\u9644\u52A0 icon: ${iconPath}`);
|
|
2520
|
+
form.append("apk", import_fs_extra5.default.createReadStream(mainPath));
|
|
2521
|
+
if (secondPath) {
|
|
2522
|
+
form.append("secondApk", import_fs_extra5.default.createReadStream(secondPath));
|
|
1979
2523
|
}
|
|
1980
|
-
|
|
1981
|
-
form.append(
|
|
1982
|
-
logger.info(`\u9644\u52A0 screenshot_${i + 1}: ${screenshotPaths[i]}`);
|
|
2524
|
+
if (assets?.icon && import_fs_extra5.default.existsSync(assets.icon)) {
|
|
2525
|
+
form.append("icon", import_fs_extra5.default.createReadStream(assets.icon));
|
|
1983
2526
|
}
|
|
1984
|
-
logger.info(`POST ${_XiaomiUploader.PUSH_API}`);
|
|
1985
2527
|
const response = await import_axios3.default.post(_XiaomiUploader.PUSH_API, form, {
|
|
1986
|
-
headers:
|
|
1987
|
-
...form.getHeaders()
|
|
1988
|
-
},
|
|
2528
|
+
headers: form.getHeaders(),
|
|
1989
2529
|
maxContentLength: Infinity,
|
|
1990
2530
|
maxBodyLength: Infinity,
|
|
1991
|
-
timeout:
|
|
1992
|
-
// 60 秒请求超时
|
|
2531
|
+
timeout: 12e4
|
|
1993
2532
|
});
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
if (data?.result !== 0) {
|
|
1997
|
-
const errMsg = data?.message || data?.msg || JSON.stringify(data);
|
|
1998
|
-
throw new Error(`\u5C0F\u7C73 API \u8FD4\u56DE\u9519\u8BEF (result=${data?.result}): ${errMsg}`);
|
|
2533
|
+
if (response.data?.result !== 0) {
|
|
2534
|
+
throw new Error(`\u5C0F\u7C73 API \u9519\u8BEF: ${response.data?.message || JSON.stringify(response.data)}`);
|
|
1999
2535
|
}
|
|
2000
|
-
|
|
2001
|
-
return data;
|
|
2536
|
+
return response.data;
|
|
2002
2537
|
}
|
|
2003
2538
|
/**
|
|
2004
2539
|
* 解析公钥: 优先使用内容字段, 其次从文件路径读取
|
|
@@ -2040,7 +2575,7 @@ ${lines.join("\n")}
|
|
|
2040
2575
|
|
|
2041
2576
|
// src/adapters/apple_store_uploader.ts
|
|
2042
2577
|
var import_fs_extra6 = __toESM(require("fs-extra"), 1);
|
|
2043
|
-
var
|
|
2578
|
+
var import_path5 = __toESM(require("path"), 1);
|
|
2044
2579
|
var import_child_process = require("child_process");
|
|
2045
2580
|
var import_util2 = require("util");
|
|
2046
2581
|
var import_axios4 = __toESM(require("axios"), 1);
|
|
@@ -2206,7 +2741,7 @@ var AppleStoreUploader = class {
|
|
|
2206
2741
|
appPassword,
|
|
2207
2742
|
"-showTransferRate"
|
|
2208
2743
|
].join(" ");
|
|
2209
|
-
logger.info(`[Transporter] Uploading: ${
|
|
2744
|
+
logger.info(`[Transporter] Uploading: ${import_path5.default.basename(ipaPath)}`);
|
|
2210
2745
|
try {
|
|
2211
2746
|
const { stdout, stderr } = await execAsync(command, {
|
|
2212
2747
|
timeout: 30 * 60 * 1e3,
|
|
@@ -2257,7 +2792,7 @@ Stderr: ${error.stderr || ""}`);
|
|
|
2257
2792
|
});
|
|
2258
2793
|
command = innerArgs.join(" ");
|
|
2259
2794
|
}
|
|
2260
|
-
logger.info(`[altool] Uploading: ${
|
|
2795
|
+
logger.info(`[altool] Uploading: ${import_path5.default.basename(ipaPath)}`);
|
|
2261
2796
|
logger.info(`[altool] Command prefix: ${tool.command}`);
|
|
2262
2797
|
try {
|
|
2263
2798
|
const { stdout, stderr } = await execAsync(command, {
|
|
@@ -2841,7 +3376,7 @@ var TestFlightUploader = class _TestFlightUploader {
|
|
|
2841
3376
|
|
|
2842
3377
|
// src/adapters/adhoc_uploader.ts
|
|
2843
3378
|
var import_fs_extra8 = __toESM(require("fs-extra"), 1);
|
|
2844
|
-
var
|
|
3379
|
+
var import_path6 = __toESM(require("path"), 1);
|
|
2845
3380
|
var import_child_process2 = require("child_process");
|
|
2846
3381
|
var AdHocUploader = class {
|
|
2847
3382
|
name = "AdHoc";
|
|
@@ -2974,8 +3509,8 @@ var AdHocUploader = class {
|
|
|
2974
3509
|
* @param changelog 更新日志
|
|
2975
3510
|
*/
|
|
2976
3511
|
async createManifest(ipaPath, version, bundleId, changelog) {
|
|
2977
|
-
const ipaFileName =
|
|
2978
|
-
const appName = bundleId ||
|
|
3512
|
+
const ipaFileName = import_path6.default.basename(ipaPath);
|
|
3513
|
+
const appName = bundleId || import_path6.default.parse(ipaFileName).name;
|
|
2979
3514
|
const ipaUrl = `itms-services://?action=download-manifest&url=https://your-distribution-server.com/manifests/${ipaFileName}.plist`;
|
|
2980
3515
|
const manifestContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
2981
3516
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
@@ -3034,14 +3569,14 @@ var AdHocUploader = class {
|
|
|
3034
3569
|
*/
|
|
3035
3570
|
async setupDistributionDirectory(ipaPath, manifestPath) {
|
|
3036
3571
|
const projectRoot = process.cwd();
|
|
3037
|
-
const distributionDir =
|
|
3572
|
+
const distributionDir = import_path6.default.join(projectRoot, "build", "adhoc-distribution");
|
|
3038
3573
|
await import_fs_extra8.default.ensureDir(distributionDir);
|
|
3039
|
-
await import_fs_extra8.default.ensureDir(
|
|
3040
|
-
await import_fs_extra8.default.ensureDir(
|
|
3041
|
-
await import_fs_extra8.default.ensureDir(
|
|
3042
|
-
const ipaFileName =
|
|
3043
|
-
await import_fs_extra8.default.copy(ipaPath,
|
|
3044
|
-
await import_fs_extra8.default.copy(manifestPath,
|
|
3574
|
+
await import_fs_extra8.default.ensureDir(import_path6.default.join(distributionDir, "apps"));
|
|
3575
|
+
await import_fs_extra8.default.ensureDir(import_path6.default.join(distributionDir, "manifests"));
|
|
3576
|
+
await import_fs_extra8.default.ensureDir(import_path6.default.join(distributionDir, "icons"));
|
|
3577
|
+
const ipaFileName = import_path6.default.basename(ipaPath);
|
|
3578
|
+
await import_fs_extra8.default.copy(ipaPath, import_path6.default.join(distributionDir, "apps", ipaFileName));
|
|
3579
|
+
await import_fs_extra8.default.copy(manifestPath, import_path6.default.join(distributionDir, "manifests", `${ipaFileName}.plist`));
|
|
3045
3580
|
logger.info(`Distribution directory: ${distributionDir}`);
|
|
3046
3581
|
return distributionDir;
|
|
3047
3582
|
}
|
|
@@ -3051,7 +3586,7 @@ var AdHocUploader = class {
|
|
|
3051
3586
|
* @param bundleId Bundle ID
|
|
3052
3587
|
*/
|
|
3053
3588
|
generateInstallUrl(distributionPath, bundleId) {
|
|
3054
|
-
const manifestPath =
|
|
3589
|
+
const manifestPath = import_path6.default.join(distributionPath, "manifests", `*.plist`);
|
|
3055
3590
|
return `itms-services://?action=download-manifest&url=file://${manifestPath}`;
|
|
3056
3591
|
}
|
|
3057
3592
|
/**
|
|
@@ -3060,7 +3595,7 @@ var AdHocUploader = class {
|
|
|
3060
3595
|
* @param distributionPath 分发目录
|
|
3061
3596
|
*/
|
|
3062
3597
|
async generateQRCode(url, distributionPath) {
|
|
3063
|
-
const qrCodePath =
|
|
3598
|
+
const qrCodePath = import_path6.default.join(distributionPath, "install-qrcode.png");
|
|
3064
3599
|
try {
|
|
3065
3600
|
logger.info(`QR code would be saved to: ${qrCodePath}`);
|
|
3066
3601
|
logger.info(`Install URL: ${url}`);
|
|
@@ -3087,8 +3622,8 @@ var AdHocUploader = class {
|
|
|
3087
3622
|
logger.newLine();
|
|
3088
3623
|
logger.info("\u{1F4E6} Distribution Files:");
|
|
3089
3624
|
logger.info(` Directory: ${distributionPath}`);
|
|
3090
|
-
logger.info(` IPA: ${
|
|
3091
|
-
logger.info(` Manifest: ${
|
|
3625
|
+
logger.info(` IPA: ${import_path6.default.join(distributionPath, "apps", "*.ipa")}`);
|
|
3626
|
+
logger.info(` Manifest: ${import_path6.default.join(distributionPath, "manifests", "*.plist")}`);
|
|
3092
3627
|
logger.info(` QR Code: ${qrCodePath}`);
|
|
3093
3628
|
logger.newLine();
|
|
3094
3629
|
logger.info("\u{1F517} Installation Link:");
|
|
@@ -3147,7 +3682,7 @@ var AdHocUploader = class {
|
|
|
3147
3682
|
|
|
3148
3683
|
// src/adapters/harmony_uploader.ts
|
|
3149
3684
|
var import_fs_extra9 = __toESM(require("fs-extra"), 1);
|
|
3150
|
-
var
|
|
3685
|
+
var import_path7 = __toESM(require("path"), 1);
|
|
3151
3686
|
var import_axios6 = __toESM(require("axios"), 1);
|
|
3152
3687
|
var import_form_data5 = __toESM(require("form-data"), 1);
|
|
3153
3688
|
var HarmonyUploader = class _HarmonyUploader {
|
|
@@ -3177,7 +3712,7 @@ var HarmonyUploader = class _HarmonyUploader {
|
|
|
3177
3712
|
const clientSecret = harmonyConfig.auth.clientSecret;
|
|
3178
3713
|
const appId = harmonyConfig.appId;
|
|
3179
3714
|
const releaseType = harmonyConfig.releaseType || "draft";
|
|
3180
|
-
const suffix =
|
|
3715
|
+
const suffix = import_path7.default.extname(filePath).substring(1);
|
|
3181
3716
|
const retryConfig = config.retry;
|
|
3182
3717
|
logger.info("Starting HarmonyOS AppGallery upload...");
|
|
3183
3718
|
try {
|
|
@@ -3294,7 +3829,7 @@ var HarmonyUploader = class _HarmonyUploader {
|
|
|
3294
3829
|
* @param filePath 文件路径
|
|
3295
3830
|
*/
|
|
3296
3831
|
async updateAppFileInfo(token, appId, authCode, filePath) {
|
|
3297
|
-
const fileName =
|
|
3832
|
+
const fileName = import_path7.default.basename(filePath);
|
|
3298
3833
|
const body = {
|
|
3299
3834
|
fileType: 7,
|
|
3300
3835
|
// 鸿蒙包的 fileType(需要根据华为最新文档确认)
|
|
@@ -3317,7 +3852,7 @@ var HarmonyUploader = class _HarmonyUploader {
|
|
|
3317
3852
|
|
|
3318
3853
|
// src/adapters/oppo_uploader.ts
|
|
3319
3854
|
var import_fs_extra10 = __toESM(require("fs-extra"), 1);
|
|
3320
|
-
var
|
|
3855
|
+
var import_path8 = __toESM(require("path"), 1);
|
|
3321
3856
|
var import_axios7 = __toESM(require("axios"), 1);
|
|
3322
3857
|
var import_form_data6 = __toESM(require("form-data"), 1);
|
|
3323
3858
|
var import_crypto4 = __toESM(require("crypto"), 1);
|
|
@@ -3358,7 +3893,7 @@ var OppoUploader = class _OppoUploader {
|
|
|
3358
3893
|
* 尝试从文件名推断包名
|
|
3359
3894
|
*/
|
|
3360
3895
|
inferPackageName(filePath) {
|
|
3361
|
-
const fileName =
|
|
3896
|
+
const fileName = import_path8.default.basename(filePath);
|
|
3362
3897
|
const match = fileName.match(/^([\w.]+?)(?:-(?:release|debug|unsigned))?\.apk$/i);
|
|
3363
3898
|
if (match && match[1].includes(".")) {
|
|
3364
3899
|
return match[1];
|
|
@@ -3376,110 +3911,47 @@ var OppoUploader = class _OppoUploader {
|
|
|
3376
3911
|
}
|
|
3377
3912
|
async upload(filePath, config, metadata) {
|
|
3378
3913
|
const oppoConfig = config.publish.oppo;
|
|
3379
|
-
const
|
|
3380
|
-
const clientSecret = oppoConfig.auth.clientSecret;
|
|
3914
|
+
const accessToken = await this.getAccessToken(oppoConfig.auth.clientId, oppoConfig.auth.clientSecret);
|
|
3381
3915
|
const packageName = oppoConfig.packageName || this.inferPackageName(filePath);
|
|
3382
|
-
if (!packageName) {
|
|
3383
|
-
return {
|
|
3384
|
-
platform: "oppo",
|
|
3385
|
-
success: false,
|
|
3386
|
-
message: "\u65E0\u6CD5\u83B7\u53D6\u5305\u540D (packageName)\uFF0C\u8BF7\u5728\u914D\u7F6E\u4E2D\u6307\u5B9A\u6216\u786E\u4FDD\u6587\u4EF6\u540D\u5305\u542B\u5305\u540D",
|
|
3387
|
-
consoleUrl: "https://open.oppomobile.com/new/ecology/app"
|
|
3388
|
-
};
|
|
3389
|
-
}
|
|
3390
|
-
const retryConfig = config.retry;
|
|
3391
3916
|
const consoleUrl = "https://open.oppomobile.com/new/ecology/app";
|
|
3392
|
-
if (!
|
|
3393
|
-
return {
|
|
3394
|
-
platform: "oppo",
|
|
3395
|
-
success: false,
|
|
3396
|
-
message: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`,
|
|
3397
|
-
consoleUrl
|
|
3398
|
-
};
|
|
3917
|
+
if (!packageName) {
|
|
3918
|
+
return { platform: "oppo", success: false, message: "\u65E0\u6CD5\u83B7\u53D6\u5305\u540D", consoleUrl };
|
|
3399
3919
|
}
|
|
3400
|
-
|
|
3401
|
-
logger.info(`\u6587\u4EF6: ${filePath}`);
|
|
3920
|
+
const artifacts = typeof metadata.artifactPath === "object" ? metadata.artifactPath : { universal: filePath || (typeof metadata.artifactPath === "string" ? metadata.artifactPath : "") };
|
|
3402
3921
|
try {
|
|
3403
|
-
const retryStrategy = createUploadRetryStrategy(
|
|
3404
|
-
|
|
3405
|
-
const
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
(
|
|
3416
|
-
|
|
3417
|
-
);
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
throw uploadUrlResult.error || new Error("Failed to get upload URL");
|
|
3432
|
-
}
|
|
3433
|
-
const { uploadUrl, sign: uploadSign } = uploadUrlResult.data;
|
|
3434
|
-
logger.info("\u6B63\u5728\u4E0A\u4F20 APK \u6587\u4EF6...");
|
|
3435
|
-
const uploadFileResult = await retryStrategy.execute(
|
|
3436
|
-
() => this.uploadFile(uploadUrl, uploadSign, filePath),
|
|
3437
|
-
"OPPO file upload"
|
|
3438
|
-
);
|
|
3439
|
-
if (!uploadFileResult.success || !uploadFileResult.data) {
|
|
3440
|
-
throw uploadFileResult.error || new Error("File upload failed");
|
|
3441
|
-
}
|
|
3442
|
-
const rawUrl = uploadFileResult.data.url;
|
|
3443
|
-
const fileUrl = rawUrl.replace(/^http:\/\//i, "https://").replace("storedl1.nearme.com.cn", "storedl.nearme.com.cn");
|
|
3444
|
-
const md5 = uploadFileResult.data.md5;
|
|
3445
|
-
logger.info("\u6B63\u5728\u63D0\u4EA4\u7248\u672C\u4FE1\u606F...");
|
|
3446
|
-
const submitResult = await retryStrategy.execute(
|
|
3447
|
-
() => this.submitVersion({
|
|
3448
|
-
accessToken,
|
|
3449
|
-
clientSecret,
|
|
3450
|
-
packageName,
|
|
3451
|
-
appName: oppoConfig.appName || metadata.appName || onlineAppInfo.app_name || this.inferAppName(packageName),
|
|
3452
|
-
fileUrl,
|
|
3453
|
-
fileMd5: md5,
|
|
3454
|
-
versionName: metadata.version,
|
|
3455
|
-
versionCode: metadata.buildNumber,
|
|
3456
|
-
updateDesc: metadata.changelog || "App Update",
|
|
3457
|
-
onlineType: oppoConfig.onlineType,
|
|
3458
|
-
// 从配置读取
|
|
3459
|
-
onlineAppInfo
|
|
3460
|
-
// 传入线上信息
|
|
3461
|
-
}),
|
|
3462
|
-
"OPPO submit version"
|
|
3463
|
-
);
|
|
3464
|
-
if (!submitResult.success) {
|
|
3465
|
-
throw submitResult.error || new Error("Submit version failed");
|
|
3466
|
-
}
|
|
3922
|
+
const retryStrategy = createUploadRetryStrategy(config.retry);
|
|
3923
|
+
const onlineAppInfo = await this.getAppInfo(accessToken, oppoConfig.auth.clientSecret, packageName) || {};
|
|
3924
|
+
const uploadResults = [];
|
|
3925
|
+
const uploadPromises = Object.entries(artifacts).map(async ([abi, p]) => {
|
|
3926
|
+
if (!p || !import_fs_extra10.default.existsSync(p)) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`);
|
|
3927
|
+
logger.info(`[OPPO] \u6B63\u5728\u5904\u7406 ${abi} \u67B6\u6784\u5305...`);
|
|
3928
|
+
const { uploadUrl, sign } = await this.getUploadUrl(accessToken, oppoConfig.auth.clientSecret);
|
|
3929
|
+
const uploadFileResult = await this.uploadFile(uploadUrl, sign, p);
|
|
3930
|
+
const fileUrl = uploadFileResult.url.replace(/^http:\/\//i, "https://").replace("storedl1.nearme.com.cn", "storedl.nearme.com.cn");
|
|
3931
|
+
let cpu_code = 0;
|
|
3932
|
+
if (abi === "arm64-v8a") cpu_code = 3;
|
|
3933
|
+
else if (abi === "armeabi-v7a") cpu_code = 4;
|
|
3934
|
+
uploadResults.push({ url: fileUrl, md5: uploadFileResult.md5, cpu_code });
|
|
3935
|
+
});
|
|
3936
|
+
await Promise.all(uploadPromises);
|
|
3937
|
+
logger.info(`[OPPO] \u6B63\u5728\u63D0\u4EA4\u6D41\u6C34\u53F7\u7EC4: ${JSON.stringify(uploadResults)}`);
|
|
3938
|
+
await this.submitVersion({
|
|
3939
|
+
accessToken,
|
|
3940
|
+
clientSecret: oppoConfig.auth.clientSecret,
|
|
3941
|
+
packageName,
|
|
3942
|
+
appName: oppoConfig.appName || onlineAppInfo.app_name || metadata.appName || this.inferAppName(packageName),
|
|
3943
|
+
apkUrls: uploadResults,
|
|
3944
|
+
versionName: metadata.version,
|
|
3945
|
+
versionCode: metadata.buildNumber,
|
|
3946
|
+
updateDesc: metadata.changelog || "App Update",
|
|
3947
|
+
onlineType: oppoConfig.onlineType,
|
|
3948
|
+
onlineAppInfo
|
|
3949
|
+
});
|
|
3467
3950
|
logger.success("\u4E0A\u4F20\u5230 OPPO \u5E94\u7528\u5546\u5E97\u6210\u529F!");
|
|
3468
|
-
return {
|
|
3469
|
-
platform: "oppo",
|
|
3470
|
-
success: true,
|
|
3471
|
-
message: "\u4E0A\u4F20\u6210\u529F, \u8BF7\u524D\u5F80\u540E\u53F0\u786E\u8BA4\u5E76\u63D0\u4EA4\u5BA1\u6838",
|
|
3472
|
-
consoleUrl
|
|
3473
|
-
};
|
|
3951
|
+
return { platform: "oppo", success: true, message: "\u4E0A\u4F20\u6210\u529F, \u8BF7\u786E\u8BA4", consoleUrl };
|
|
3474
3952
|
} catch (error) {
|
|
3475
3953
|
logger.error(`\u4E0A\u4F20\u5230 OPPO \u5931\u8D25: ${error.message}`);
|
|
3476
|
-
return {
|
|
3477
|
-
platform: "oppo",
|
|
3478
|
-
success: false,
|
|
3479
|
-
message: this.formatError(error),
|
|
3480
|
-
error,
|
|
3481
|
-
consoleUrl
|
|
3482
|
-
};
|
|
3954
|
+
return { platform: "oppo", success: false, message: error.message, error, consoleUrl };
|
|
3483
3955
|
}
|
|
3484
3956
|
}
|
|
3485
3957
|
/**
|
|
@@ -3600,16 +4072,7 @@ var OppoUploader = class _OppoUploader {
|
|
|
3600
4072
|
const signParams = {
|
|
3601
4073
|
access_token: params.accessToken,
|
|
3602
4074
|
timestamp,
|
|
3603
|
-
|
|
3604
|
-
// cpu_code: 0=通用包, 3=arm64-v8a, 4=armeabi-v7a, 5=x86_64
|
|
3605
|
-
apk_url: JSON.stringify([
|
|
3606
|
-
{
|
|
3607
|
-
url: params.fileUrl,
|
|
3608
|
-
md5: params.fileMd5,
|
|
3609
|
-
cpu_code: 0
|
|
3610
|
-
// 通用包
|
|
3611
|
-
}
|
|
3612
|
-
]),
|
|
4075
|
+
apk_url: JSON.stringify(params.apkUrls),
|
|
3613
4076
|
version_name: params.versionName.split("+")[0],
|
|
3614
4077
|
// 仅保留版本名部分
|
|
3615
4078
|
version_code: vCode,
|
|
@@ -3711,7 +4174,7 @@ var OppoUploader = class _OppoUploader {
|
|
|
3711
4174
|
|
|
3712
4175
|
// src/adapters/vivo_uploader.ts
|
|
3713
4176
|
var import_fs_extra11 = __toESM(require("fs-extra"), 1);
|
|
3714
|
-
var
|
|
4177
|
+
var import_path9 = __toESM(require("path"), 1);
|
|
3715
4178
|
var import_axios8 = __toESM(require("axios"), 1);
|
|
3716
4179
|
var import_form_data7 = __toESM(require("form-data"), 1);
|
|
3717
4180
|
var import_crypto5 = __toESM(require("crypto"), 1);
|
|
@@ -3719,26 +4182,14 @@ var VivoUploader = class _VivoUploader {
|
|
|
3719
4182
|
name = "vivo";
|
|
3720
4183
|
/** vivo 开放 API 基础地址 */
|
|
3721
4184
|
static API_BASE = "https://developer-api.vivo.com.cn/router/rest";
|
|
3722
|
-
/**
|
|
3723
|
-
* vivo API 签名生成
|
|
3724
|
-
* 规则: 所有参数按 ASCII 码排序后拼接为 key=val&... 字符串,
|
|
3725
|
-
* 以 accessSecret 为密钥进行 HMAC-SHA256 加密,结果转为小写 16 进制字符串
|
|
3726
|
-
*/
|
|
3727
4185
|
generateSign(params, accessSecret) {
|
|
3728
4186
|
const sorted = Object.keys(params).sort().filter((key) => params[key] !== void 0 && params[key] !== null).map((key) => `${key}=${params[key]}`).join("&");
|
|
3729
|
-
|
|
3730
|
-
logger.info(`[VIVO DEBUG] \u5F85\u7B7E\u540D\u4E32: ${sorted}
|
|
3731
|
-
-> \u7B7E\u540D\u7ED3\u679C: ${sign}`);
|
|
3732
|
-
return sign;
|
|
4187
|
+
return import_crypto5.default.createHmac("sha256", accessSecret).update(sorted).digest("hex");
|
|
3733
4188
|
}
|
|
3734
4189
|
validateConfig(config) {
|
|
3735
4190
|
if (!config?.publish?.vivo?.enable) return false;
|
|
3736
4191
|
const vivo = config.publish.vivo;
|
|
3737
|
-
|
|
3738
|
-
logger.error("vivo config missing: accessKey or accessSecret");
|
|
3739
|
-
return false;
|
|
3740
|
-
}
|
|
3741
|
-
return true;
|
|
4192
|
+
return !!(vivo.auth?.accessKey && vivo.auth?.accessSecret);
|
|
3742
4193
|
}
|
|
3743
4194
|
canHandle(filePath) {
|
|
3744
4195
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
@@ -3748,67 +4199,51 @@ var VivoUploader = class _VivoUploader {
|
|
|
3748
4199
|
const vivoConfig = config.publish.vivo;
|
|
3749
4200
|
const accessKey = vivoConfig.auth.accessKey;
|
|
3750
4201
|
const accessSecret = vivoConfig.auth.accessSecret;
|
|
3751
|
-
const retryConfig = config.retry;
|
|
3752
4202
|
const consoleUrl = "https://dev.vivo.com.cn/manage/app";
|
|
3753
|
-
|
|
3754
|
-
return {
|
|
3755
|
-
platform: "vivo",
|
|
3756
|
-
success: false,
|
|
3757
|
-
message: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`,
|
|
3758
|
-
consoleUrl
|
|
3759
|
-
};
|
|
3760
|
-
}
|
|
3761
|
-
const fileSize = import_fs_extra11.default.statSync(filePath).size;
|
|
3762
|
-
logger.info("\u5F00\u59CB\u4E0A\u4F20\u5230 vivo \u5E94\u7528\u5546\u5E97...");
|
|
3763
|
-
logger.info(`\u6587\u4EF6: ${filePath} (${(fileSize / 1024 / 1024).toFixed(2)} MB)`);
|
|
4203
|
+
const artifacts = typeof metadata.artifactPath === "object" ? metadata.artifactPath : { universal: filePath || (typeof metadata.artifactPath === "string" ? metadata.artifactPath : "") };
|
|
3764
4204
|
try {
|
|
3765
|
-
const
|
|
3766
|
-
const
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
4205
|
+
const uploadResults = {};
|
|
4206
|
+
const uploadPromises = Object.entries(artifacts).map(async ([abi, p]) => {
|
|
4207
|
+
if (!p || !import_fs_extra11.default.existsSync(p)) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`);
|
|
4208
|
+
const md5 = await this.calculateFileMD5(p);
|
|
4209
|
+
logger.info(`[vivo] \u6B63\u5728\u5904\u7406 ${abi} \u67B6\u6784\u5305: ${import_path9.default.basename(p)}`);
|
|
4210
|
+
const serialnumber = await this.uploadApk(accessKey, accessSecret, p, vivoConfig.packageName || "", md5);
|
|
4211
|
+
const pkgInfo = await parsePackageInfo(p, { androidSdkPath: config.globalSettings?.androidSdkPath });
|
|
4212
|
+
const nativeCodes = pkgInfo?.nativeCode || [];
|
|
4213
|
+
const has64Bit = nativeCodes.includes("arm64-v8a") || nativeCodes.includes("x86_64") || abi === "arm64-v8a";
|
|
4214
|
+
const has32Bit = nativeCodes.includes("armeabi-v7a") || nativeCodes.includes("armeabi") || abi === "armeabi-v7a";
|
|
4215
|
+
uploadResults[abi] = { serialnumber, md5, is64Bit: has64Bit && !has32Bit };
|
|
4216
|
+
});
|
|
4217
|
+
await Promise.all(uploadPromises);
|
|
4218
|
+
const arm64Result = uploadResults["arm64-v8a"] || Object.values(uploadResults).find((r) => r.is64Bit);
|
|
4219
|
+
const arm32Result = uploadResults["armeabi-v7a"] || Object.values(uploadResults).find((r) => !r.is64Bit);
|
|
4220
|
+
const submitData = {
|
|
4221
|
+
packageName: vivoConfig.packageName,
|
|
4222
|
+
versionCode: parseInt(metadata.buildNumber) || 1,
|
|
4223
|
+
updateDesc: metadata.changelog || "App Update"
|
|
4224
|
+
};
|
|
4225
|
+
if (arm64Result) {
|
|
4226
|
+
submitData.serialnumber = arm64Result.serialnumber;
|
|
4227
|
+
submitData.fileMd5 = arm64Result.md5;
|
|
3775
4228
|
}
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
updateDesc: metadata.changelog || "App Update"
|
|
3785
|
-
}),
|
|
3786
|
-
"vivo submit version"
|
|
3787
|
-
);
|
|
3788
|
-
if (!submitResult.success) {
|
|
3789
|
-
throw submitResult.error || new Error("Submit version failed");
|
|
4229
|
+
if (arm32Result) {
|
|
4230
|
+
submitData.apk32 = arm32Result.serialnumber;
|
|
4231
|
+
submitData.md532 = arm32Result.md5;
|
|
4232
|
+
}
|
|
4233
|
+
if (!submitData.serialnumber && !submitData.apk32) {
|
|
4234
|
+
const single = Object.values(uploadResults)[0];
|
|
4235
|
+
submitData.serialnumber = single.serialnumber;
|
|
4236
|
+
submitData.fileMd5 = single.md5;
|
|
3790
4237
|
}
|
|
4238
|
+
logger.info(`[vivo] \u6B63\u5728\u63D0\u4EA4\u5BA1\u6838\u7533\u62A5: ${JSON.stringify(submitData)}`);
|
|
4239
|
+
await this.submitVersion(accessKey, accessSecret, submitData);
|
|
3791
4240
|
logger.success("\u4E0A\u4F20\u5230 vivo \u5E94\u7528\u5546\u5E97\u6210\u529F!");
|
|
3792
|
-
return {
|
|
3793
|
-
platform: "vivo",
|
|
3794
|
-
success: true,
|
|
3795
|
-
message: "\u4E0A\u4F20\u6210\u529F, \u8BF7\u524D\u5F80\u540E\u53F0\u786E\u8BA4\u5E76\u63D0\u4EA4\u5BA1\u6838",
|
|
3796
|
-
consoleUrl
|
|
3797
|
-
};
|
|
4241
|
+
return { platform: "vivo", success: true, message: "\u4E0A\u4F20\u5E76\u63D0\u4EA4\u5BA1\u6838\u6210\u529F", consoleUrl };
|
|
3798
4242
|
} catch (error) {
|
|
3799
4243
|
logger.error(`\u4E0A\u4F20\u5230 vivo \u5931\u8D25: ${error.message}`);
|
|
3800
|
-
return {
|
|
3801
|
-
platform: "vivo",
|
|
3802
|
-
success: false,
|
|
3803
|
-
message: this.formatError(error),
|
|
3804
|
-
error,
|
|
3805
|
-
consoleUrl
|
|
3806
|
-
};
|
|
4244
|
+
return { platform: "vivo", success: false, message: error.message, error, consoleUrl };
|
|
3807
4245
|
}
|
|
3808
4246
|
}
|
|
3809
|
-
/**
|
|
3810
|
-
* 计算文件 MD5
|
|
3811
|
-
*/
|
|
3812
4247
|
calculateFileMD5(filePath) {
|
|
3813
4248
|
return new Promise((resolve, reject) => {
|
|
3814
4249
|
const hash = import_crypto5.default.createHash("md5");
|
|
@@ -3818,14 +4253,9 @@ var VivoUploader = class _VivoUploader {
|
|
|
3818
4253
|
stream.on("error", reject);
|
|
3819
4254
|
});
|
|
3820
4255
|
}
|
|
3821
|
-
/**
|
|
3822
|
-
* 上传 APK 文件并获取流水号
|
|
3823
|
-
* 将公共参数与业务参数放入一个 multipart 请求中直接上传至 API_BASE
|
|
3824
|
-
*/
|
|
3825
4256
|
async uploadApk(accessKey, accessSecret, filePath, packageName, fileMd5) {
|
|
3826
4257
|
const timestamp = String(Date.now());
|
|
3827
|
-
const
|
|
3828
|
-
// 公共参数
|
|
4258
|
+
const params = {
|
|
3829
4259
|
access_key: accessKey,
|
|
3830
4260
|
timestamp,
|
|
3831
4261
|
format: "json",
|
|
@@ -3833,41 +4263,19 @@ var VivoUploader = class _VivoUploader {
|
|
|
3833
4263
|
sign_method: "hmac",
|
|
3834
4264
|
target_app_key: "developer",
|
|
3835
4265
|
method: "app.upload.apk.app",
|
|
3836
|
-
// 业务参数
|
|
3837
4266
|
packageName,
|
|
3838
4267
|
fileMd5
|
|
3839
4268
|
};
|
|
3840
|
-
const sign = this.generateSign(
|
|
4269
|
+
const sign = this.generateSign(params, accessSecret);
|
|
3841
4270
|
const form = new import_form_data7.default();
|
|
3842
|
-
|
|
3843
|
-
form.append(key, value);
|
|
3844
|
-
}
|
|
4271
|
+
Object.entries(params).forEach(([k, v]) => form.append(k, v));
|
|
3845
4272
|
form.append("sign", sign);
|
|
3846
|
-
form.append("file", import_fs_extra11.default.createReadStream(filePath), {
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
logger.info(
|
|
3851
|
-
`[VIVO DEBUG] \u5F00\u59CB\u4E0A\u4F20 APK (API\u8BF7\u6C42) \u53C2\u6570(\u4E0D\u542B\u6587\u4EF6): ${JSON.stringify({ ...paramsForSign, sign })}`
|
|
3852
|
-
);
|
|
3853
|
-
const res = await import_axios8.default.post(_VivoUploader.API_BASE, form, {
|
|
3854
|
-
headers: form.getHeaders(),
|
|
3855
|
-
maxContentLength: Infinity,
|
|
3856
|
-
maxBodyLength: Infinity,
|
|
3857
|
-
timeout: 3e5
|
|
3858
|
-
});
|
|
3859
|
-
logger.info(`[VIVO DEBUG] \u4E0A\u4F20\u54CD\u5E94: ${JSON.stringify(res.data)}`);
|
|
3860
|
-
if (res.data.code !== 0) {
|
|
3861
|
-
throw new Error(`\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: ${res.data.msg || JSON.stringify(res.data)}`);
|
|
3862
|
-
}
|
|
3863
|
-
const serialnumber = res.data.data?.serialnumber || res.data.data;
|
|
3864
|
-
logger.info(`APK \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210\uFF0C\u6D41\u6C34\u53F7: ${serialnumber}`);
|
|
3865
|
-
return serialnumber;
|
|
4273
|
+
form.append("file", import_fs_extra11.default.createReadStream(filePath), { filename: import_path9.default.basename(filePath) });
|
|
4274
|
+
const res = await import_axios8.default.post(_VivoUploader.API_BASE, form, { headers: form.getHeaders(), timeout: 3e5 });
|
|
4275
|
+
if (res.data.code !== 0) throw new Error(`\u4E0A\u4F20\u5305\u5931\u8D25: ${res.data.msg}`);
|
|
4276
|
+
return res.data.data?.serialnumber || res.data.data;
|
|
3866
4277
|
}
|
|
3867
|
-
|
|
3868
|
-
* 提交版本更新信息
|
|
3869
|
-
*/
|
|
3870
|
-
async submitVersion(accessKey, accessSecret, params) {
|
|
4278
|
+
async submitVersion(accessKey, accessSecret, data) {
|
|
3871
4279
|
const timestamp = String(Date.now());
|
|
3872
4280
|
const reqParams = {
|
|
3873
4281
|
access_key: accessKey,
|
|
@@ -3877,51 +4285,32 @@ var VivoUploader = class _VivoUploader {
|
|
|
3877
4285
|
sign_method: "hmac",
|
|
3878
4286
|
target_app_key: "developer",
|
|
3879
4287
|
method: "app.sync.update.app",
|
|
3880
|
-
packageName:
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
apk: params.serialnumber,
|
|
3885
|
-
// 文档中的 apk 字段即为上传接口返回的 serialnumber
|
|
3886
|
-
fileMd5: params.fileMd5,
|
|
3887
|
-
// 文档必填
|
|
4288
|
+
packageName: data.packageName || "",
|
|
4289
|
+
versionCode: String(data.versionCode),
|
|
4290
|
+
apk: data.serialnumber || "",
|
|
4291
|
+
fileMd5: data.fileMd5 || "",
|
|
3888
4292
|
onlineType: "1",
|
|
3889
|
-
// 1:立即上架 2:定时上架 (必填)
|
|
3890
4293
|
compatibleDevice: "1",
|
|
3891
|
-
|
|
3892
|
-
updateDesc: params.updateDesc
|
|
4294
|
+
updateDesc: data.updateDesc
|
|
3893
4295
|
};
|
|
4296
|
+
if (data.apk32) {
|
|
4297
|
+
reqParams.apk32 = data.apk32;
|
|
4298
|
+
if (data.md532) reqParams.md532 = data.md532;
|
|
4299
|
+
}
|
|
3894
4300
|
reqParams.sign = this.generateSign(reqParams, accessSecret);
|
|
3895
4301
|
const formData = new URLSearchParams();
|
|
3896
|
-
|
|
3897
|
-
formData.append(key, value);
|
|
3898
|
-
}
|
|
4302
|
+
Object.entries(reqParams).forEach(([k, v]) => formData.append(k, v));
|
|
3899
4303
|
const res = await import_axios8.default.post(_VivoUploader.API_BASE, formData.toString(), {
|
|
3900
|
-
headers: {
|
|
3901
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
3902
|
-
},
|
|
4304
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
3903
4305
|
timeout: 3e4
|
|
3904
4306
|
});
|
|
3905
|
-
if (res.data.code !== 0) {
|
|
3906
|
-
throw new Error(`\u63D0\u4EA4\u7248\u672C\u5931\u8D25: ${res.data.msg || JSON.stringify(res.data)}`);
|
|
3907
|
-
}
|
|
3908
|
-
logger.info("\u7248\u672C\u4FE1\u606F\u5DF2\u63D0\u4EA4");
|
|
3909
|
-
}
|
|
3910
|
-
/**
|
|
3911
|
-
* 格式化错误信息
|
|
3912
|
-
*/
|
|
3913
|
-
formatError(error) {
|
|
3914
|
-
if (error.response?.data) {
|
|
3915
|
-
const data = error.response.data;
|
|
3916
|
-
return data.msg || data.message || error.message;
|
|
3917
|
-
}
|
|
3918
|
-
return error.message;
|
|
4307
|
+
if (res.data.code !== 0) throw new Error(`\u63D0\u4EA4\u5931\u8D25: ${res.data.msg}`);
|
|
3919
4308
|
}
|
|
3920
4309
|
};
|
|
3921
4310
|
|
|
3922
4311
|
// src/adapters/tencent_uploader.ts
|
|
3923
4312
|
var import_fs_extra12 = __toESM(require("fs-extra"), 1);
|
|
3924
|
-
var
|
|
4313
|
+
var import_path10 = __toESM(require("path"), 1);
|
|
3925
4314
|
var import_axios9 = __toESM(require("axios"), 1);
|
|
3926
4315
|
var import_crypto6 = __toESM(require("crypto"), 1);
|
|
3927
4316
|
var TencentUploader = class _TencentUploader {
|
|
@@ -3953,54 +4342,71 @@ var TencentUploader = class _TencentUploader {
|
|
|
3953
4342
|
async upload(filePath, config, metadata) {
|
|
3954
4343
|
const tencentConfig = config.publish.tencent;
|
|
3955
4344
|
const auth = tencentConfig.auth;
|
|
3956
|
-
logger.info(`Tencent \u8FD0\u884C\u65F6\u914D\u7F6E: ${JSON.stringify(tencentConfig)}`);
|
|
3957
4345
|
const consoleUrl = "https://app.open.qq.com";
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
}
|
|
4346
|
+
const pkgName = tencentConfig.packageName || "";
|
|
4347
|
+
const artifacts = typeof metadata.artifactPath === "object" ? metadata.artifactPath : { universal: filePath || (typeof metadata.artifactPath === "string" ? metadata.artifactPath : "") };
|
|
3961
4348
|
try {
|
|
3962
|
-
const
|
|
3963
|
-
const
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
4349
|
+
const uploadResults = {};
|
|
4350
|
+
const uploadPromises = Object.entries(artifacts).map(async ([abi, p]) => {
|
|
4351
|
+
if (!p || !import_fs_extra12.default.existsSync(p)) throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${p}`);
|
|
4352
|
+
const stats = import_fs_extra12.default.statSync(p);
|
|
4353
|
+
const fileName = import_path10.default.basename(p);
|
|
4354
|
+
logger.info(`[Tencent] \u6B63\u5728\u5904\u7406 ${abi} \u67B6\u6784\u5305: ${fileName}`);
|
|
4355
|
+
const uploadInfo = await this.getFileUploadInfo(auth, stats.size, fileName, pkgName);
|
|
4356
|
+
await this.uploadToCos(uploadInfo.pre_sign_url, p, stats.size);
|
|
4357
|
+
const pkgInfo = await parsePackageInfo(p, {
|
|
4358
|
+
androidSdkPath: config.globalSettings?.androidSdkPath
|
|
4359
|
+
});
|
|
4360
|
+
const nativeCodes = pkgInfo?.nativeCode || [];
|
|
4361
|
+
const has64Bit = nativeCodes.includes("arm64-v8a") || nativeCodes.includes("x86_64") || abi === "arm64-v8a";
|
|
4362
|
+
const has32Bit = nativeCodes.includes("armeabi-v7a") || nativeCodes.includes("armeabi") || nativeCodes.includes("x86") || abi === "armeabi-v7a";
|
|
4363
|
+
uploadResults[abi] = {
|
|
4364
|
+
serial_number: uploadInfo.serial_number,
|
|
4365
|
+
is64Bit: has64Bit && !has32Bit,
|
|
4366
|
+
md5: pkgInfo?.md5 || ""
|
|
4367
|
+
};
|
|
4368
|
+
});
|
|
4369
|
+
await Promise.all(uploadPromises);
|
|
4370
|
+
logger.info("[Tencent] \u6B63\u5728\u83B7\u53D6\u7EBF\u4E0A\u5E94\u7528\u8BE6\u60C5...");
|
|
4371
|
+
const anyPkgPath = Object.values(artifacts)[0];
|
|
4372
|
+
const samplePkgInfo = await parsePackageInfo(anyPkgPath, {
|
|
3972
4373
|
androidSdkPath: config.globalSettings?.androidSdkPath
|
|
3973
4374
|
});
|
|
3974
|
-
const nativeCodes = pkgInfo?.nativeCode || [];
|
|
3975
|
-
const has64Bit = nativeCodes.includes("arm64-v8a") || nativeCodes.includes("x86_64");
|
|
3976
|
-
const has32Bit = nativeCodes.includes("armeabi-v7a") || nativeCodes.includes("armeabi") || nativeCodes.includes("x86");
|
|
3977
|
-
const is64Bit = has64Bit && !has32Bit;
|
|
3978
|
-
const md5 = pkgInfo?.md5;
|
|
3979
4375
|
const onlineDetail = await this.queryAppDetail(
|
|
3980
4376
|
auth,
|
|
3981
|
-
|
|
4377
|
+
pkgName || samplePkgInfo?.packageName || ""
|
|
3982
4378
|
);
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
4379
|
+
const submitData = {
|
|
4380
|
+
...onlineDetail,
|
|
4381
|
+
pkg_name: pkgName || samplePkgInfo?.packageName || onlineDetail.pkg_name || "",
|
|
4382
|
+
update_desc: metadata.changelog || "\u7248\u672C\u66F4\u65B0"
|
|
4383
|
+
};
|
|
4384
|
+
const arm64Result = uploadResults["arm64-v8a"] || Object.values(uploadResults).find((r) => r.is64Bit);
|
|
4385
|
+
const arm32Result = uploadResults["armeabi-v7a"] || Object.values(uploadResults).find((r) => !r.is64Bit);
|
|
4386
|
+
if (arm64Result) {
|
|
4387
|
+
submitData.apk64_serial_number = arm64Result.serial_number;
|
|
4388
|
+
submitData.apk64_md5 = arm64Result.md5;
|
|
4389
|
+
}
|
|
4390
|
+
if (arm32Result) {
|
|
4391
|
+
submitData.apk32_serial_number = arm32Result.serial_number;
|
|
4392
|
+
submitData.apk32_md5 = arm32Result.md5;
|
|
4393
|
+
}
|
|
4394
|
+
if (Object.keys(uploadResults).length === 1 && !submitData.apk64_serial_number && !submitData.apk32_serial_number) {
|
|
4395
|
+
const single = Object.values(uploadResults)[0];
|
|
4396
|
+
if (single.is64Bit) {
|
|
4397
|
+
submitData.apk64_serial_number = single.serial_number;
|
|
4398
|
+
submitData.apk64_md5 = single.md5;
|
|
4399
|
+
} else {
|
|
4400
|
+
submitData.apk32_serial_number = single.serial_number;
|
|
4401
|
+
submitData.apk32_md5 = single.md5;
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
logger.info("[Tencent] \u6B63\u5728\u63D0\u4EA4\u5BA1\u6838\u7533\u62A5...");
|
|
4405
|
+
await this.submitModifyAppInfo(auth, submitData, { timeout: tencentConfig.timeout || 6e4 });
|
|
3999
4406
|
logger.success("\u817E\u8BAF\u5E94\u7528\u5B9D\u4E0A\u4F20\u5E76\u63D0\u4EA4\u6210\u529F!");
|
|
4000
4407
|
return { platform: "tencent", success: true, message: "\u4E0A\u4F20\u5E76\u63D0\u4EA4\u5BA1\u6838\u6210\u529F", consoleUrl };
|
|
4001
4408
|
} catch (error) {
|
|
4002
|
-
logger.error(`\u817E\u8BAF\u4E0A\u4F20\u5931\u8D25: ${
|
|
4003
|
-
logger.error(`\u817E\u8BAF\u4E0A\u4F20\u5931\u8D25: ${error.stack}`);
|
|
4409
|
+
logger.error(`\u817E\u8BAF\u4E0A\u4F20\u5931\u8D25: ${error.message}`);
|
|
4004
4410
|
return { platform: "tencent", success: false, message: error.message, error, consoleUrl };
|
|
4005
4411
|
}
|
|
4006
4412
|
}
|
|
@@ -4114,16 +4520,22 @@ var TencentUploader = class _TencentUploader {
|
|
|
4114
4520
|
signParams[key] = String(data[key]);
|
|
4115
4521
|
}
|
|
4116
4522
|
});
|
|
4117
|
-
if (data.
|
|
4118
|
-
signParams.apk64_file_serial_number = String(data.
|
|
4119
|
-
if (data.
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
signParams.
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4523
|
+
if (data.apk64_serial_number) {
|
|
4524
|
+
signParams.apk64_file_serial_number = String(data.apk64_serial_number);
|
|
4525
|
+
if (data.apk64_md5) signParams.apk64_file_md5 = data.apk64_md5;
|
|
4526
|
+
}
|
|
4527
|
+
if (data.apk32_serial_number) {
|
|
4528
|
+
signParams.apk32_file_serial_number = String(data.apk32_serial_number);
|
|
4529
|
+
if (data.apk32_md5) signParams.apk32_file_md5 = data.apk32_md5;
|
|
4530
|
+
}
|
|
4531
|
+
if (!data.apk64_serial_number && !data.apk32_serial_number && data.serial_number) {
|
|
4532
|
+
if (data.is64Bit) {
|
|
4533
|
+
signParams.apk64_file_serial_number = String(data.serial_number || "");
|
|
4534
|
+
if (data.md5) signParams.apk64_file_md5 = data.md5;
|
|
4535
|
+
} else {
|
|
4536
|
+
signParams.apk32_file_serial_number = String(data.serial_number || "");
|
|
4537
|
+
if (data.md5) signParams.apk32_file_md5 = data.md5;
|
|
4538
|
+
}
|
|
4127
4539
|
}
|
|
4128
4540
|
const sign = this.generateSign(signParams, accessSecret);
|
|
4129
4541
|
const formParams = {
|