rn-update-cli 1.0.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 (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +167 -0
  3. package/README.zh-CN.md +167 -0
  4. package/cli.json +525 -0
  5. package/lib/api.d.ts +56 -0
  6. package/lib/api.js +671 -0
  7. package/lib/app.d.ts +107 -0
  8. package/lib/app.js +329 -0
  9. package/lib/auto-update.d.ts +35 -0
  10. package/lib/auto-update.js +507 -0
  11. package/lib/bin.d.ts +2 -0
  12. package/lib/bin.js +133 -0
  13. package/lib/bundle-pack.d.ts +6 -0
  14. package/lib/bundle-pack.js +91 -0
  15. package/lib/bundle-runner.d.ts +168 -0
  16. package/lib/bundle-runner.js +1305 -0
  17. package/lib/bundle.d.ts +45 -0
  18. package/lib/bundle.js +226 -0
  19. package/lib/cache.d.ts +10 -0
  20. package/lib/cache.js +25 -0
  21. package/lib/commands.d.ts +11 -0
  22. package/lib/commands.js +72 -0
  23. package/lib/diff.d.ts +18 -0
  24. package/lib/diff.js +690 -0
  25. package/lib/exports.d.ts +11 -0
  26. package/lib/exports.js +20 -0
  27. package/lib/install.d.ts +9 -0
  28. package/lib/install.js +51 -0
  29. package/lib/locales/en.d.ts +187 -0
  30. package/lib/locales/en.js +194 -0
  31. package/lib/locales/zh.d.ts +187 -0
  32. package/lib/locales/zh.js +194 -0
  33. package/lib/native-package.d.ts +21 -0
  34. package/lib/native-package.js +298 -0
  35. package/lib/package.d.ts +68 -0
  36. package/lib/package.js +487 -0
  37. package/lib/provider.d.ts +24 -0
  38. package/lib/provider.js +244 -0
  39. package/lib/standalone-publish.d.ts +17 -0
  40. package/lib/standalone-publish.js +433 -0
  41. package/lib/symbolicate.d.ts +35 -0
  42. package/lib/symbolicate.js +130 -0
  43. package/lib/types.d.ts +152 -0
  44. package/lib/types.js +2 -0
  45. package/lib/user.d.ts +8 -0
  46. package/lib/user.js +50 -0
  47. package/lib/utils/add-gitignore.d.ts +6 -0
  48. package/lib/utils/add-gitignore.js +44 -0
  49. package/lib/utils/app-info-parser/aab.d.ts +27 -0
  50. package/lib/utils/app-info-parser/aab.js +256 -0
  51. package/lib/utils/app-info-parser/apk.d.ts +19 -0
  52. package/lib/utils/app-info-parser/apk.js +95 -0
  53. package/lib/utils/app-info-parser/app.d.ts +9 -0
  54. package/lib/utils/app-info-parser/app.js +15 -0
  55. package/lib/utils/app-info-parser/index.d.ts +21 -0
  56. package/lib/utils/app-info-parser/index.js +51 -0
  57. package/lib/utils/app-info-parser/ipa.d.ts +19 -0
  58. package/lib/utils/app-info-parser/ipa.js +101 -0
  59. package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
  60. package/lib/utils/app-info-parser/resource-finder.js +429 -0
  61. package/lib/utils/app-info-parser/utils.d.ts +36 -0
  62. package/lib/utils/app-info-parser/utils.js +140 -0
  63. package/lib/utils/app-info-parser/xml-parser/binary.d.ts +61 -0
  64. package/lib/utils/app-info-parser/xml-parser/binary.js +577 -0
  65. package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +15 -0
  66. package/lib/utils/app-info-parser/xml-parser/manifest.js +207 -0
  67. package/lib/utils/app-info-parser/zip.d.ts +29 -0
  68. package/lib/utils/app-info-parser/zip.js +97 -0
  69. package/lib/utils/check-lockfile.d.ts +6 -0
  70. package/lib/utils/check-lockfile.js +93 -0
  71. package/lib/utils/check-plugin.d.ts +12 -0
  72. package/lib/utils/check-plugin.js +36 -0
  73. package/lib/utils/command-result.d.ts +8 -0
  74. package/lib/utils/command-result.js +27 -0
  75. package/lib/utils/constants.d.ts +10 -0
  76. package/lib/utils/constants.js +39 -0
  77. package/lib/utils/dep-versions.d.ts +20 -0
  78. package/lib/utils/dep-versions.js +129 -0
  79. package/lib/utils/git.d.ts +14 -0
  80. package/lib/utils/git.js +64 -0
  81. package/lib/utils/hbcTransform.d.ts +111 -0
  82. package/lib/utils/hbcTransform.js +561 -0
  83. package/lib/utils/hermes-base.d.ts +227 -0
  84. package/lib/utils/hermes-base.js +1287 -0
  85. package/lib/utils/hermes-literals.d.ts +64 -0
  86. package/lib/utils/hermes-literals.js +260 -0
  87. package/lib/utils/http-helper.d.ts +10 -0
  88. package/lib/utils/http-helper.js +150 -0
  89. package/lib/utils/i18n.d.ts +22 -0
  90. package/lib/utils/i18n.js +46 -0
  91. package/lib/utils/index.d.ts +67 -0
  92. package/lib/utils/index.js +545 -0
  93. package/lib/utils/latest-version/index.d.ts +154 -0
  94. package/lib/utils/latest-version/index.js +331 -0
  95. package/lib/utils/options.d.ts +10 -0
  96. package/lib/utils/options.js +68 -0
  97. package/lib/utils/plugin-config.d.ts +14 -0
  98. package/lib/utils/plugin-config.js +66 -0
  99. package/lib/utils/runtime.d.ts +54 -0
  100. package/lib/utils/runtime.js +263 -0
  101. package/lib/utils/slim-sourcemap.d.ts +28 -0
  102. package/lib/utils/slim-sourcemap.js +106 -0
  103. package/lib/utils/zip-entries.d.ts +10 -0
  104. package/lib/utils/zip-entries.js +211 -0
  105. package/lib/utils/zip-options.d.ts +17 -0
  106. package/lib/utils/zip-options.js +190 -0
  107. package/lib/utils/zip-range.d.ts +148 -0
  108. package/lib/utils/zip-range.js +581 -0
  109. package/lib/utils/zip-raw-writer.d.ts +52 -0
  110. package/lib/utils/zip-raw-writer.js +209 -0
  111. package/lib/version-operations.d.ts +21 -0
  112. package/lib/version-operations.js +320 -0
  113. package/lib/versions.d.ts +66 -0
  114. package/lib/versions.js +402 -0
  115. package/package.json +113 -0
  116. package/proto/Configuration.proto +183 -0
  117. package/proto/Resources.proto +569 -0
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * [INPUT]: 依赖通用 Zip 容器读取能力
4
+ * [OUTPUT]: 对外提供 AppParser,处理 macOS .app 包的通用归档边界
5
+ * [POS]: 应用包解析子域的轻量 fallback,实现与平台特定解析器一致的 parse 接口
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.AppParser = void 0;
9
+ const zip_1 = require("./zip");
10
+ class AppParser extends zip_1.Zip {
11
+ async parse() {
12
+ return {};
13
+ }
14
+ }
15
+ exports.AppParser = AppParser;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * [INPUT]: 依赖 AAB、APK、APP、IPA 四类平台包解析器与支持类型判定
3
+ * [OUTPUT]: 对外提供默认 AppInfoParser,按文件类型路由到具体解析器
4
+ * [POS]: 应用包解析子域的统一入口,隔离调用方与各平台归档格式差异
5
+ */
6
+ import { AabParser } from './aab';
7
+ import { ApkParser } from './apk';
8
+ import { AppParser } from './app';
9
+ import { IpaParser } from './ipa';
10
+ type AppInfoInnerParser = AabParser | ApkParser | AppParser | IpaParser;
11
+ declare class AppInfoParser {
12
+ file: string | File;
13
+ parser: AppInfoInnerParser;
14
+ /**
15
+ * parser for parsing .ipa or .apk file
16
+ * @param {String | File} file // file's path in Node, instance of File in Browser
17
+ */
18
+ constructor(file: string | File);
19
+ parse<T = unknown>(): Promise<T>;
20
+ }
21
+ export default AppInfoParser;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * [INPUT]: 依赖 AAB、APK、APP、IPA 四类平台包解析器与支持类型判定
4
+ * [OUTPUT]: 对外提供默认 AppInfoParser,按文件类型路由到具体解析器
5
+ * [POS]: 应用包解析子域的统一入口,隔离调用方与各平台归档格式差异
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const aab_1 = require("./aab");
9
+ const apk_1 = require("./apk");
10
+ const app_1 = require("./app");
11
+ const ipa_1 = require("./ipa");
12
+ const supportFileTypes = ['ipa', 'apk', 'app', 'aab'];
13
+ class AppInfoParser {
14
+ file;
15
+ parser;
16
+ /**
17
+ * parser for parsing .ipa or .apk file
18
+ * @param {String | File} file // file's path in Node, instance of File in Browser
19
+ */
20
+ constructor(file) {
21
+ if (!file) {
22
+ throw new Error("Param miss: file(file's path in Node, instance of File in browser).");
23
+ }
24
+ const splits = (typeof file === 'string' ? file : file.name).split('.');
25
+ const fileType = splits[splits.length - 1].toLowerCase();
26
+ if (!supportFileTypes.includes(fileType)) {
27
+ throw new Error('Unsupported file type, only support .ipa, .apk, .app, or .aab file.');
28
+ }
29
+ this.file = file;
30
+ switch (fileType) {
31
+ case 'ipa':
32
+ this.parser = new ipa_1.IpaParser(this.file);
33
+ break;
34
+ case 'apk':
35
+ this.parser = new apk_1.ApkParser(this.file);
36
+ break;
37
+ case 'app':
38
+ this.parser = new app_1.AppParser(this.file);
39
+ break;
40
+ case 'aab':
41
+ this.parser = new aab_1.AabParser(this.file);
42
+ break;
43
+ default:
44
+ throw new Error('Unsupported parser file type.');
45
+ }
46
+ }
47
+ parse() {
48
+ return this.parser.parse();
49
+ }
50
+ }
51
+ exports.default = AppInfoParser;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * [INPUT]: 依赖 bplist/cgbi 解码、IPA ZIP、图标资源和平台元数据解析工具
3
+ * [OUTPUT]: 对外提供 IpaParser,提取 iOS 应用的版本、标识和图标信息
4
+ * [POS]: 应用包解析子域的 IPA 实现,兼容压缩 PNG 与 binary plist 变体
5
+ */
6
+ import { Zip } from './zip';
7
+ export declare class IpaParser extends Zip {
8
+ parse(): Promise<any>;
9
+ /**
10
+ * Parse plist
11
+ * @param {Buffer} buffer // plist file's buffer
12
+ */
13
+ private _parsePlist;
14
+ /**
15
+ * parse provision
16
+ * @param {Buffer} buffer // provision file's buffer
17
+ */
18
+ private _parseProvision;
19
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * [INPUT]: 依赖 bplist/cgbi 解码、IPA ZIP、图标资源和平台元数据解析工具
4
+ * [OUTPUT]: 对外提供 IpaParser,提取 iOS 应用的版本、标识和图标信息
5
+ * [POS]: 应用包解析子域的 IPA 实现,兼容压缩 PNG 与 binary plist 变体
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.IpaParser = void 0;
9
+ const parseBplist = require('bplist-parser').parseBuffer;
10
+ const cgbiToPng = require('cgbi-to-png');
11
+ const utils_1 = require("./utils");
12
+ const zip_1 = require("./zip");
13
+ const PlistName = /payload\/[^/]+?.app\/info.plist$/i;
14
+ const ProvisionName = /payload\/.+?\.app\/embedded.mobileprovision/;
15
+ let parsePlistPromise;
16
+ function loadParsePlist() {
17
+ if (!parsePlistPromise) {
18
+ parsePlistPromise = Promise.resolve().then(async () => {
19
+ try {
20
+ return require('plist').parse;
21
+ }
22
+ catch (requireError) {
23
+ const importModule = new Function('specifier', 'return import(specifier)');
24
+ const plistModule = await importModule('plist');
25
+ const parsePlist = plistModule.parse ?? plistModule.default?.parse;
26
+ if (!parsePlist) {
27
+ throw requireError;
28
+ }
29
+ return parsePlist;
30
+ }
31
+ });
32
+ }
33
+ return parsePlistPromise;
34
+ }
35
+ class IpaParser extends zip_1.Zip {
36
+ async parse() {
37
+ const parsePlist = await loadParsePlist();
38
+ const buffers = await this.getEntries([PlistName, ProvisionName]);
39
+ if (!buffers[PlistName]) {
40
+ throw new Error("Info.plist can't be found.");
41
+ }
42
+ const plistInfo = this._parsePlist(buffers[PlistName], parsePlist);
43
+ const provisionInfo = this._parseProvision(buffers[ProvisionName], parsePlist);
44
+ plistInfo.mobileProvision = provisionInfo;
45
+ const iconRegex = new RegExp((0, utils_1.findIpaIconPath)(plistInfo).toLowerCase());
46
+ const iconBuffer = await this.getEntry(iconRegex);
47
+ try {
48
+ plistInfo.icon = iconBuffer
49
+ ? (0, utils_1.getBase64FromBuffer)(cgbiToPng.revert(iconBuffer))
50
+ : null;
51
+ }
52
+ catch (err) {
53
+ if ((0, utils_1.isBrowser)()) {
54
+ plistInfo.icon = iconBuffer
55
+ ? (0, utils_1.getBase64FromBuffer)(window.btoa(String.fromCharCode(...iconBuffer)))
56
+ : null;
57
+ }
58
+ else {
59
+ plistInfo.icon = null;
60
+ console.warn('[Warning] failed to parse icon: ', err);
61
+ }
62
+ }
63
+ return plistInfo;
64
+ }
65
+ /**
66
+ * Parse plist
67
+ * @param {Buffer} buffer // plist file's buffer
68
+ */
69
+ _parsePlist(buffer, parsePlist) {
70
+ let result;
71
+ const bufferType = buffer[0];
72
+ if (bufferType === 60 || bufferType === 239) {
73
+ result = parsePlist(buffer.toString());
74
+ }
75
+ else if (bufferType === 98) {
76
+ result = parseBplist(buffer)[0];
77
+ }
78
+ else {
79
+ throw new Error('Unknown plist buffer type.');
80
+ }
81
+ return result;
82
+ }
83
+ /**
84
+ * parse provision
85
+ * @param {Buffer} buffer // provision file's buffer
86
+ */
87
+ _parseProvision(buffer, parsePlist) {
88
+ let info = {};
89
+ if (buffer) {
90
+ let content = buffer.toString('utf-8');
91
+ const firstIndex = content.indexOf('<?xml');
92
+ const endIndex = content.indexOf('</plist>');
93
+ content = content.slice(firstIndex, endIndex + 8);
94
+ if (content) {
95
+ info = parsePlist(content);
96
+ }
97
+ }
98
+ return info;
99
+ }
100
+ }
101
+ exports.IpaParser = IpaParser;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * [INPUT]: 依赖 bytebuffer 与 Android resources.arsc 二进制资源表格式
3
+ * [OUTPUT]: 对外提供 ResourceFinder,按资源标识解析包内字符串和图标引用
4
+ * [POS]: Android 资源解析底座,被 ApkParser/AabParser 消费,不负责 ZIP 生命周期
5
+ */
6
+ export declare class ResourceFinder {
7
+ private valueStringPool;
8
+ private typeStringPool;
9
+ private keyStringPool;
10
+ private packageId;
11
+ private responseMap;
12
+ private entryMap;
13
+ /**
14
+ * Same to C# BinaryReader.readBytes
15
+ *
16
+ * @param bb ByteBuffer
17
+ * @param len length
18
+ * @returns {Buffer}
19
+ */
20
+ static readBytes(bb: any, len: number): any;
21
+ /**
22
+ *
23
+ * @param {ByteBuffer} bb
24
+ * @return {Map<String, Set<String>>}
25
+ */
26
+ processResourceTable(resourceBuffer: Buffer): Record<string, any[]>;
27
+ /**
28
+ *
29
+ * @param {ByteBuffer} bb
30
+ */
31
+ private processPackage;
32
+ /**
33
+ *
34
+ * @param {ByteBuffer} bb
35
+ */
36
+ private processType;
37
+ /**
38
+ *
39
+ * @param {ByteBuffer} bb
40
+ * @return {Array}
41
+ */
42
+ private processStringPool;
43
+ /**
44
+ *
45
+ * @param {ByteBuffer} bb
46
+ */
47
+ private processTypeSpec;
48
+ private putIntoMap;
49
+ }
@@ -0,0 +1,429 @@
1
+ "use strict";
2
+ /**
3
+ * [INPUT]: 依赖 bytebuffer 与 Android resources.arsc 二进制资源表格式
4
+ * [OUTPUT]: 对外提供 ResourceFinder,按资源标识解析包内字符串和图标引用
5
+ * [POS]: Android 资源解析底座,被 ApkParser/AabParser 消费,不负责 ZIP 生命周期
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.ResourceFinder = void 0;
9
+ /**
10
+ * Code translated from a C# project https://github.com/hylander0/Iteedee.ApkReader/blob/master/Iteedee.ApkReader/ApkResourceFinder.cs
11
+ *
12
+ * Decode binary file `resources.arsc` from a .apk file to a JavaScript Object.
13
+ */
14
+ const ByteBuffer = require('bytebuffer');
15
+ const DEBUG = false;
16
+ const RES_STRING_POOL_TYPE = 0x0001;
17
+ const RES_TABLE_TYPE = 0x0002;
18
+ const RES_TABLE_PACKAGE_TYPE = 0x0200;
19
+ const RES_TABLE_TYPE_TYPE = 0x0201;
20
+ const RES_TABLE_TYPE_SPEC_TYPE = 0x0202;
21
+ const TYPE_REFERENCE = 0x01;
22
+ const TYPE_STRING = 0x03;
23
+ class ResourceFinder {
24
+ valueStringPool = null;
25
+ typeStringPool = null;
26
+ keyStringPool = null;
27
+ packageId = 0;
28
+ responseMap = {};
29
+ entryMap = {};
30
+ /**
31
+ * Same to C# BinaryReader.readBytes
32
+ *
33
+ * @param bb ByteBuffer
34
+ * @param len length
35
+ * @returns {Buffer}
36
+ */
37
+ static readBytes(bb, len) {
38
+ const uint8Array = new Uint8Array(len);
39
+ for (let i = 0; i < len; i++) {
40
+ uint8Array[i] = bb.readUint8();
41
+ }
42
+ return ByteBuffer.wrap(uint8Array, 'binary', true);
43
+ }
44
+ /**
45
+ *
46
+ * @param {ByteBuffer} bb
47
+ * @return {Map<String, Set<String>>}
48
+ */
49
+ processResourceTable(resourceBuffer) {
50
+ const bb = ByteBuffer.wrap(resourceBuffer, 'binary', true);
51
+ const type = bb.readShort();
52
+ const headerSize = bb.readShort();
53
+ const size = bb.readInt();
54
+ const packageCount = bb.readInt();
55
+ let buffer;
56
+ let bb2;
57
+ if (type !== RES_TABLE_TYPE) {
58
+ throw new Error('No RES_TABLE_TYPE found!');
59
+ }
60
+ if (size !== bb.limit) {
61
+ throw new Error('The buffer size not matches to the resource table size.');
62
+ }
63
+ bb.offset = headerSize;
64
+ let realStringPoolCount = 0;
65
+ let realPackageCount = 0;
66
+ while (true) {
67
+ let pos = 0;
68
+ let t = 0;
69
+ let _hs = 0;
70
+ let s = 0;
71
+ try {
72
+ pos = bb.offset;
73
+ t = bb.readShort();
74
+ _hs = bb.readShort();
75
+ s = bb.readInt();
76
+ }
77
+ catch (_e) {
78
+ break;
79
+ }
80
+ if (t === RES_STRING_POOL_TYPE) {
81
+ if (realStringPoolCount === 0) {
82
+ if (DEBUG) {
83
+ console.log('Processing the string pool ...');
84
+ }
85
+ buffer = new ByteBuffer(s);
86
+ bb.offset = pos;
87
+ bb.prependTo(buffer);
88
+ bb2 = ByteBuffer.wrap(buffer, 'binary', true);
89
+ bb2.LE();
90
+ this.valueStringPool = this.processStringPool(bb2);
91
+ }
92
+ realStringPoolCount++;
93
+ }
94
+ else if (t === RES_TABLE_PACKAGE_TYPE) {
95
+ if (DEBUG) {
96
+ console.log(`Processing the package ${realPackageCount} ...`);
97
+ }
98
+ buffer = new ByteBuffer(s);
99
+ bb.offset = pos;
100
+ bb.prependTo(buffer);
101
+ bb2 = ByteBuffer.wrap(buffer, 'binary', true);
102
+ bb2.LE();
103
+ this.processPackage(bb2);
104
+ realPackageCount++;
105
+ }
106
+ else {
107
+ throw new Error('Unsupported type');
108
+ }
109
+ bb.offset = pos + s;
110
+ if (!bb.remaining())
111
+ break;
112
+ }
113
+ if (realStringPoolCount !== 1) {
114
+ throw new Error('More than 1 string pool found!');
115
+ }
116
+ if (realPackageCount !== packageCount) {
117
+ throw new Error('Real package count not equals the declared count.');
118
+ }
119
+ return this.responseMap;
120
+ }
121
+ /**
122
+ *
123
+ * @param {ByteBuffer} bb
124
+ */
125
+ processPackage(bb) {
126
+ const type = bb.readShort();
127
+ const headerSize = bb.readShort();
128
+ const size = bb.readInt();
129
+ const id = bb.readInt();
130
+ void type;
131
+ void size;
132
+ this.packageId = id;
133
+ for (let i = 0; i < 256; ++i) {
134
+ bb.readUint8();
135
+ }
136
+ const typeStrings = bb.readInt();
137
+ const lastPublicType = bb.readInt();
138
+ const keyStrings = bb.readInt();
139
+ const lastPublicKey = bb.readInt();
140
+ void lastPublicType;
141
+ void lastPublicKey;
142
+ if (typeStrings !== headerSize) {
143
+ throw new Error('TypeStrings must immediately following the package structure header.');
144
+ }
145
+ if (DEBUG) {
146
+ console.log('Type strings:');
147
+ }
148
+ let lastPosition = bb.offset;
149
+ bb.offset = typeStrings;
150
+ const bbTypeStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
151
+ bb.offset = lastPosition;
152
+ this.typeStringPool = this.processStringPool(bbTypeStrings);
153
+ if (DEBUG) {
154
+ console.log('Key strings:');
155
+ }
156
+ bb.offset = keyStrings;
157
+ const keyType = bb.readShort();
158
+ const keyHeaderSize = bb.readShort();
159
+ const keySize = bb.readInt();
160
+ void keyType;
161
+ void keyHeaderSize;
162
+ lastPosition = bb.offset;
163
+ bb.offset = keyStrings;
164
+ const bbKeyStrings = ResourceFinder.readBytes(bb, bb.limit - bb.offset);
165
+ bb.offset = lastPosition;
166
+ this.keyStringPool = this.processStringPool(bbKeyStrings);
167
+ let typeSpecCount = 0;
168
+ let typeCount = 0;
169
+ bb.offset = keyStrings + keySize;
170
+ let bb2;
171
+ while (true) {
172
+ const pos = bb.offset;
173
+ try {
174
+ const t = bb.readShort();
175
+ const hs = bb.readShort();
176
+ const s = bb.readInt();
177
+ void hs;
178
+ if (t === RES_TABLE_TYPE_SPEC_TYPE) {
179
+ bb.offset = pos;
180
+ bb2 = ResourceFinder.readBytes(bb, s);
181
+ this.processTypeSpec(bb2);
182
+ typeSpecCount++;
183
+ }
184
+ else if (t === RES_TABLE_TYPE_TYPE) {
185
+ bb.offset = pos;
186
+ bb2 = ResourceFinder.readBytes(bb, s);
187
+ this.processType(bb2);
188
+ typeCount++;
189
+ }
190
+ if (s === 0) {
191
+ break;
192
+ }
193
+ bb.offset = pos + s;
194
+ if (!bb.remaining()) {
195
+ break;
196
+ }
197
+ }
198
+ catch (_e) {
199
+ break;
200
+ }
201
+ }
202
+ void typeSpecCount;
203
+ void typeCount;
204
+ }
205
+ /**
206
+ *
207
+ * @param {ByteBuffer} bb
208
+ */
209
+ processType(bb) {
210
+ const type = bb.readShort();
211
+ const headerSize = bb.readShort();
212
+ const size = bb.readInt();
213
+ const id = bb.readByte();
214
+ const res0 = bb.readByte();
215
+ const res1 = bb.readShort();
216
+ const entryCount = bb.readInt();
217
+ const entriesStart = bb.readInt();
218
+ void type;
219
+ void size;
220
+ void res0;
221
+ void res1;
222
+ const refKeys = {};
223
+ const configSize = bb.readInt();
224
+ void configSize;
225
+ bb.offset = headerSize;
226
+ if (headerSize + entryCount * 4 !== entriesStart) {
227
+ throw new Error('HeaderSize, entryCount and entriesStart are not valid.');
228
+ }
229
+ const entryIndices = new Array(entryCount);
230
+ for (let i = 0; i < entryCount; ++i) {
231
+ entryIndices[i] = bb.readInt();
232
+ }
233
+ for (let i = 0; i < entryCount; ++i) {
234
+ if (entryIndices[i] === -1)
235
+ continue;
236
+ const resourceId = (this.packageId << 24) | (id << 16) | i;
237
+ let entrySize = 0;
238
+ let entryFlag = 0;
239
+ let entryKey = 0;
240
+ try {
241
+ entrySize = bb.readShort();
242
+ entryFlag = bb.readShort();
243
+ entryKey = bb.readInt();
244
+ }
245
+ catch (_e) {
246
+ break;
247
+ }
248
+ void entrySize;
249
+ const FLAG_COMPLEX = 0x0001;
250
+ if ((entryFlag & FLAG_COMPLEX) === 0) {
251
+ const valueSize = bb.readShort();
252
+ const valueRes0 = bb.readByte();
253
+ const valueDataType = bb.readByte();
254
+ const valueData = bb.readInt();
255
+ void valueSize;
256
+ void valueRes0;
257
+ const idStr = Number(resourceId).toString(16);
258
+ const keyStr = this.keyStringPool ? this.keyStringPool[entryKey] : '';
259
+ let data = null;
260
+ if (DEBUG) {
261
+ console.log(`Entry 0x${idStr}, key: ${keyStr}, simple value type: `);
262
+ }
263
+ const key = Number.parseInt(idStr, 16);
264
+ const entryArr = this.entryMap[key] ?? [];
265
+ entryArr.push(keyStr);
266
+ this.entryMap[key] = entryArr;
267
+ if (valueDataType === TYPE_STRING) {
268
+ data = this.valueStringPool ? this.valueStringPool[valueData] : null;
269
+ if (DEBUG && this.valueStringPool) {
270
+ console.log(`, data: ${this.valueStringPool[valueData]}`);
271
+ }
272
+ }
273
+ else if (valueDataType === TYPE_REFERENCE) {
274
+ refKeys[idStr] = valueData;
275
+ }
276
+ else {
277
+ data = `${valueData}`;
278
+ if (DEBUG) {
279
+ console.log(`, data: ${valueData}`);
280
+ }
281
+ }
282
+ this.putIntoMap(`@${idStr}`, data);
283
+ }
284
+ else {
285
+ const entryParent = bb.readInt();
286
+ const entryCountValue = bb.readInt();
287
+ void entryParent;
288
+ for (let j = 0; j < entryCountValue; ++j) {
289
+ const refName = bb.readInt();
290
+ const valueSize = bb.readShort();
291
+ const valueRes0 = bb.readByte();
292
+ const valueDataType = bb.readByte();
293
+ const valueData = bb.readInt();
294
+ void refName;
295
+ void valueSize;
296
+ void valueRes0;
297
+ void valueDataType;
298
+ void valueData;
299
+ }
300
+ if (DEBUG) {
301
+ const keyStr = this.keyStringPool ? this.keyStringPool[entryKey] : '';
302
+ console.log(`Entry 0x${Number(resourceId).toString(16)}, key: ${keyStr}, complex value, not printed.`);
303
+ }
304
+ }
305
+ }
306
+ for (const refKey in refKeys) {
307
+ const values = this.responseMap[`@${Number(refKeys[refKey]).toString(16).toUpperCase()}`];
308
+ if (values != null && Object.keys(values).length < 1000) {
309
+ for (const value of values) {
310
+ this.putIntoMap(`@${refKey}`, value);
311
+ }
312
+ }
313
+ }
314
+ }
315
+ /**
316
+ *
317
+ * @param {ByteBuffer} bb
318
+ * @return {Array}
319
+ */
320
+ processStringPool(bb) {
321
+ const type = bb.readShort();
322
+ const headerSize = bb.readShort();
323
+ const size = bb.readInt();
324
+ const stringCount = bb.readInt();
325
+ const styleCount = bb.readInt();
326
+ const flags = bb.readInt();
327
+ const stringsStart = bb.readInt();
328
+ const stylesStart = bb.readInt();
329
+ void type;
330
+ void headerSize;
331
+ void size;
332
+ void styleCount;
333
+ void stylesStart;
334
+ const isUtf8 = (flags & 256) !== 0;
335
+ const offsets = new Array(stringCount);
336
+ for (let i = 0; i < stringCount; ++i) {
337
+ offsets[i] = bb.readInt();
338
+ }
339
+ const strings = new Array(stringCount);
340
+ for (let i = 0; i < stringCount; ++i) {
341
+ const pos = stringsStart + offsets[i];
342
+ bb.offset = pos;
343
+ strings[i] = '';
344
+ if (isUtf8) {
345
+ let u16len = bb.readUint8();
346
+ if ((u16len & 0x80) !== 0) {
347
+ u16len = ((u16len & 0x7f) << 8) + bb.readUint8();
348
+ }
349
+ let u8len = bb.readUint8();
350
+ if ((u8len & 0x80) !== 0) {
351
+ u8len = ((u8len & 0x7f) << 8) + bb.readUint8();
352
+ }
353
+ if (u8len > 0) {
354
+ const buffer = ResourceFinder.readBytes(bb, u8len);
355
+ try {
356
+ strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
357
+ }
358
+ catch (e) {
359
+ if (DEBUG) {
360
+ console.error(e);
361
+ console.log('Error when turning buffer to utf-8 string.');
362
+ }
363
+ }
364
+ }
365
+ else {
366
+ strings[i] = '';
367
+ }
368
+ }
369
+ else {
370
+ let u16len = bb.readUint16();
371
+ if ((u16len & 0x8000) !== 0) {
372
+ u16len = ((u16len & 0x7fff) << 16) + bb.readUint16();
373
+ }
374
+ if (u16len > 0) {
375
+ const len = u16len * 2;
376
+ const buffer = ResourceFinder.readBytes(bb, len);
377
+ try {
378
+ strings[i] = ByteBuffer.wrap(buffer, 'utf8', true).toString('utf8');
379
+ }
380
+ catch (e) {
381
+ if (DEBUG) {
382
+ console.error(e);
383
+ console.log('Error when turning buffer to utf-8 string.');
384
+ }
385
+ }
386
+ }
387
+ }
388
+ if (DEBUG) {
389
+ console.log('Parsed value: {0}', strings[i]);
390
+ }
391
+ }
392
+ return strings;
393
+ }
394
+ /**
395
+ *
396
+ * @param {ByteBuffer} bb
397
+ */
398
+ processTypeSpec(bb) {
399
+ const type = bb.readShort();
400
+ const headerSize = bb.readShort();
401
+ const size = bb.readInt();
402
+ const id = bb.readByte();
403
+ const res0 = bb.readByte();
404
+ const res1 = bb.readShort();
405
+ const entryCount = bb.readInt();
406
+ void type;
407
+ void headerSize;
408
+ void size;
409
+ void res0;
410
+ void res1;
411
+ if (DEBUG && this.typeStringPool) {
412
+ console.log(`Processing type spec ${this.typeStringPool[id - 1]}...`);
413
+ }
414
+ const flags = new Array(entryCount);
415
+ for (let i = 0; i < entryCount; ++i) {
416
+ flags[i] = bb.readInt();
417
+ }
418
+ }
419
+ putIntoMap(resId, value) {
420
+ const key = resId.toUpperCase();
421
+ if (this.responseMap[key] == null) {
422
+ this.responseMap[key] = [];
423
+ }
424
+ if (value) {
425
+ this.responseMap[key].push(value);
426
+ }
427
+ }
428
+ }
429
+ exports.ResourceFinder = ResourceFinder;