react-native-update-cli 2.4.2 → 2.6.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 (49) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/cli.json +40 -0
  4. package/lib/api.js +1 -1
  5. package/lib/locales/en.js +16 -1
  6. package/lib/locales/zh.js +16 -1
  7. package/lib/package.js +60 -6
  8. package/lib/provider.js +3 -0
  9. package/lib/utils/app-info-parser/aab.js +230 -0
  10. package/lib/utils/app-info-parser/apk.js +25 -27
  11. package/lib/utils/app-info-parser/app.js +10 -11
  12. package/lib/utils/app-info-parser/index.js +13 -8
  13. package/lib/utils/app-info-parser/ipa.js +16 -21
  14. package/lib/utils/app-info-parser/resource-finder.js +365 -305
  15. package/lib/utils/app-info-parser/utils.js +78 -63
  16. package/lib/utils/app-info-parser/xml-parser/binary.js +57 -51
  17. package/lib/utils/app-info-parser/xml-parser/manifest.js +47 -39
  18. package/lib/utils/app-info-parser/zip.js +21 -11
  19. package/lib/utils/http-helper.js +1 -1
  20. package/lib/utils/index.js +137 -0
  21. package/lib/versions.js +22 -0
  22. package/package.json +3 -2
  23. package/proto/Configuration.proto +183 -0
  24. package/proto/Resources.proto +569 -0
  25. package/src/api.ts +2 -6
  26. package/src/locales/en.ts +20 -0
  27. package/src/locales/zh.ts +18 -0
  28. package/src/modules/version-module.ts +1 -1
  29. package/src/package.ts +112 -12
  30. package/src/provider.ts +3 -0
  31. package/src/utils/app-info-parser/aab.ts +240 -0
  32. package/src/utils/app-info-parser/{apk.js → apk.ts} +30 -41
  33. package/src/utils/app-info-parser/app.ts +3 -0
  34. package/src/utils/app-info-parser/index.ts +9 -5
  35. package/src/utils/app-info-parser/{ipa.js → ipa.ts} +17 -31
  36. package/src/utils/app-info-parser/resource-finder.ts +508 -0
  37. package/src/utils/app-info-parser/utils.ts +162 -0
  38. package/src/utils/app-info-parser/xml-parser/{binary.js → binary.ts} +69 -61
  39. package/src/utils/app-info-parser/xml-parser/{manifest.js → manifest.ts} +50 -51
  40. package/src/utils/app-info-parser/zip.ts +86 -0
  41. package/src/utils/dep-versions.ts +7 -4
  42. package/src/utils/http-helper.ts +1 -1
  43. package/src/utils/index.ts +154 -0
  44. package/src/utils/latest-version/index.ts +2 -1
  45. package/src/versions.ts +27 -2
  46. package/src/utils/app-info-parser/app.js +0 -16
  47. package/src/utils/app-info-parser/resource-finder.js +0 -495
  48. package/src/utils/app-info-parser/utils.js +0 -172
  49. package/src/utils/app-info-parser/zip.js +0 -66
