react-native-update-cli 1.34.2 → 1.36.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/cli.json CHANGED
@@ -3,11 +3,9 @@
3
3
  "defaultCommand": "help",
4
4
  "commands": {
5
5
  "help": {},
6
-
7
6
  "login": {},
8
7
  "logout": {},
9
8
  "me": {},
10
-
11
9
  "createApp": {
12
10
  "options": {
13
11
  "name": {
@@ -33,7 +31,6 @@
33
31
  }
34
32
  }
35
33
  },
36
-
37
34
  "uploadIpa": {},
38
35
  "uploadApk": {},
39
36
  "parseIpa": {},
@@ -45,7 +42,6 @@
45
42
  }
46
43
  }
47
44
  },
48
-
49
45
  "publish": {
50
46
  "options": {
51
47
  "platform": {
@@ -69,7 +65,6 @@
69
65
  }
70
66
  }
71
67
  },
72
-
73
68
  "update": {
74
69
  "options": {
75
70
  "platform": {
@@ -95,7 +90,6 @@
95
90
  }
96
91
  }
97
92
  },
98
-
99
93
  "updateVersionInfo": {
100
94
  "options": {
101
95
  "platform": {
@@ -118,7 +112,6 @@
118
112
  }
119
113
  }
120
114
  },
121
-
122
115
  "build": {
123
116
  "description": "Bundle javascript and copy assets."
124
117
  },
@@ -201,6 +194,24 @@
201
194
  }
202
195
  }
203
196
  },
197
+ "hdiffFromPPK": {
198
+ "description": "Create hdiff patch from a Prepare package(.ppk)",
199
+ "options": {
200
+ "output": {
201
+ "default": ".pushy/output/hdiff-${time}.ppk-patch",
202
+ "hasValue": true
203
+ }
204
+ }
205
+ },
206
+ "hdiffFromApp": {
207
+ "description": "Create hdiff patch from a Harmony package(.app)",
208
+ "options": {
209
+ "output": {
210
+ "default": ".pushy/output/hdiff-${time}.app-patch",
211
+ "hasValue": true
212
+ }
213
+ }
214
+ },
204
215
  "hdiffFromIpa": {
205
216
  "description": "Create hdiff patch from a iOS package(.ipa)",
206
217
  "options": {
@@ -216,4 +227,4 @@
216
227
  "default": false
217
228
  }
218
229
  }
219
- }
230
+ }
package/lib/bundle.js CHANGED
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "commands", {
8
8
  return commands;
9
9
  }
10
10
  });
11
- const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
12
11
  const _utils = require("./utils");
13
12
  const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
14
13
  const _yazl = require("yazl");
@@ -64,6 +63,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
64
63
  }
65
64
  const g2js = require('gradle-to-js/lib/parser');
66
65
  const properties = require('properties');
66
+ const path = require('path');
67
67
  let bsdiff, hdiff, diff;
68
68
  try {
69
69
  bsdiff = require('node-bsdiff').diff;
@@ -86,58 +86,69 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
86
86
  }
87
87
  _fsextra.emptyDirSync(outputFolder);
88
88
  let cliPath;
89
- try {
90
- // rn >= 0.75
91
- cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
92
- paths: [
93
- process.cwd()
94
- ]
95
- });
96
- } catch (e) {
97
- // rn < 0.75
98
- cliPath = require.resolve('react-native/local-cli/cli.js', {
99
- paths: [
100
- process.cwd()
101
- ]
102
- });
103
- }
104
89
  let usingExpo = false;
