react-native-update-cli 1.38.1 → 1.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/app.js +1 -1
- package/lib/bundle.js +152 -57
- package/lib/package.js +8 -8
- package/lib/utils/check-plugin.js +30 -0
- package/lib/utils/index.js +7 -5
- package/lib/utils/plugin-config.js +39 -0
- package/lib/versions.js +3 -1
- package/package.json +1 -1
- package/src/{app.js → app.ts} +6 -5
- package/src/bundle.js +184 -64
- package/src/{package.js → package.ts} +10 -11
- package/src/types.ts +2 -0
- package/src/{user.js → user.ts} +2 -2
- package/src/utils/check-plugin.ts +30 -0
- package/src/utils/{index.js → index.ts} +10 -6
- package/src/utils/plugin-config.ts +34 -0
- package/src/versions.js +3 -1
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
|
|
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
|
|
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
|
-
|
|
78
|
-
let
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
108
|
-
|
|
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', {
|
|
@@ -122,8 +134,11 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
122
134
|
});
|
|
123
135
|
}
|
|
124
136
|
}
|
|
137
|
+
const bundleParams = await (0, _utils.checkPlugins)();
|
|
138
|
+
const minifyOption = bundleParams.minify;
|
|
139
|
+
const isSentry = bundleParams.sentry;
|
|
125
140
|
const bundleCommand = usingExpo ? 'export:embed' : platform === 'harmony' ? 'bundle-harmony' : 'bundle';
|
|
126
|
-
if (platform
|
|
141
|
+
if (platform === 'harmony') {
|
|
127
142
|
Array.prototype.push.apply(reactNativeBundleArgs, [
|
|
128
143
|
cliPath,
|
|
129
144
|
bundleCommand,
|
|
@@ -145,14 +160,16 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
145
160
|
'--assets-dest',
|
|
146
161
|
outputFolder,
|
|
147
162
|
'--bundle-output',
|
|
148
|
-
|
|
163
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
149
164
|
'--dev',
|
|
150
165
|
development,
|
|
151
166
|
'--entry-file',
|
|
152
167
|
entryFile,
|
|
153
168
|
'--platform',
|
|
154
169
|
platform,
|
|
155
|
-
'--reset-cache'
|
|
170
|
+
'--reset-cache',
|
|
171
|
+
'--minify',
|
|
172
|
+
minifyOption
|
|
156
173
|
]);
|
|
157
174
|
if (sourcemapOutput) {
|
|
158
175
|
reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
|
|
@@ -179,7 +196,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
179
196
|
const gradlePropeties = await new Promise((resolve)=>{
|
|
180
197
|
properties.parse('./android/gradle.properties', {
|
|
181
198
|
path: true
|
|
182
|
-
},
|
|
199
|
+
}, (error, props)=>{
|
|
183
200
|
if (error) {
|
|
184
201
|
console.error(error);
|
|
185
202
|
resolve(null);
|
|
@@ -195,7 +212,7 @@ async function runReactNativeBundleCommand(bundleName, development, entryFile, o
|
|
|
195
212
|
await copyHarmonyBundle(outputFolder);
|
|
196
213
|
}
|
|
197
214
|
if (hermesEnabled) {
|
|
198
|
-
await compileHermesByteCode(bundleName, outputFolder, sourcemapOutput);
|
|
215
|
+
await compileHermesByteCode(bundleName, outputFolder, sourcemapOutput, !isSentry);
|
|
199
216
|
}
|
|
200
217
|
resolve(null);
|
|
201
218
|
}
|
|
@@ -211,8 +228,8 @@ async function copyHarmonyBundle(outputFolder) {
|
|
|
211
228
|
} catch (error) {
|
|
212
229
|
await _fsextra.chmod(harmonyRawPath, 0o755);
|
|
213
230
|
}
|
|
214
|
-
await _fsextra.remove(
|
|
215
|
-
await _fsextra.copy('update.json',
|
|
231
|
+
await _fsextra.remove(_nodepath.default.join(harmonyRawPath, 'update.json'));
|
|
232
|
+
await _fsextra.copy('update.json', _nodepath.default.join(harmonyRawPath, 'update.json'));
|
|
216
233
|
await _fsextra.ensureDir(outputFolder);
|
|
217
234
|
await _fsextra.copy(harmonyRawPath, outputFolder);
|
|
218
235
|
} catch (error) {
|
|
@@ -221,9 +238,9 @@ async function copyHarmonyBundle(outputFolder) {
|
|
|
221
238
|
}
|
|
222
239
|
}
|
|
223
240
|
function getHermesOSBin() {
|
|
224
|
-
if (
|
|
225
|
-
if (
|
|
226
|
-
if (
|
|
241
|
+
if (_nodeos.default.platform() === 'win32') return 'win64-bin';
|
|
242
|
+
if (_nodeos.default.platform() === 'darwin') return 'osx-bin';
|
|
243
|
+
if (_nodeos.default.platform() === 'linux') return 'linux64-bin';
|
|
227
244
|
}
|
|
228
245
|
async function checkGradleConfig() {
|
|
229
246
|
let enableHermes = false;
|
|
@@ -246,15 +263,15 @@ async function checkGradleConfig() {
|
|
|
246
263
|
crunchPngs
|
|
247
264
|
};
|
|
248
265
|
}
|
|
249
|
-
async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput) {
|
|
250
|
-
console.log(
|
|
266
|
+
async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput, shouldCleanSourcemap) {
|
|
267
|
+
console.log('Hermes enabled, now compiling to hermes bytecode:\n');
|
|
251
268
|
// >= rn 0.69
|
|
252
|
-
const rnDir =
|
|
269
|
+
const rnDir = _nodepath.default.dirname(require.resolve('react-native', {
|
|
253
270
|
paths: [
|
|
254
271
|
process.cwd()
|
|
255
272
|
]
|
|
256
273
|
}));
|
|
257
|
-
let hermesPath =
|
|
274
|
+
let hermesPath = _nodepath.default.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
|
|
258
275
|
// < rn 0.69
|
|
259
276
|
if (!_fsextra.existsSync(hermesPath)) {
|
|
260
277
|
hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
|
|
@@ -263,15 +280,15 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
|
|
|
263
280
|
const args = [
|
|
264
281
|
'-emit-binary',
|
|
265
282
|
'-out',
|
|
266
|
-
|
|
267
|
-
|
|
283
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
284
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
268
285
|
'-O'
|
|
269
286
|
];
|
|
270
287
|
if (sourcemapOutput) {
|
|
271
|
-
_fsextra.copyFileSync(sourcemapOutput,
|
|
288
|
+
_fsextra.copyFileSync(sourcemapOutput, _nodepath.default.join(outputFolder, `${bundleName}.txt.map`));
|
|
272
289
|
args.push('-output-source-map');
|
|
273
290
|
}
|
|
274
|
-
console.log(
|
|
291
|
+
console.log(`Running hermesc: ${hermesCommand} ${args.join(' ')}`);
|
|
275
292
|
(0, _nodechild_process.spawnSync)(hermesCommand, args, {
|
|
276
293
|
stdio: 'ignore'
|
|
277
294
|
});
|
|
@@ -280,22 +297,93 @@ async function compileHermesByteCode(bundleName, outputFolder, sourcemapOutput)
|
|
|
280
297
|
if (!_fsextra.existsSync(composerPath)) {
|
|
281
298
|
return;
|
|
282
299
|
}
|
|
283
|
-
console.log(
|
|
300
|
+
console.log('Composing source map');
|
|
284
301
|
(0, _nodechild_process.spawnSync)('node', [
|
|
285
302
|
composerPath,
|
|
286
|
-
|
|
287
|
-
|
|
303
|
+
_nodepath.default.join(outputFolder, `${bundleName}.txt.map`),
|
|
304
|
+
_nodepath.default.join(outputFolder, `${bundleName}.map`),
|
|
288
305
|
'-o',
|
|
289
306
|
sourcemapOutput
|
|
290
307
|
], {
|
|
291
308
|
stdio: 'ignore'
|
|
292
309
|
});
|
|
293
310
|
}
|
|
294
|
-
|
|
311
|
+
if (shouldCleanSourcemap) {
|
|
312
|
+
_fsextra.removeSync(_nodepath.default.join(outputFolder, `${bundleName}.txt.map`));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
async function copyDebugidForSentry(bundleName, outputFolder, sourcemapOutput) {
|
|
316
|
+
if (sourcemapOutput) {
|
|
317
|
+
let copyDebugidPath;
|
|
318
|
+
try {
|
|
319
|
+
copyDebugidPath = require.resolve('@sentry/react-native/scripts/copy-debugid.js', {
|
|
320
|
+
paths: [
|
|
321
|
+
process.cwd()
|
|
322
|
+
]
|
|
323
|
+
});
|
|
324
|
+
} catch (error) {
|
|
325
|
+
console.error('无法找到 Sentry copy-debugid.js 脚本文件,请确保已正确安装 @sentry/react-native');
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (!_fsextra.existsSync(copyDebugidPath)) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
console.log('Copying debugid');
|
|
332
|
+
(0, _nodechild_process.spawnSync)('node', [
|
|
333
|
+
copyDebugidPath,
|
|
334
|
+
_nodepath.default.join(outputFolder, `${bundleName}.txt.map`),
|
|
335
|
+
_nodepath.default.join(outputFolder, `${bundleName}.map`)
|
|
336
|
+
], {
|
|
337
|
+
stdio: 'ignore'
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
_fsextra.removeSync(_nodepath.default.join(outputFolder, `${bundleName}.txt.map`));
|
|
341
|
+
}
|
|
342
|
+
async function uploadSourcemapForSentry(bundleName, outputFolder, sourcemapOutput, version) {
|
|
343
|
+
if (sourcemapOutput) {
|
|
344
|
+
let sentryCliPath;
|
|
345
|
+
try {
|
|
346
|
+
sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
|
|
347
|
+
paths: [
|
|
348
|
+
process.cwd()
|
|
349
|
+
]
|
|
350
|
+
});
|
|
351
|
+
} catch (error) {
|
|
352
|
+
console.error('无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli');
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
if (!_fsextra.existsSync(sentryCliPath)) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
(0, _nodechild_process.spawnSync)('node', [
|
|
359
|
+
sentryCliPath,
|
|
360
|
+
'releases',
|
|
361
|
+
'set-commits',
|
|
362
|
+
version,
|
|
363
|
+
'--auto'
|
|
364
|
+
], {
|
|
365
|
+
stdio: 'inherit'
|
|
366
|
+
});
|
|
367
|
+
console.log(`Sentry release created for version: ${version}`);
|
|
368
|
+
console.log('Uploading sourcemap');
|
|
369
|
+
(0, _nodechild_process.spawnSync)('node', [
|
|
370
|
+
sentryCliPath,
|
|
371
|
+
'releases',
|
|
372
|
+
'files',
|
|
373
|
+
version,
|
|
374
|
+
'upload-sourcemaps',
|
|
375
|
+
'--strip-prefix',
|
|
376
|
+
_nodepath.default.join(process.cwd(), outputFolder),
|
|
377
|
+
_nodepath.default.join(outputFolder, bundleName),
|
|
378
|
+
_nodepath.default.join(outputFolder, `${bundleName}.map`)
|
|
379
|
+
], {
|
|
380
|
+
stdio: 'inherit'
|
|
381
|
+
});
|
|
382
|
+
}
|
|
295
383
|
}
|
|
296
384
|
async function pack(dir, output) {
|
|
297
385
|
console.log('Packing');
|
|
298
|
-
_fsextra.ensureDirSync(
|
|
386
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
299
387
|
await new Promise((resolve, reject)=>{
|
|
300
388
|
const zipfile = new _yazl.ZipFile();
|
|
301
389
|
function addDirectory(root, rel) {
|
|
@@ -307,25 +395,25 @@ async function pack(dir, output) {
|
|
|
307
395
|
if (name === '.' || name === '..' || name === 'index.bundlejs.map') {
|
|
308
396
|
continue;
|
|
309
397
|
}
|
|
310
|
-
const fullPath =
|
|
398
|
+
const fullPath = _nodepath.default.join(root, name);
|
|
311
399
|
const stat = _fsextra.statSync(fullPath);
|
|
312
400
|
if (stat.isFile()) {
|
|
313
401
|
//console.log('adding: ' + rel+name);
|
|
314
402
|
zipfile.addFile(fullPath, rel + name);
|
|
315
403
|
} else if (stat.isDirectory()) {
|
|
316
404
|
//console.log('adding: ' + rel+name+'/');
|
|
317
|
-
addDirectory(fullPath, rel
|
|
405
|
+
addDirectory(fullPath, `${rel}${name}/`);
|
|
318
406
|
}
|
|
319
407
|
}
|
|
320
408
|
}
|
|
321
409
|
addDirectory(dir, '');
|
|
322
410
|
zipfile.outputStream.on('error', (err)=>reject(err));
|
|
323
|
-
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close',
|
|
411
|
+
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
|
|
324
412
|
resolve();
|
|
325
413
|
});
|
|
326
414
|
zipfile.end();
|
|
327
415
|
});
|
|
328
|
-
console.log(
|
|
416
|
+
console.log(`ppk热更包已生成并保存到: ${output}`);
|
|
329
417
|
}
|
|
330
418
|
function readEntire(entry, zipFile) {
|
|
331
419
|
const buffers = [];
|
|
@@ -348,10 +436,10 @@ function readEntire(entry, zipFile) {
|
|
|
348
436
|
}
|
|
349
437
|
function basename(fn) {
|
|
350
438
|
const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
|
|
351
|
-
return m
|
|
439
|
+
return m == null ? void 0 : m[1];
|
|
352
440
|
}
|
|
353
441
|
async function diffFromPPK(origin, next, output) {
|
|
354
|
-
_fsextra.ensureDirSync(
|
|
442
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
355
443
|
const originEntries = {};
|
|
356
444
|
const originMap = {};
|
|
357
445
|
let originSource;
|
|
@@ -367,7 +455,7 @@ async function diffFromPPK(origin, next, output) {
|
|
|
367
455
|
}
|
|
368
456
|
});
|
|
369
457
|
if (!originSource) {
|
|
370
|
-
throw new Error(
|
|
458
|
+
throw new Error('Bundle file not found! Please use default bundle file name and path.');
|
|
371
459
|
}
|
|
372
460
|
const copies = {};
|
|
373
461
|
const zipfile = new _yazl.ZipFile();
|
|
@@ -375,7 +463,7 @@ async function diffFromPPK(origin, next, output) {
|
|
|
375
463
|
zipfile.outputStream.on('error', (err)=>{
|
|
376
464
|
throw err;
|
|
377
465
|
});
|
|
378
|
-
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close',
|
|
466
|
+
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
|
|
379
467
|
resolve();
|
|
380
468
|
});
|
|
381
469
|
});
|
|
@@ -432,7 +520,7 @@ async function diffFromPPK(origin, next, output) {
|
|
|
432
520
|
// New file.
|
|
433
521
|
addEntry(basename(entry.fileName));
|
|
434
522
|
return new Promise((resolve, reject)=>{
|
|
435
|
-
nextZipfile.openReadStream(entry,
|
|
523
|
+
nextZipfile.openReadStream(entry, (err, readStream)=>{
|
|
436
524
|
if (err) {
|
|
437
525
|
return reject(err);
|
|
438
526
|
}
|
|
@@ -446,9 +534,9 @@ async function diffFromPPK(origin, next, output) {
|
|
|
446
534
|
}
|
|
447
535
|
});
|
|
448
536
|
const deletes = {};
|
|
449
|
-
for(
|
|
537
|
+
for(const k in originEntries){
|
|
450
538
|
if (!newEntries[k]) {
|
|
451
|
-
console.log(
|
|
539
|
+
console.log(`Delete ${k}`);
|
|
452
540
|
deletes[k] = 1;
|
|
453
541
|
}
|
|
454
542
|
}
|
|
@@ -461,7 +549,7 @@ async function diffFromPPK(origin, next, output) {
|
|
|
461
549
|
await writePromise;
|
|
462
550
|
}
|
|
463
551
|
async function diffFromPackage(origin, next, output, originBundleName, transformPackagePath = (v)=>v) {
|
|
464
|
-
_fsextra.ensureDirSync(
|
|
552
|
+
_fsextra.ensureDirSync(_nodepath.default.dirname(output));
|
|
465
553
|
const originEntries = {};
|
|
466
554
|
const originMap = {};
|
|
467
555
|
let originSource;
|
|
@@ -482,7 +570,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
|
|
|
482
570
|
}
|
|
483
571
|
});
|
|
484
572
|
if (!originSource) {
|
|
485
|
-
throw new Error(
|
|
573
|
+
throw new Error('Bundle file not found! Please use default bundle file name and path.');
|
|
486
574
|
}
|
|
487
575
|
const copies = {};
|
|
488
576
|
const zipfile = new _yazl.ZipFile();
|
|
@@ -490,7 +578,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
|
|
|
490
578
|
zipfile.outputStream.on('error', (err)=>{
|
|
491
579
|
throw err;
|
|
492
580
|
});
|
|
493
|
-
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close',
|
|
581
|
+
zipfile.outputStream.pipe(_fsextra.createWriteStream(output)).on('close', ()=>{
|
|
494
582
|
resolve();
|
|
495
583
|
});
|
|
496
584
|
});
|
|
@@ -524,7 +612,7 @@ async function diffFromPackage(origin, next, output, originBundleName, transform
|
|
|
524
612
|
return;
|
|
525
613
|
}
|
|
526
614
|
return new Promise((resolve, reject)=>{
|
|
527
|
-
nextZipfile.openReadStream(entry,
|
|
615
|
+
nextZipfile.openReadStream(entry, (err, readStream)=>{
|
|
528
616
|
if (err) {
|
|
529
617
|
return reject(err);
|
|
530
618
|
}
|
|
@@ -557,9 +645,9 @@ async function enumZipEntries(zipFn, callback, nestedPath = '') {
|
|
|
557
645
|
const fullPath = nestedPath + entry.fileName;
|
|
558
646
|
try {
|
|
559
647
|
if (!entry.fileName.endsWith('/') && entry.fileName.toLowerCase().endsWith('.hap')) {
|
|
560
|
-
const tempDir =
|
|
648
|
+
const tempDir = _nodepath.default.join(_nodeos.default.tmpdir(), `nested_zip_${Date.now()}`);
|
|
561
649
|
await _fsextra.ensureDir(tempDir);
|
|
562
|
-
const tempZipPath =
|
|
650
|
+
const tempZipPath = _nodepath.default.join(tempDir, 'temp.zip');
|
|
563
651
|
await new Promise((res, rej)=>{
|
|
564
652
|
zipfile.openReadStream(entry, async (err, readStream)=>{
|
|
565
653
|
if (err) return rej(err);
|
|
@@ -569,7 +657,7 @@ async function enumZipEntries(zipFn, callback, nestedPath = '') {
|
|
|
569
657
|
writeStream.on('error', rej);
|
|
570
658
|
});
|
|
571
659
|
});
|
|
572
|
-
await enumZipEntries(tempZipPath, callback, fullPath
|
|
660
|
+
await enumZipEntries(tempZipPath, callback, `${fullPath}/`);
|
|
573
661
|
await _fsextra.remove(tempDir);
|
|
574
662
|
}
|
|
575
663
|
const result = callback(entry, zipfile, fullPath);
|
|
@@ -610,28 +698,31 @@ function diffArgsCheck(args, options, diffFn) {
|
|
|
610
698
|
return {
|
|
611
699
|
origin,
|
|
612
700
|
next,
|
|
613
|
-
realOutput: output.replace(/\$\{time\}/g,
|
|
701
|
+
realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`)
|
|
614
702
|
};
|
|
615
703
|
}
|
|
616
704
|
const commands = {
|
|
617
705
|
bundle: async function({ options }) {
|
|
618
706
|
const platform = (0, _app.checkPlatform)(options.platform || await (0, _utils.question)('平台(ios/android/harmony):'));
|
|
619
|
-
|
|
707
|
+
const { bundleName, entryFile, intermediaDir, output, dev } = (0, _utils.translateOptions)({
|
|
620
708
|
...options,
|
|
621
709
|
platform
|
|
622
710
|
});
|
|
623
|
-
const
|
|
624
|
-
const
|
|
711
|
+
const bundleParams = await (0, _utils.checkPlugins)();
|
|
712
|
+
const sourcemap = bundleParams.sourcemap;
|
|
713
|
+
const isSentry = bundleParams.sentry;
|
|
714
|
+
const sourcemapOutput = _nodepath.default.join(intermediaDir, `${bundleName}.map`);
|
|
715
|
+
const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
|
|
625
716
|
if (!platform) {
|
|
626
717
|
throw new Error('Platform must be specified.');
|
|
627
718
|
}
|
|
628
719
|
const { version, major, minor } = (0, _utils.getRNVersion)();
|
|
629
|
-
console.log(
|
|
720
|
+
console.log(`Bundling with react-native: ${version}`);
|
|
630
721
|
await runReactNativeBundleCommand(bundleName, dev, entryFile, intermediaDir, platform, sourcemap ? sourcemapOutput : '');
|
|
631
|
-
await pack(
|
|
722
|
+
await pack(_nodepath.default.resolve(intermediaDir), realOutput);
|
|
632
723
|
const v = await (0, _utils.question)('是否现在上传此热更包?(Y/N)');
|
|
633
724
|
if (v.toLowerCase() === 'y') {
|
|
634
|
-
await this.publish({
|
|
725
|
+
const versionName = await this.publish({
|
|
635
726
|
args: [
|
|
636
727
|
realOutput
|
|
637
728
|
],
|
|
@@ -639,6 +730,10 @@ const commands = {
|
|
|
639
730
|
platform
|
|
640
731
|
}
|
|
641
732
|
});
|
|
733
|
+
if (isSentry) {
|
|
734
|
+
await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
|
|
735
|
+
await uploadSourcemapForSentry(bundleName, intermediaDir, sourcemapOutput, versionName);
|
|
736
|
+
}
|
|
642
737
|
}
|
|
643
738
|
},
|
|
644
739
|
async diff ({ args, options }) {
|
|
@@ -670,7 +765,7 @@ const commands = {
|
|
|
670
765
|
const { origin, next, realOutput } = diffArgsCheck(args, options, 'diffFromIpa');
|
|
671
766
|
await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
|
|
672
767
|
const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
673
|
-
return m
|
|
768
|
+
return m == null ? void 0 : m[1];
|
|
674
769
|
});
|
|
675
770
|
console.log(`${realOutput} generated.`);
|
|
676
771
|
},
|
|
@@ -678,7 +773,7 @@ const commands = {
|
|
|
678
773
|
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiffFromIpa');
|
|
679
774
|
await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v)=>{
|
|
680
775
|
const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
681
|
-
return m
|
|
776
|
+
return m == null ? void 0 : m[1];
|
|
682
777
|
});
|
|
683
778
|
console.log(`${realOutput} generated.`);
|
|
684
779
|
}
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "checkPlugins", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return checkPlugins;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _pluginconfig = require("./plugin-config");
|
|
12
|
+
async function checkPlugins() {
|
|
13
|
+
const params = {
|
|
14
|
+
sentry: false,
|
|
15
|
+
minify: true,
|
|
16
|
+
sourcemap: false
|
|
17
|
+
};
|
|
18
|
+
for (const plugin of _pluginconfig.plugins){
|
|
19
|
+
try {
|
|
20
|
+
const isEnabled = await plugin.detect();
|
|
21
|
+
if (isEnabled && plugin.bundleParams) {
|
|
22
|
+
Object.assign(params, plugin.bundleParams);
|
|
23
|
+
console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`);
|
|
24
|
+
}
|
|
25
|
+
} catch (err) {
|
|
26
|
+
console.warn(`检测 ${plugin.name} 插件时出错:`, err);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return params;
|
|
30
|
+
}
|
package/lib/utils/index.js
CHANGED
|
@@ -9,6 +9,9 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
checkPlugins: function() {
|
|
13
|
+
return _checkplugin.checkPlugins;
|
|
14
|
+
},
|
|
12
15
|
getApkInfo: function() {
|
|
13
16
|
return getApkInfo;
|
|
14
17
|
},
|
|
@@ -45,6 +48,7 @@ const _appinfoparser = /*#__PURE__*/ _interop_require_default(require("./app-inf
|
|
|
45
48
|
const _satisfies = /*#__PURE__*/ _interop_require_default(require("semver/functions/satisfies"));
|
|
46
49
|
const _chalk = /*#__PURE__*/ _interop_require_default(require("chalk"));
|
|
47
50
|
const _latestversion = /*#__PURE__*/ _interop_require_default(require("@badisi/latest-version"));
|
|
51
|
+
const _checkplugin = require("./check-plugin");
|
|
48
52
|
const _read = require("read");
|
|
49
53
|
function _interop_require_default(obj) {
|
|
50
54
|
return obj && obj.__esModule ? obj : {
|
|
@@ -63,12 +67,10 @@ async function question(query, password) {
|
|
|
63
67
|
}
|
|
64
68
|
function translateOptions(options) {
|
|
65
69
|
const ret = {};
|
|
66
|
-
for(
|
|
70
|
+
for(const key in options){
|
|
67
71
|
const v = options[key];
|
|
68
72
|
if (typeof v === 'string') {
|
|
69
|
-
ret[key] = v.replace(/\$\{(\w+)\}/g,
|
|
70
|
-
return options[n] || process.env[n] || v;
|
|
71
|
-
});
|
|
73
|
+
ret[key] = v.replace(/\$\{(\w+)\}/g, (v, n)=>options[n] || process.env[n] || v);
|
|
72
74
|
} else {
|
|
73
75
|
ret[key] = v;
|
|
74
76
|
}
|
|
@@ -215,7 +217,7 @@ async function printVersionCommand() {
|
|
|
215
217
|
console.warn(`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
|
|
216
218
|
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`);
|
|
217
219
|
} else if ((0, _satisfies.default)(pushyVersion, '10.0.0 - 10.17.0')) {
|
|
218
|
-
console.warn(
|
|
220
|
+
console.warn('当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10');
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
223
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "plugins", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return plugins;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _fsextra = /*#__PURE__*/ _interop_require_default(require("fs-extra"));
|
|
12
|
+
function _interop_require_default(obj) {
|
|
13
|
+
return obj && obj.__esModule ? obj : {
|
|
14
|
+
default: obj
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const plugins = [
|
|
18
|
+
{
|
|
19
|
+
name: 'sentry',
|
|
20
|
+
bundleParams: {
|
|
21
|
+
sentry: true,
|
|
22
|
+
minify: false,
|
|
23
|
+
sourcemap: true
|
|
24
|
+
},
|
|
25
|
+
detect: async ()=>{
|
|
26
|
+
try {
|
|
27
|
+
await _fsextra.default.access('ios/sentry.properties');
|
|
28
|
+
return true;
|
|
29
|
+
} catch (e) {
|
|
30
|
+
try {
|
|
31
|
+
await _fsextra.default.access('android/sentry.properties');
|
|
32
|
+
return true;
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
];
|