react-native-update-cli 1.35.0 → 1.37.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/app.js CHANGED
@@ -36,7 +36,8 @@ function _interop_require_default(obj) {
36
36
  }
37
37
  const validPlatforms = {
38
38
  ios: 1,
39
- android: 1
39
+ android: 1,
40
+ harmony: 1
40
41
  };
41
42
  function checkPlatform(platform) {
42
43
  if (!validPlatforms[platform]) {
@@ -99,7 +100,7 @@ const commands = {
99
100
  createApp: async function({ options }) {
100
101
  const name = options.name || await (0, _utils.question)('应用名称:');
101
102
  const { downloadUrl } = options;
102
- const platform = checkPlatform(options.platform || await (0, _utils.question)('平台(ios/android):'));
103
+ const platform = checkPlatform(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
103
104
  const { id } = await (0, _api.post)('/app/create', {
104
105
  name,
105
106
  platform
@@ -129,7 +130,7 @@ const commands = {
129
130
  listApp(platform);
130
131
  },
131
132
  selectApp: async function({ args, options }) {
132
- const platform = checkPlatform(options.platform || await (0, _utils.question)('平台(ios/android):'));
133
+ const platform = checkPlatform(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
133
134
  const id = args[0] ? parseInt(args[0]) : (await chooseApp(platform)).id;
134
135
  let updateInfo = {};
135
136
  if (_fs.default.existsSync('update.json')) {
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;
@@ -111,27 +111,44 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
111
111
  });
112
112
  }
113
113
  }
114
- const bundleCommand = usingExpo ? 'export:embed' : 'bundle';
115
- Array.prototype.push.apply(reactNativeBundleArgs, [
116
- cliPath,
117
- bundleCommand,
118
- '--assets-dest',
119
- outputFolder,
120
- '--bundle-output',
121
- _nodepath.default.join(outputFolder, bundleName),
122
- '--dev',
123
- development,
124
- '--entry-file',
125
- entryFile,
126
- '--platform',
127
- platform,
128
- '--reset-cache'
129
- ]);
130
- if (sourcemapOutput) {
131
- reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
132
- }
133
- if (config) {
134
- 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
+ }
135
152
  }
136
153
  const reactNativeBundleProcess = (0, _nodechild_process.spawn)('node', reactNativeBundleArgs);
137
154
  console.log(`Running bundle command: node ${reactNativeBundleArgs.join(' ')}`);
@@ -163,6 +180,8 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
163
180
  if (typeof hermesEnabled !== 'boolean') hermesEnabled = gradleConfig.enableHermes;
164
181
  } else if (platform === 'ios' && _fsextra.existsSync('ios/Pods/hermes-engine')) {
165
182
  hermesEnabled = true;
183
+ } else if (platform === 'harmony') {
184
+ await copyHarmonyBundle(outputFolder);
166
185
  }
167
186
  if (hermesEnabled) {
168
187
  await compileHermesByteCode(bundleName, outputFolder, sourcemapOutput);
@@ -172,6 +191,16 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
172
191
  });
173
192
  });
174
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
+ }
175
204
  function getHermesOSBin() {
176
205
  if (_os.default.platform() === 'win32') return 'win64-bin';
177
206
  if (_os.default.platform() === 'darwin') return 'osx-bin';
@@ -201,12 +230,12 @@ async function checkGradleConfig() {
201
230
  async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput) {
202
231
  console.log(`Hermes enabled, now compiling to hermes bytecode:\n`);
203
232
  // >= rn 0.69
204
- const rnDir = _nodepath.default.dirname(require.resolve('react-native', {
233
+ const rnDir = path.dirname(require.resolve('react-native', {
205
234
  paths: [
206
235
  process.cwd()
207
236
  ]
208
237
  }));
209
- let hermesPath = _nodepath.default.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
238
+ let hermesPath = path.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
210
239
  // < rn 0.69
211
240
  if (!_fsextra.existsSync(hermesPath)) {
212
241
  hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
@@ -215,12 +244,12 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
215
244
  const args = [
216
245
  '-emit-binary',
217
246
  '-out',
218
- _nodepath.default.join(outputFolder, bundleName),
219
- _nodepath.default.join(outputFolder, bundleName),
247
+ path.join(outputFolder, bundleName),
248
+ path.join(outputFolder, bundleName),
220
249
  '-O'
221
250
  ];
222
251
  if (sourcemapOutput) {
223
- _fsextra.copyFileSync(sourcemapOutput, _nodepath.default.join(outputFolder, bundleName + '.txt.map'));
252
+ _fsextra.copyFileSync(sourcemapOutput, path.join(outputFolder, bundleName + '.txt.map'));
224
253
  args.push('-output-source-map');
225
254
  }
226
255
  console.log('Running hermesc: ' + hermesCommand + ' ' + args.join(' ') + '\n');
@@ -235,19 +264,19 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
235
264
  console.log(`Composing source map`);
236
265
  (0, _nodechild_process.spawnSync)('node', [
237
266
  composerPath,
238
- _nodepath.default.join(outputFolder, bundleName + '.txt.map'),
239
- _nodepath.default.join(outputFolder, bundleName + '.map'),
267
+ path.join(outputFolder, bundleName + '.txt.map'),
268
+ path.join(outputFolder, bundleName + '.map'),
240
269
  '-o',
241
270
  sourcemapOutput
242
271
  ], {
243
272
  stdio: 'ignore'
244
273
  });
245
274
  }
246
- _fsextra.removeSync(_nodepath.default.join(outputFolder, bundleName + '.txt.map'));
275
+ _fsextra.removeSync(path.join(outputFolder, bundleName + '.txt.map'));
247
276
  }
248
277
  async function pack(dir, output) {
249
278
  console.log('Packing');
250
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
279
+ _fsextra.ensureDirSync(path.dirname(output));
251
280
  await new Promise((resolve, reject)=>{
252
281
  const zipfile = new _yazl.ZipFile();
253
282
  function addDirectory(root, rel) {
@@ -259,7 +288,7 @@ async function pack(dir, output) {
259
288
  if (name === '.' || name === '..' || name === 'index.bundlejs.map') {
260
289
  continue;
261
290
  }
262
- const fullPath = _nodepath.default.join(root, name);
291
+ const fullPath = path.join(root, name);
263
292
  const stat = _fsextra.statSync(fullPath);
264
293
  if (stat.isFile()) {
265
294
  //console.log('adding: ' + rel+name);
@@ -303,7 +332,7 @@ function basename(fn) {
303
332
  return m && m[1];
304
333
  }
305
334
  async function diffFromPPK(origin, next, output) {
306
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
335
+ _fsextra.ensureDirSync(path.dirname(output));
307
336
  const originEntries = {};
308
337
  const originMap = {};
309
338
  let originSource;
@@ -312,7 +341,7 @@ async function diffFromPPK(origin, next, output) {
312
341
  if (!/\/$/.test(entry.fileName)) {
313
342
  // isFile
314
343
  originMap[entry.crc32] = entry.fileName;
315
- if (entry.fileName === 'index.bundlejs') {
344
+ if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
316
345
  // This is source.
317
346
  return readEntire(entry, zipFile).then((v)=>originSource = v);
318
347
  }
@@ -358,6 +387,13 @@ async function diffFromPPK(origin, next, output) {
358
387
  zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch');
359
388
  //console.log('End diff');
360
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
+ });
361
397
  } else {
362
398
  // If same file.
363
399
  const originEntry = originEntries[entry.fileName];
@@ -406,7 +442,7 @@ async function diffFromPPK(origin, next, output) {
406
442
  await writePromise;
407
443
  }
408
444
  async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
409
- _fsextra.ensureDirSync(_nodepath.default.dirname(output));
445
+ _fsextra.ensureDirSync(path.dirname(output));
410
446
  const originEntries = {};
411
447
  const originMap = {};
412
448
  let originSource;
@@ -450,6 +486,13 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
450
486
  zipfile.addBuffer(diff(originSource, newSource), 'index.bundlejs.patch');
451
487
  //console.log('End diff');
452
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
+ });
453
496
  } else {
454
497
  // If same file.
455
498
  if (originEntries[entry.fileName] === entry.crc32) {
@@ -481,23 +524,43 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
481
524
  zipfile.end();
482
525
  await writePromise;
483
526
  }
484
- function enumZipEntries(zipFn, callback) {
527
+ async function enumZipEntries(zipFn, callback, nestedPath = '') {
485
528
  return new Promise((resolve, reject)=>{
486
529
  (0, _yauzl.open)(zipFn, {
487
530
  lazyEntries: true
488
- }, (err, zipfile)=>{
531
+ }, async (err, zipfile)=>{
489
532
  if (err) {
490
533
  return reject(err);
491
534
  }
492
535
  zipfile.on('end', resolve);
493
536
  zipfile.on('error', reject);
494
- zipfile.on('entry', (entry)=>{
495
- const result = callback(entry, zipfile);
496
- if (result && typeof result.then === 'function') {
497
- result.then(()=>zipfile.readEntry());
498
- } else {
499
- 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);
500
562
  }
563
+ zipfile.readEntry();
501
564
  });
502
565
  zipfile.readEntry();
503
566
  });
@@ -533,12 +596,12 @@ function diffArgsCheck(args, options, diffFn) {
533
596
  }
534
597
  const commands = {
535
598
  bundle: async function({ options }) {
536
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
599
+ const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
537
600
  let { bundleName, entryFile, intermediaDir, output, dev, sourcemap } = (0, _utils.translateOptions)({
538
601
  ...options,
539
602
  platform
540
603
  });
541
- const sourcemapOutput = _nodepath.default.join(intermediaDir, bundleName + '.map');
604
+ const sourcemapOutput = path.join(intermediaDir, bundleName + '.map');
542
605
  const realOutput = output.replace(/\$\{time\}/g, '' + Date.now());
543
606
  if (!platform) {
544
607
  throw new Error('Platform must be specified.');
@@ -546,7 +609,7 @@ const commands = {
546
609
  const { version, major, minor } = (0, _utils.getRNVersion)();
547
610
  console.log('Bundling with react-native: ', version);
548
611
  await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform, sourcemap ? sourcemapOutput : '');
549
- await pack(_nodepath.default.resolve(intermediaDir), realOutput);
612
+ await pack(path.resolve(intermediaDir), realOutput);
550
613
  const v = await (0, _utils.question)('是否现在上传此热更包?(Y/N)');
551
614
  if (v.toLowerCase() === 'y') {
552
615
  await this.publish({
@@ -579,6 +642,11 @@ const commands = {
579
642
  await diffFromPackage(origin, next, realOutput, 'assets/index.android.bundle');
580
643
  console.log(`${realOutput} generated.`);
581
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
+ },
582
650
  async diffFromIpa ({ args, options }) {
583
651
  const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromIpa');
584
652
  await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
package/lib/package.js CHANGED
@@ -134,7 +134,7 @@ const commands = {
134
134
  console.log(await (0, _utils.getApkInfo)(fn));
135
135
  },
136
136
  packages: async function({ options }) {
137
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
137
+ const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
138
138
  const { appId } = await (0, _app.getSelectedApp)(platform);
139
139
  await listPackage(appId);
140
140
  }
package/lib/versions.js CHANGED
@@ -81,9 +81,9 @@ const commands = {
81
81
  const fn = args[0];
82
82
  const { name, description, metaInfo } = options;
83
83
  if (!fn || !fn.endsWith('.ppk')) {
84
- throw new Error('使用方法: pushy publish ppk后缀文件 --platform ios|android');
84
+ throw new Error('使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony');
85
85
  }
86
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
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
89
  const { id } = await (0, _api.post)(`/app/${appId}/version/create`, {
@@ -107,12 +107,12 @@ const commands = {
107
107
  }
108
108
  },
109
109
  versions: async function({ options }) {
110
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
110
+ const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
111
111
  const { appId } = await (0, _app.getSelectedApp)(platform);
112
112
  await listVersions(appId);
113
113
  },
114
114
  update: async function({ args, options }) {
115
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
115
+ const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
116
116
  const { appId } = await (0, _app.getSelectedApp)(platform);
117
117
  let versionId = options.versionId || (await chooseVersion(appId)).id;
118
118
  if (versionId === 'null') {
@@ -229,7 +229,7 @@ const commands = {
229
229
  console.log(`已将热更版本 ${versionId} 绑定到原生版本 ${pkgVersion} (id: ${pkgId})`);
230
230
  },
231
231
  updateVersionInfo: async function({ args, options }) {
232
- const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android):'));
232
+ const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
233
233
  const { appId } = await (0, _app.getSelectedApp)(platform);
234
234
  const versionId = options.versionId || (await chooseVersion(appId)).id;
235
235
  const updateParams = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update-cli",
3
- "version": "1.35.0",
3
+ "version": "1.37.0",
4
4
  "description": "Command tools for javaScript updater with `pushy` service for react native apps.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -23,6 +23,7 @@
23
23
  "react-native",
24
24
  "ios",
25
25
  "android",
26
+ "harmony",
26
27
  "update"
27
28
  ],
28
29
  "author": "reactnativecn",
package/src/app.js CHANGED
@@ -7,6 +7,7 @@ import { post, get, doDelete } from './api';
7
7
  const validPlatforms = {
8
8
  ios: 1,
9
9
  android: 1,
10
+ harmony: 1,
10
11
  };
11
12
 
12
13
  export function checkPlatform(platform) {
@@ -74,7 +75,7 @@ export const commands = {
74
75
  const name = options.name || (await question('应用名称:'));
75
76
  const { downloadUrl } = options;
76
77
  const platform = checkPlatform(
77
- options.platform || (await question('平台(ios/android):')),
78
+ options.platform || (await question('平台(ios/android/harmony):')),
78
79
  );
79
80
  const { id } = await post('/app/create', { name, platform });
80
81
  console.log(`已成功创建应用(id: ${id})`);
@@ -98,7 +99,7 @@ export const commands = {
98
99
  },
99
100
  selectApp: async function ({ args, options }) {
100
101
  const platform = checkPlatform(
101
- options.platform || (await question('平台(ios/android):')),
102
+ options.platform || (await question('平台(ios/android/harmony):')),
102
103
  );
103
104
  const id = args[0] ? parseInt(args[0]) : (await chooseApp(platform)).id;
104
105
 
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 {
@@ -72,32 +73,51 @@ async function runReactNativeBundleCommand(
72
73
  });
73
74
  }
74
75
  }
75
- const bundleCommand = usingExpo ? 'export:embed' : 'bundle';
76
-
77
- Array.prototype.push.apply(reactNativeBundleArgs, [
78
- cliPath,
79
- bundleCommand,
80
- '--assets-dest',
81
- outputFolder,
82
- '--bundle-output',
83
- path.join(outputFolder, bundleName),
84
- '--dev',
85
- development,
86
- '--entry-file',
87
- entryFile,
88
- '--platform',
89
- platform,
90
- '--reset-cache',
91
- ]);
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
+ ]);
92
86
 
93
- if (sourcemapOutput) {
94
- reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
95
- }
87
+ if (sourcemapOutput) {
88
+ reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
89
+ }
96
90
 
97
- if (config) {
98
- reactNativeBundleArgs.push('--config', config);
91
+ if (config) {
92
+ reactNativeBundleArgs.push('--config', config);
93
+ }
99
94
  }
100
-
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
+
101
121
  const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
102
122
  console.log(
103
123
  `Running bundle command: node ${reactNativeBundleArgs.join(' ')}`,
@@ -146,6 +166,8 @@ async function runReactNativeBundleCommand(
146
166
  fs.existsSync('ios/Pods/hermes-engine')
147
167
  ) {
148
168
  hermesEnabled = true;
169
+ }else if (platform === 'harmony') {
170
+ await copyHarmonyBundle(outputFolder);
149
171
  }
150
172
  if (hermesEnabled) {
151
173
  await compileHermesByteCode(
@@ -160,6 +182,21 @@ async function runReactNativeBundleCommand(
160
182
  });
161
183
  }
162
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
+
163
200
  function getHermesOSBin() {
164
201
  if (os.platform() === 'win32') return 'win64-bin';
165
202
  if (os.platform() === 'darwin') return 'osx-bin';
@@ -335,7 +372,7 @@ async function diffFromPPK(origin, next, output) {
335
372
  // isFile
336
373
  originMap[entry.crc32] = entry.fileName;
337
374
 
338
- if (entry.fileName === 'index.bundlejs') {
375
+ if (entry.fileName === 'index.bundlejs' || entry.fileName === 'bundle.harmony.js') {
339
376
  // This is source.
340
377
  return readEntire(entry, zipFile).then((v) => (originSource = v));
341
378
  }
@@ -397,6 +434,16 @@ async function diffFromPPK(origin, next, output) {
397
434
  );
398
435
  //console.log('End diff');
399
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
+ });
400
447
  } else {
401
448
  // If same file.
402
449
  const originEntry = originEntries[entry.fileName];
@@ -519,7 +566,17 @@ async function diffFromPackage(
519
566
  );
520
567
  //console.log('End diff');
521
568
  });
522
- } 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 {
523
580
  // If same file.
524
581
  if (originEntries[entry.fileName] === entry.crc32) {
525
582
  copies[entry.fileName] = '';
@@ -551,22 +608,53 @@ async function diffFromPackage(
551
608
  await writePromise;
552
609
  }
553
610
 
554
- function enumZipEntries(zipFn, callback) {
611
+ async function enumZipEntries(zipFn, callback, nestedPath = '') {
555
612
  return new Promise((resolve, reject) => {
556
- openZipFile(zipFn, { lazyEntries: true }, (err, zipfile) => {
613
+ openZipFile(zipFn, { lazyEntries: true }, async (err, zipfile) => {
557
614
  if (err) {
558
615
  return reject(err);
559
616
  }
617
+
560
618
  zipfile.on('end', resolve);
561
619
  zipfile.on('error', reject);
562
- zipfile.on('entry', (entry) => {
563
- const result = callback(entry, zipfile);
564
- if (result && typeof result.then === 'function') {
565
- result.then(() => zipfile.readEntry());
566
- } else {
567
- 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);
568
653
  }
654
+
655
+ zipfile.readEntry();
569
656
  });
657
+
570
658
  zipfile.readEntry();
571
659
  });
572
660
  });
@@ -611,7 +699,7 @@ function diffArgsCheck(args, options, diffFn) {
611
699
  export const commands = {
612
700
  bundle: async function ({ options }) {
613
701
  const platform = checkPlatform(
614
- options.platform || (await question('平台(ios/android):')),
702
+ options.platform || (await question('平台(ios/android/harmony):')),
615
703
  );
616
704
 
617
705
  let { bundleName, entryFile, intermediaDir, output, dev, sourcemap } =
@@ -700,6 +788,21 @@ export const commands = {
700
788
  console.log(`${realOutput} generated.`);
701
789
  },
702
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
+
703
806
  async diffFromIpa({ args, options }) {
704
807
  const { origin, next, realOutput } = diffArgsCheck(
705
808
  args,
package/src/package.js CHANGED
@@ -138,7 +138,7 @@ export const commands = {
138
138
  },
139
139
  packages: async function ({ options }) {
140
140
  const platform = checkPlatform(
141
- options.platform || (await question('平台(ios/android):')),
141
+ options.platform || (await question('平台(ios/android/harmony):')),
142
142
  );
143
143
  const { appId } = await getSelectedApp(platform);
144
144
  await listPackage(appId);
package/src/versions.js CHANGED
@@ -86,12 +86,12 @@ export const commands = {
86
86
 
87
87
  if (!fn || !fn.endsWith('.ppk')) {
88
88
  throw new Error(
89
- '使用方法: pushy publish ppk后缀文件 --platform ios|android',
89
+ '使用方法: pushy publish ppk后缀文件 --platform ios|android|harmony',
90
90
  );
91
91
  }
92
92
 
93
93
  const platform = checkPlatform(
94
- options.platform || (await question('平台(ios/android):')),
94
+ options.platform || (await question('平台(ios/android/harmony):')),
95
95
  );
96
96
  const { appId } = await getSelectedApp(platform);
97
97
 
@@ -114,14 +114,14 @@ export const commands = {
114
114
  },
115
115
  versions: async function ({ options }) {
116
116
  const platform = checkPlatform(
117
- options.platform || (await question('平台(ios/android):')),
117
+ options.platform || (await question('平台(ios/android/harmony):')),
118
118
  );
119
119
  const { appId } = await getSelectedApp(platform);
120
120
  await listVersions(appId);
121
121
  },
122
122
  update: async function ({ args, options }) {
123
123
  const platform = checkPlatform(
124
- options.platform || (await question('平台(ios/android):')),
124
+ options.platform || (await question('平台(ios/android/harmony):')),
125
125
  );
126
126
  const { appId } = await getSelectedApp(platform);
127
127
  let versionId = options.versionId || (await chooseVersion(appId)).id;
@@ -255,7 +255,7 @@ export const commands = {
255
255
  },
256
256
  updateVersionInfo: async function ({ args, options }) {
257
257
  const platform = checkPlatform(
258
- options.platform || (await question('平台(ios/android):')),
258
+ options.platform || (await question('平台(ios/android/harmony):')),
259
259
  );
260
260
  const { appId } = await getSelectedApp(platform);
261
261
  const versionId = options.versionId || (await chooseVersion(appId)).id;