react-native-update-cli 1.38.1 → 1.38.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/lib/app.js CHANGED
@@ -90,7 +90,7 @@ async function chooseApp(platform) {
90
90
  const list = await listApp(platform);
91
91
  while(true){
92
92
  const id = await (0, _utils.question)('输入应用 id:');
93
- const app = list.find((v)=>v.id === (id | 0));
93
+ const app = list.find((v)=>v.id === Number(id));
94
94
  if (app) {
95
95
  return app;
96
96
  }
package/lib/bundle.js CHANGED
@@ -19,13 +19,15 @@ _export(exports, {
19
19
  return readEntire;
20
20
  }
21
21
  });
22
+ const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
22
23
  const _utils = require("./utils");
23
24
  const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
24
25
  const _yazl = require("yazl");
25
26
  const _yauzl = require("yauzl");
26
27
  const _app = require("./app");
27
28
  const _nodechild_process = require("node:child_process");
28
- const _os = /*#__PURE__*/ _interop_require_default(require("os"));
29
+ const _satisfies = /*#__PURE__*/ _interop_require_default(require("semver/functions/satisfies"));
30
+ const _nodeos = /*#__PURE__*/ _interop_require_default(require("node:os"));
29
31
  function _interop_require_default(obj) {
30
32
  return obj && obj.__esModule ? obj : {
31
33
  default: obj
@@ -74,8 +76,9 @@ function _interop_require_wildcard(obj, nodeInterop) {
74
76
  }
75
77
  const g2js = require('gradle-to-js/lib/parser');
76
78
  const properties = require('properties');
77
- const path = require('path');
78
- let bsdiff, hdiff, diff;
79
+ let bsdiff;
80
+ let hdiff;
81
+ let diff;
79
82
  try {
80
83
  bsdiff = require('node-bsdiff').diff;
81
84
  } catch (e) {}
@@ -90,8 +93,8 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
90
93
  console.warn('android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n');
91
94
  }
92
95
  }
93
- let reactNativeBundleArgs = [];
94
- let envArgs = process.env.PUSHY_ENV_ARGS;
96
+ const reactNativeBundleArgs = [];
97
+ const envArgs = process.env.PUSHY_ENV_ARGS;
95
98
  if (envArgs) {
96
99
  Array.prototype.push.apply(reactNativeBundleArgs, envArgs.trim().split(/\s+/));
97
100
  }
@@ -104,8 +107,17 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
104
107
  process.cwd()
105
108
  ]
106
109
  });
107
- usingExpo = true;
108
- } catch (e) {
110
+ const expoCliVersion = JSON.parse(_fsextra.readFileSync(require.resolve('@expo/cli/package.json', {
111
+ paths: [
112
+ process.cwd()
113
+ ]
114
+ }))).version;
115
+ // expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
116
+ if ((0, _satisfies.default)(expoCliVersion, '>= 0.10.17')) {
117
+ usingExpo = true;
118
+ }
119
+ } catch (e) {}
120
+ if (!usingExpo) {
109
121
  try {
110
122
  // rn >= 0.75
111
123
  cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
@@ -123,7 +135,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
123
135
  }
124
136
  }
125
137
  const bundleCommand = usingExpo ? 'export:embed' : platform === 'harmony' ? 'bundle-harmony' : 'bundle';