@@ -1,495 +0,0 @@
1
- /**
2
- * Code translated from a C# project https://github.com/hylander0/Iteedee.ApkReader/blob/master/Iteedee.ApkReader/ApkResourceFinder.cs
3
- *
4
- * Decode binary file `resources.arsc` from a .apk file to a JavaScript Object.
5
- */
6
-
7
- var ByteBuffer = require('bytebuffer');
8
-
9
- var DEBUG = false;
10
-
11
- var RES_STRING_POOL_TYPE = 0x0001;
12
- var RES_TABLE_TYPE = 0x0002;
13
- var RES_TABLE_PACKAGE_TYPE = 0x0200;
14
- var RES_TABLE_TYPE_TYPE = 0x0201;
15
- var RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
16
-
17
- // The 'data' holds a ResTable_ref, a reference to another resource
18
- // table entry.
19
- var TYPE_REFERENCE = 0x01;
20
- // The 'data' holds an index into the containing resource table's
21
- // global value string pool.
22
- var TYPE_STRING = 0x03;
23
-
24
- function ResourceFinder() {
25
- this.valueStringPool = null;
26
- this.typeStringPool = null;
27
- this.keyStringPool = null;
28
-
29
- this.package_id = 0;
30
-
31
- this.responseMap = {};
32
- this.entryMap = {};
33
- }
34
-
35
- /**
36
- * Same to C# BinaryReader.readBytes
37
- *
38
- * @param bb ByteBuffer
39
- * @param len length
40
- * @returns {Buffer}
41
- */
42
- ResourceFinder.readBytes = (bb, len) => {
43
- var uint8Array = new Uint8Array(len);
44
- for (var i = 0; i < len; i++) {
45
- uint8Array[i] = bb.readUint8();
46
- }
47
-
48
- return ByteBuffer.wrap(uint8Array, 'binary', true);
49
- };
50
-
51
- //
52
- /**
53
- *
54
- * @param {ByteBuffer} bb
55
- * @return {Map<String, Set<String>>}
56
- */
57
- ResourceFinder.prototype.processResourceTable = function (resourceBuffer) {
58
- const bb = ByteBuffer.wrap(resourceBuffer, 'binary', true);
59
-
60
- // Resource table structure
61
- var type = bb.readShort(),
62
- headerSize = bb.readShort(),
63
- size = bb.readInt(),
64
- packageCount = bb.readInt(),
65
- buffer,
66
- bb2;
67
- if (type != RES_TABLE_TYPE) {
68
- throw new Error('No RES_TABLE_TYPE found!');
69
- }
70
- if (size != bb.limit) {
71
- throw new Error('The buffer size not matches to the resource table size.');
72
- }
73
- bb.offset = headerSize;
74
-
75
- var realStringPoolCount = 0,
76
- realPackageCount = 0;
77
-
78
- while (true) {
79
- var pos, t, hs, s;
80
- try {
81
- pos = bb.offset;
82
- t = bb.readShort();
83
- hs = bb.readShort();
84
- s = bb.readInt();
85
- } catch (e) {
86
- break;
87
- }
88
- if (t == RES_STRING_POOL_TYPE) {
89
- // Process the string pool
90
- if (realStringPoolCount == 0) {
91
- // Only the first string pool is processed.
92
- if (DEBUG) {
93
- console.log('Processing the string pool ...');
94
- }
95
-
96
- buffer = new ByteBuffer(s);
97
- bb.offset = pos;
98
- bb.prependTo(buffer);
99
-
100
- bb2 = ByteBuffer.wrap(buffer, 'binary', true);
101
-
102
- bb2.LE();
103
- this.valueStringPool = this.processStringPool(bb2);
104
- }
105
- realStringPoolCount++;
106
- } else if (t == RES_TABLE_PACKAGE_TYPE) {
107
- // Process the package
108
- if (DEBUG) {
109
- console.log('Processing the package ' + realPackageCount + ' ...');
110
- }
111
-
112
- buffer = new ByteBuffer(s);
113
- bb.offset = pos;
114
- bb.prependTo(buffer);
115
-
116
- bb2 = ByteBuffer.wrap(buffer, 'binary', true);
117
- bb2.LE();
118
- this.processPackage(bb2);
119
-
120
- realPackageCount++;
121
- } else {
122
- throw new Error('Unsupported type');
123
- }
124
- bb.offset = pos + s;
125
- if (!bb.remaining()) break;
126
- }
127
-
128
- if (realStringPoolCount != 1) {
129
- throw new Error('More than 1 string pool found!');
130
- }
131
- if (realPackageCount != packageCount) {
132
- throw new Error('Real package count not equals the declared count.');
133
- }
134
-
135
- return this.responseMap;
136
- };
137
-
138
- /**
139
- *
140
- * @param {ByteBuffer} bb
141
- */
142
- ResourceFinder.prototype.processPackage = function (bb) {
143
- // Package structure
144
- var type = bb.readShort(),
145
- headerSize = bb.readShort(),
146
- size = bb.readInt(),
147
- id = bb.readInt();
148
-
149
- this.package_id = id;
150
-
151
- for (var i = 0; i < 256; ++i) {
152
- bb.readUint8();
153
- }
154
-
155
- var typeStrings = bb.readInt(),
156
- lastPublicType = bb.readInt(),
157
- keyStrings = bb.readInt(),
158
- lastPublicKey = bb.readInt();
159
-
160
- if (typeStrings != headerSize) {
161
- throw new Error(
162
- 'TypeStrings must immediately following the package structure header.',
163
- );
164
- }
165
-
166
- if (DEBUG) {
167
- console.log('Type strings:');
168
- }
169
-
170
- var lastPosition = bb.offset;
171
- bb.offset = typeStrings;
172
- var bbTypeStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
173
- bb.offset = lastPosition;
174
- this.typeStringPool = this.processStringPool(bbTypeStrings);
175
-
176
- // Key strings
177
- if (DEBUG) {
178
- console.log('Key strings:');
179
- }
180
-
181
- bb.offset = keyStrings;
182
- var key_type = bb.readShort(),
183
- key_headerSize = bb.readShort(),
184
- key_size = bb.readInt();
185
-
186
- lastPosition = bb.offset;
187
- bb.offset = keyStrings;
188
- var bbKeyStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
189
- bb.offset = lastPosition;
190
- this.keyStringPool = this.processStringPool(bbKeyStrings);
191
-
192
- // Iterate through all chunks
193
- var typeSpecCount = 0;
194
- var typeCount = 0;
195
-
196
- bb.offset = keyStrings + key_size;
197
-
198
- var bb2;
199
-
200
- while (true) {
201
- var pos = bb.offset;
202
- try {
203
- var t = bb.readShort();
204
- var hs = bb.readShort();
205
- var s = bb.readInt();
206
- } catch (e) {
207
- break;
208
- }
209
-
210
- if (t == RES_TABLE_TYPE_SPEC_TYPE) {
211
- bb.offset = pos;
212
- bb2 = ResourceFinder.readBytes(bb, s);
213
- this.processTypeSpec(bb2);
214
-
215
- typeSpecCount++;
216
- } else if (t == RES_TABLE_TYPE_TYPE) {
217
- bb.offset = pos;
218
- bb2 = ResourceFinder.readBytes(bb, s);
219
- this.processType(bb2);
220
-
221
- typeCount++;
222
- }
223
-
224
- if (s == 0) {
225
- break;
226
- }
227
-
228
- bb.offset = pos + s;
229
-
230
- if (!bb.remaining()) {
231
- break;
232
- }
233
- }
234
- };
235
-
236
- /**
237
- *
238
- * @param {ByteBuffer} bb
239
- */
240
- ResourceFinder.prototype.processType = function (bb) {
241
- var type = bb.readShort(),
242
- headerSize = bb.readShort(),
243
- size = bb.readInt(),
244
- id = bb.readByte(),
245
- res0 = bb.readByte(),
246
- res1 = bb.readShort(),
247
- entryCount = bb.readInt(),
248
- entriesStart = bb.readInt();
249
-
250
- var refKeys = {};
251
-
252
- var config_size = bb.readInt();
253
-
254
- // Skip the config data
255
- bb.offset = headerSize;
256
-
257
- if (headerSize + entryCount * 4 != entriesStart) {
258
- throw new Error('HeaderSize, entryCount and entriesStart are not valid.');
259
- }
260
-
261
- // Start to get entry indices
262
- var entryIndices = new Array(entryCount);
263
- for (var i = 0; i < entryCount; ++i) {
264
- entryIndices[i] = bb.readInt();
265
- }
266
-
267
- // Get entries
268
- for (var i = 0; i < entryCount; ++i) {
269
- if (entryIndices[i] == -1) continue;
270
-
271
- var resource_id = (this.package_id << 24) | (id << 16) | i;
272
-
273
- var pos = bb.offset,
274
- entry_size,
275
- entry_flag,
276
- entry_key,
277
- value_size,
278
- value_res0,
279
- value_dataType,
280
- value_data;
281
- try {
282
- entry_size = bb.readShort();
283
- entry_flag = bb.readShort();
284
- entry_key = bb.readInt();
285
- } catch (e) {
286
- break;
287
- }
288
-
289
- // Get the value (simple) or map (complex)
290
-
291
- var FLAG_COMPLEX = 0x0001;
292
- if ((entry_flag & FLAG_COMPLEX) == 0) {
293
- // Simple case
294
- value_size = bb.readShort();
295
- value_res0 = bb.readByte();
296
- value_dataType = bb.readByte();
297
- value_data = bb.readInt();
298
-
299
- var idStr = Number(resource_id).toString(16);
300
- var keyStr = this.keyStringPool[entry_key];
301
-
302
- var data = null;
303
-
304
- if (DEBUG) {
305
- console.log(
306
- 'Entry 0x' + idStr + ', key: ' + keyStr + ', simple value type: ',
307
- );
308
- }
309
-
310
- var key = Number.parseInt(idStr, 16);
311
-
312
- var entryArr = this.entryMap[key];
313
- if (entryArr == null) {
314
- entryArr = [];
315
- }
316
- entryArr.push(keyStr);
317
-
318
- this.entryMap[key] = entryArr;
319
-
320
- if (value_dataType == TYPE_STRING) {
321
- data = this.valueStringPool[value_data];
322
-
323
- if (DEBUG) {
324
- console.log(', data: ' + this.valueStringPool[value_data] + '');
325
- }
326
- } else if (value_dataType == TYPE_REFERENCE) {
327
- var hexIndex = Number(value_data).toString(16);
328
-
329
- refKeys[idStr] = value_data;
330
- } else {
331
- data = '' + value_data;
332
- if (DEBUG) {
333
- console.log(', data: ' + value_data + '');
334
- }
335
- }
336
-
337
- this.putIntoMap('@' + idStr, data);
338
- } else {
339
- // Complex case
340
- var entry_parent = bb.readInt();
341
- var entry_count = bb.readInt();
342
-
343
- for (var j = 0; j < entry_count; ++j) {
344
- var ref_name = bb.readInt();
345
- value_size = bb.readShort();
346
- value_res0 = bb.readByte();
347
- value_dataType = bb.readByte();
348
- value_data = bb.readInt();
349
- }
350
-
351
- if (DEBUG) {
352
- console.log(
353
- 'Entry 0x' +
354
- Number(resource_id).toString(16) +
355
- ', key: ' +
356
- this.keyStringPool[entry_key] +
357
- ', complex value, not printed.',
358
- );
359
- }
360
- }
361
- }
362
-
363
- for (var refK in refKeys) {
364
- var values =
365
- this.responseMap['@' + Number(refKeys[refK]).toString(16).toUpperCase()];
366
- if (values != null && Object.keys(values).length < 1000) {
367
- for (var value in values) {
368
- this.putIntoMap('@' + refK, values[value]);
369
- }
370
- }
371
- }
372
- };
373
-
374
- /**
375
- *
376
- * @param {ByteBuffer} bb
377
- * @return {Array}
378
- */
379
- ResourceFinder.prototype.processStringPool = (bb) => {
380
- // String pool structure
381
- //
382
- var type = bb.readShort(),
383
- headerSize = bb.readShort(),
384
- size = bb.readInt(),
385
- stringCount = bb.readInt(),
386
- styleCount = bb.readInt(),
387
- flags = bb.readInt(),
388
- stringsStart = bb.readInt(),
389
- stylesStart = bb.readInt(),
390
- u16len,
391
- buffer;
392
-
393
- var isUTF_8 = (flags & 256) != 0;
394
-
395
- var offsets = new Array(stringCount);
396
- for (var i = 0; i < stringCount; ++i) {
397
- offsets[i] = bb.readInt();
398
- }
399
-
400
- var strings = new Array(stringCount);
401
-
402
- for (var i = 0; i < stringCount; ++i) {
403
- var pos = stringsStart + offsets[i];
404
- bb.offset = pos;
405
-
406
- strings[i] = '';
407
-
408
- if (isUTF_8) {
409
- u16len = bb.readUint8();
410
-
411
- if ((u16len & 0x80) != 0) {
412
- u16len = ((u16len & 0x7f) << 8) + bb.readUint8();
413
- }
414
-
415
- var u8len = bb.readUint8();
416
- if ((u8len & 0x80) != 0) {
417
- u8len = ((u8len & 0x7f) << 8) + bb.readUint8();
418
- }
419
-
420
- if (u8len > 0) {
421
- buffer = ResourceFinder.readBytes(bb, u8len);
422
- try {
423
- strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
424
- } catch (e) {
425
- if (DEBUG) {
426
- console.error(e);
427
- console.log('Error when turning buffer to utf-8 string.');
428
- }
429
- }
430
- } else {
431
- strings[i] = '';
432
- }
433
- } else {
434
- u16len = bb.readUint16();
435
- if ((u16len & 0x8000) != 0) {
436
- // larger than 32768
437
- u16len = ((u16len & 0x7fff) << 16) + bb.readUint16();
438
- }
439
-
440
- if (u16len > 0) {
441
- var len = u16len * 2;
442
- buffer = ResourceFinder.readBytes(bb, len);
443
- try {
444
- strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
445
- } catch (e) {
446
- if (DEBUG) {
447
- console.error(e);
448
- console.log('Error when turning buffer to utf-8 string.');
449
- }
450
- }
451
- }
452
- }
453
-
454
- if (DEBUG) {
455
- console.log('Parsed value: {0}', strings[i]);
456
- }
457
- }
458
-
459
- return strings;
460
- };
461
-
462
- /**
463
- *
464
- * @param {ByteBuffer} bb
465
- */
466
- ResourceFinder.prototype.processTypeSpec = function (bb) {
467
- var type = bb.readShort(),
468
- headerSize = bb.readShort(),
469
- size = bb.readInt(),
470
- id = bb.readByte(),
471
- res0 = bb.readByte(),
472
- res1 = bb.readShort(),
473
- entryCount = bb.readInt();
474
-
475
- if (DEBUG) {
476
- console.log('Processing type spec ' + this.typeStringPool[id - 1] + '...');
477
- }
478
-
479
- var flags = new Array(entryCount);
480
-
481
- for (var i = 0; i < entryCount; ++i) {
482
- flags[i] = bb.readInt();
483
- }
484
- };
485
-
486
- ResourceFinder.prototype.putIntoMap = function (resId, value) {
487
- if (this.responseMap[resId.toUpperCase()] == null) {
488
- this.responseMap[resId.toUpperCase()] = [];
489
- }
490
- if (value) {
491
- this.responseMap[resId.toUpperCase()].push(value);
492
- }
493
- };
494
-
495
- module.exports = ResourceFinder;
@@ -1,172 +0,0 @@
1
- function objectType(o) {
2
- return Object.prototype.toString.call(o).slice(8, -1).toLowerCase();
3
- }
4
-
5
- function isArray(o) {
6
- return objectType(o) === 'array';
7
- }
8
-
9
- function isObject(o) {
10
- return objectType(o) === 'object';
11
- }
12
-
13
- function isPrimitive(o) {
14
- return (
15
- o === null ||
16
- ['boolean', 'number', 'string', 'undefined'].includes(objectType(o))
17
- );
18
- }
19
-
20
- function isBrowser() {
21
- return (
22
- typeof process === 'undefined' ||
23
- Object.prototype.toString.call(process) !== '[object process]'
24
- );
25
- }
26
-
27
- /**
28
- * map file place with resourceMap
29
- * @param {Object} apkInfo // json info parsed from .apk file
30
- * @param {Object} resourceMap // resourceMap
31
- */
32
- function mapInfoResource(apkInfo, resourceMap) {
33
- iteratorObj(apkInfo);
34
- return apkInfo;
35
- function iteratorObj(obj) {
36
- for (const i in obj) {
37
- if (isArray(obj[i])) {
38
- iteratorArray(obj[i]);
39
- } else if (isObject(obj[i])) {
40
- iteratorObj(obj[i]);
41
- } else if (isPrimitive(obj[i])) {
42
- if (isResources(obj[i])) {
43
- obj[i] = resourceMap[transKeyToMatchResourceMap(obj[i])];
44
- }
45
- }
46
- }
47
- }
48
-
49
- function iteratorArray(array) {
50
- const l = array.length;
51
- for (let i = 0; i < l; i++) {
52
- if (isArray(array[i])) {
53
- iteratorArray(array[i]);
54
- } else if (isObject(array[i])) {
55
- iteratorObj(array[i]);
56
- } else if (isPrimitive(array[i])) {
57
- if (isResources(array[i])) {
58
- array[i] = resourceMap[transKeyToMatchResourceMap(array[i])];
59
- }
60
- }
61
- }
62
- }
63
-
64
- function isResources(attrValue) {
65
- if (!attrValue) return false;
66
- if (typeof attrValue !== 'string') {
67
- attrValue = attrValue.toString();
68
- }
69
- return attrValue.indexOf('resourceId:') === 0;
70
- }
71
-
72
- function transKeyToMatchResourceMap(resourceId) {
73
- return '@' + resourceId.replace('resourceId:0x', '').toUpperCase();
74
- }
75
- }
76
-
77
- /**
78
- * find .apk file's icon path from json info
79
- * @param info // json info parsed from .apk file
80
- */
81
- function findApkIconPath(info) {
82
- if (!info.application.icon || !info.application.icon.splice) {
83
- return '';
84
- }
85
- const rulesMap = {
86
- mdpi: 48,
87
- hdpi: 72,
88
- xhdpi: 96,
89
- xxdpi: 144,
90
- xxxhdpi: 192,
91
- };
92
- const resultMap = {};
93
- const maxDpiIcon = { dpi: 120, icon: '' };
94
-
95
- for (const i in rulesMap) {
96
- info.application.icon.some((icon) => {
97
- if (icon && icon.indexOf(i) !== -1) {
98
- resultMap['application-icon-' + rulesMap[i]] = icon;
99
- return true;
100
- }
101
- });
102
-
103
- // get the maximal size icon
104
- if (
105
- resultMap['application-icon-' + rulesMap[i]] &&
106
- rulesMap[i] >= maxDpiIcon.dpi
107
- ) {
108
- maxDpiIcon.dpi = rulesMap[i];
109
- maxDpiIcon.icon = resultMap['application-icon-' + rulesMap[i]];
110
- }
111
- }
112
-
113
- if (Object.keys(resultMap).length === 0 || !maxDpiIcon.icon) {
114
- maxDpiIcon.dpi = 120;
115
- maxDpiIcon.icon = info.application.icon[0] || '';
116
- resultMap['applicataion-icon-120'] = maxDpiIcon.icon;
117
- }
118
- return maxDpiIcon.icon;
119
- }
120
-
121
- /**
122
- * find .ipa file's icon path from json info
123
- * @param info // json info parsed from .ipa file
124
- */
125
- function findIpaIconPath(info) {
126
- if (
127
- info.CFBundleIcons &&
128
- info.CFBundleIcons.CFBundlePrimaryIcon &&
129
- info.CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles &&
130
- info.CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles.length
131
- ) {
132
- return info.CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles[
133
- info.CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles.length - 1
134
- ];
135
- } else if (info.CFBundleIconFiles && info.CFBundleIconFiles.length) {
136
- return info.CFBundleIconFiles[info.CFBundleIconFiles.length - 1];
137
- } else {
138
- return '.app/Icon.png';
139
- }
140
- }
141
-
142
- /**
143
- * transform buffer to base64
144
- * @param {Buffer} buffer
145
- */
146
- function getBase64FromBuffer(buffer) {
147
- return 'data:image/png;base64,' + buffer.toString('base64');
148
- }
149
-
150
- /**
151
- * 去除unicode空字符
152
- * @param {String} str
153
- */
154
- function decodeNullUnicode(str) {
155
- if (typeof str === 'string') {
156
- // eslint-disable-next-line
157
- str = str.replace(/\u0000/g, '');
158
- }
159
- return str;
160
- }
161
-
162
- module.exports = {
163
- isArray,
164
- isObject,
165
- isPrimitive,
166
- isBrowser,
167
- mapInfoResource,
168
- findApkIconPath,
169
- findIpaIconPath,
170
- getBase64FromBuffer,
171
- decodeNullUnicode,
172
- };