react-native-update-cli 2.8.4 → 2.9.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/api.d.ts +18 -0
- package/lib/app.d.ts +38 -0
- package/lib/app.js +5 -4
- package/lib/bundle-pack.d.ts +1 -0
- package/lib/bundle-pack.js +104 -0
- package/lib/bundle-runner.d.ts +20 -0
- package/lib/bundle-runner.js +404 -0
- package/lib/bundle.d.ts +6 -0
- package/lib/bundle.js +73 -471
- package/lib/diff.d.ts +13 -0
- package/lib/diff.js +144 -123
- package/lib/exports.d.ts +12 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -13
- package/lib/install.d.ts +4 -0
- package/lib/locales/en.d.ts +137 -0
- package/lib/locales/en.js +11 -0
- package/lib/locales/zh.d.ts +136 -0
- package/lib/locales/zh.js +11 -0
- package/lib/module-manager.d.ts +20 -0
- package/lib/module-manager.js +3 -9
- package/lib/modules/app-module.d.ts +2 -0
- package/lib/modules/app-module.js +84 -44
- package/lib/modules/bundle-module.d.ts +2 -0
- package/lib/modules/bundle-module.js +7 -8
- package/lib/modules/index.d.ts +6 -0
- package/lib/modules/package-module.d.ts +2 -0
- package/lib/modules/user-module.d.ts +2 -0
- package/lib/modules/user-module.js +55 -44
- package/lib/modules/version-module.d.ts +2 -0
- package/lib/package.d.ts +58 -0
- package/lib/package.js +103 -139
- package/lib/provider.d.ts +26 -0
- package/lib/provider.js +115 -217
- package/lib/types.d.ts +120 -0
- package/lib/user.d.ts +8 -0
- package/lib/utils/add-gitignore.d.ts +1 -0
- package/lib/utils/app-info-parser/aab.d.ts +22 -0
- package/lib/utils/app-info-parser/aab.js +0 -4
- package/lib/utils/app-info-parser/apk.d.ts +14 -0
- package/lib/utils/app-info-parser/apk.js +6 -4
- package/lib/utils/app-info-parser/app.d.ts +4 -0
- package/lib/utils/app-info-parser/app.js +3 -0
- package/lib/utils/app-info-parser/index.d.ts +16 -0
- package/lib/utils/app-info-parser/index.js +2 -0
- package/lib/utils/app-info-parser/ipa.d.ts +14 -0
- package/lib/utils/app-info-parser/ipa.js +1 -1
- package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
- package/lib/utils/app-info-parser/utils.d.ts +31 -0
- package/lib/utils/app-info-parser/utils.js +1 -0
- package/lib/utils/app-info-parser/xml-parser/binary.d.ts +56 -0
- package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +10 -0
- package/lib/utils/app-info-parser/zip.d.ts +18 -0
- package/lib/utils/app-info-parser/zip.js +7 -9
- package/lib/utils/check-lockfile.d.ts +1 -0
- package/lib/utils/check-plugin.d.ts +7 -0
- package/lib/utils/command-result.d.ts +3 -0
- package/lib/utils/command-result.js +35 -0
- package/lib/utils/constants.d.ts +9 -0
- package/lib/utils/dep-versions.d.ts +1 -0
- package/lib/utils/git.d.ts +8 -0
- package/lib/utils/http-helper.d.ts +4 -0
- package/lib/utils/i18n.d.ts +12 -0
- package/lib/utils/index.d.ts +22 -0
- package/lib/utils/index.js +52 -22
- package/lib/utils/latest-version/cli.d.ts +1 -0
- package/lib/utils/latest-version/cli.js +24 -60
- package/lib/utils/latest-version/index.d.ts +146 -0
- package/lib/utils/latest-version/index.js +22 -22
- package/lib/utils/options.d.ts +4 -0
- package/lib/utils/options.js +63 -0
- package/lib/utils/plugin-config.d.ts +9 -0
- package/lib/utils/zip-entries.d.ts +3 -0
- package/lib/versions.d.ts +43 -0
- package/lib/versions.js +186 -2
- package/lib/workflow-runner.d.ts +2 -0
- package/lib/workflow-runner.js +25 -0
- package/package.json +20 -5
- package/src/api.ts +1 -1
- package/src/app.ts +20 -11
- package/src/bundle-pack.ts +51 -0
- package/src/bundle-runner.ts +463 -0
- package/src/bundle.ts +184 -571
- package/src/diff.ts +208 -174
- package/src/index.ts +15 -17
- package/src/locales/en.ts +15 -0
- package/src/locales/zh.ts +13 -0
- package/src/module-manager.ts +15 -15
- package/src/modules/app-module.ts +120 -48
- package/src/modules/bundle-module.ts +21 -11
- package/src/modules/package-module.ts +0 -1
- package/src/modules/user-module.ts +117 -58
- package/src/package.ts +158 -138
- package/src/provider.ts +164 -240
- package/src/types.ts +15 -8
- package/src/utils/app-info-parser/aab.ts +0 -7
- package/src/utils/app-info-parser/apk.ts +9 -6
- package/src/utils/app-info-parser/app.ts +5 -1
- package/src/utils/app-info-parser/index.ts +11 -6
- package/src/utils/app-info-parser/ipa.ts +1 -1
- package/src/utils/app-info-parser/utils.ts +3 -0
- package/src/utils/app-info-parser/xml-parser/manifest.ts +3 -1
- package/src/utils/app-info-parser/zip.ts +12 -14
- package/src/utils/command-result.ts +24 -0
- package/src/utils/index.ts +138 -39
- package/src/utils/latest-version/cli.ts +22 -20
- package/src/utils/latest-version/index.ts +20 -20
- package/src/utils/options.ts +56 -0
- package/src/utils/zip-entries.ts +1 -1
- package/src/versions.ts +265 -2
- package/src/workflow-runner.ts +24 -0
- package/index.js +0 -1
package/src/diff.ts
CHANGED
|
@@ -2,12 +2,29 @@ import path from 'path';
|
|
|
2
2
|
import * as fs from 'fs-extra';
|
|
3
3
|
import { npm, yarn } from 'global-dirs';
|
|
4
4
|
import { ZipFile as YazlZipFile } from 'yazl';
|
|
5
|
+
import type { CommandContext } from './types';
|
|
5
6
|
import { translateOptions } from './utils';
|
|
6
7
|
import { isPPKBundleFileName, scriptName, tempDir } from './utils/constants';
|
|
7
8
|
import { t } from './utils/i18n';
|
|
8
9
|
import { enumZipEntries, readEntry } from './utils/zip-entries';
|
|
9
10
|
|
|
10
11
|
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
|
|
12
|
+
type EntryMap = Record<string, { crc32: number; fileName: string }>;
|
|
13
|
+
type CrcMap = Record<number, string>;
|
|
14
|
+
type CopyMap = Record<string, string>;
|
|
15
|
+
type PackagePathTransform = (v: string) => string | undefined;
|
|
16
|
+
type DiffTarget =
|
|
17
|
+
| { kind: 'ppk' }
|
|
18
|
+
| {
|
|
19
|
+
kind: 'package';
|
|
20
|
+
originBundleName: string;
|
|
21
|
+
transformPackagePath?: PackagePathTransform;
|
|
22
|
+
};
|
|
23
|
+
type DiffCommandConfig = {
|
|
24
|
+
diffFnName: string;
|
|
25
|
+
useHdiff: boolean;
|
|
26
|
+
target: DiffTarget;
|
|
27
|
+
};
|
|
11
28
|
|
|
12
29
|
export { enumZipEntries, readEntry };
|
|
13
30
|
|
|
@@ -25,26 +42,28 @@ const loadDiffModule = (pkgName: string): Diff | undefined => {
|
|
|
25
42
|
return undefined;
|
|
26
43
|
};
|
|
27
44
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
let bsdiff: Diff | undefined;
|
|
31
|
-
let diff: Diff;
|
|
32
|
-
bsdiff = loadDiffModule('node-bsdiff');
|
|
45
|
+
const hdiff = loadDiffModule('node-hdiffpatch');
|
|
46
|
+
const bsdiff = loadDiffModule('node-bsdiff');
|
|
33
47
|
|
|
34
|
-
function basename(fn: string) {
|
|
48
|
+
function basename(fn: string): string | undefined {
|
|
35
49
|
const m = /^(.+\/)[^\/]+\/?$/.exec(fn);
|
|
36
50
|
return m?.[1];
|
|
37
51
|
}
|
|
38
52
|
|
|
39
|
-
async function diffFromPPK(
|
|
53
|
+
async function diffFromPPK(
|
|
54
|
+
origin: string,
|
|
55
|
+
next: string,
|
|
56
|
+
output: string,
|
|
57
|
+
diffFn: Diff,
|
|
58
|
+
) {
|
|
40
59
|
fs.ensureDirSync(path.dirname(output));
|
|
41
60
|
|
|
42
|
-
const originEntries = {};
|
|
43
|
-
const originMap = {};
|
|
61
|
+
const originEntries: EntryMap = {};
|
|
62
|
+
const originMap: CrcMap = {};
|
|
44
63
|
|
|
45
64
|
let originSource: Buffer | undefined;
|
|
46
65
|
|
|
47
|
-
await enumZipEntries(origin, (entry, zipFile) => {
|
|
66
|
+
await enumZipEntries(origin, async (entry, zipFile) => {
|
|
48
67
|
originEntries[entry.fileName] = entry;
|
|
49
68
|
if (!/\/$/.test(entry.fileName)) {
|
|
50
69
|
// isFile
|
|
@@ -52,7 +71,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
52
71
|
|
|
53
72
|
if (isPPKBundleFileName(entry.fileName)) {
|
|
54
73
|
// This is source.
|
|
55
|
-
|
|
74
|
+
originSource = await readEntry(entry, zipFile);
|
|
56
75
|
}
|
|
57
76
|
}
|
|
58
77
|
});
|
|
@@ -61,26 +80,25 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
61
80
|
throw new Error(t('bundleFileNotFound'));
|
|
62
81
|
}
|
|
63
82
|
|
|
64
|
-
const copies = {};
|
|
83
|
+
const copies: CopyMap = {};
|
|
65
84
|
|
|
66
85
|
const zipfile = new YazlZipFile();
|
|
67
86
|
|
|
68
|
-
const writePromise = new Promise((resolve, reject) => {
|
|
69
|
-
zipfile.outputStream.on('error',
|
|
70
|
-
throw err;
|
|
71
|
-
});
|
|
87
|
+
const writePromise = new Promise<void>((resolve, reject) => {
|
|
88
|
+
zipfile.outputStream.on('error', reject);
|
|
72
89
|
zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
|
|
73
90
|
resolve(void 0);
|
|
74
91
|
});
|
|
75
92
|
});
|
|
76
93
|
|
|
77
|
-
const addedEntry = {};
|
|
94
|
+
const addedEntry: Record<string, true> = {};
|
|
78
95
|
|
|
79
96
|
function addEntry(fn: string) {
|
|
80
97
|
//console.log(fn);
|
|
81
98
|
if (!fn || addedEntry[fn]) {
|
|
82
99
|
return;
|
|
83
100
|
}
|
|
101
|
+
addedEntry[fn] = true;
|
|
84
102
|
const base = basename(fn);
|
|
85
103
|
if (base) {
|
|
86
104
|
addEntry(base);
|
|
@@ -88,9 +106,9 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
88
106
|
zipfile.addEmptyDirectory(fn);
|
|
89
107
|
}
|
|
90
108
|
|
|
91
|
-
const newEntries = {};
|
|
109
|
+
const newEntries: EntryMap = {};
|
|
92
110
|
|
|
93
|
-
await enumZipEntries(next, (entry, nextZipfile) => {
|
|
111
|
+
await enumZipEntries(next, async (entry, nextZipfile) => {
|
|
94
112
|
newEntries[entry.fileName] = entry;
|
|
95
113
|
|
|
96
114
|
if (/\/$/.test(entry.fileName)) {
|
|
@@ -100,14 +118,13 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
100
118
|
}
|
|
101
119
|
} else if (isPPKBundleFileName(entry.fileName)) {
|
|
102
120
|
//console.log('Found bundle');
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
});
|
|
121
|
+
const newSource = await readEntry(entry, nextZipfile);
|
|
122
|
+
//console.log('Begin diff');
|
|
123
|
+
zipfile.addBuffer(
|
|
124
|
+
diffFn(originSource, newSource),
|
|
125
|
+
`${entry.fileName}.patch`,
|
|
126
|
+
);
|
|
127
|
+
//console.log('End diff');
|
|
111
128
|
} else {
|
|
112
129
|
// If same file.
|
|
113
130
|
const originEntry = originEntries[entry.fileName];
|
|
@@ -117,23 +134,32 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
117
134
|
}
|
|
118
135
|
|
|
119
136
|
// If moved from other place
|
|
120
|
-
|
|
137
|
+
const movedFrom = originMap[entry.crc32];
|
|
138
|
+
if (movedFrom) {
|
|
121
139
|
const base = basename(entry.fileName);
|
|
122
|
-
if (!originEntries[base]) {
|
|
140
|
+
if (base && !originEntries[base]) {
|
|
123
141
|
addEntry(base);
|
|
124
142
|
}
|
|
125
|
-
copies[entry.fileName] =
|
|
143
|
+
copies[entry.fileName] = movedFrom;
|
|
126
144
|
return;
|
|
127
145
|
}
|
|
128
146
|
|
|
129
147
|
// New file.
|
|
130
|
-
|
|
148
|
+
const basePath = basename(entry.fileName);
|
|
149
|
+
if (basePath) {
|
|
150
|
+
addEntry(basePath);
|
|
151
|
+
}
|
|
131
152
|
|
|
132
|
-
|
|
153
|
+
await new Promise<void>((resolve, reject) => {
|
|
133
154
|
nextZipfile.openReadStream(entry, (err, readStream) => {
|
|
134
155
|
if (err) {
|
|
135
156
|
return reject(err);
|
|
136
157
|
}
|
|
158
|
+
if (!readStream) {
|
|
159
|
+
return reject(
|
|
160
|
+
new Error(`Unable to read zip entry: ${entry.fileName}`),
|
|
161
|
+
);
|
|
162
|
+
}
|
|
137
163
|
zipfile.addReadStream(readStream, entry.fileName);
|
|
138
164
|
readStream.on('end', () => {
|
|
139
165
|
//console.log('add finished');
|
|
@@ -144,7 +170,7 @@ async function diffFromPPK(origin: string, next: string, output: string) {
|
|
|
144
170
|
}
|
|
145
171
|
});
|
|
146
172
|
|
|
147
|
-
const deletes = {};
|
|
173
|
+
const deletes: Record<string, 1> = {};
|
|
148
174
|
|
|
149
175
|
for (const k in originEntries) {
|
|
150
176
|
if (!newEntries[k]) {
|
|
@@ -166,17 +192,18 @@ async function diffFromPackage(
|
|
|
166
192
|
origin: string,
|
|
167
193
|
next: string,
|
|
168
194
|
output: string,
|
|
195
|
+
diffFn: Diff,
|
|
169
196
|
originBundleName: string,
|
|
170
|
-
transformPackagePath = (v: string) => v,
|
|
197
|
+
transformPackagePath: (v: string) => string | undefined = (v: string) => v,
|
|
171
198
|
) {
|
|
172
199
|
fs.ensureDirSync(path.dirname(output));
|
|
173
200
|
|
|
174
|
-
const originEntries = {};
|
|
175
|
-
const originMap = {};
|
|
201
|
+
const originEntries: Record<string, number> = {};
|
|
202
|
+
const originMap: CrcMap = {};
|
|
176
203
|
|
|
177
204
|
let originSource: Buffer | undefined;
|
|
178
205
|
|
|
179
|
-
await enumZipEntries(origin, (entry, zipFile) => {
|
|
206
|
+
await enumZipEntries(origin, async (entry, zipFile) => {
|
|
180
207
|
if (!/\/$/.test(entry.fileName)) {
|
|
181
208
|
const fn = transformPackagePath(entry.fileName);
|
|
182
209
|
if (!fn) {
|
|
@@ -190,7 +217,7 @@ async function diffFromPackage(
|
|
|
190
217
|
|
|
191
218
|
if (fn === originBundleName) {
|
|
192
219
|
// This is source.
|
|
193
|
-
|
|
220
|
+
originSource = await readEntry(entry, zipFile);
|
|
194
221
|
}
|
|
195
222
|
}
|
|
196
223
|
});
|
|
@@ -199,33 +226,30 @@ async function diffFromPackage(
|
|
|
199
226
|
throw new Error(t('bundleFileNotFound'));
|
|
200
227
|
}
|
|
201
228
|
|
|
202
|
-
const copies = {};
|
|
229
|
+
const copies: CopyMap = {};
|
|
203
230
|
|
|
204
231
|
const zipfile = new YazlZipFile();
|
|
205
232
|
|
|
206
|
-
const writePromise = new Promise((resolve, reject) => {
|
|
207
|
-
zipfile.outputStream.on('error',
|
|
208
|
-
throw err;
|
|
209
|
-
});
|
|
233
|
+
const writePromise = new Promise<void>((resolve, reject) => {
|
|
234
|
+
zipfile.outputStream.on('error', reject);
|
|
210
235
|
zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
|
|
211
236
|
resolve(void 0);
|
|
212
237
|
});
|
|
213
238
|
});
|
|
214
239
|
|
|
215
|
-
await enumZipEntries(next, (entry, nextZipfile) => {
|
|
240
|
+
await enumZipEntries(next, async (entry, nextZipfile) => {
|
|
216
241
|
if (/\/$/.test(entry.fileName)) {
|
|
217
242
|
// Directory
|
|
218
243
|
zipfile.addEmptyDirectory(entry.fileName);
|
|
219
244
|
} else if (isPPKBundleFileName(entry.fileName)) {
|
|
220
245
|
//console.log('Found bundle');
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
});
|
|
246
|
+
const newSource = await readEntry(entry, nextZipfile);
|
|
247
|
+
//console.log('Begin diff');
|
|
248
|
+
zipfile.addBuffer(
|
|
249
|
+
diffFn(originSource, newSource),
|
|
250
|
+
`${entry.fileName}.patch`,
|
|
251
|
+
);
|
|
252
|
+
//console.log('End diff');
|
|
229
253
|
} else {
|
|
230
254
|
// If same file.
|
|
231
255
|
if (originEntries[entry.fileName] === entry.crc32) {
|
|
@@ -233,16 +257,22 @@ async function diffFromPackage(
|
|
|
233
257
|
return;
|
|
234
258
|
}
|
|
235
259
|
// If moved from other place
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
const movedFrom = originMap[entry.crc32];
|
|
261
|
+
if (movedFrom) {
|
|
262
|
+
copies[entry.fileName] = movedFrom;
|
|
238
263
|
return;
|
|
239
264
|
}
|
|
240
265
|
|
|
241
|
-
|
|
266
|
+
await new Promise<void>((resolve, reject) => {
|
|
242
267
|
nextZipfile.openReadStream(entry, (err, readStream) => {
|
|
243
268
|
if (err) {
|
|
244
269
|
return reject(err);
|
|
245
270
|
}
|
|
271
|
+
if (!readStream) {
|
|
272
|
+
return reject(
|
|
273
|
+
new Error(`Unable to read zip entry: ${entry.fileName}`),
|
|
274
|
+
);
|
|
275
|
+
}
|
|
246
276
|
zipfile.addReadStream(readStream, entry.fileName);
|
|
247
277
|
readStream.on('end', () => {
|
|
248
278
|
//console.log('add finished');
|
|
@@ -258,147 +288,151 @@ async function diffFromPackage(
|
|
|
258
288
|
await writePromise;
|
|
259
289
|
}
|
|
260
290
|
|
|
261
|
-
|
|
262
|
-
|
|
291
|
+
type DiffCommandOptions = {
|
|
292
|
+
customDiff?: Diff;
|
|
293
|
+
[key: string]: any;
|
|
294
|
+
};
|
|
263
295
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
296
|
+
function resolveDiffImplementation(
|
|
297
|
+
useHdiff: boolean,
|
|
298
|
+
options: DiffCommandOptions,
|
|
299
|
+
): Diff {
|
|
300
|
+
if (options.customDiff) {
|
|
301
|
+
return options.customDiff;
|
|
267
302
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
if (!hdiff) {
|
|
273
|
-
console.error(t('nodeHdiffpatchRequired', { scriptName }));
|
|
274
|
-
process.exit(1);
|
|
275
|
-
}
|
|
276
|
-
diff = hdiff;
|
|
277
|
-
} else {
|
|
278
|
-
if (!bsdiff) {
|
|
279
|
-
console.error(t('nodeBsdiffRequired', { scriptName }));
|
|
280
|
-
process.exit(1);
|
|
281
|
-
}
|
|
282
|
-
diff = bsdiff;
|
|
303
|
+
|
|
304
|
+
if (useHdiff) {
|
|
305
|
+
if (!hdiff) {
|
|
306
|
+
throw new Error(t('nodeHdiffpatchRequired', { scriptName }));
|
|
283
307
|
}
|
|
308
|
+
return hdiff;
|
|
284
309
|
}
|
|
285
310
|
|
|
311
|
+
if (!bsdiff) {
|
|
312
|
+
throw new Error(t('nodeBsdiffRequired', { scriptName }));
|
|
313
|
+
}
|
|
314
|
+
return bsdiff;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function diffArgsCheck(
|
|
318
|
+
args: string[],
|
|
319
|
+
options: DiffCommandOptions,
|
|
320
|
+
diffFnName: string,
|
|
321
|
+
useHdiff: boolean,
|
|
322
|
+
) {
|
|
323
|
+
const [origin, next] = args;
|
|
324
|
+
|
|
325
|
+
if (!origin || !next) {
|
|
326
|
+
throw new Error(t('usageDiff', { command: diffFnName }));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const diffFn = resolveDiffImplementation(useHdiff, options);
|
|
286
330
|
const { output } = translateOptions({
|
|
287
331
|
...options,
|
|
288
332
|
tempDir,
|
|
289
333
|
});
|
|
334
|
+
if (typeof output !== 'string') {
|
|
335
|
+
throw new Error('Output path is required.');
|
|
336
|
+
}
|
|
290
337
|
|
|
291
338
|
return {
|
|
292
339
|
origin,
|
|
293
340
|
next,
|
|
341
|
+
diffFn,
|
|
294
342
|
realOutput: output.replace(/\$\{time\}/g, `${Date.now()}`),
|
|
295
343
|
};
|
|
296
344
|
}
|
|
297
345
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
await diffFromPPK(origin, next, realOutput);
|
|
303
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
304
|
-
},
|
|
305
|
-
|
|
306
|
-
async hdiff({ args, options }) {
|
|
307
|
-
const { origin, next, realOutput } = diffArgsCheck(args, options, 'hdiff');
|
|
308
|
-
|
|
309
|
-
await diffFromPPK(origin, next, realOutput);
|
|
310
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
311
|
-
},
|
|
312
|
-
|
|
313
|
-
async diffFromApk({ args, options }) {
|
|
314
|
-
const { origin, next, realOutput } = diffArgsCheck(
|
|
315
|
-
args,
|
|
316
|
-
options,
|
|
317
|
-
'diffFromApk',
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
await diffFromPackage(
|
|
321
|
-
origin,
|
|
322
|
-
next,
|
|
323
|
-
realOutput,
|
|
324
|
-
'assets/index.android.bundle',
|
|
325
|
-
);
|
|
326
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
327
|
-
},
|
|
328
|
-
|
|
329
|
-
async hdiffFromApk({ args, options }) {
|
|
330
|
-
const { origin, next, realOutput } = diffArgsCheck(
|
|
331
|
-
args,
|
|
332
|
-
options,
|
|
333
|
-
'hdiffFromApk',
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
await diffFromPackage(
|
|
337
|
-
origin,
|
|
338
|
-
next,
|
|
339
|
-
realOutput,
|
|
340
|
-
'assets/index.android.bundle',
|
|
341
|
-
);
|
|
342
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
343
|
-
},
|
|
344
|
-
|
|
345
|
-
async diffFromApp({ args, options }) {
|
|
346
|
-
const { origin, next, realOutput } = diffArgsCheck(
|
|
347
|
-
args,
|
|
348
|
-
options,
|
|
349
|
-
'diffFromApp',
|
|
350
|
-
);
|
|
351
|
-
await diffFromPackage(
|
|
352
|
-
origin,
|
|
353
|
-
next,
|
|
354
|
-
realOutput,
|
|
355
|
-
'resources/rawfile/bundle.harmony.js',
|
|
356
|
-
);
|
|
357
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
async hdiffFromApp({ args, options }) {
|
|
361
|
-
const { origin, next, realOutput } = diffArgsCheck(
|
|
362
|
-
args,
|
|
363
|
-
options,
|
|
364
|
-
'hdiffFromApp',
|
|
365
|
-
);
|
|
366
|
-
await diffFromPackage(
|
|
367
|
-
origin,
|
|
368
|
-
next,
|
|
369
|
-
realOutput,
|
|
370
|
-
'resources/rawfile/bundle.harmony.js',
|
|
371
|
-
);
|
|
372
|
-
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
373
|
-
},
|
|
346
|
+
const transformIpaPackagePath: PackagePathTransform = (v) => {
|
|
347
|
+
const match = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
348
|
+
return match?.[1];
|
|
349
|
+
};
|
|
374
350
|
|
|
375
|
-
|
|
376
|
-
|
|
351
|
+
const createDiffCommand =
|
|
352
|
+
({ diffFnName, useHdiff, target }: DiffCommandConfig) =>
|
|
353
|
+
async ({ args, options }: CommandContext) => {
|
|
354
|
+
const { origin, next, realOutput, diffFn } = diffArgsCheck(
|
|
377
355
|
args,
|
|
378
|
-
options,
|
|
379
|
-
|
|
356
|
+
options as DiffCommandOptions,
|
|
357
|
+
diffFnName,
|
|
358
|
+
useHdiff,
|
|
380
359
|
);
|
|
381
360
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
361
|
+
if (target.kind === 'ppk') {
|
|
362
|
+
await diffFromPPK(origin, next, realOutput, diffFn);
|
|
363
|
+
} else {
|
|
364
|
+
await diffFromPackage(
|
|
365
|
+
origin,
|
|
366
|
+
next,
|
|
367
|
+
realOutput,
|
|
368
|
+
diffFn,
|
|
369
|
+
target.originBundleName,
|
|
370
|
+
target.transformPackagePath,
|
|
371
|
+
);
|
|
372
|
+
}
|
|
386
373
|
|
|
387
374
|
console.log(t('diffPackageGenerated', { output: realOutput }));
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
async hdiffFromIpa({ args, options }) {
|
|
391
|
-
const { origin, next, realOutput } = diffArgsCheck(
|
|
392
|
-
args,
|
|
393
|
-
options,
|
|
394
|
-
'hdiffFromIpa',
|
|
395
|
-
);
|
|
396
|
-
|
|
397
|
-
await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
|
|
398
|
-
const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
|
|
399
|
-
return m?.[1];
|
|
400
|
-
});
|
|
375
|
+
};
|
|
401
376
|
|
|
402
|
-
|
|
403
|
-
|
|
377
|
+
export const diffCommands = {
|
|
378
|
+
diff: createDiffCommand({
|
|
379
|
+
diffFnName: 'diff',
|
|
380
|
+
useHdiff: false,
|
|
381
|
+
target: { kind: 'ppk' },
|
|
382
|
+
}),
|
|
383
|
+
hdiff: createDiffCommand({
|
|
384
|
+
diffFnName: 'hdiff',
|
|
385
|
+
useHdiff: true,
|
|
386
|
+
target: { kind: 'ppk' },
|
|
387
|
+
}),
|
|
388
|
+
diffFromApk: createDiffCommand({
|
|
389
|
+
diffFnName: 'diffFromApk',
|
|
390
|
+
useHdiff: false,
|
|
391
|
+
target: {
|
|
392
|
+
kind: 'package',
|
|
393
|
+
originBundleName: 'assets/index.android.bundle',
|
|
394
|
+
},
|
|
395
|
+
}),
|
|
396
|
+
hdiffFromApk: createDiffCommand({
|
|
397
|
+
diffFnName: 'hdiffFromApk',
|
|
398
|
+
useHdiff: true,
|
|
399
|
+
target: {
|
|
400
|
+
kind: 'package',
|
|
401
|
+
originBundleName: 'assets/index.android.bundle',
|
|
402
|
+
},
|
|
403
|
+
}),
|
|
404
|
+
diffFromApp: createDiffCommand({
|
|
405
|
+
diffFnName: 'diffFromApp',
|
|
406
|
+
useHdiff: false,
|
|
407
|
+
target: {
|
|
408
|
+
kind: 'package',
|
|
409
|
+
originBundleName: 'resources/rawfile/bundle.harmony.js',
|
|
410
|
+
},
|
|
411
|
+
}),
|
|
412
|
+
hdiffFromApp: createDiffCommand({
|
|
413
|
+
diffFnName: 'hdiffFromApp',
|
|
414
|
+
useHdiff: true,
|
|
415
|
+
target: {
|
|
416
|
+
kind: 'package',
|
|
417
|
+
originBundleName: 'resources/rawfile/bundle.harmony.js',
|
|
418
|
+
},
|
|
419
|
+
}),
|
|
420
|
+
diffFromIpa: createDiffCommand({
|
|
421
|
+
diffFnName: 'diffFromIpa',
|
|
422
|
+
useHdiff: false,
|
|
423
|
+
target: {
|
|
424
|
+
kind: 'package',
|
|
425
|
+
originBundleName: 'main.jsbundle',
|
|
426
|
+
transformPackagePath: transformIpaPackagePath,
|
|
427
|
+
},
|
|
428
|
+
}),
|
|
429
|
+
hdiffFromIpa: createDiffCommand({
|
|
430
|
+
diffFnName: 'hdiffFromIpa',
|
|
431
|
+
useHdiff: true,
|
|
432
|
+
target: {
|
|
433
|
+
kind: 'package',
|
|
434
|
+
originBundleName: 'main.jsbundle',
|
|
435
|
+
transformPackagePath: transformIpaPackagePath,
|
|
436
|
+
},
|
|
437
|
+
}),
|
|
404
438
|
};
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,14 @@ import { printVersionCommand } from './utils';
|
|
|
14
14
|
import { t } from './utils/i18n';
|
|
15
15
|
import { versionCommands } from './versions';
|
|
16
16
|
|
|
17
|
+
type LegacyCommandHandler = (argv: any) => Promise<unknown> | unknown;
|
|
18
|
+
|
|
19
|
+
interface CliArgv {
|
|
20
|
+
command: string;
|
|
21
|
+
args: string[];
|
|
22
|
+
options: Record<string, any>;
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
function registerBuiltinModules() {
|
|
18
26
|
for (const module of builtinModules) {
|
|
19
27
|
try {
|
|
@@ -28,24 +36,13 @@ function printUsage() {
|
|
|
28
36
|
console.log('React Native Update CLI');
|
|
29
37
|
console.log('');
|
|
30
38
|
console.log('Traditional commands:');
|
|
31
|
-
|
|
32
|
-
const legacyCommands = {
|
|
33
|
-
...userCommands,
|
|
34
|
-
...bundleCommands,
|
|
35
|
-
...diffCommands,
|
|
36
|
-
...appCommands,
|
|
37
|
-
...packageCommands,
|
|
38
|
-
...versionCommands,
|
|
39
|
-
...installCommands,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
for (const [name, handler] of Object.entries(legacyCommands)) {
|
|
39
|
+
for (const name of Object.keys(legacyCommands)) {
|
|
43
40
|
console.log(` ${name}: Legacy command`);
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
console.log('');
|
|
47
44
|
console.log('Modular commands:');
|
|
48
|
-
const commands = moduleManager.
|
|
45
|
+
const commands = moduleManager.listCommands();
|
|
49
46
|
for (const command of commands) {
|
|
50
47
|
console.log(
|
|
51
48
|
` ${command.name}: ${command.description || 'No description'}`,
|
|
@@ -54,7 +51,7 @@ function printUsage() {
|
|
|
54
51
|
|
|
55
52
|
console.log('');
|
|
56
53
|
console.log('Available workflows:');
|
|
57
|
-
const workflows = moduleManager.
|
|
54
|
+
const workflows = moduleManager.listWorkflows();
|
|
58
55
|
for (const workflow of workflows) {
|
|
59
56
|
console.log(
|
|
60
57
|
` ${workflow.name}: ${workflow.description || 'No description'}`,
|
|
@@ -74,7 +71,7 @@ function printUsage() {
|
|
|
74
71
|
process.exit(1);
|
|
75
72
|
}
|
|
76
73
|
|
|
77
|
-
const legacyCommands = {
|
|
74
|
+
const legacyCommands: Record<string, LegacyCommandHandler> = {
|
|
78
75
|
...userCommands,
|
|
79
76
|
...bundleCommands,
|
|
80
77
|
...diffCommands,
|
|
@@ -94,7 +91,7 @@ async function run() {
|
|
|
94
91
|
// Register builtin modules for modular functionality
|
|
95
92
|
registerBuiltinModules();
|
|
96
93
|
|
|
97
|
-
const argv = require('cli-arguments').parse(require('../cli.json'));
|
|
94
|
+
const argv: CliArgv = require('cli-arguments').parse(require('../cli.json'));
|
|
98
95
|
global.NO_INTERACTIVE = argv.options['no-interactive'];
|
|
99
96
|
global.USE_ACC_OSS = argv.options.acc;
|
|
100
97
|
|
|
@@ -127,7 +124,8 @@ async function run() {
|
|
|
127
124
|
}
|
|
128
125
|
// Try legacy commands first for backward compatibility
|
|
129
126
|
else if (legacyCommands[argv.command]) {
|
|
130
|
-
|
|
127
|
+
const legacyHandler = legacyCommands[argv.command];
|
|
128
|
+
await legacyHandler(argv);
|
|
131
129
|
}
|
|
132
130
|
// Fall back to modular commands
|
|
133
131
|
else {
|
package/src/locales/en.ts
CHANGED
|
@@ -96,6 +96,21 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
|
|
96
96
|
packageIdRequired: 'Please provide packageId or packageVersion parameter',
|
|
97
97
|
packageUploadSuccess:
|
|
98
98
|
'Successfully uploaded new hot update package (id: {{id}})',
|
|
99
|
+
depsChangeSummary:
|
|
100
|
+
'Dependency changes: added {{added}}, removed {{removed}}, changed {{changed}}.',
|
|
101
|
+
depsChangeTargetPackage:
|
|
102
|
+
'Target native package: {{packageName}} (id: {{packageId}})',
|
|
103
|
+
depsChangeDependencyHeader: 'Dependency',
|
|
104
|
+
depsChangeVersionHeader: 'Version change',
|
|
105
|
+
depsChangeAddedLabel: 'Added',
|
|
106
|
+
depsChangeRemovedLabel: 'Removed',
|
|
107
|
+
depsChangeChangedLabel: 'Changed',
|
|
108
|
+
depsChangeArrow: '->',
|
|
109
|
+
depsChangeRiskWarning:
|
|
110
|
+
'Warning: if changed dependencies are pure JS modules, impact is usually low; if native code is newly introduced or changed, OTA update may cause abnormal behavior or even crashes. Test thoroughly before production release.',
|
|
111
|
+
depsChangeFetchFailed: 'Failed to fetch OTA dependency info: {{error}}',
|
|
112
|
+
depsChangeNonBlockingHint:
|
|
113
|
+
'This is only a dependency change warning and will not block publishing.',
|
|
99
114
|
packing: 'Packing',
|
|
100
115
|
pausedStatus: '(Paused)',
|
|
101
116
|
platform: 'Platform',
|
package/src/locales/zh.ts
CHANGED
|
@@ -89,6 +89,19 @@ export default {
|
|
|
89
89
|
operationSuccess: '操作成功',
|
|
90
90
|
packageIdRequired: '请提供 packageId 或 packageVersion 参数',
|
|
91
91
|
packageUploadSuccess: '已成功上传新热更包(id: {{id}})',
|
|
92
|
+
depsChangeSummary:
|
|
93
|
+
'依赖变化:新增 {{added}} 项,移除 {{removed}} 项,版本变更 {{changed}} 项。',
|
|
94
|
+
depsChangeTargetPackage: '目标原生包:{{packageName}} (id: {{packageId}})',
|
|
95
|
+
depsChangeDependencyHeader: '依赖',
|
|
96
|
+
depsChangeVersionHeader: '版本变化',
|
|
97
|
+
depsChangeAddedLabel: '新增',
|
|
98
|
+
depsChangeRemovedLabel: '移除',
|
|
99
|
+
depsChangeChangedLabel: '变更',
|
|
100
|
+
depsChangeArrow: '->',
|
|
101
|
+
depsChangeRiskWarning:
|
|
102
|
+
'警告:如果变更依赖是纯 JS 模块,则一般没有影响;若包含原生代码新增或变化,热更可能导致功能不正常甚至闪退,建议发布前使用扫码功能完整测试。',
|
|
103
|
+
depsChangeFetchFailed: '获取热更依赖信息失败:{{error}}',
|
|
104
|
+
depsChangeNonBlockingHint: '以上仅为依赖变化提示,不会阻止本次发布。',
|
|
92
105
|
packing: '正在打包',
|
|
93
106
|
pausedStatus: '(已暂停)',
|
|
94
107
|
platform: '平台',
|