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.
Files changed (112) hide show
  1. package/lib/api.d.ts +18 -0
  2. package/lib/app.d.ts +38 -0
  3. package/lib/app.js +5 -4
  4. package/lib/bundle-pack.d.ts +1 -0
  5. package/lib/bundle-pack.js +104 -0
  6. package/lib/bundle-runner.d.ts +20 -0
  7. package/lib/bundle-runner.js +404 -0
  8. package/lib/bundle.d.ts +6 -0
  9. package/lib/bundle.js +73 -471
  10. package/lib/diff.d.ts +13 -0
  11. package/lib/diff.js +144 -123
  12. package/lib/exports.d.ts +12 -0
  13. package/lib/index.d.ts +5 -0
  14. package/lib/index.js +5 -13
  15. package/lib/install.d.ts +4 -0
  16. package/lib/locales/en.d.ts +137 -0
  17. package/lib/locales/en.js +11 -0
  18. package/lib/locales/zh.d.ts +136 -0
  19. package/lib/locales/zh.js +11 -0
  20. package/lib/module-manager.d.ts +20 -0
  21. package/lib/module-manager.js +3 -9
  22. package/lib/modules/app-module.d.ts +2 -0
  23. package/lib/modules/app-module.js +84 -44
  24. package/lib/modules/bundle-module.d.ts +2 -0
  25. package/lib/modules/bundle-module.js +7 -8
  26. package/lib/modules/index.d.ts +6 -0
  27. package/lib/modules/package-module.d.ts +2 -0
  28. package/lib/modules/user-module.d.ts +2 -0
  29. package/lib/modules/user-module.js +55 -44
  30. package/lib/modules/version-module.d.ts +2 -0
  31. package/lib/package.d.ts +58 -0
  32. package/lib/package.js +103 -139
  33. package/lib/provider.d.ts +26 -0
  34. package/lib/provider.js +115 -217
  35. package/lib/types.d.ts +120 -0
  36. package/lib/user.d.ts +8 -0
  37. package/lib/utils/add-gitignore.d.ts +1 -0
  38. package/lib/utils/app-info-parser/aab.d.ts +22 -0
  39. package/lib/utils/app-info-parser/aab.js +0 -4
  40. package/lib/utils/app-info-parser/apk.d.ts +14 -0
  41. package/lib/utils/app-info-parser/apk.js +6 -4
  42. package/lib/utils/app-info-parser/app.d.ts +4 -0
  43. package/lib/utils/app-info-parser/app.js +3 -0
  44. package/lib/utils/app-info-parser/index.d.ts +16 -0
  45. package/lib/utils/app-info-parser/index.js +2 -0
  46. package/lib/utils/app-info-parser/ipa.d.ts +14 -0
  47. package/lib/utils/app-info-parser/ipa.js +1 -1
  48. package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
  49. package/lib/utils/app-info-parser/utils.d.ts +31 -0
  50. package/lib/utils/app-info-parser/utils.js +1 -0
  51. package/lib/utils/app-info-parser/xml-parser/binary.d.ts +56 -0
  52. package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +10 -0
  53. package/lib/utils/app-info-parser/zip.d.ts +18 -0
  54. package/lib/utils/app-info-parser/zip.js +7 -9
  55. package/lib/utils/check-lockfile.d.ts +1 -0
  56. package/lib/utils/check-plugin.d.ts +7 -0
  57. package/lib/utils/command-result.d.ts +3 -0
  58. package/lib/utils/command-result.js +35 -0
  59. package/lib/utils/constants.d.ts +9 -0
  60. package/lib/utils/dep-versions.d.ts +1 -0
  61. package/lib/utils/git.d.ts +8 -0
  62. package/lib/utils/http-helper.d.ts +4 -0
  63. package/lib/utils/i18n.d.ts +12 -0
  64. package/lib/utils/index.d.ts +22 -0
  65. package/lib/utils/index.js +52 -22
  66. package/lib/utils/latest-version/cli.d.ts +1 -0
  67. package/lib/utils/latest-version/cli.js +24 -60
  68. package/lib/utils/latest-version/index.d.ts +146 -0
  69. package/lib/utils/latest-version/index.js +22 -22
  70. package/lib/utils/options.d.ts +4 -0
  71. package/lib/utils/options.js +63 -0
  72. package/lib/utils/plugin-config.d.ts +9 -0
  73. package/lib/utils/zip-entries.d.ts +3 -0
  74. package/lib/versions.d.ts +43 -0
  75. package/lib/versions.js +186 -2
  76. package/lib/workflow-runner.d.ts +2 -0
  77. package/lib/workflow-runner.js +25 -0
  78. package/package.json +20 -5
  79. package/src/api.ts +1 -1
  80. package/src/app.ts +20 -11
  81. package/src/bundle-pack.ts +51 -0
  82. package/src/bundle-runner.ts +463 -0
  83. package/src/bundle.ts +184 -571
  84. package/src/diff.ts +208 -174
  85. package/src/index.ts +15 -17
  86. package/src/locales/en.ts +15 -0
  87. package/src/locales/zh.ts +13 -0
  88. package/src/module-manager.ts +15 -15
  89. package/src/modules/app-module.ts +120 -48
  90. package/src/modules/bundle-module.ts +21 -11
  91. package/src/modules/package-module.ts +0 -1
  92. package/src/modules/user-module.ts +117 -58
  93. package/src/package.ts +158 -138
  94. package/src/provider.ts +164 -240
  95. package/src/types.ts +15 -8
  96. package/src/utils/app-info-parser/aab.ts +0 -7
  97. package/src/utils/app-info-parser/apk.ts +9 -6
  98. package/src/utils/app-info-parser/app.ts +5 -1
  99. package/src/utils/app-info-parser/index.ts +11 -6
  100. package/src/utils/app-info-parser/ipa.ts +1 -1
  101. package/src/utils/app-info-parser/utils.ts +3 -0
  102. package/src/utils/app-info-parser/xml-parser/manifest.ts +3 -1
  103. package/src/utils/app-info-parser/zip.ts +12 -14
  104. package/src/utils/command-result.ts +24 -0
  105. package/src/utils/index.ts +138 -39
  106. package/src/utils/latest-version/cli.ts +22 -20
  107. package/src/utils/latest-version/index.ts +20 -20
  108. package/src/utils/options.ts +56 -0
  109. package/src/utils/zip-entries.ts +1 -1
  110. package/src/versions.ts +265 -2
  111. package/src/workflow-runner.ts +24 -0
  112. 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