105
90
  try {
106
- require.resolve('expo-router', {
107
- paths: [
108
- process.cwd()
109
- ]
110
- });
111
- console.log(`expo-router detected, will use @expo/cli to bundle.\n`);
112
- // if using expo-router, use expo-cli
113
91
  cliPath = require.resolve('@expo/cli', {
114
92
  paths: [
115
93
  process.cwd()
116
94
  ]
117
95
  });
118
96
  usingExpo = true;
119
- } catch (e) {}
120
- const bundleCommand = usingExpo ? 'export:embed' : 'bundle';
121
- Array.prototype.push.apply(reactNativeBundleArgs, [
122
- cliPath,
123
- bundleCommand,
124
- '--assets-dest',
125
- outputFolder,
126
- '--bundle-output',
127
- _nodepath.default.join(outputFolder, bundleName),
128
- '--dev',
129
- development,
130
- '--entry-file',
131
- entryFile,
132
- '--platform',
133
- platform,
134
- '--reset-cache'
135
- ]);
136
- if (sourcemapOutput) {
137
- reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
97
+ } catch (e) {
98
+ try {
99
+ // rn >= 0.75
100
+ cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
101
+ paths: [
102
+ process.cwd()
103
+ ]
104
+ });
105
+ } catch (e) {
106
+ // rn < 0.75
107
+ cliPath = require.resolve('react-native/local-cli/cli.js', {
108
+ paths: [
109
+ process.cwd()
110
+ ]
111
+ });
112
+ }
138
113
  }
139
- if (config) {
140
- reactNativeBundleArgs.push('--config', config);
114
+ const bundleCommand = usingExpo ? 'export:embed' : platform === 'harmony' ? 'bundle-harmony' : 'bundle';
115
+ if (platform == 'harmony') {
116
+ Array.prototype.push.apply(reactNativeBundleArgs, [
117
+ cliPath,
118
+ bundleCommand,
119
+ '--dev',
120
+ development,
121
+ '--entry-file',
122
+ entryFile
123
+ ]);
124
+ if (sourcemapOutput) {
125
+ reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
126
+ }
127
+ if (config) {
128
+ reactNativeBundleArgs.push('--config', config);
129
+ }
130
+ } else {
131
+ Array.prototype.push.apply(reactNativeBundleArgs, [
132
+ cliPath,
133
+ bundleCommand,
134
+ '--assets-dest',
135
+ outputFolder,
136
+ '--bundle-output',
137
+ path.join(outputFolder, bundleName),
138
+ '--dev',
139
+ development,
140
+ '--entry-file',
141
+ entryFile,
142
+ '--platform',
143
+ platform,
144
+ '--reset-cache'
145
+ ]);
146
+ if (sourcemapOutput) {
147
+ reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
148
+ }
149
+ if (config) {
150
+ reactNativeBundleArgs.push('--config', config);
151
+ }
141
152
  }
142
153
  const reactNativeBundleProcess = (0, _nodechild_process.spawn)('node', reactNativeBundleArgs);
143
154
  console.log(`Running bundle command: node ${reactNativeBundleArgs.join(' ')}`);
@@ -169,6 +180,8 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
169
180
  if (typeof hermesEnabled !== 'boolean') hermesEnabled = gradleConfig.enableHermes;
170
181
  } else if (platform === 'ios' && _fsextra.existsSync('ios/Pods/hermes-engine')) {
171
182
  hermesEnabled = true;
183
+ } else if (platform === 'harmony') {
184
+ await copyHarmonyBundle(outputFolder);
172
185
  }
173
186
  if (hermesEnabled) {
174
187
  await compileHermesByteCode(bundleName, outputFolder, sourcemapOutput);
@@ -178,6 +191,16 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
178
191
  });
179
192
  });
180
193
  }
