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 +19 -8
- package/lib/app.js +4 -3
- package/lib/bundle.js +114 -46
- package/lib/package.js +1 -1
- package/lib/versions.js +5 -5
- package/package.json +2 -1
- package/src/app.js +3 -2
- package/src/bundle.js +137 -34
- package/src/package.js +1 -1
- package/src/versions.js +5 -5
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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 =
|
|
233
|
+
const rnDir = path.dirname(require.resolve('react-native', {
|
|
205
234
|
paths: [
|
|
206
235
|
process.cwd()
|
|
207
236
|
]
|
|
208
237
|
}));
|
|
209
|
-
let hermesPath =
|
|
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
|
-
|
|
219
|
-
|
|
247
|
+
path.join(outputFolder, bundleName),
|
|
248
|
+
path.join(outputFolder, bundleName),
|
|
220
249
|
'-O'
|
|
221
250
|
];
|
|
222
251
|
if (sourcemapOutput) {
|
|
223
|
-
_fsextra.copyFileSync(sourcemapOutput,
|
|
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
|
-
|
|
239
|
-
|
|
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(
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
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 =
|
|
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(
|
|
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.
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
if (sourcemapOutput) {
|
|
88
|
+
reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
|
|
89
|
+
}
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
|
|
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
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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;
|