- let hdiff: Diff | undefined;
29
- hdiff = (loadDiffModule('node-hdiffpatch') as any)?.diff;
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(origin: string, next: string, output: string) {
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
- return readEntry(entry, zipFile).then((v) => (originSource = v));
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', (err) => {
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
- return readEntry(entry, nextZipfile).then((newSource) => {
104
- //console.log('Begin diff');
105
- zipfile.addBuffer(
106
- diff(originSource, newSource),
107
- `${entry.fileName}.patch`,
108
- );
109
- //console.log('End diff');
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
- if (originMap[entry.crc32]) {
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] = originMap[entry.crc32];
143
+ copies[entry.fileName] = movedFrom;
126
144
  return;
127
145
  }
128
146
 
129
147
  // New file.
130
- addEntry(basename(entry.fileName));
148
+ const basePath = basename(entry.fileName);
149
+ if (basePath) {
150
+ addEntry(basePath);
151
+ }
131
152
 
132
- return new Promise((resolve, reject) => {
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
- return readEntry(entry, zipFile).then((v) => (originSource = v));
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', (err) => {
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
- return readEntry(entry, nextZipfile).then((newSource) => {
222
- //console.log('Begin diff');
223
- zipfile.addBuffer(
224
- diff(originSource, newSource),
225
- `${entry.fileName}.patch`,
226
- );
227
- //console.log('End diff');
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
- if (originMap[entry.crc32]) {
237
- copies[entry.fileName] = originMap[entry.crc32];
260
+ const movedFrom = originMap[entry.crc32];
261
+ if (movedFrom) {
262
+ copies[entry.fileName] = movedFrom;
238
263
  return;
239
264
  }
240
265
 
241
- return new Promise((resolve, reject) => {
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
- function diffArgsCheck(args: string[], options: any, diffFn: string) {
262
- const [origin, next] = args;
291
+ type DiffCommandOptions = {
292
+ customDiff?: Diff;
293
+ [key: string]: any;
294
+ };
263
295
 
264
- if (!origin || !next) {
265
- console.error(t('usageDiff', { command: diffFn }));
266
- process.exit(1);
296
+ function resolveDiffImplementation(
297
+ useHdiff: boolean,
298
+ options: DiffCommandOptions,
299
+ ): Diff {
300
+ if (options.customDiff) {
301
+ return options.customDiff;
267
302
  }
268
- if (options?.customDiff) {
269
- diff = options.customDiff;
270
- } else {
271
- if (diffFn.startsWith('hdiff')) {
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
- export const diffCommands = {
299
- async diff({ args, options }) {
300
- const { origin, next, realOutput } = diffArgsCheck(args, options, 'diff');
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
- async diffFromIpa({ args, options }) {
376
- const { origin, next, realOutput } = diffArgsCheck(
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
- 'diffFromIpa',
356
+ options as DiffCommandOptions,
357
+ diffFnName,
358
+ useHdiff,
380
359
  );
381
360
 
382
- await diffFromPackage(origin, next, realOutput, 'main.jsbundle', (v) => {
383
- const m = /^Payload\/[^/]+\/(.+)$/.exec(v);
384
- return m?.[1];
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
- console.log(t('diffPackageGenerated', { output: realOutput }));
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.getRegisteredCommands();
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.getRegisteredWorkflows();
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
- await legacyCommands[argv.command](argv);
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: '平台',