194
+ async function copyHarmonyBundle(outputFolder) {
195
+ const harmonyRawPath = 'harmony/entry/src/main/resources/rawfile';
196
+ try {
197
+ await _fsextra.ensureDir(outputFolder);
198
+ await _fsextra.copy(harmonyRawPath, outputFolder);
199
+ console.log(`Successfully copied from ${harmonyRawPath} to ${outputFolder}`);
200
+ } catch (error) {
201
+ console.error('Error in copyHarmonyBundle:', error);
202
+ }
203
+ }
181
204
  function getHermesOSBin() {
182
205
  if (_os.default.platform() === 'win32') return 'win64-bin';
183
206
  if (_os.default.platform() === 'darwin') return 'osx-bin';
@@ -207,12 +230,12 @@ async function checkGradleConfig() {
207
230
  async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput) {
208
231
  console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
209
232
  // >= rn 0.69
210
- const rnDir = _nodepath.default.dirname(require.resolve('react-native', {
233
+ const rnDir = path.dirname(require.resolve('react-native', {
211
234
  paths: [
212
235
  process.cwd()
213
236
  ]
214
237
  }));
215
- let hermesPath = _nodepath.default.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
238
+ let hermesPath = path.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
216
239
  // < rn 0.69
217
240
  if (!_fsextra.existsSync(hermesPath)) {
218
241
  hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
@@ -221,12 +244,12 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
221
244
  const args = [
222
245
  '-emit-binary',
223
246
  '-out',
224
- _nodepath.default.join(outputFolder, bundleName),
225
- _nodepath.default.join(outputFolder, bundleName),
247
+ path.join(outputFolder, bundleName),
248
+ path.join(outputFolder, bundleName),
226
249
  '-O'
227
250
  ];
228
251
  if (sourcemapOutput) {
229
- _fsextra.copyFileSync(sourcemapOutput, _nodepath.default.join(outputFolder, bundleName + '.txt.map'));
252
+ _fsextra.copyFileSync(sourcemapOutput, path.join(outputFolder, bundleName + '.txt.map'));
230
253
  args.push('-output-source-map');
231
254
  }
232
255
  console.log('Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n');
@@ -241,19 +264,19 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
241
264
  console.log(`Composing source map`);
242
265
  (0, _nodechild_process.spawnSync)('node', [
243
266
  composerPath,
244
- _nodepath.default.join(outputFolder, bundleName + '.txt.map'),
245
- _nodepath.default.join(outputFolder, bundleName + '.map'),
267
+ path.join(outputFolder, bundleName + '.txt.map'),
268
+ path.join(outputFolder, bundleName + '.map'),
246
269
  '-o',
247
270
  sourcemapOutput
248
271
  ], {
249
272
  stdio: 'ignore'
250
273
  });
251
274
  }
252
- _fsextra.removeSync(_nodepath.default.join(outputFolder, bundleName + '.txt.map'));
275
+ _fsextra.removeSync(path.join(outputFolder, bundleName + '.txt.map'));
253
276
  }
254
277
  async function pack(dir, output) {
255
278
  console.log('Packing');
256
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
279
+ _fsextra.ensureDirSync(path.dirname(output));
257
280
  await new Promise((resolve, reject)=>{
258
281
  const zipfile = new _yazl.ZipFile();
259
282
  function addDirectory(root, rel) {
@@ -265,7 +288,7 @@ async function pack(dir, output) {
265
288
  if (name === '.' || name === '..' || name === 'index.bundlejs.map') {
266
289
  continue;
267
290
  }
268
- const fullPath = _nodepath.default.join(root, name);
291
+ const fullPath = path.join(root, name);
269
292
  const stat = _fsextra.statSync(fullPath);
270
293
  if (stat.isFile()) {
271
294
  //console.log('adding: ' + rel+name);
@@ -309,7 +332,7 @@ function basename(fn) {
309
332
  return m && m[1];
310
333
  }
311
334
  async function diffFromPPK(origin, next, output) {
312
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
335
+ _fsextra.ensureDirSync(path.dirname(output));
313
336
  const originEntries = {};
314
337
  const originMap = {};
315
338
  let originSource;
@@ -318,7 +341,7 @@ async function diffFromPPK(origin, next, output) {
318
341
  if (!/\/$/.test(entry.fileName)) {
319
342
  // isFile
320
343
  originMap[entry.crc32] = entry.fileName;
321
- if (entry.fileName === 'index.bundlejs') {
344
+ if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
322
345
  // This is source.
323
346
  return readEntire(entry, zipFile).then((v)=>originSource = v);
324
347
  }
@@ -364,6 +387,13 @@ async function diffFromPPK(origin, next, output) {
364
387
  zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch');
365
388
  //console.log('End diff');
366
389
  });
390
+ } else if (entry.fileName === 'bundle.harmony.js') {
391
+ //console.log('Found bundle');
392
+ return readEntire(entry, nextZipfile).then((newSource)=>{
393
+ //console.log('Begin diff');
394
+ zipfile.addBuffer(diff(originSource, newSource), 'bundle.harmony.js.patch');
395
+ //console.log('End diff');
396
+ });
367
397
  } else {
368
398
  // If same file.
369
399
  const originEntry = originEntries[entry.fileName];
@@ -412,7 +442,7 @@ async function diffFromPPK(origin, next, output) {
412
442
  await writePromise;
413
443
  }
414
444
  async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
415
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
445
+ _fsextra.ensureDirSync(path.dirname(output));
416
446
  const originEntries = {};
417
447
  const originMap = {};
418
448
  let originSource;
@@ -456,6 +486,13 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
456
486
  zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch');
457
487
  //console.log('End diff');
458
488
  });
489
+ } else if (entry.fileName === 'bundle.harmony.js') {
490
+ //console.log('Found bundle');
491
+ return readEntire(entry, nextZipfile).then((newSource)=>{
492
+ //console.log('Begin diff');
493
+ zipfile.addBuffer(diff(originSource, newSource), 'bundle.harmony.js.patch');
494
+ //console.log('End diff');
495
+ });
459
496
  } else {
460
497
  // If same file.
461
498
  if (originEntries[entry.fileName] === entry.crc32) {
@@ -487,23 +524,43 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
487
524
  zipfile.end();
488
525
  await writePromise;
489
526
  }
490
- function enumZipEntries(zipFn, callback) {
527
+ async function enumZipEntries(zipFn, callback, nestedPath = '') {
491
528
  return new Promise((resolve, reject)=>{
492
529
  (0, _yauzl.open)(zipFn, {
493
530
  lazyEntries: true
494
- }, (err, zipfile)=>{
531
+ }, async (err, zipfile)=>{
495
532
  if (err) {
496
533
  return reject(err);
497
534
  }
498
535
  zipfile.on('end', resolve);
499
536
  zipfile.on('error', reject);
500
- zipfile.on('entry', (entry)=>{
501
- const result = callback(entry, zipfile);
502
- if (result && typeof result.then === 'function') {
503
- result.then(()=>zipfile.readEntry());
504
- } else {
505
- zipfile.readEntry();
537
+ zipfile.on('entry', async (entry)=>{
538
+ const fullPath = nestedPath + entry.fileName;
539
+ try {
540
+ if (!entry.fileName.endsWith('/') && entry.fileName.toLowerCase().endsWith('.hap')) {
541
+ const tempDir = path.join(_os.default.tmpdir(), 'nested_zip_' + Date.now());
542
+ await _fsextra.ensureDir(tempDir);
543
+ const tempZipPath = path.join(tempDir, 'temp.zip');
544
+ await new Promise((res, rej)=>{
545
+ zipfile.openReadStream(entry, async (err, readStream)=>{
546
+ if (err) return rej(err);
547
+ const writeStream = _fsextra.createWriteStream(tempZipPath);
548
+ readStream.pipe(writeStream);
549
+ writeStream.on('finish', res);
550
+ writeStream.on('error', rej);
551
+ });
552
+ });
553
+ await enumZipEntries(tempZipPath, callback, fullPath + '/');
554
+ await _fsextra.remove(tempDir);
555
+ }
556
+ const result = callback(entry, zipfile, fullPath);
557
+ if (result && typeof result.then === 'function') {
558
+ await result;
559
+ }
560
+ } catch (error) {
561
+ console.error('处理文件时出错:', error);
506
562
  }
563
+ zipfile.readEntry();
507
564
  });
508
565
  zipfile.readEntry();
509
566
  });
@@ -544,7 +601,7 @@ const commands = {
544
601
  ...options,
545
602
  platform
546
603
  });
547
- const sourcemapOutput = _nodepath.default.join(intermediaDir, bundleName + '.map');
604
+ const sourcemapOutput = path.join(intermediaDir, bundleName + '.map');
548
605
  const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
549
606
  if (!platform) {
550
607
  throw new Error('Platform must be specified.');
@@ -552,7 +609,7 @@ const commands = {
552
609
  const { version, major, minor } = (0, _utils.getRNVersion)();
553
610
  console.log('Bundling with react-native: ', version);
554
611
  await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform, sourcemap ? sourcemapOutput : '');
555
- await pack(_nodepath.default.resolve(intermediaDir), realOutput);
612
+ await pack(path.resolve(intermediaDir), realOutput);
556
613
  const v = await (0, _utils.question)('是否现在上传此热更包?(Y/N)');
557
614
  if (v.toLowerCase() === 'y') {
558
615
  await this.publish({
@@ -585,6 +642,11 @@ const commands = {
585
642
  await diffFromPackage(origin, next, realOutput, 'assets/index.android.bundle');
586
643
  console.log(`${realOutput} generated.`);
587
644
  },
645
+ async hdiffFromApp ({ args, options }) {
646
+ const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromApp');
647
+ await diffFromPackage(origin, next, realOutput, 'resources/rawfile/bundle.harmony.js');
648
+ console.log(`${realOutput} generated.`);
649
+ },
588
650
  async diffFromIpa ({ args, options }) {
589
651
  const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromIpa');
590
652
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update-cli",
3
- "version": "1.34.2",
3
+ "version": "1.36.0",
4
4
  "description": "Command tools for javaScript updater with `pushy` service for react native apps.",
5
5
  "main": "index.js",
6
6
  "bin": {
package/src/bundle.js CHANGED
@@ -9,6 +9,7 @@ import { spawn, spawnSync } from 'node:child_process';
9
9
  const g2js = require('gradle-to-js/lib/parser');
10
10
  import os from 'os';
11
11
  const properties = require('properties');
12
+ const path = require('path');
12
13
 
13
14
  let bsdiff, hdiff, diff;
14
15
  try {
@@ -53,57 +54,70 @@ async function runReactNativeBundleCommand(
53
54
 
54
55
  let cliPath;
55
56
 
56
- try {
57
- // rn >= 0.75
58
- cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
59
- paths: [process.cwd()],
60
- });
61
- } catch (e) {
62
- // rn < 0.75
63
- cliPath = require.resolve('react-native/local-cli/cli.js', {
64
- paths: [process.cwd()],
65
- });
66
- }
67
-
68
57
  let usingExpo = false;
69
58
  try {
70
- require.resolve('expo-router', {
71
- paths: [process.cwd()],
72
- });
73
-
74
- console.log(`expo-router detected, will use @expo/cli to bundle.\n`);
75
- // if using expo-router, use expo-cli
76
59
  cliPath = require.resolve('@expo/cli', {
77
60
  paths: [process.cwd()],
78
61
  });
79
62
  usingExpo = true;
80
- } catch (e) {}
81
- const bundleCommand = usingExpo ? 'export:embed' : 'bundle';
82
-
83
- Array.prototype.push.apply(reactNativeBundleArgs, [
84
- cliPath,
85
- bundleCommand,
86
- '--assets-dest',
87
- outputFolder,
88
- '--bundle-output',
89
- path.join(outputFolder, bundleName),
90
- '--dev',
91
- development,
92
- '--entry-file',
93
- entryFile,
94
- '--platform',
95
- platform,
96
- '--reset-cache',
97
- ]);
98
-
99
- if (sourcemapOutput) {
100
- reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
63
+ } catch (e) {
64
+ try {
65
+ // rn >= 0.75
66
+ cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
67
+ paths: [process.cwd()],
68
+ });
69
+ } catch (e) {
70
+ // rn < 0.75
71
+ cliPath = require.resolve('react-native/local-cli/cli.js', {
72
+ paths: [process.cwd()],
73
+ });
74
+ }
101
75
  }
76
+ const bundleCommand = usingExpo ? 'export:embed' : platform === 'harmony' ? 'bundle-harmony' : 'bundle';
77
+ if (platform == 'harmony') {
78
+ Array.prototype.push.apply(reactNativeBundleArgs, [
79
+ cliPath,
80
+ bundleCommand,
81
+ '--dev',
82
+ development,
83
+ '--entry-file',
84
+ entryFile,
85
+ ]);
102
86
 
103
- if (config) {
104
- reactNativeBundleArgs.push('--config', config);
105
- }
87
+ if (sourcemapOutput) {
88
+ reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
89
+ }
106
90
 
91
+ if (config) {
92
+ reactNativeBundleArgs.push('--config', config);
93
+ }
94
+ }
95
+ else{
96
+ Array.prototype.push.apply(reactNativeBundleArgs, [
97
+ cliPath,
98
+ bundleCommand,
99
+ '--assets-dest',
100
+ outputFolder,
101
+ '--bundle-output',
102
+ path.join(outputFolder, bundleName),
103
+ '--dev',
104
+ development,
105
+ '--entry-file',
106
+ entryFile,
107
+ '--platform',
108
+ platform,
109
+ '--reset-cache',
110
+ ]);
111
+
112
+ if (sourcemapOutput) {
113
+ reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
114
+ }
115
+
116
+ if (config) {
117
+ reactNativeBundleArgs.push('--config', config);
118
+ }
119
+ }
120
+
107
121
  const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
108
122
  console.log(
109
123
  `Running bundle command: node ${reactNativeBundleArgs.join(' ')}`,
@@ -152,6 +166,8 @@ async function runReactNativeBundleCommand(
152
166
  fs.existsSync('ios/Pods/hermes-engine')
153
167
  ) {
154
168
  hermesEnabled = true;
169
+ }else if (platform === 'harmony') {
170
+ await copyHarmonyBundle(outputFolder);
155
171
  }
156
172
  if (hermesEnabled) {
157
173
  await compileHermesByteCode(
@@ -166,6 +182,21 @@ async function runReactNativeBundleCommand(
166
182
  });
167
183
  }
168
184
 
185
+ async function copyHarmonyBundle(outputFolder) {
186
+ const harmonyRawPath = 'harmony/entry/src/main/resources/rawfile';
187
+
188
+ try {
189
+ await fs.ensureDir(outputFolder);
190
+ await fs.copy(harmonyRawPath, outputFolder);
191
+
192
+ console.log(
193
+ `Successfully copied from ${harmonyRawPath} to ${outputFolder}`,
194
+ );
195
+ } catch (error) {
196
+ console.error('Error in copyHarmonyBundle:', error);
197
+ }
198
+ }
199
+
169
200
  function getHermesOSBin() {
170
201
  if (os.platform() === 'win32') return 'win64-bin';
171
202
  if (os.platform() === 'darwin') return 'osx-bin';
@@ -341,7 +372,7 @@ async function diffFromPPK(origin, next, output) {
341
372
  // isFile
342
373
  originMap[entry.crc32] = entry.fileName;
343
374
 
344
- if (entry.fileName === 'index.bundlejs') {
375
+ if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
345
376
  // This is source.
346
377
  return readEntire(entry, zipFile).then((v) => (originSource = v));
347
378
  }
@@ -403,6 +434,16 @@ async function diffFromPPK(origin, next, output) {
403
434
  );
404
435
  //console.log('End diff');
405
436
  });
437
+ }else if (entry.fileName === 'bundle.harmony.js') {
438
+ //console.log('Found bundle');
439
+ return readEntire(entry, nextZipfile).then((newSource) => {
440
+ //console.log('Begin diff');
441
+ zipfile.addBuffer(
442
+ diff(originSource, newSource),
443
+ 'bundle.harmony.js.patch',
444
+ );
445
+ //console.log('End diff');
446
+ });
406
447
  } else {
407
448
  // If same file.
408
449
  const originEntry = originEntries[entry.fileName];
@@ -525,7 +566,17 @@ async function diffFromPackage(
525
566
  );
526
567
  //console.log('End diff');
527
568
  });
528
- } else {
569
+ } else if (entry.fileName === 'bundle.harmony.js') {
570
+ //console.log('Found bundle');
571
+ return readEntire(entry, nextZipfile).then((newSource) => {
572
+ //console.log('Begin diff');
573
+ zipfile.addBuffer(
574
+ diff(originSource, newSource),
575
+ 'bundle.harmony.js.patch',
576
+ );
577
+ //console.log('End diff');
578
+ });
579
+ }else {
529
580
  // If same file.
530
581
  if (originEntries[entry.fileName] === entry.crc32) {
531
582
  copies[entry.fileName] = '';
@@ -557,22 +608,53 @@ async function diffFromPackage(
557
608
  await writePromise;
558
609
  }
559
610
 
560
- function enumZipEntries(zipFn, callback) {
611
+ async function enumZipEntries(zipFn, callback, nestedPath = '') {
561
612
  return new Promise((resolve, reject) => {
562
- openZipFile(zipFn, { lazyEntries: true }, (err, zipfile) => {
613
+ openZipFile(zipFn, { lazyEntries: true }, async (err, zipfile) => {
563
614
  if (err) {
564
615
  return reject(err);
565
616
  }
617
+
566
618
  zipfile.on('end', resolve);
567
619
  zipfile.on('error', reject);
568
- zipfile.on('entry', (entry) => {
569
- const result = callback(entry, zipfile);
570
- if (result && typeof result.then === 'function') {
571
- result.then(() => zipfile.readEntry());
572
- } else {
573
- zipfile.readEntry();
620
+ zipfile.on('entry', async (entry) => {
621
+ const fullPath = nestedPath + entry.fileName;
622
+
623
+ try {
624
+ if (
625
+ !entry.fileName.endsWith('/') &&
626
+ entry.fileName.toLowerCase().endsWith('.hap')
627
+ ) {
628
+ const tempDir = path.join(os.tmpdir(), 'nested_zip_' + Date.now());
629
+ await fs.ensureDir(tempDir);
630
+ const tempZipPath = path.join(tempDir, 'temp.zip');
631
+
632
+ await new Promise((res, rej) => {
633
+ zipfile.openReadStream(entry, async (err, readStream) => {
634
+ if (err) return rej(err);
635
+ const writeStream = fs.createWriteStream(tempZipPath);
636
+ readStream.pipe(writeStream);
637
+ writeStream.on('finish', res);
638
+ writeStream.on('error', rej);
639
+ });
640
+ });
641
+
642
+ await enumZipEntries(tempZipPath, callback, fullPath + '/');
643
+
644
+ await fs.remove(tempDir);
645
+ }
646
+
647
+ const result = callback(entry, zipfile, fullPath);
648
+ if (result && typeof result.then === 'function') {
649
+ await result;
650
+ }
651
+ } catch (error) {
652
+ console.error('处理文件时出错:', error);
574
653
  }
654
+
655
+ zipfile.readEntry();
575
656
  });
657
+
576
658
  zipfile.readEntry();
577
659
  });
578
660
  });
@@ -706,6 +788,21 @@ export const commands = {
706
788
  console.log(`${realOutput} generated.`);
707
789
  },
708
790
 
791
+ async hdiffFromApp({ args, options }) {
792
+ const { origin, next, realOutput } = diffArgsCheck(
793
+ args,
794
+ options,
795
+ 'hdiffFromApp',
796
+ );
797
+ await diffFromPackage(
798
+ origin,
799
+ next,
800
+ realOutput,
801
+ 'resources/rawfile/bundle.harmony.js',
802
+ );
803
+ console.log(`${realOutput} generated.`);
804
+ },
805
+
709
806
  async diffFromIpa({ args, options }) {
710
807
  const { origin, next, realOutput } = diffArgsCheck(
711
808
  args,