react-native-update-cli 1.38.1 → 1.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/versions.js CHANGED
@@ -86,8 +86,9 @@ const commands = {
86
86
  const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
87
87
  const { appId } = await (0, _app.getSelectedApp)(platform);
88
88
  const { hash } = await (0, _api.uploadFile)(fn);
89
+ const versionName = name || await (0, _utils.question)('输入版本名称: ') || '(未命名)';
89
90
  const { id } = await (0, _api.post)(`/app/${appId}/version/create`, {
90
- name: name || await (0, _utils.question)('输入版本名称: ') || '(未命名)',
91
+ name: versionName,
91
92
  hash,
92
93
  description: description || await (0, _utils.question)('输入版本描述:'),
93
94
  metaInfo: metaInfo || await (0, _utils.question)('输入自定义的 meta info:')
@@ -105,6 +106,7 @@ const commands = {
105
106
  }
106
107
  });
107
108
  }
109
+ return versionName;
108
110
  },
109
111
  versions: async ({ options })=>{
110
112
  const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update-cli",
3
- "version": "1.38.1",
3
+ "version": "1.39.0",
4
4
  "description": "Command tools for javaScript updater with `pushy` service for react native apps.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -3,6 +3,7 @@ import fs from 'node:fs';
3
3
  import Table from 'tty-table';
4
4
 
5
5
  import { post, get, doDelete } from './api';
6
+ import type { Platform } from './types';
6
7
 
7
8
  const validPlatforms = {
8
9
  ios: 1,
@@ -10,14 +11,14 @@ const validPlatforms = {
10
11
  harmony: 1,
11
12
  };
12
13
 
13
- export function checkPlatform(platform) {
14
+ export function checkPlatform(platform: Platform) {
14
15
  if (!validPlatforms[platform]) {
15
16
  throw new Error(`无法识别的平台 '${platform}'`);
16
17
  }
17
18
  return platform;
18
19
  }
19
20
 
20
- export function getSelectedApp(platform) {
21
+ export function getSelectedApp(platform: Platform) {
21
22
  checkPlatform(platform);
22
23
 
23
24
  if (!fs.existsSync('update.json')) {
@@ -34,7 +35,7 @@ export function getSelectedApp(platform) {
34
35
  return updateInfo[platform];
35
36
  }
36
37
 
37
- export async function listApp(platform) {
38
+ export async function listApp(platform: Platform) {
38
39
  const { data } = await get('/app/list');
39
40
  const list = platform ? data.filter((v) => v.platform === platform) : data;
40
41
 
@@ -58,12 +59,12 @@ export async function listApp(platform) {
58
59
  return list;
59
60
  }
60
61
 
61
- export async function chooseApp(platform) {
62
+ export async function chooseApp(platform: Platform) {
62
63
  const list = await listApp(platform);
63
64
 
64
65
  while (true) {
65
66
  const id = await question('输入应用 id:');
66
- const app = list.find((v) => v.id === (id | 0));
67
+ const app = list.find((v) => v.id === Number(id));
67
68
  if (app) {
68
69
  return app;
69
70
  }
package/src/bundle.js CHANGED
@@ -3,15 +3,17 @@ import { getRNVersion, translateOptions } from './utils';
3
3
  import * as fs from 'fs-extra';
4
4
  import { ZipFile } from 'yazl';
5
5
  import { open as openZipFile } from 'yauzl';
6
- import { question, printVersionCommand } from './utils';
6
+ import { question, checkPlugins } from './utils';
7
7
  import { checkPlatform } from './app';
8
8
  import { spawn, spawnSync } from 'node:child_process';
9
+ import semverSatisfies from 'semver/functions/satisfies';
9
10
  const g2js = require('gradle-to-js/lib/parser');
10
- import os from 'os';
11
+ import os from 'node:os';
11
12
  const properties = require('properties');
12
- const path = require('path');
13
13
 
14
- let bsdiff, hdiff, diff;
14
+ let bsdiff;
15
+ let hdiff;
16
+ let diff;
15
17
  try {
16
18
  bsdiff = require('node-bsdiff').diff;
17
19
  } catch (e) {}
@@ -39,9 +41,9 @@ async function runReactNativeBundleCommand(
39
41
  }
40
42
  }
41
43
 
42
- let reactNativeBundleArgs = [];
44
+ const reactNativeBundleArgs = [];
43
45
 
44
- let envArgs = process.env.PUSHY_ENV_ARGS;
46
+ const envArgs = process.env.PUSHY_ENV_ARGS;
45
47
 
46
48
  if (envArgs) {
47
49
  Array.prototype.push.apply(
@@ -59,8 +61,19 @@ async function runReactNativeBundleCommand(
59
61
  cliPath = require.resolve('@expo/cli', {
60
62
  paths: [process.cwd()],
61
63
  });
62
- usingExpo = true;
63
- } catch (e) {
64
+ const expoCliVersion = JSON.parse(
65
+ fs.readFileSync(
66
+ require.resolve('@expo/cli/package.json', {
67
+ paths: [process.cwd()],
68
+ }),
69
+ ),
70
+ ).version;
71
+ // expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
72
+ if (semverSatisfies(expoCliVersion, '>= 0.10.17')) {
73
+ usingExpo = true;
74
+ }
75
+ } catch (e) {}
76
+ if (!usingExpo) {
64
77
  try {
65
78
  // rn >= 0.75
66
79
  cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
@@ -73,8 +86,15 @@ async function runReactNativeBundleCommand(
73
86
  });
74
87
  }
75
88
  }
76
- const bundleCommand = usingExpo ? 'export:embed' : platform === 'harmony' ? 'bundle-harmony' : 'bundle';
77
- if (platform == 'harmony') {
89
+ const bundleParams = await checkPlugins();
90
+ const minifyOption = bundleParams.minify;
91
+ const isSentry = bundleParams.sentry;
92
+ const bundleCommand = usingExpo
93
+ ? 'export:embed'
94
+ : platform === 'harmony'
95
+ ? 'bundle-harmony'
96
+ : 'bundle';
97
+ if (platform === 'harmony') {
78
98
  Array.prototype.push.apply(reactNativeBundleArgs, [
79
99
  cliPath,
80
100
  bundleCommand,
@@ -91,8 +111,7 @@ async function runReactNativeBundleCommand(
91
111
  if (config) {
92
112
  reactNativeBundleArgs.push('--config', config);
93
113
  }
94
- }
95
- else{
114
+ } else {
96
115
  Array.prototype.push.apply(reactNativeBundleArgs, [
97
116
  cliPath,
98
117
  bundleCommand,
@@ -107,17 +126,19 @@ async function runReactNativeBundleCommand(
107
126
  '--platform',
108
127
  platform,
109
128
  '--reset-cache',
129
+ '--minify',
130
+ minifyOption,
110
131
  ]);
111
-
132
+
112
133
  if (sourcemapOutput) {
113
134
  reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
114
135
  }
115
-
136
+
116
137
  if (config) {
117
138
  reactNativeBundleArgs.push('--config', config);
118
139
  }
119
140
  }
120
-
141
+
121
142
  const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
122
143
  console.log(
123
144
  `Running bundle command: node ${reactNativeBundleArgs.join(' ')}`,
@@ -147,7 +168,7 @@ async function runReactNativeBundleCommand(
147
168
  properties.parse(
148
169
  './android/gradle.properties',
149
170
  { path: true },
150
- function (error, props) {
171
+ (error, props) => {
151
172
  if (error) {
152
173
  console.error(error);
153
174
  resolve(null);
@@ -166,7 +187,7 @@ async function runReactNativeBundleCommand(
166
187
  fs.existsSync('ios/Pods/hermes-engine')
167
188
  ) {
168
189
  hermesEnabled = true;
169
- }else if (platform === 'harmony') {
190
+ } else if (platform === 'harmony') {
170
191
  await copyHarmonyBundle(outputFolder);
171
192
  }
172
193
  if (hermesEnabled) {
@@ -174,6 +195,7 @@ async function runReactNativeBundleCommand(
174
195
  bundleName,
175
196
  outputFolder,
176
197
  sourcemapOutput,
198
+ !isSentry,
177
199
  );
178
200
  }
179
201
  resolve(null);
@@ -193,7 +215,7 @@ async function copyHarmonyBundle(outputFolder) {
193
215
  }
194
216
  await fs.remove(path.join(harmonyRawPath, 'update.json'));
195
217
  await fs.copy('update.json', path.join(harmonyRawPath, 'update.json'));
196
-
218
+
197
219
  await fs.ensureDir(outputFolder);
198
220
  await fs.copy(harmonyRawPath, outputFolder);
199
221
  } catch (error) {
@@ -237,8 +259,9 @@ async function compileHermesByteCode(
237
259
  bundleName,
238
260
  outputFolder,
239
261
  sourcemapOutput,
262
+ shouldCleanSourcemap,
240
263
  ) {
241
- console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
264
+ console.log('Hermes enabled, now compiling to hermes bytecode:\n');
242
265
  // >= rn 0.69
243
266
  const rnDir = path.dirname(
244
267
  require.resolve('react-native', {
@@ -264,13 +287,11 @@ async function compileHermesByteCode(
264
287
  if (sourcemapOutput) {
265
288
  fs.copyFileSync(
266
289
  sourcemapOutput,
267
- path.join(outputFolder, bundleName + '.txt.map'),
290
+ path.join(outputFolder, `${bundleName}.txt.map`),
268
291
  );
269
292
  args.push('-output-source-map');
270
293
  }
271
- console.log(
272
- 'Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n',
273
- );
294
+ console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
274
295
  spawnSync(hermesCommand, args, {
275
296
  stdio: 'ignore',
276
297
  });
@@ -280,13 +301,13 @@ async function compileHermesByteCode(
280
301
  if (!fs.existsSync(composerPath)) {
281
302
  return;
282
303
  }
283
- console.log(`Composing source map`);
304
+ console.log('Composing source map');
284
305
  spawnSync(
285
306
  'node',
286
307
  [
287
308
  composerPath,
288
- path.join(outputFolder, bundleName + '.txt.map'),
289
- path.join(outputFolder, bundleName + '.map'),
309
+ path.join(outputFolder, `${bundleName}.txt.map`),
310
+ path.join(outputFolder, `${bundleName}.map`),
290
311
  '-o',
291
312
  sourcemapOutput,
292
313
  ],
@@ -295,7 +316,96 @@ async function compileHermesByteCode(
295
316
  },
296
317
  );
297
318
  }
298
- fs.removeSync(path.join(outputFolder, bundleName + '.txt.map'));
319
+ if (shouldCleanSourcemap) {
320
+ fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
321
+ }
322
+ }
323
+
324
+ async function copyDebugidForSentry(bundleName, outputFolder, sourcemapOutput) {
325
+ if (sourcemapOutput) {
326
+ let copyDebugidPath;
327
+ try {
328
+ copyDebugidPath = require.resolve(
329
+ '@sentry/react-native/scripts/copy-debugid.js',
330
+ {
331
+ paths: [process.cwd()],
332
+ },
333
+ );
334
+ } catch (error) {
335
+ console.error(
336
+ '无法找到 Sentry copy-debugid.js 脚本文件,请确保已正确安装 @sentry/react-native',
337
+ );
338
+ return;
339
+ }
340
+
341
+ if (!fs.existsSync(copyDebugidPath)) {
342
+ return;
343
+ }
344
+ console.log('Copying debugid');
345
+ spawnSync(
346
+ 'node',
347
+ [
348
+ copyDebugidPath,
349
+ path.join(outputFolder, `${bundleName}.txt.map`),
350
+ path.join(outputFolder, `${bundleName}.map`),
351
+ ],
352
+ {
353
+ stdio: 'ignore',
354
+ },
355
+ );
356
+ }
357
+ fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
358
+ }
359
+
360
+ async function uploadSourcemapForSentry(
361
+ bundleName,
362
+ outputFolder,
363
+ sourcemapOutput,
364
+ version,
365
+ ) {
366
+ if (sourcemapOutput) {
367
+ let sentryCliPath;
368
+ try {
369
+ sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
370
+ paths: [process.cwd()],
371
+ });
372
+ } catch (error) {
373
+ console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
374
+ return;
375
+ }
376
+
377
+ if (!fs.existsSync(sentryCliPath)) {
378
+ return;
379
+ }
380
+
381
+ spawnSync(
382
+ 'node',
383
+ [sentryCliPath, 'releases', 'set-commits', version, '--auto'],
384
+ {
385
+ stdio: 'inherit',
386
+ },
387
+ );
388
+ console.log(`Sentry release created for version: ${version}`);
389
+
390
+ console.log('Uploading sourcemap');
391
+ spawnSync(
392
+ 'node',
393
+ [
394
+ sentryCliPath,
395
+ 'releases',
396
+ 'files',
397
+ version,
398
+ 'upload-sourcemaps',
399
+ '--strip-prefix',
400
+ path.join(process.cwd(), outputFolder),
401
+ path.join(outputFolder, bundleName),
402
+ path.join(outputFolder, `${bundleName}.map`),
403
+ ],
404
+ {
405
+ stdio: 'inherit',
406
+ },
407
+ );
408
+ }
299
409
  }
300
410
 
301
411
  async function pack(dir, output) {
@@ -320,7 +430,7 @@ async function pack(dir, output) {
320
430
  zipfile.addFile(fullPath, rel + name);
321
431
  } else if (stat.isDirectory()) {
322
432
  //console.log('adding: ' + rel+name+'/');
323
- addDirectory(fullPath, rel + name + '/');
433
+ addDirectory(fullPath, `${rel}${name}/`);
324
434
  }
325
435
  }
326
436
  }
@@ -328,14 +438,12 @@ async function pack(dir, output) {
328
438
  addDirectory(dir, '');
329
439
 
330
440
  zipfile.outputStream.on('error', (err) => reject(err));
331
- zipfile.outputStream
332
- .pipe(fs.createWriteStream(output))
333
- .on('close', function () {
334
- resolve();
335
- });
441
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
442
+ resolve();
443
+ });
336
444
  zipfile.end();
337
445
  });
338
- console.log('ppk热更包已生成并保存到: ' + output);
446
+ console.log(`ppk热更包已生成并保存到: ${output}`);
339
447
  }
340
448
 
341
449
  export function readEntire(entry, zipFile) {
@@ -360,7 +468,7 @@ export function readEntire(entry, zipFile) {
360
468
 
361
469
  function basename(fn) {
362
470
  const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
363
- return m && m[1];
471
+ return m?.[1];
364
472
  }
365
473
 
366
474
  async function diffFromPPK(origin, next, output) {
@@ -377,7 +485,10 @@ async function diffFromPPK(origin, next, output) {
377
485
  // isFile
378
486
  originMap[entry.crc32] = entry.fileName;
379
487
 
380
- if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
488
+ if (
489
+ entry.fileName === 'index.bundlejs' ||
490
+ entry.fileName === 'bundle.harmony.js'
491
+ ) {
381
492
  // This is source.
382
493
  return readEntire(entry, zipFile).then((v) => (originSource = v));
383
494
  }
@@ -386,7 +497,7 @@ async function diffFromPPK(origin, next, output) {
386
497
 
387
498
  if (!originSource) {
388
499
  throw new Error(
389
- `Bundle file not found! Please use default bundle file name and path.`,
500
+ 'Bundle file not found! Please use default bundle file name and path.',
390
501
  );
391
502
  }
392
503
 
@@ -398,11 +509,9 @@ async function diffFromPPK(origin, next, output) {
398
509
  zipfile.outputStream.on('error', (err) => {
399
510
  throw err;
400
511
  });
401
- zipfile.outputStream
402
- .pipe(fs.createWriteStream(output))
403
- .on('close', function () {
404
- resolve();
405
- });
512
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
513
+ resolve();
514
+ });
406
515
  });
407
516
 
408
517
  const addedEntry = {};
@@ -439,7 +548,7 @@ async function diffFromPPK(origin, next, output) {
439
548
  );
440
549
  //console.log('End diff');
441
550
  });
442
- }else if (entry.fileName === 'bundle.harmony.js') {
551
+ } else if (entry.fileName === 'bundle.harmony.js') {
443
552
  //console.log('Found bundle');
444
553
  return readEntire(entry, nextZipfile).then((newSource) => {
445
554
  //console.log('Begin diff');
@@ -471,7 +580,7 @@ async function diffFromPPK(origin, next, output) {
471
580
  addEntry(basename(entry.fileName));
472
581
 
473
582
  return new Promise((resolve, reject) => {
474
- nextZipfile.openReadStream(entry, function (err, readStream) {
583
+ nextZipfile.openReadStream(entry, (err, readStream) => {
475
584
  if (err) {
476
585
  return reject(err);
477
586
  }
@@ -487,9 +596,9 @@ async function diffFromPPK(origin, next, output) {
487
596
 
488
597
  const deletes = {};
489
598
 
490
- for (let k in originEntries) {
599
+ for (const k in originEntries) {
491
600
  if (!newEntries[k]) {
492
- console.log('Delete ' + k);
601
+ console.log(`Delete ${k}`);
493
602
  deletes[k] = 1;
494
603
  }
495
604
  }
@@ -538,7 +647,7 @@ async function diffFromPackage(
538
647
 
539
648
  if (!originSource) {
540
649
  throw new Error(
541
- `Bundle file not found! Please use default bundle file name and path.`,
650
+ 'Bundle file not found! Please use default bundle file name and path.',
542
651
  );
543
652
  }
544
653
 
@@ -550,11 +659,9 @@ async function diffFromPackage(
550
659
  zipfile.outputStream.on('error', (err) => {
551
660
  throw err;
552
661
  });
553
- zipfile.outputStream
554
- .pipe(fs.createWriteStream(output))
555
- .on('close', function () {
556
- resolve();
557
- });
662
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
663
+ resolve();
664
+ });
558
665
  });
559
666
 
560
667
  await enumZipEntries(next, (entry, nextZipfile) => {
@@ -581,7 +688,7 @@ async function diffFromPackage(
581
688
  );
582
689
  //console.log('End diff');
583
690
  });
584
- }else {
691
+ } else {
585
692
  // If same file.
586
693
  if (originEntries[entry.fileName] === entry.crc32) {
587
694
  copies[entry.fileName] = '';
@@ -594,7 +701,7 @@ async function diffFromPackage(
594
701
  }
595
702
 
596
703
  return new Promise((resolve, reject) => {
597
- nextZipfile.openReadStream(entry, function (err, readStream) {
704
+ nextZipfile.openReadStream(entry, (err, readStream) => {
598
705
  if (err) {
599
706
  return reject(err);
600
707
  }
@@ -630,7 +737,7 @@ export async function enumZipEntries(zipFn, callback, nestedPath = '') {
630
737
  !entry.fileName.endsWith('/') &&
631
738
  entry.fileName.toLowerCase().endsWith('.hap')
632
739
  ) {
633
- const tempDir = path.join(os.tmpdir(), 'nested_zip_' + Date.now());
740
+ const tempDir = path.join(os.tmpdir(), `nested_zip_${Date.now()}`);
634
741
  await fs.ensureDir(tempDir);
635
742
  const tempZipPath = path.join(tempDir, 'temp.zip');
636
743
 
@@ -644,7 +751,7 @@ export async function enumZipEntries(zipFn, callback, nestedPath = '') {
644
751
  });
645
752
  });
646
753
 
647
- await enumZipEntries(tempZipPath, callback, fullPath + '/');
754
+ await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
648
755
 
649
756
  await fs.remove(tempDir);
650
757
  }
@@ -697,7 +804,7 @@ function diffArgsCheck(args, options, diffFn) {
697
804
  return {
698
805
  origin,
699
806
  next,
700
- realOutput: output.replace(/\$\{time\}/g, '' + Date.now()),
807
+ realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`),
701
808
  };
702
809
  }
703
810
 
@@ -707,15 +814,19 @@ export const commands = {
707
814
  options.platform || (await question('平台(ios/android/harmony):')),
708
815
  );
709
816
 
710
- let { bundleName, entryFile, intermediaDir, output, dev, sourcemap } =
817
+ const { bundleName, entryFile, intermediaDir, output, dev } =
711
818
  translateOptions({
712
819
  ...options,
713
820
  platform,
714
821
  });
715
822
 
716
- const sourcemapOutput = path.join(intermediaDir, bundleName + '.map');
823
+ const bundleParams = await checkPlugins();
824
+ const sourcemap = bundleParams.sourcemap;
825
+ const isSentry = bundleParams.sentry;
826
+
827
+ const sourcemapOutput = path.join(intermediaDir, `${bundleName}.map`);
717
828
 
718
- const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
829
+ const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
719
830
 
720
831
  if (!platform) {
721
832
  throw new Error('Platform must be specified.');
@@ -723,7 +834,7 @@ export const commands = {
723
834
 
724
835
  const { version, major, minor } = getRNVersion();
725
836
 
726
- console.log('Bundling with react-native: ', version);
837
+ console.log(`Bundling with react-native: ${version}`);
727
838
 
728
839
  await runReactNativeBundleCommand(
729
840
  bundleName,
@@ -738,12 +849,21 @@ export const commands = {
738
849
 
739
850
  const v = await question('是否现在上传此热更包?(Y/N)');
740
851
  if (v.toLowerCase() === 'y') {
741
- await this.publish({
852
+ const versionName = await this.publish({
742
853
  args: [realOutput],
743
854
  options: {
744
855
  platform,
745
856
  },
746
857
  });
858
+ if (isSentry) {
859
+ await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
860
+ await uploadSourcemapForSentry(
861
+ bundleName,
862
+ intermediaDir,
863
+ sourcemapOutput,
864
+ versionName,
865
+ );
866
+ }
747
867
  }
748
868
  },
749
869
 
@@ -817,7 +937,7 @@ export const commands = {
817
937
 
818
938
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
819
939
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
820
- return m && m[1];
940
+ return m?.[1];
821
941
  });
822
942
 
823
943
  console.log(`${realOutput} generated.`);
@@ -832,7 +952,7 @@ export const commands = {
832
952
 
833
953
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
834
954
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
835
- return m && m[1];
955
+ return m?.[1];
836
956
  });
837
957
 
838
958
  console.log(`${realOutput} generated.`);
@@ -6,7 +6,7 @@ import { checkPlatform, getSelectedApp } from './app';
6
6
  import { getApkInfo, getIpaInfo, getAppInfo } from './utils';
7
7
  import Table from 'tty-table';
8
8
 
9
- export async function listPackage(appId) {
9
+ export async function listPackage(appId: string) {
10
10
  const { data } = await get(`/app/${appId}/package/list?limit=1000`);
11
11
 
12
12
  const header = [{ value: '原生包 Id' }, { value: '原生版本' }];
@@ -35,12 +35,12 @@ export async function listPackage(appId) {
35
35
  return data;
36
36
  }
37
37
 
38
- export async function choosePackage(appId) {
38
+ export async function choosePackage(appId: string) {
39
39
  const list = await listPackage(appId);
40
40
 
41
41
  while (true) {
42
42
  const id = await question('输入原生包 id:');
43
- const app = list.find((v) => v.id === (id | 0));
43
+ const app = list.find((v) => v.id === Number(id));
44
44
  if (app) {
45
45
  return app;
46
46
  }
@@ -48,7 +48,7 @@ export async function choosePackage(appId) {
48
48
  }
49
49
 
50
50
  export const commands = {
51
- uploadIpa: async function ({ args }) {
51
+ uploadIpa: async ({ args }: { args: string[] }) => {
52
52
  const fn = args[0];
53
53
  if (!fn || !fn.endsWith('.ipa')) {
54
54
  throw new Error('使用方法: pushy uploadIpa ipa后缀文件');
@@ -85,7 +85,7 @@ export const commands = {
85
85
  `已成功上传ipa原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
86
86
  );
87
87
  },
88
- uploadApk: async function ({ args }) {
88
+ uploadApk: async ({ args }) => {
89
89
  const fn = args[0];
90
90
  if (!fn || !fn.endsWith('.apk')) {
91
91
  throw new Error('使用方法: pushy uploadApk apk后缀文件');
@@ -122,7 +122,7 @@ export const commands = {
122
122
  `已成功上传apk原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
123
123
  );
124
124
  },
125
- uploadApp: async function ({ args }) {
125
+ uploadApp: async ({ args }) => {
126
126
  const fn = args[0];
127
127
  if (!fn || !fn.endsWith('.app')) {
128
128
  throw new Error('使用方法: pushy uploadApp app后缀文件');
@@ -134,7 +134,6 @@ export const commands = {
134
134
  appKey: appKeyInPkg,
135
135
  } = await getAppInfo(fn);
136
136
  const { appId, appKey } = await getSelectedApp('harmony');
137
-
138
137
 
139
138
  if (appIdInPkg && appIdInPkg != appId) {
140
139
  throw new Error(
@@ -160,28 +159,28 @@ export const commands = {
160
159
  `已成功上传app原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`,
161
160
  );
162
161
  },
163
- parseApp: async function ({ args }) {
162
+ parseApp: async ({ args }) => {
164
163
  const fn = args[0];
165
164
  if (!fn || !fn.endsWith('.app')) {
166
165
  throw new Error('使用方法: pushy parseApp app后缀文件');
167
166
  }
168
167
  console.log(await getAppInfo(fn));
169
168
  },
170
- parseIpa: async function ({ args }) {
169
+ parseIpa: async ({ args }) => {
171
170
  const fn = args[0];
172
171
  if (!fn || !fn.endsWith('.ipa')) {
173
172
  throw new Error('使用方法: pushy parseIpa ipa后缀文件');
174
173
  }
175
174
  console.log(await getIpaInfo(fn));
176
175
  },
177
- parseApk: async function ({ args }) {
176
+ parseApk: async ({ args }) => {
178
177
  const fn = args[0];
179
178
  if (!fn || !fn.endsWith('.apk')) {
180
179
  throw new Error('使用方法: pushy parseApk apk后缀文件');
181
180
  }
182
181
  console.log(await getApkInfo(fn));
183
182
  },
184
- packages: async function ({ options }) {
183
+ packages: async ({ options }) => {
185
184
  const platform = checkPlatform(
186
185
  options.platform || (await question('平台(ios/android/harmony):')),
187
186
  );
package/src/types.ts CHANGED
@@ -6,3 +6,5 @@ declare global {
6
6
  export interface Session {
7
7
  token: string;
8
8
  }
9
+
10
+ export type Platform = 'ios' | 'android' | 'harmony';