126
- if (platform == 'harmony') {
138
+ if (platform === 'harmony') {
127
139
  Array.prototype.push.apply(reactNativeBundleArgs, [
128
140
  cliPath,
129
141
  bundleCommand,
@@ -145,7 +157,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
145
157
  '--assets-dest',
146
158
  outputFolder,
147
159
  '--bundle-output',
148
- path.join(outputFolder, bundleName),
160
+ _nodepath.default.join(outputFolder, bundleName),
149
161
  '--dev',
150
162
  development,
151
163
  '--entry-file',
@@ -179,7 +191,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
179
191
  const gradlePropeties = await new Promise((resolve)=>{
180
192
  properties.parse('./android/gradle.properties', {
181
193
  path: true
182
- }, function(error, props) {
194
+ }, (error, props)=>{
183
195
  if (error) {
184
196
  console.error(error);
185
197
  resolve(null);
@@ -211,8 +223,8 @@ async function copyHarmonyBundle(outputFolder) {
211
223
  } catch (error) {
212
224
  await _fsextra.chmod(harmonyRawPath, 0o755);
213
225
  }
214
- await _fsextra.remove(path.join(harmonyRawPath, 'update.json'));
215
- await _fsextra.copy('update.json', path.join(harmonyRawPath, 'update.json'));
226
+ await _fsextra.remove(_nodepath.default.join(harmonyRawPath, 'update.json'));
227
+ await _fsextra.copy('update.json', _nodepath.default.join(harmonyRawPath, 'update.json'));
216
228
  await _fsextra.ensureDir(outputFolder);
217
229
  await _fsextra.copy(harmonyRawPath, outputFolder);
218
230
  } catch (error) {
@@ -221,9 +233,9 @@ async function copyHarmonyBundle(outputFolder) {
221
233
  }
222
234
  }
223
235
  function getHermesOSBin() {
224
- if (_os.default.platform() === 'win32') return 'win64-bin';
225
- if (_os.default.platform() === 'darwin') return 'osx-bin';
226
- if (_os.default.platform() === 'linux') return 'linux64-bin';
236
+ if (_nodeos.default.platform() === 'win32') return 'win64-bin';
237
+ if (_nodeos.default.platform() === 'darwin') return 'osx-bin';
238
+ if (_nodeos.default.platform() === 'linux') return 'linux64-bin';
227
239
  }
228
240
  async function checkGradleConfig() {
229
241
  let enableHermes = false;
@@ -247,14 +259,14 @@ async function checkGradleConfig() {
247
259
  };
248
260
  }
249
261
  async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput) {
250
- console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
262
+ console.log('Hermes enabled, now compiling to hermes bytecode:\n');
251
263
  // >= rn 0.69
252
- const rnDir = path.dirname(require.resolve('react-native', {
264
+ const rnDir = _nodepath.default.dirname(require.resolve('react-native', {
253
265
  paths: [
254
266
  process.cwd()
255
267
  ]
256
268
  }));
257
- let hermesPath = path.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
269
+ let hermesPath = _nodepath.default.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
258
270
  // < rn 0.69
259
271
  if (!_fsextra.existsSync(hermesPath)) {
260
272
  hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
@@ -263,15 +275,15 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
263
275
  const args = [
264
276
  '-emit-binary',
265
277
  '-out',
266
- path.join(outputFolder, bundleName),
267
- path.join(outputFolder, bundleName),
278
+ _nodepath.default.join(outputFolder, bundleName),
279
+ _nodepath.default.join(outputFolder, bundleName),
268
280
  '-O'
269
281
  ];
270
282
  if (sourcemapOutput) {
271
- _fsextra.copyFileSync(sourcemapOutput, path.join(outputFolder, bundleName + '.txt.map'));
283
+ _fsextra.copyFileSync(sourcemapOutput, _nodepath.default.join(outputFolder, `${bundleName}.txt.map`));
272
284
  args.push('-output-source-map');
273
285
  }
274
- console.log('Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n');
286
+ console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
275
287
  (0, _nodechild_process.spawnSync)(hermesCommand, args, {
276
288
  stdio: 'ignore'
277
289
  });
@@ -280,22 +292,22 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
280
292
  if (!_fsextra.existsSync(composerPath)) {
281
293
  return;
282
294
  }
283
- console.log(`Composing source map`);
295
+ console.log('Composing source map');
284
296
  (0, _nodechild_process.spawnSync)('node', [
285
297
  composerPath,
286
- path.join(outputFolder, bundleName + '.txt.map'),
287
- path.join(outputFolder, bundleName + '.map'),
298
+ _nodepath.default.join(outputFolder, `${bundleName}.txt.map`),
299
+ _nodepath.default.join(outputFolder, `${bundleName}.map`),
288
300
  '-o',
289
301
  sourcemapOutput
290
302
  ], {
291
303
  stdio: 'ignore'
292
304
  });
293
305
  }
294
- _fsextra.removeSync(path.join(outputFolder, bundleName + '.txt.map'));
306
+ _fsextra.removeSync(_nodepath.default.join(outputFolder, `${bundleName}.txt.map`));
295
307
  }
296
308
  async function pack(dir, output) {
297
309
  console.log('Packing');
298
- _fsextra.ensureDirSync(path.dirname(output));
310
+ _fsextra.ensureDirSync(_nodepath.default.dirname(output));
299
311
  await new Promise((resolve, reject)=>{
300
312
  const zipfile = new _yazl.ZipFile();
301
313
  function addDirectory(root, rel) {
@@ -307,25 +319,25 @@ async function pack(dir, output) {
307
319
  if (name === '.' || name === '..' || name === 'index.bundlejs.map') {
308
320
  continue;
309
321
  }
310
- const fullPath = path.join(root, name);
322
+ const fullPath = _nodepath.default.join(root, name);
311
323
  const stat = _fsextra.statSync(fullPath);
312
324
  if (stat.isFile()) {
313
325
  //console.log('adding: ' + rel+name);
314
326
  zipfile.addFile(fullPath, rel + name);
315
327
  } else if (stat.isDirectory()) {
316
328
  //console.log('adding: ' + rel+name+'/');
317
- addDirectory(fullPath, rel + name + '/');
329
+ addDirectory(fullPath, `${rel}${name}/`);
318
330
  }
319
331
  }
320
332
  }
321
333
  addDirectory(dir, '');
322
334
  zipfile.outputStream.on('error', (err)=>reject(err));
323
- zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', function() {
335
+ zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
324
336
  resolve();
325
337
  });
326
338
  zipfile.end();
327
339
  });
328
- console.log('ppk热更包已生成并保存到: ' + output);
340
+ console.log(`ppk热更包已生成并保存到: ${output}`);
329
341
  }
330
342
  function readEntire(entry, zipFile) {
331
343
  const buffers = [];
@@ -348,10 +360,10 @@ function readEntire(entry, zipFile) {
348
360
  }
349
361
  function basename(fn) {
350
362
  const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
351
- return m && m[1];
363
+ return m == null ? void 0 : m[1];
352
364
  }
353
365
  async function diffFromPPK(origin, next, output) {
354
- _fsextra.ensureDirSync(path.dirname(output));
366
+ _fsextra.ensureDirSync(_nodepath.default.dirname(output));
355
367
  const originEntries = {};
356
368
  const originMap = {};
357
369
  let originSource;
@@ -367,7 +379,7 @@ async function diffFromPPK(origin, next, output) {
367
379
  }
368
380
  });
369
381
  if (!originSource) {
370
- throw new Error(`Bundle file not found! Please use default bundle file name and path.`);
382
+ throw new Error('Bundle file not found! Please use default bundle file name and path.');
371
383
  }
372
384
  const copies = {};
373
385
  const zipfile = new _yazl.ZipFile();
@@ -375,7 +387,7 @@ async function diffFromPPK(origin, next, output) {
375
387
  zipfile.outputStream.on('error', (err)=>{
376
388
  throw err;
377
389
  });
378
- zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', function() {
390
+ zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
379
391
  resolve();
380
392
  });
381
393
  });
@@ -432,7 +444,7 @@ async function diffFromPPK(origin, next, output) {
432
444
  // New file.
433
445
  addEntry(basename(entry.fileName));
434
446
  return new Promise((resolve, reject)=>{
435
- nextZipfile.openReadStream(entry, function(err, readStream) {
447
+ nextZipfile.openReadStream(entry, (err, readStream)=>{
436
448
  if (err) {
437
449
  return reject(err);
438
450
  }
@@ -446,9 +458,9 @@ async function diffFromPPK(origin, next, output) {
446
458
  }
447
459
  });
448
460
  const deletes = {};
449
- for(let k in originEntries){
461
+ for(const k in originEntries){
450
462
  if (!newEntries[k]) {
451
- console.log('Delete ' + k);
463
+ console.log(`Delete ${k}`);
452
464
  deletes[k] = 1;
453
465
  }
454
466
  }
@@ -461,7 +473,7 @@ async function diffFromPPK(origin, next, output) {
461
473
  await writePromise;
462
474
  }
463
475
  async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
464
- _fsextra.ensureDirSync(path.dirname(output));
476
+ _fsextra.ensureDirSync(_nodepath.default.dirname(output));
465
477
  const originEntries = {};
466
478
  const originMap = {};
467
479
  let originSource;
@@ -482,7 +494,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
482
494
  }
483
495
  });
484
496
  if (!originSource) {
485
- throw new Error(`Bundle file not found! Please use default bundle file name and path.`);
497
+ throw new Error('Bundle file not found! Please use default bundle file name and path.');
486
498
  }
487
499
  const copies = {};
488
500
  const zipfile = new _yazl.ZipFile();
@@ -490,7 +502,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
490
502
  zipfile.outputStream.on('error', (err)=>{
491
503
  throw err;
492
504
  });
493
- zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', function() {
505
+ zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
494
506
  resolve();
495
507
  });
496
508
  });
@@ -524,7 +536,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
524
536
  return;
525
537
  }
526
538
  return new Promise((resolve, reject)=>{
527
- nextZipfile.openReadStream(entry, function(err, readStream) {
539
+ nextZipfile.openReadStream(entry, (err, readStream)=>{
528
540
  if (err) {
529
541
  return reject(err);
530
542
  }
@@ -557,9 +569,9 @@ async function enumZipEntries(zipFn, callback, nestedPath = '') {
557
569
  const fullPath = nestedPath + entry.fileName;
558
570
  try {
559
571
  if (!entry.fileName.endsWith('/') && entry.fileName.toLowerCase().endsWith('.hap')) {
560
- const tempDir = path.join(_os.default.tmpdir(), 'nested_zip_' + Date.now());
572
+ const tempDir = _nodepath.default.join(_nodeos.default.tmpdir(), `nested_zip_${Date.now()}`);
561
573
  await _fsextra.ensureDir(tempDir);
562
- const tempZipPath = path.join(tempDir, 'temp.zip');
574
+ const tempZipPath = _nodepath.default.join(tempDir, 'temp.zip');
563
575
  await new Promise((res, rej)=>{
564
576
  zipfile.openReadStream(entry, async (err, readStream)=>{
565
577
  if (err) return rej(err);
@@ -569,7 +581,7 @@ async function enumZipEntries(zipFn, callback, nestedPath = '') {
569
581
  writeStream.on('error', rej);
570
582
  });
571
583
  });
572
- await enumZipEntries(tempZipPath, callback, fullPath + '/');
584
+ await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
573
585
  await _fsextra.remove(tempDir);
574
586
  }
575
587
  const result = callback(entry, zipfile, fullPath);
@@ -610,25 +622,25 @@ function diffArgsCheck(args, options, diffFn) {
610
622
  return {
611
623
  origin,
612
624
  next,
613
- realOutput: output.replace(/\$\{time\}/g, '' + Date.now())
625
+ realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`)
614
626
  };
615
627
  }
616
628
  const commands = {
617
629
  bundle: async function({ options }) {
618
630
  const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
619
- let { bundleName, entryFile, intermediaDir, output, dev, sourcemap } = (0, _utils.translateOptions)({
631
+ const { bundleName, entryFile, intermediaDir, output, dev, sourcemap } = (0, _utils.translateOptions)({
620
632
  ...options,
621
633
  platform
622
634
  });
623
- const sourcemapOutput = path.join(intermediaDir, bundleName + '.map');
624
- const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
635
+ const sourcemapOutput = _nodepath.default.join(intermediaDir, `${bundleName}.map`);
636
+ const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
625
637
  if (!platform) {
626
638
  throw new Error('Platform must be specified.');
627
639
  }
628
640
  const { version, major, minor } = (0, _utils.getRNVersion)();
629
- console.log('Bundling with react-native: ', version);
641
+ console.log(`Bundling with react-native: ${version}`);
630
642
  await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform, sourcemap ? sourcemapOutput : '');
631
- await pack(path.resolve(intermediaDir), realOutput);
643
+ await pack(_nodepath.default.resolve(intermediaDir), realOutput);
632
644
  const v = await (0, _utils.question)('是否现在上传此热更包?(Y/N)');
633
645
  if (v.toLowerCase() === 'y') {
634
646
  await this.publish({
@@ -670,7 +682,7 @@ const commands = {
670
682
  const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromIpa');
671
683
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
672
684
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
673
- return m && m[1];
685
+ return m == null ? void 0 : m[1];
674
686
  });
675
687
  console.log(`${realOutput} generated.`);
676
688
  },
@@ -678,7 +690,7 @@ const commands = {
678
690
  const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromIpa');
679
691
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
680
692
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
681
- return m && m[1];
693
+ return m == null ? void 0 : m[1];
682
694
  });
683
695
  console.log(`${realOutput} generated.`);
684
696
  }
package/lib/package.js CHANGED
@@ -68,14 +68,14 @@ async function choosePackage(appId) {
68
68
  const list = await listPackage(appId);
69
69
  while(true){
70
70
  const id = await (0, _utils.question)('输入原生包 id:');
71
- const app = list.find((v)=>v.id === (id | 0));
71
+ const app = list.find((v)=>v.id === Number(id));
72
72
  if (app) {
73
73
  return app;
74
74
  }
75
75
  }
76
76
  }
77
77
  const commands = {
78
- uploadIpa: async function({ args }) {
78
+ uploadIpa: async ({ args })=>{
79
79
  const fn = args[0];
80
80
  if (!fn || !fn.endsWith('.ipa')) {
81
81
  throw new Error('使用方法: pushy uploadIpa ipa后缀文件');
@@ -97,7 +97,7 @@ const commands = {
97
97
  (0, _utils.saveToLocal)(fn, `${appId}/package/${id}.ipa`);
98
98
  console.log(`已成功上传ipa原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`);
99
99
  },
100
- uploadApk: async function({ args }) {
100
+ uploadApk: async ({ args })=>{
101
101
  const fn = args[0];
102
102
  if (!fn || !fn.endsWith('.apk')) {
103
103
  throw new Error('使用方法: pushy uploadApk apk后缀文件');
@@ -119,7 +119,7 @@ const commands = {
119
119
  (0, _utils.saveToLocal)(fn, `${appId}/package/${id}.apk`);
120
120
  console.log(`已成功上传apk原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`);
121
121
  },
122
- uploadApp: async function({ args }) {
122
+ uploadApp: async ({ args })=>{
123
123
  const fn = args[0];
124
124
  if (!fn || !fn.endsWith('.app')) {
125
125
  throw new Error('使用方法: pushy uploadApp app后缀文件');
@@ -141,28 +141,28 @@ const commands = {
141
141
  (0, _utils.saveToLocal)(fn, `${appId}/package/${id}.app`);
142
142
  console.log(`已成功上传app原生包(id: ${id}, version: ${versionName}, buildTime: ${buildTime})`);
143
143
  },
144
- parseApp: async function({ args }) {
144
+ parseApp: async ({ args })=>{
145
145
  const fn = args[0];
146
146
  if (!fn || !fn.endsWith('.app')) {
147
147
  throw new Error('使用方法: pushy parseApp app后缀文件');
148
148
  }
149
149
  console.log(await (0, _utils.getAppInfo)(fn));
150
150
  },
151
- parseIpa: async function({ args }) {
151
+ parseIpa: async ({ args })=>{
152
152
  const fn = args[0];
153
153
  if (!fn || !fn.endsWith('.ipa')) {
154
154
  throw new Error('使用方法: pushy parseIpa ipa后缀文件');
155
155
  }
156
156
  console.log(await (0, _utils.getIpaInfo)(fn));
157
157
  },
158
- parseApk: async function({ args }) {
158
+ parseApk: async ({ args })=>{
159
159
  const fn = args[0];
160
160
  if (!fn || !fn.endsWith('.apk')) {
161
161
  throw new Error('使用方法: pushy parseApk apk后缀文件');
162
162
  }
163
163
  console.log(await (0, _utils.getApkInfo)(fn));
164
164
  },
165
- packages: async function({ options }) {
165
+ packages: async ({ options })=>{
166
166
  const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
167
167
  const { appId } = await (0, _app.getSelectedApp)(platform);
168
168
  await listPackage(appId);
@@ -63,12 +63,10 @@ async function question(query, password) {
63
63
  }
64
64
  function translateOptions(options) {
65
65
  const ret = {};
66
- for(let key in options){
66
+ for(const key in options){
67
67
  const v = options[key];
68
68
  if (typeof v === 'string') {
69
- ret[key] = v.replace(/\$\{(\w+)\}/g, function(v, n) {
70
- return options[n] || process.env[n] || v;
71
- });
69
+ ret[key] = v.replace(/\$\{(\w+)\}/g, (v, n)=>options[n] || process.env[n] || v);
72
70
  } else {
73
71
  ret[key] = v;
74
72
  }
@@ -215,7 +213,7 @@ async function printVersionCommand() {
215
213
  console.warn(`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
216
214
  如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
217
215
  } else if ((0, _satisfies.default)(pushyVersion, '10.0.0 - 10.17.0')) {
218
- console.warn(`当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10`);
216
+ console.warn('当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10');
219
217
  }
220
218
  }
221
219
  }
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.38.2",
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
@@ -6,12 +6,14 @@ import { open as openZipFile } from 'yauzl';
6
6
  import { question, printVersionCommand } 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,12 @@ 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 bundleCommand = usingExpo
90
+ ? 'export:embed'
91
+ : platform === 'harmony'
92
+ ? 'bundle-harmony'
93
+ : 'bundle';
94
+ if (platform === 'harmony') {
78
95
  Array.prototype.push.apply(reactNativeBundleArgs, [
79
96
  cliPath,
80
97
  bundleCommand,
@@ -91,8 +108,7 @@ async function runReactNativeBundleCommand(
91
108
  if (config) {
92
109
  reactNativeBundleArgs.push('--config', config);
93
110
  }
94
- }
95
- else{
111
+ } else {
96
112
  Array.prototype.push.apply(reactNativeBundleArgs, [
97
113
  cliPath,
98
114
  bundleCommand,
@@ -108,16 +124,16 @@ async function runReactNativeBundleCommand(
108
124
  platform,
109
125
  '--reset-cache',
110
126
  ]);
111
-
127
+
112
128
  if (sourcemapOutput) {
113
129
  reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
114
130
  }
115
-
131
+
116
132
  if (config) {
117
133
  reactNativeBundleArgs.push('--config', config);
118
134
  }
119
135
  }
120
-
136
+
121
137
  const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
122
138
  console.log(
123
139
  `Running bundle command: node ${reactNativeBundleArgs.join(' ')}`,
@@ -147,7 +163,7 @@ async function runReactNativeBundleCommand(
147
163
  properties.parse(
148
164
  './android/gradle.properties',
149
165
  { path: true },
150
- function (error, props) {
166
+ (error, props) => {
151
167
  if (error) {
152
168
  console.error(error);
153
169
  resolve(null);
@@ -166,7 +182,7 @@ async function runReactNativeBundleCommand(
166
182
  fs.existsSync('ios/Pods/hermes-engine')
167
183
  ) {
168
184
  hermesEnabled = true;
169
- }else if (platform === 'harmony') {
185
+ } else if (platform === 'harmony') {
170
186
  await copyHarmonyBundle(outputFolder);
171
187
  }
172
188
  if (hermesEnabled) {
@@ -193,7 +209,7 @@ async function copyHarmonyBundle(outputFolder) {
193
209
  }
194
210
  await fs.remove(path.join(harmonyRawPath, 'update.json'));
195
211
  await fs.copy('update.json', path.join(harmonyRawPath, 'update.json'));
196
-
212
+
197
213
  await fs.ensureDir(outputFolder);
198
214
  await fs.copy(harmonyRawPath, outputFolder);
199
215
  } catch (error) {
@@ -238,7 +254,7 @@ async function compileHermesByteCode(
238
254
  outputFolder,
239
255
  sourcemapOutput,
240
256
  ) {
241
- console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
257
+ console.log('Hermes enabled, now compiling to hermes bytecode:\n');
242
258
  // >= rn 0.69
243
259
  const rnDir = path.dirname(
244
260
  require.resolve('react-native', {
@@ -264,13 +280,11 @@ async function compileHermesByteCode(
264
280
  if (sourcemapOutput) {
265
281
  fs.copyFileSync(
266
282
  sourcemapOutput,
267
- path.join(outputFolder, bundleName + '.txt.map'),
283
+ path.join(outputFolder, `${bundleName}.txt.map`),
268
284
  );
269
285
  args.push('-output-source-map');
270
286
  }
271
- console.log(
272
- 'Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n',
273
- );
287
+ console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
274
288
  spawnSync(hermesCommand, args, {
275
289
  stdio: 'ignore',
276
290
  });
@@ -280,13 +294,13 @@ async function compileHermesByteCode(
280
294
  if (!fs.existsSync(composerPath)) {
281
295
  return;
282
296
  }
283
- console.log(`Composing source map`);
297
+ console.log('Composing source map');
284
298
  spawnSync(
285
299
  'node',
286
300
  [
287
301
  composerPath,
288
- path.join(outputFolder, bundleName + '.txt.map'),
289
- path.join(outputFolder, bundleName + '.map'),
302
+ path.join(outputFolder, `${bundleName}.txt.map`),
303
+ path.join(outputFolder, `${bundleName}.map`),
290
304
  '-o',
291
305
  sourcemapOutput,
292
306
  ],
@@ -295,7 +309,7 @@ async function compileHermesByteCode(
295
309
  },
296
310
  );
297
311
  }
298
- fs.removeSync(path.join(outputFolder, bundleName + '.txt.map'));
312
+ fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
299
313
  }
300
314
 
301
315
  async function pack(dir, output) {
@@ -320,7 +334,7 @@ async function pack(dir, output) {
320
334
  zipfile.addFile(fullPath, rel + name);
321
335
  } else if (stat.isDirectory()) {
322
336
  //console.log('adding: ' + rel+name+'/');
323
- addDirectory(fullPath, rel + name + '/');
337
+ addDirectory(fullPath, `${rel}${name}/`);
324
338
  }
325
339
  }
326
340
  }
@@ -328,14 +342,12 @@ async function pack(dir, output) {
328
342
  addDirectory(dir, '');
329
343
 
330
344
  zipfile.outputStream.on('error', (err) => reject(err));
331
- zipfile.outputStream
332
- .pipe(fs.createWriteStream(output))
333
- .on('close', function () {
334
- resolve();
335
- });
345
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
346
+ resolve();
347
+ });
336
348
  zipfile.end();
337
349
  });
338
- console.log('ppk热更包已生成并保存到: ' + output);
350
+ console.log(`ppk热更包已生成并保存到: ${output}`);
339
351
  }
340
352
 
341
353
  export function readEntire(entry, zipFile) {
@@ -360,7 +372,7 @@ export function readEntire(entry, zipFile) {
360
372
 
361
373
  function basename(fn) {
362
374
  const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
363
- return m && m[1];
375
+ return m?.[1];
364
376
  }
365
377
 
366
378
  async function diffFromPPK(origin, next, output) {
@@ -377,7 +389,10 @@ async function diffFromPPK(origin, next, output) {
377
389
  // isFile
378
390
  originMap[entry.crc32] = entry.fileName;
379
391
 
380
- if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
392
+ if (
393
+ entry.fileName === 'index.bundlejs' ||
394
+ entry.fileName === 'bundle.harmony.js'
395
+ ) {
381
396
  // This is source.
382
397
  return readEntire(entry, zipFile).then((v) => (originSource = v));
383
398
  }
@@ -386,7 +401,7 @@ async function diffFromPPK(origin, next, output) {
386
401
 
387
402
  if (!originSource) {
388
403
  throw new Error(
389
- `Bundle file not found! Please use default bundle file name and path.`,
404
+ 'Bundle file not found! Please use default bundle file name and path.',
390
405
  );
391
406
  }
392
407
 
@@ -398,11 +413,9 @@ async function diffFromPPK(origin, next, output) {
398
413
  zipfile.outputStream.on('error', (err) => {
399
414
  throw err;
400
415
  });
401
- zipfile.outputStream
402
- .pipe(fs.createWriteStream(output))
403
- .on('close', function () {
404
- resolve();
405
- });
416
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
417
+ resolve();
418
+ });
406
419
  });
407
420
 
408
421
  const addedEntry = {};
@@ -439,7 +452,7 @@ async function diffFromPPK(origin, next, output) {
439
452
  );
440
453
  //console.log('End diff');
441
454
  });
442
- }else if (entry.fileName === 'bundle.harmony.js') {
455
+ } else if (entry.fileName === 'bundle.harmony.js') {
443
456
  //console.log('Found bundle');
444
457
  return readEntire(entry, nextZipfile).then((newSource) => {
445
458
  //console.log('Begin diff');
@@ -471,7 +484,7 @@ async function diffFromPPK(origin, next, output) {
471
484
  addEntry(basename(entry.fileName));
472
485
 
473
486
  return new Promise((resolve, reject) => {
474
- nextZipfile.openReadStream(entry, function (err, readStream) {
487
+ nextZipfile.openReadStream(entry, (err, readStream) => {
475
488
  if (err) {
476
489
  return reject(err);
477
490
  }
@@ -487,9 +500,9 @@ async function diffFromPPK(origin, next, output) {
487
500
 
488
501
  const deletes = {};
489
502
 
490
- for (let k in originEntries) {
503
+ for (const k in originEntries) {
491
504
  if (!newEntries[k]) {
492
- console.log('Delete ' + k);
505
+ console.log(`Delete ${k}`);
493
506
  deletes[k] = 1;
494
507
  }
495
508
  }
@@ -538,7 +551,7 @@ async function diffFromPackage(
538
551
 
539
552
  if (!originSource) {
540
553
  throw new Error(
541
- `Bundle file not found! Please use default bundle file name and path.`,
554
+ 'Bundle file not found! Please use default bundle file name and path.',
542
555
  );
543
556
  }
544
557
 
@@ -550,11 +563,9 @@ async function diffFromPackage(
550
563
  zipfile.outputStream.on('error', (err) => {
551
564
  throw err;
552
565
  });
553
- zipfile.outputStream
554
- .pipe(fs.createWriteStream(output))
555
- .on('close', function () {
556
- resolve();
557
- });
566
+ zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
567
+ resolve();
568
+ });
558
569
  });
559
570
 
560
571
  await enumZipEntries(next, (entry, nextZipfile) => {
@@ -581,7 +592,7 @@ async function diffFromPackage(
581
592
  );
582
593
  //console.log('End diff');
583
594
  });
584
- }else {
595
+ } else {
585
596
  // If same file.
586
597
  if (originEntries[entry.fileName] === entry.crc32) {
587
598
  copies[entry.fileName] = '';
@@ -594,7 +605,7 @@ async function diffFromPackage(
594
605
  }
595
606
 
596
607
  return new Promise((resolve, reject) => {
597
- nextZipfile.openReadStream(entry, function (err, readStream) {
608
+ nextZipfile.openReadStream(entry, (err, readStream) => {
598
609
  if (err) {
599
610
  return reject(err);
600
611
  }
@@ -630,7 +641,7 @@ export async function enumZipEntries(zipFn, callback, nestedPath = '') {
630
641
  !entry.fileName.endsWith('/') &&
631
642
  entry.fileName.toLowerCase().endsWith('.hap')
632
643
  ) {
633
- const tempDir = path.join(os.tmpdir(), 'nested_zip_' + Date.now());
644
+ const tempDir = path.join(os.tmpdir(), `nested_zip_${Date.now()}`);
634
645
  await fs.ensureDir(tempDir);
635
646
  const tempZipPath = path.join(tempDir, 'temp.zip');
636
647
 
@@ -644,7 +655,7 @@ export async function enumZipEntries(zipFn, callback, nestedPath = '') {
644
655
  });
645
656
  });
646
657
 
647
- await enumZipEntries(tempZipPath, callback, fullPath + '/');
658
+ await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
648
659
 
649
660
  await fs.remove(tempDir);
650
661
  }
@@ -697,7 +708,7 @@ function diffArgsCheck(args, options, diffFn) {
697
708
  return {
698
709
  origin,
699
710
  next,
700
- realOutput: output.replace(/\$\{time\}/g, '' + Date.now()),
711
+ realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`),
701
712
  };
702
713
  }
703
714
 
@@ -707,15 +718,15 @@ export const commands = {
707
718
  options.platform || (await question('平台(ios/android/harmony):')),
708
719
  );
709
720
 
710
- let { bundleName, entryFile, intermediaDir, output, dev, sourcemap } =
721
+ const { bundleName, entryFile, intermediaDir, output, dev, sourcemap } =
711
722
  translateOptions({
712
723
  ...options,
713
724
  platform,
714
725
  });
715
726
 
716
- const sourcemapOutput = path.join(intermediaDir, bundleName + '.map');
727
+ const sourcemapOutput = path.join(intermediaDir, `${bundleName}.map`);
717
728
 
718
- const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
729
+ const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
719
730
 
720
731
  if (!platform) {
721
732
  throw new Error('Platform must be specified.');
@@ -723,7 +734,7 @@ export const commands = {
723
734
 
724
735
  const { version, major, minor } = getRNVersion();
725
736
 
726
- console.log('Bundling with react-native: ', version);
737
+ console.log(`Bundling with react-native: ${version}`);
727
738
 
728
739
  await runReactNativeBundleCommand(
729
740
  bundleName,
@@ -817,7 +828,7 @@ export const commands = {
817
828
 
818
829
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
819
830
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
820
- return m && m[1];
831
+ return m?.[1];
821
832
  });
822
833
 
823
834
  console.log(`${realOutput} generated.`);
@@ -832,7 +843,7 @@ export const commands = {
832
843
 
833
844
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
834
845
  const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
835
- return m && m[1];
846
+ return m?.[1];
836
847
  });
837
848
 
838
849
  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';
@@ -2,12 +2,12 @@ import { question } from './utils';
2
2
  import { post, get, replaceSession, saveSession, closeSession } from './api';
3
3
  import crypto from 'node:crypto';
4
4
 
5
- function md5(str) {
5
+ function md5(str: string) {
6
6
  return crypto.createHash('md5').update(str).digest('hex');
7
7
  }
8
8
 
9
9
  export const commands = {
10
- login: async ({ args }) => {
10
+ login: async ({ args }: { args: string[] }) => {
11
11
  const email = args[0] || (await question('email:'));
12
12
  const pwd = args[1] || (await question('password:', true));
13
13
  const { token, info } = await post('/user/login', {
@@ -22,12 +22,13 @@ export async function question(query, password) {
22
22
 
23
23
  export function translateOptions(options) {
24
24
  const ret = {};
25
- for (let key in options) {
25
+ for (const key in options) {
26
26
  const v = options[key];
27
27
  if (typeof v === 'string') {
28
- ret[key] = v.replace(/\$\{(\w+)\}/g, function (v, n) {
29
- return options[n] || process.env[n] || v;
30
- });
28
+ ret[key] = v.replace(
29
+ /\$\{(\w+)\}/g,
30
+ (v, n) => options[n] || process.env[n] || v,
31
+ );
31
32
  } else {
32
33
  ret[key] = v;
33
34
  }
@@ -124,7 +125,7 @@ export async function getAppInfo(fn) {
124
125
  return { versionName, buildTime, ...appCredential };
125
126
  }
126
127
 
127
- export async function getIpaInfo(fn) {
128
+ export async function getIpaInfo(fn: string) {
128
129
  const appInfoParser = new AppInfoParser(fn);
129
130
  const bundleFile = await appInfoParser.parser.getEntry(
130
131
  /payload\/.+?\.app\/main.jsbundle/,
@@ -217,7 +218,7 @@ export async function printVersionCommand() {
217
218
  );
218
219
  } else if (semverSatisfies(pushyVersion, '10.0.0 - 10.17.0')) {
219
220
  console.warn(
220
- `当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10`,
221
+ '当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
221
222
  );
222
223
  }
223
224
  }